commit 25c8be1dce0cb13087483c4e1090cf93e18efc78 Author: Mario Fetka Date: Fri May 19 22:22:40 2017 +0200 Imported Upstream version 3.5.1.dfsg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca81938 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..a58855c --- /dev/null +++ b/Changelog @@ -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 ) +* 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$, $_SERVICE, or $_CONTACT$. + 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 + + + + diff --git a/INSTALLING b/INSTALLING new file mode 100644 index 0000000..e17ba49 --- /dev/null +++ b/INSTALLING @@ -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! + + + diff --git a/LEGAL b/LEGAL new file mode 100644 index 0000000..278eeee --- /dev/null +++ b/LEGAL @@ -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). + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2ba72d5 --- /dev/null +++ b/LICENSE @@ -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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..5cc7f81 --- /dev/null +++ b/Makefile.in @@ -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 diff --git a/OutputTrap.pm b/OutputTrap.pm new file mode 100644 index 0000000..73eac36 --- /dev/null +++ b/OutputTrap.pm @@ -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__ diff --git a/README b/README new file mode 100644 index 0000000..0e7de62 --- /dev/null +++ b/README @@ -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) + + diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..b7c666e --- /dev/null +++ b/THANKS @@ -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 diff --git a/UPGRADING b/UPGRADING new file mode 100644 index 0000000..2b97924 --- /dev/null +++ b/UPGRADING @@ -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) + + + + + + diff --git a/base/.gitignore b/base/.gitignore new file mode 100644 index 0000000..84e0544 --- /dev/null +++ b/base/.gitignore @@ -0,0 +1,3 @@ +*.o +nagios +nagiostats diff --git a/base/Makefile.in b/base/Makefile.in new file mode 100644 index 0000000..868e1d1 --- /dev/null +++ b/base/Makefile.in @@ -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@ diff --git a/base/broker.c b/base/broker.c new file mode 100644 index 0000000..0d3adef --- /dev/null +++ b/base/broker.c @@ -0,0 +1,1017 @@ +/***************************************************************************** + * + * BROKER.C - Event broker routines for Nagios + * + * Copyright (c) 2010 Nagios Core Development Team + * Copyright (c) 2002-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-03-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/nagios.h" +#include "../include/broker.h" +#include "../include/nebcallbacks.h" +#include "../include/nebstructs.h" +#include "../include/nebmods.h" + +extern unsigned long event_broker_options; + +extern time_t program_start; +extern int nagios_pid; +extern int daemon_mode; +extern time_t last_command_check; +extern time_t last_log_rotation; +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int enable_flap_detection; +extern int enable_failure_prediction; +extern int process_performance_data; +extern int aggregate_status_updates; +extern unsigned long modified_host_process_attributes; +extern unsigned long modified_service_process_attributes; +extern char *global_host_event_handler; +extern char *global_service_event_handler; + + +#ifdef USE_EVENT_BROKER + + + +/******************************************************************/ +/************************* EVENT FUNCTIONS ************************/ +/******************************************************************/ + + +/* sends program data (starts, restarts, stops, etc.) to broker */ +void broker_program_state(int type, int flags, int attr, struct timeval *timestamp) { + nebstruct_process_data ds; + + if(!(event_broker_options & BROKER_PROGRAM_STATE)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_PROCESS_DATA, (void *)&ds); + + return; + } + + +/* send timed event data to broker */ +void broker_timed_event(int type, int flags, int attr, timed_event *event, struct timeval *timestamp) { + nebstruct_timed_event_data ds; + + if(!(event_broker_options & BROKER_TIMED_EVENTS)) + return; + + if(event == NULL) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.event_type = event->event_type; + ds.recurring = event->recurring; + ds.run_time = event->run_time; + ds.event_data = event->event_data; + ds.event_ptr = (void *)event; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_TIMED_EVENT_DATA, (void *)&ds); + + return; + } + + + +/* send log data to broker */ +void broker_log_data(int type, int flags, int attr, char *data, unsigned long data_type, time_t entry_time, struct timeval *timestamp) { + nebstruct_log_data ds; + + if(!(event_broker_options & BROKER_LOGGED_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.entry_time = entry_time; + ds.data_type = data_type; + ds.data = data; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_LOG_DATA, (void *)&ds); + + return; + } + + + +/* send system command data to broker */ +void broker_system_command(int type, int flags, int attr, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *cmd, char *output, struct timeval *timestamp) { + nebstruct_system_command_data ds; + + if(!(event_broker_options & BROKER_SYSTEM_COMMANDS)) + return; + + if(cmd == NULL) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.start_time = start_time; + ds.end_time = end_time; + ds.timeout = timeout; + ds.command_line = cmd; + ds.early_timeout = early_timeout; + ds.execution_time = exectime; + ds.return_code = retcode; + ds.output = output; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_SYSTEM_COMMAND_DATA, (void *)&ds); + + return; + } + + + +/* send event handler data to broker */ +int broker_event_handler(int type, int flags, int attr, int eventhandler_type, void *data, int state, int state_type, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *cmd, char *cmdline, char *output, struct timeval *timestamp) { + service *temp_service = NULL; + host *temp_host = NULL; + char *command_buf = NULL; + char *command_name = NULL; + char *command_args = NULL; + nebstruct_event_handler_data ds; + int return_code = OK; + + if(!(event_broker_options & BROKER_EVENT_HANDLERS)) + return return_code; + + if(data == NULL) + return ERROR; + + /* get command name/args */ + if(cmd != NULL) { + command_buf = (char *)strdup(cmd); + command_name = strtok(command_buf, "!"); + command_args = strtok(NULL, "\x0"); + } + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.eventhandler_type = eventhandler_type; + if(eventhandler_type == SERVICE_EVENTHANDLER || eventhandler_type == GLOBAL_SERVICE_EVENTHANDLER) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + } + ds.object_ptr = data; + ds.state = state; + ds.state_type = state_type; + ds.start_time = start_time; + ds.end_time = end_time; + ds.timeout = timeout; + ds.command_name = command_name; + ds.command_args = command_args; + ds.command_line = cmdline; + ds.early_timeout = early_timeout; + ds.execution_time = exectime; + ds.return_code = retcode; + ds.output = output; + + /* make callbacks */ + return_code = neb_make_callbacks(NEBCALLBACK_EVENT_HANDLER_DATA, (void *)&ds); + + /* free memory */ + my_free(command_buf); + + return return_code; + } + + + + +/* send host check data to broker */ +int broker_host_check(int type, int flags, int attr, host *hst, int check_type, int state, int state_type, struct timeval start_time, struct timeval end_time, char *cmd, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, char *output, char *long_output, char *perfdata, struct timeval *timestamp) { + char *command_buf = NULL; + char *command_name = NULL; + char *command_args = NULL; + nebstruct_host_check_data ds; + int return_code = OK; + + if(!(event_broker_options & BROKER_HOST_CHECKS)) + return OK; + + if(hst == NULL) + return ERROR; + + /* get command name/args */ + if(cmd != NULL) { + command_buf = (char *)strdup(cmd); + command_name = strtok(command_buf, "!"); + command_args = strtok(NULL, "\x0"); + } + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.host_name = hst->name; + ds.object_ptr = (void *)hst; + ds.check_type = check_type; + ds.current_attempt = hst->current_attempt; + ds.max_attempts = hst->max_attempts; + ds.state = state; + ds.state_type = state_type; + ds.timeout = timeout; + ds.command_name = command_name; + ds.command_args = command_args; + ds.command_line = cmdline; + ds.start_time = start_time; + ds.end_time = end_time; + ds.early_timeout = early_timeout; + ds.execution_time = exectime; + ds.latency = latency; + ds.return_code = retcode; + ds.output = output; + ds.long_output = long_output; + ds.perf_data = perfdata; + + /* make callbacks */ + return_code = neb_make_callbacks(NEBCALLBACK_HOST_CHECK_DATA, (void *)&ds); + + /* free data */ + my_free(command_buf); + + return return_code; + } + + + +/* send service check data to broker */ +int broker_service_check(int type, int flags, int attr, service *svc, int check_type, struct timeval start_time, struct timeval end_time, char *cmd, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, struct timeval *timestamp) { + char *command_buf = NULL; + char *command_name = NULL; + char *command_args = NULL; + nebstruct_service_check_data ds; + int return_code = OK; + + if(!(event_broker_options & BROKER_SERVICE_CHECKS)) + return OK; + + if(svc == NULL) + return ERROR; + + /* get command name/args */ + if(cmd != NULL) { + command_buf = (char *)strdup(cmd); + command_name = strtok(command_buf, "!"); + command_args = strtok(NULL, "\x0"); + } + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.host_name = svc->host_name; + ds.service_description = svc->description; + ds.object_ptr = (void *)svc; + ds.check_type = check_type; + ds.current_attempt = svc->current_attempt; + ds.max_attempts = svc->max_attempts; + ds.state = svc->current_state; + ds.state_type = svc->state_type; + ds.timeout = timeout; + ds.command_name = command_name; + ds.command_args = command_args; + ds.command_line = cmdline; + ds.start_time = start_time; + ds.end_time = end_time; + ds.early_timeout = early_timeout; + ds.execution_time = exectime; + ds.latency = latency; + ds.return_code = retcode; + ds.output = svc->plugin_output; + ds.long_output = svc->long_plugin_output; + ds.perf_data = svc->perf_data; + + /* make callbacks */ + return_code = neb_make_callbacks(NEBCALLBACK_SERVICE_CHECK_DATA, (void *)&ds); + + /* free data */ + my_free(command_buf); + + return return_code; + } + + + +/* send comment data to broker */ +void broker_comment_data(int type, int flags, int attr, int comment_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, struct timeval *timestamp) { + nebstruct_comment_data ds; + + if(!(event_broker_options & BROKER_COMMENT_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.comment_type = comment_type; + ds.entry_type = entry_type; + ds.host_name = host_name; + ds.service_description = svc_description; + ds.object_ptr = NULL; /* not implemented yet */ + ds.entry_time = entry_time; + ds.author_name = author_name; + ds.comment_data = comment_data; + ds.persistent = persistent; + ds.source = source; + ds.expires = expires; + ds.expire_time = expire_time; + ds.comment_id = comment_id; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_COMMENT_DATA, (void *)&ds); + + return; + } + + + +/* send downtime data to broker */ +void broker_downtime_data(int type, int flags, int attr, int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, struct timeval *timestamp) { + nebstruct_downtime_data ds; + + if(!(event_broker_options & BROKER_DOWNTIME_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.downtime_type = downtime_type; + ds.host_name = host_name; + ds.service_description = svc_description; + ds.object_ptr = NULL; /* not implemented yet */ + ds.entry_time = entry_time; + ds.author_name = author_name; + ds.comment_data = comment_data; + ds.start_time = start_time; + ds.end_time = end_time; + ds.fixed = fixed; + ds.duration = duration; + ds.triggered_by = triggered_by; + ds.downtime_id = downtime_id; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_DOWNTIME_DATA, (void *)&ds); + + return; + } + + + +/* send flapping data to broker */ +void broker_flapping_data(int type, int flags, int attr, int flapping_type, void *data, double percent_change, double high_threshold, double low_threshold, struct timeval *timestamp) { + nebstruct_flapping_data ds; + host *temp_host = NULL; + service *temp_service = NULL; + + if(!(event_broker_options & BROKER_FLAPPING_DATA)) + return; + + if(data == NULL) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.flapping_type = flapping_type; + if(flapping_type == SERVICE_FLAPPING) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + ds.comment_id = temp_service->flapping_comment_id; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + ds.comment_id = temp_host->flapping_comment_id; + } + ds.object_ptr = data; + ds.percent_change = percent_change; + ds.high_threshold = high_threshold; + ds.low_threshold = low_threshold; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_FLAPPING_DATA, (void *)&ds); + + return; + } + + +/* sends program status updates to broker */ +void broker_program_status(int type, int flags, int attr, struct timeval *timestamp) { + nebstruct_program_status_data ds; + + if(!(event_broker_options & BROKER_STATUS_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.program_start = program_start; + ds.pid = nagios_pid; + ds.daemon_mode = daemon_mode; + ds.last_command_check = last_command_check; + ds.last_log_rotation = last_log_rotation; + ds.notifications_enabled = enable_notifications; + ds.active_service_checks_enabled = execute_service_checks; + ds.passive_service_checks_enabled = accept_passive_service_checks; + ds.active_host_checks_enabled = execute_host_checks; + ds.passive_host_checks_enabled = accept_passive_host_checks; + ds.event_handlers_enabled = enable_event_handlers; + ds.flap_detection_enabled = enable_flap_detection; + ds.failure_prediction_enabled = enable_failure_prediction; + ds.process_performance_data = process_performance_data; + ds.obsess_over_hosts = obsess_over_hosts; + ds.obsess_over_services = obsess_over_services; + ds.modified_host_attributes = modified_host_process_attributes; + ds.modified_service_attributes = modified_service_process_attributes; + ds.global_host_event_handler = global_host_event_handler; + ds.global_service_event_handler = global_service_event_handler; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_PROGRAM_STATUS_DATA, (void *)&ds); + + return; + } + + + +/* sends host status updates to broker */ +void broker_host_status(int type, int flags, int attr, host *hst, struct timeval *timestamp) { + nebstruct_host_status_data ds; + + if(!(event_broker_options & BROKER_STATUS_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.object_ptr = (void *)hst; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_HOST_STATUS_DATA, (void *)&ds); + + return; + } + + + +/* sends service status updates to broker */ +void broker_service_status(int type, int flags, int attr, service *svc, struct timeval *timestamp) { + nebstruct_service_status_data ds; + + if(!(event_broker_options & BROKER_STATUS_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.object_ptr = (void *)svc; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_SERVICE_STATUS_DATA, (void *)&ds); + + return; + } + + + +/* sends contact status updates to broker */ +void broker_contact_status(int type, int flags, int attr, contact *cntct, struct timeval *timestamp) { + nebstruct_service_status_data ds; + + if(!(event_broker_options & BROKER_STATUS_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.object_ptr = (void *)cntct; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_CONTACT_STATUS_DATA, (void *)&ds); + + return; + } + + + +/* send notification data to broker */ +int broker_notification_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, char *ack_author, char *ack_data, int escalated, int contacts_notified, struct timeval *timestamp) { + nebstruct_notification_data ds; + host *temp_host = NULL; + service *temp_service = NULL; + int return_code = OK; + + if(!(event_broker_options & BROKER_NOTIFICATIONS)) + return return_code; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.notification_type = notification_type; + ds.start_time = start_time; + ds.end_time = end_time; + ds.reason_type = reason_type; + if(notification_type == SERVICE_NOTIFICATION) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + ds.state = temp_service->current_state; + ds.output = temp_service->plugin_output; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + ds.state = temp_host->current_state; + ds.output = temp_host->plugin_output; + } + ds.object_ptr = data; + ds.ack_author = ack_author; + ds.ack_data = ack_data; + ds.escalated = escalated; + ds.contacts_notified = contacts_notified; + + /* make callbacks */ + return_code = neb_make_callbacks(NEBCALLBACK_NOTIFICATION_DATA, (void *)&ds); + + return return_code; + } + + + +/* send contact notification data to broker */ +int broker_contact_notification_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, contact *cntct, char *ack_author, char *ack_data, int escalated, struct timeval *timestamp) { + nebstruct_contact_notification_data ds; + host *temp_host = NULL; + service *temp_service = NULL; + int return_code = OK; + + if(!(event_broker_options & BROKER_NOTIFICATIONS)) + return return_code; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.notification_type = notification_type; + ds.start_time = start_time; + ds.end_time = end_time; + ds.reason_type = reason_type; + ds.contact_name = cntct->name; + if(notification_type == SERVICE_NOTIFICATION) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + ds.state = temp_service->current_state; + ds.output = temp_service->plugin_output; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + ds.state = temp_host->current_state; + ds.output = temp_host->plugin_output; + } + ds.object_ptr = data; + ds.contact_ptr = (void *)cntct; + ds.ack_author = ack_author; + ds.ack_data = ack_data; + ds.escalated = escalated; + + /* make callbacks */ + return_code = neb_make_callbacks(NEBCALLBACK_CONTACT_NOTIFICATION_DATA, (void *)&ds); + + return return_code; + } + + +/* send contact notification data to broker */ +int broker_contact_notification_method_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, contact *cntct, char *cmd, char *ack_author, char *ack_data, int escalated, struct timeval *timestamp) { + nebstruct_contact_notification_method_data ds; + host *temp_host = NULL; + service *temp_service = NULL; + char *command_buf = NULL; + char *command_name = NULL; + char *command_args = NULL; + int return_code = OK; + + if(!(event_broker_options & BROKER_NOTIFICATIONS)) + return return_code; + + /* get command name/args */ + if(cmd != NULL) { + command_buf = (char *)strdup(cmd); + command_name = strtok(command_buf, "!"); + command_args = strtok(NULL, "\x0"); + } + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.notification_type = notification_type; + ds.start_time = start_time; + ds.end_time = end_time; + ds.reason_type = reason_type; + ds.contact_name = cntct->name; + ds.command_name = command_name; + ds.command_args = command_args; + if(notification_type == SERVICE_NOTIFICATION) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + ds.state = temp_service->current_state; + ds.output = temp_service->plugin_output; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + ds.state = temp_host->current_state; + ds.output = temp_host->plugin_output; + } + ds.object_ptr = data; + ds.contact_ptr = (void *)cntct; + ds.ack_author = ack_author; + ds.ack_data = ack_data; + ds.escalated = escalated; + + /* make callbacks */ + return_code = neb_make_callbacks(NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA, (void *)&ds); + + /* free memory */ + my_free(command_buf); + + return return_code; + } + + +/* sends adaptive programs updates to broker */ +void broker_adaptive_program_data(int type, int flags, int attr, int command_type, unsigned long modhattr, unsigned long modhattrs, unsigned long modsattr, unsigned long modsattrs, struct timeval *timestamp) { + nebstruct_adaptive_program_data ds; + + if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.command_type = command_type; + ds.modified_host_attribute = modhattr; + ds.modified_host_attributes = modhattrs; + ds.modified_service_attribute = modsattr; + ds.modified_service_attributes = modsattrs; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_ADAPTIVE_PROGRAM_DATA, (void *)&ds); + + return; + } + + +/* sends adaptive host updates to broker */ +void broker_adaptive_host_data(int type, int flags, int attr, host *hst, int command_type, unsigned long modattr, unsigned long modattrs, struct timeval *timestamp) { + nebstruct_adaptive_host_data ds; + + if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.command_type = command_type; + ds.modified_attribute = modattr; + ds.modified_attributes = modattrs; + ds.object_ptr = (void *)hst; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_ADAPTIVE_HOST_DATA, (void *)&ds); + + return; + } + + +/* sends adaptive service updates to broker */ +void broker_adaptive_service_data(int type, int flags, int attr, service *svc, int command_type, unsigned long modattr, unsigned long modattrs, struct timeval *timestamp) { + nebstruct_adaptive_service_data ds; + + if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.command_type = command_type; + ds.modified_attribute = modattr; + ds.modified_attributes = modattrs; + ds.object_ptr = (void *)svc; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_ADAPTIVE_SERVICE_DATA, (void *)&ds); + + return; + } + + +/* sends adaptive contact updates to broker */ +void broker_adaptive_contact_data(int type, int flags, int attr, contact *cntct, int command_type, unsigned long modattr, unsigned long modattrs, unsigned long modhattr, unsigned long modhattrs, unsigned long modsattr, unsigned long modsattrs, struct timeval *timestamp) { + nebstruct_adaptive_contact_data ds; + + if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.command_type = command_type; + ds.modified_attribute = modattr; + ds.modified_attributes = modattrs; + ds.modified_host_attribute = modhattr; + ds.modified_host_attributes = modhattrs; + ds.modified_service_attribute = modsattr; + ds.modified_service_attributes = modsattrs; + ds.object_ptr = (void *)cntct; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_ADAPTIVE_CONTACT_DATA, (void *)&ds); + + return; + } + + +/* sends external commands to broker */ +void broker_external_command(int type, int flags, int attr, int command_type, time_t entry_time, char *command_string, char *command_args, struct timeval *timestamp) { + nebstruct_external_command_data ds; + + if(!(event_broker_options & BROKER_EXTERNALCOMMAND_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.command_type = command_type; + ds.entry_time = entry_time; + ds.command_string = command_string; + ds.command_args = command_args; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_EXTERNAL_COMMAND_DATA, (void *)&ds); + + return; + } + + +/* brokers aggregated status dumps */ +void broker_aggregated_status_data(int type, int flags, int attr, struct timeval *timestamp) { + nebstruct_aggregated_status_data ds; + + if(!(event_broker_options & BROKER_STATUS_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_AGGREGATED_STATUS_DATA, (void *)&ds); + + return; + } + + +/* brokers retention data */ +void broker_retention_data(int type, int flags, int attr, struct timeval *timestamp) { + nebstruct_retention_data ds; + + if(!(event_broker_options & BROKER_RETENTION_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_RETENTION_DATA, (void *)&ds); + + return; + } + + +/* send acknowledgement data to broker */ +void broker_acknowledgement_data(int type, int flags, int attr, int acknowledgement_type, void *data, char *ack_author, char *ack_data, int subtype, int notify_contacts, int persistent_comment, struct timeval *timestamp) { + nebstruct_acknowledgement_data ds; + host *temp_host = NULL; + service *temp_service = NULL; + + if(!(event_broker_options & BROKER_ACKNOWLEDGEMENT_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.acknowledgement_type = acknowledgement_type; + if(acknowledgement_type == SERVICE_ACKNOWLEDGEMENT) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + ds.state = temp_service->current_state; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + ds.state = temp_host->current_state; + } + ds.object_ptr = data; + ds.author_name = ack_author; + ds.comment_data = ack_data; + ds.is_sticky = (subtype == ACKNOWLEDGEMENT_STICKY) ? TRUE : FALSE; + ds.notify_contacts = notify_contacts; + ds.persistent_comment = persistent_comment; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_ACKNOWLEDGEMENT_DATA, (void *)&ds); + + return; + } + + +/* send state change data to broker */ +void broker_statechange_data(int type, int flags, int attr, int statechange_type, void *data, int state, int state_type, int current_attempt, int max_attempts, struct timeval *timestamp) { + nebstruct_statechange_data ds; + host *temp_host = NULL; + service *temp_service = NULL; + + if(!(event_broker_options & BROKER_STATECHANGE_DATA)) + return; + + /* fill struct with relevant data */ + ds.type = type; + ds.flags = flags; + ds.attr = attr; + ds.timestamp = get_broker_timestamp(timestamp); + + ds.statechange_type = statechange_type; + if(statechange_type == SERVICE_STATECHANGE) { + temp_service = (service *)data; + ds.host_name = temp_service->host_name; + ds.service_description = temp_service->description; + ds.output = temp_service->plugin_output; + } + else { + temp_host = (host *)data; + ds.host_name = temp_host->name; + ds.service_description = NULL; + ds.output = temp_host->plugin_output; + } + ds.object_ptr = data; + ds.state = state; + ds.state_type = state_type; + ds.current_attempt = current_attempt; + ds.max_attempts = max_attempts; + + /* make callbacks */ + neb_make_callbacks(NEBCALLBACK_STATE_CHANGE_DATA, (void *)&ds); + + return; + } + + + +/******************************************************************/ +/************************ UTILITY FUNCTIONS ***********************/ +/******************************************************************/ + +/* gets timestamp for use by broker */ +struct timeval get_broker_timestamp(struct timeval *timestamp) { + struct timeval tv; + + if(timestamp == NULL) + gettimeofday(&tv, NULL); + else + tv = *timestamp; + + return tv; + } + + + +#endif diff --git a/base/checks.c b/base/checks.c new file mode 100644 index 0000000..df4a092 --- /dev/null +++ b/base/checks.c @@ -0,0 +1,4405 @@ +/***************************************************************************** + * + * CHECKS.C - Service and host check functions for Nagios + * + * Copyright (c) 2011 Nagios Core Development Team + * Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 01-20-2011 + * + * 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/broker.h" +#include "../include/perfdata.h" + +/*#define DEBUG_CHECKS*/ +/*#define DEBUG_HOST_CHECKS 1*/ + + +#ifdef EMBEDDEDPERL +#include "../include/epn_nagios.h" +#endif + +#ifdef USE_EVENT_BROKER +#include "../include/neberrors.h" +#endif + +extern int sigshutdown; +extern int sigrestart; + +extern char *temp_file; +extern char *temp_path; +extern char *check_result_path; + +extern int interval_length; + +extern int command_check_interval; + +extern int log_initial_states; +extern int log_passive_checks; +extern int log_host_retries; + +extern int service_check_timeout; +extern int host_check_timeout; + +extern int check_reaper_interval; +extern int max_check_reaper_time; + +extern int use_aggressive_host_checking; +extern unsigned long cached_host_check_horizon; +extern unsigned long cached_service_check_horizon; +extern int enable_predictive_host_dependency_checks; +extern int enable_predictive_service_dependency_checks; + +extern int soft_state_dependencies; + +extern int currently_running_service_checks; +extern int currently_running_host_checks; + +extern int accept_passive_service_checks; +extern int execute_service_checks; +extern int accept_passive_host_checks; +extern int execute_host_checks; +extern int obsess_over_services; +extern int obsess_over_hosts; + +extern int translate_passive_host_checks; +extern int passive_host_checks_are_soft; + +extern int check_service_freshness; +extern int check_host_freshness; +extern int additional_freshness_latency; + +extern int max_host_check_spread; +extern int max_service_check_spread; + +extern int use_large_installation_tweaks; +extern int free_child_process_memory; +extern int child_processes_fork_twice; + +extern time_t last_program_stop; +extern time_t program_start; +extern time_t event_start; + +extern timed_event *event_list_low; +extern timed_event *event_list_low_tail; + +extern host *host_list; +extern service *service_list; +extern servicedependency *servicedependency_list; +extern hostdependency *hostdependency_list; + +extern unsigned long next_event_id; +extern unsigned long next_problem_id; + +extern check_result check_result_info; +extern check_result *check_result_list; + +extern pthread_t worker_threads[TOTAL_WORKER_THREADS]; + +extern unsigned long max_debug_file_size; + +#ifdef EMBEDDEDPERL +extern int use_embedded_perl; +#endif + + + + + +/******************************************************************/ +/********************** CHECK REAPER FUNCTIONS ********************/ +/******************************************************************/ + +/* reaps host and service check results */ +int reap_check_results(void) { + check_result *queued_check_result = NULL; + service *temp_service = NULL; + host *temp_host = NULL; + time_t current_time = 0L; + time_t reaper_start_time = 0L; + int reaped_checks = 0; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "reap_check_results() start\n"); + log_debug_info(DEBUGL_CHECKS, 0, "Starting to reap check results.\n"); + + /* get the start time */ + time(&reaper_start_time); + + /* process files in the check result queue */ + process_check_result_queue(check_result_path); + + /* read all check results that have come in... */ + while((queued_check_result = read_check_result(&check_result_list))) { + + reaped_checks++; + + log_debug_info(DEBUGL_CHECKS, 2, "Found a check result (#%d) to handle...\n", reaped_checks); + + /* service check */ + if(queued_check_result->object_check_type == SERVICE_CHECK) { + + /* make sure the service exists */ + if((temp_service = find_service(queued_check_result->host_name, queued_check_result->service_description)) == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Check result queue contained results for service '%s' on host '%s', but the service could not be found! Perhaps you forgot to define the service in your config files?\n", queued_check_result->service_description, queued_check_result->host_name); + + /* free memory */ + free_check_result(queued_check_result); + my_free(queued_check_result); + + /* TODO - add new service definition automatically */ + + continue; + } + + log_debug_info(DEBUGL_CHECKS, 1, "Handling check result for service '%s' on host '%s'...\n", temp_service->description, temp_service->host_name); + + /* process the check result */ + handle_async_service_check_result(temp_service, queued_check_result); + } + + /* host check */ + else { + if((temp_host = find_host(queued_check_result->host_name)) == NULL) { + + /* make sure the host exists */ + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Check result queue contained results for host '%s', but the host could not be found! Perhaps you forgot to define the host in your config files?\n", queued_check_result->host_name); + + /* free memory */ + free_check_result(queued_check_result); + my_free(queued_check_result); + + /* TODO - add new host definition automatically */ + + continue; + } + + log_debug_info(DEBUGL_CHECKS, 1, "Handling check result for host '%s'...\n", temp_host->name); + + /* process the check result */ + handle_async_host_check_result_3x(temp_host, queued_check_result); + } + + log_debug_info(DEBUGL_CHECKS | DEBUGL_IPC, 1, "Deleted check result file '%s'\n", queued_check_result->output_file); + + /* free allocated memory */ + free_check_result(queued_check_result); + my_free(queued_check_result); + + /* break out if we've been here too long (max_check_reaper_time seconds) */ + time(¤t_time); + if((int)(current_time - reaper_start_time) > max_check_reaper_time) { + log_debug_info(DEBUGL_CHECKS, 0, "Breaking out of check result reaper: max reaper time exceeded\n"); + break; + } + + /* bail out if we encountered a signal */ + if(sigshutdown == TRUE || sigrestart == TRUE) { + log_debug_info(DEBUGL_CHECKS, 0, "Breaking out of check result reaper: signal encountered\n"); + break; + } + } + + log_debug_info(DEBUGL_CHECKS, 0, "Finished reaping %d check results\n", reaped_checks); + log_debug_info(DEBUGL_FUNCTIONS, 0, "reap_check_results() end\n"); + + return OK; + } + + + + +/******************************************************************/ +/****************** SERVICE MONITORING FUNCTIONS ******************/ +/******************************************************************/ + +/* executes a scheduled service check */ +int run_scheduled_service_check(service *svc, int check_options, double latency) { + int result = OK; + time_t current_time = 0L; + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + int time_is_valid = TRUE; + + if(svc == NULL) + return ERROR; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_scheduled_service_check() start\n"); + log_debug_info(DEBUGL_CHECKS, 0, "Attempting to run scheduled check of service '%s' on host '%s': check options=%d, latency=%lf\n", svc->description, svc->host_name, check_options, latency); + + /* + * reset the next_check_event so we know it's + * no longer in the scheduling queue + */ + svc->next_check_event = NULL; + + /* attempt to run the check */ + result = run_async_service_check(svc, check_options, latency, TRUE, TRUE, &time_is_valid, &preferred_time); + + /* an error occurred, so reschedule the check */ + if(result == ERROR) { + + log_debug_info(DEBUGL_CHECKS, 1, "Unable to run scheduled service check at this time\n"); + + /* only attempt to (re)schedule checks that should get checked... */ + if(svc->should_be_scheduled == TRUE) { + + /* get current time */ + time(¤t_time); + + /* determine next time we should check the service if needed */ + /* if service has no check interval, schedule it again for 5 minutes from now */ + if(current_time >= preferred_time) + preferred_time = current_time + ((svc->check_interval <= 0) ? 300 : (svc->check_interval * interval_length)); + + /* make sure we rescheduled the next service check at a valid time */ + get_next_valid_time(preferred_time, &next_valid_time, svc->check_period_ptr); + + /* + logit(NSLOG_RUNTIME_WARNING,TRUE,"Warning: Service '%s' on host '%s' timeperiod check failed...\n",svc->description,svc->host_name); + logit(NSLOG_RUNTIME_WARNING,TRUE,"Current time: %s",ctime(¤t_time)); + logit(NSLOG_RUNTIME_WARNING,TRUE,"Preferred time: %s",ctime(&preferred_time)); + logit(NSLOG_RUNTIME_WARNING,TRUE,"Next valid time: %s",ctime(&next_valid_time)); + */ + + /* the service could not be rescheduled properly - set the next check time for next week */ + /*if(time_is_valid==FALSE && next_valid_time==preferred_time){*/ + /* UPDATED 08/12/09 EG to reflect proper timeperod check logic */ + if(time_is_valid == FALSE && check_time_against_period(next_valid_time, svc->check_period_ptr) == ERROR) { + + /* + svc->next_check=(time_t)(next_valid_time+(60*60*24*365)); + svc->should_be_scheduled=FALSE; + */ + + svc->next_check = (time_t)(next_valid_time + (60 * 60 * 24 * 7)); + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Check of service '%s' on host '%s' could not be rescheduled properly. Scheduling check for next week...\n", svc->description, svc->host_name); + + log_debug_info(DEBUGL_CHECKS, 1, "Unable to find any valid times to reschedule the next service check!\n"); + } + + /* this service could be rescheduled... */ + else { + svc->next_check = next_valid_time; + svc->should_be_scheduled = TRUE; + + log_debug_info(DEBUGL_CHECKS, 1, "Rescheduled next service check for %s", ctime(&next_valid_time)); + } + } + + /* reschedule the next service check - unless we couldn't find a valid next check time */ + /* 10/19/07 EG - keep original check options */ + if(svc->should_be_scheduled == TRUE) + schedule_service_check(svc, svc->next_check, check_options); + + /* update the status log */ + update_service_status(svc, FALSE); + + return ERROR; + } + + return OK; + } + + +/* forks a child process to run a service check, but does not wait for the service check result */ +int run_async_service_check(service *svc, int check_options, double latency, int scheduled_check, int reschedule_check, int *time_is_valid, time_t *preferred_time) { + nagios_macros mac; + char *raw_command = NULL; + char *processed_command = NULL; + char output_buffer[MAX_INPUT_BUFFER] = ""; + char *temp_buffer = NULL; + struct timeval start_time, end_time; + pid_t pid = 0; + int fork_error = FALSE; + int wait_result = 0; + host *temp_host = NULL; + FILE *fp = NULL; + int pclose_result = 0; + mode_t new_umask = 077; + mode_t old_umask; + char *output_file = NULL; + double old_latency = 0.0; + dbuf checkresult_dbuf; + int dbuf_chunk = 1024; +#ifdef USE_EVENT_BROKER + int neb_result = OK; +#endif +#ifdef EMBEDDEDPERL + char fname[512] = ""; + char *args[5] = {"", DO_CLEAN, "", "", NULL }; + char *perl_plugin_output = NULL; + SV *plugin_hndlr_cr = NULL; + int count ; + int use_epn = FALSE; +#ifdef aTHX + dTHX; +#endif + dSP; +#endif + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_async_service_check()\n"); + + /* make sure we have something */ + if(svc == NULL) + return ERROR; + + /* is the service check viable at this time? */ + if(check_service_check_viability(svc, check_options, time_is_valid, preferred_time) == ERROR) + return ERROR; + + /* find the host associated with this service */ + if((temp_host = svc->host_ptr) == NULL) + return ERROR; + + /******** GOOD TO GO FOR A REAL SERVICE CHECK AT THIS POINT ********/ + +#ifdef USE_EVENT_BROKER + /* initialize start/end times */ + start_time.tv_sec = 0L; + start_time.tv_usec = 0L; + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + + /* send data to event broker */ + neb_result = broker_service_check(NEBTYPE_SERVICECHECK_ASYNC_PRECHECK, NEBFLAG_NONE, NEBATTR_NONE, svc, SERVICE_CHECK_ACTIVE, start_time, end_time, svc->service_check_command, svc->latency, 0.0, 0, FALSE, 0, NULL, NULL); + + /* neb module wants to cancel the service check - the check will be rescheduled for a later time by the scheduling logic */ + if(neb_result == NEBERROR_CALLBACKCANCEL) { + if(preferred_time) + *preferred_time += (svc->check_interval * interval_length); + return ERROR; + } + + /* neb module wants to override (or cancel) the service check - perhaps it will check the service itself */ + /* NOTE: if a module does this, it has to do a lot of the stuff found below to make sure things don't get whacked out of shape! */ + /* NOTE: if would be easier for modules to override checks when the NEBTYPE_SERVICECHECK_INITIATE event is called (later) */ + if(neb_result == NEBERROR_CALLBACKOVERRIDE) + return OK; +#endif + + + log_debug_info(DEBUGL_CHECKS, 0, "Checking service '%s' on host '%s'...\n", svc->description, svc->host_name); + + /* clear check options - we don't want old check options retained */ + /* only clear check options for scheduled checks - ondemand checks shouldn't affected retained check options */ + if(scheduled_check == TRUE) + svc->check_options = CHECK_OPTION_NONE; + + /* update latency for macros, event broker, save old value for later */ + old_latency = svc->latency; + svc->latency = latency; + + /* grab the host and service macro variables */ + 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, svc->check_command_ptr, svc->service_check_command, &raw_command, 0); + if(raw_command == NULL) { + clear_volatile_macros_r(&mac); + log_debug_info(DEBUGL_CHECKS, 0, "Raw check command for service '%s' on host '%s' was NULL - aborting.\n", svc->description, svc->host_name); + if(preferred_time) + *preferred_time += (svc->check_interval * interval_length); + svc->latency = old_latency; + return ERROR; + } + + /* process any macros contained in the argument */ + process_macros_r(&mac, raw_command, &processed_command, 0); + my_free(raw_command); + if(processed_command == NULL) { + clear_volatile_macros_r(&mac); + log_debug_info(DEBUGL_CHECKS, 0, "Processed check command for service '%s' on host '%s' was NULL - aborting.\n", svc->description, svc->host_name); + if(preferred_time) + *preferred_time += (svc->check_interval * interval_length); + svc->latency = old_latency; + return ERROR; + } + + /* get the command start time */ + gettimeofday(&start_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + neb_result = broker_service_check(NEBTYPE_SERVICECHECK_INITIATE, NEBFLAG_NONE, NEBATTR_NONE, svc, SERVICE_CHECK_ACTIVE, start_time, end_time, svc->service_check_command, svc->latency, 0.0, service_check_timeout, FALSE, 0, processed_command, NULL); + + /* neb module wants to override the service check - perhaps it will check the service itself */ + if(neb_result == NEBERROR_CALLBACKOVERRIDE) { + clear_volatile_macros_r(&mac); + svc->latency = old_latency; + my_free(processed_command); + return OK; + } +#endif + + /* increment number of service checks that are currently running... */ + currently_running_service_checks++; + + /* set the execution flag */ + svc->is_executing = TRUE; + + /* start save check info */ + check_result_info.object_check_type = SERVICE_CHECK; + check_result_info.check_type = SERVICE_CHECK_ACTIVE; + check_result_info.check_options = check_options; + check_result_info.scheduled_check = scheduled_check; + check_result_info.reschedule_check = reschedule_check; + check_result_info.start_time = start_time; + check_result_info.finish_time = start_time; + check_result_info.early_timeout = FALSE; + check_result_info.exited_ok = TRUE; + check_result_info.return_code = STATE_OK; + check_result_info.output = NULL; + + /* open a temp file for storing check output */ + old_umask = umask(new_umask); + asprintf(&output_file, "%s/checkXXXXXX", temp_path); + check_result_info.output_file_fd = mkstemp(output_file); + if(check_result_info.output_file_fd >= 0) + check_result_info.output_file_fp = fdopen(check_result_info.output_file_fd, "w"); + else { + check_result_info.output_file_fp = NULL; + check_result_info.output_file_fd = -1; + } + umask(old_umask); + + log_debug_info(DEBUGL_CHECKS | DEBUGL_IPC, 1, "Check result output will be written to '%s' (fd=%d)\n", output_file, check_result_info.output_file_fd); + + + /* finish save check info */ + check_result_info.host_name = (char *)strdup(svc->host_name); + check_result_info.service_description = (char *)strdup(svc->description); + check_result_info.output_file = (check_result_info.output_file_fd < 0 || output_file == NULL) ? NULL : strdup(output_file); + + /* free memory */ + my_free(output_file); + + /* write start of check result file */ + /* if things go really bad later on down the line, the user will at least have a partial file to help debug missing output results */ + if(check_result_info.output_file_fp) { + + fprintf(check_result_info.output_file_fp, "### Active Check Result File ###\n"); + fprintf(check_result_info.output_file_fp, "file_time=%lu\n", (unsigned long)check_result_info.start_time.tv_sec); + fprintf(check_result_info.output_file_fp, "\n"); + + fprintf(check_result_info.output_file_fp, "### Nagios Service Check Result ###\n"); + fprintf(check_result_info.output_file_fp, "# Time: %s", ctime(&check_result_info.start_time.tv_sec)); + fprintf(check_result_info.output_file_fp, "host_name=%s\n", check_result_info.host_name); + fprintf(check_result_info.output_file_fp, "service_description=%s\n", check_result_info.service_description); + fprintf(check_result_info.output_file_fp, "check_type=%d\n", check_result_info.check_type); + fprintf(check_result_info.output_file_fp, "check_options=%d\n", check_result_info.check_options); + fprintf(check_result_info.output_file_fp, "scheduled_check=%d\n", check_result_info.scheduled_check); + fprintf(check_result_info.output_file_fp, "reschedule_check=%d\n", check_result_info.reschedule_check); + fprintf(check_result_info.output_file_fp, "latency=%f\n", svc->latency); + fprintf(check_result_info.output_file_fp, "start_time=%lu.%lu\n", check_result_info.start_time.tv_sec, check_result_info.start_time.tv_usec); + + /* flush output or it'll get written again when we fork() */ + fflush(check_result_info.output_file_fp); + } + + /* initialize dynamic buffer for storing plugin output */ + dbuf_init(&checkresult_dbuf, dbuf_chunk); + + + /* reset latency (permanent value will be set later) */ + svc->latency = old_latency; + + /* update check statistics */ + update_check_stats((scheduled_check == TRUE) ? ACTIVE_SCHEDULED_SERVICE_CHECK_STATS : ACTIVE_ONDEMAND_SERVICE_CHECK_STATS, start_time.tv_sec); + +#ifdef EMBEDDEDPERL + + /* get"filename" component of command */ + strncpy(fname, processed_command, strcspn(processed_command, " ")); + fname[strcspn(processed_command, " ")] = '\x0'; + + /* should we use the embedded Perl interpreter to run this script? */ + use_epn = file_uses_embedded_perl(fname); + + /* if yes, do some initialization */ + if(use_epn == TRUE) { + + log_debug_info(DEBUGL_CHECKS, 1, "** Using Embedded Perl interpreter to run service check...\n"); + + args[0] = fname; + args[2] = ""; + + if(strchr(processed_command, ' ') == NULL) + args[3] = ""; + else + args[3] = processed_command + strlen(fname) + 1; + + ENTER; + SAVETMPS; + PUSHMARK(SP); + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(sv_2mortal(newSVpv(args[2], 0))); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + PUTBACK; + + /* call our perl interpreter to compile and optionally cache the command */ + + call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL); + + SPAGAIN ; + + if(SvTRUE(ERRSV)) { + + /* + * if SvTRUE(ERRSV) + * write failure to IPC pipe + * return + */ + + /* remove the top element of the Perl stack (undef) */ + (void) POPs ; + + pclose_result = STATE_UNKNOWN; + perl_plugin_output = SvPVX(ERRSV); + + log_debug_info(DEBUGL_CHECKS, 0, "Embedded Perl failed to compile %s, compile error %s - skipping plugin\n", fname, perl_plugin_output); + + /* save plugin output */ + if(perl_plugin_output != NULL) { + temp_buffer = escape_newlines(perl_plugin_output); + dbuf_strcat(&checkresult_dbuf, temp_buffer); + my_free(temp_buffer); + } + + /* get the check finish time */ + gettimeofday(&end_time, NULL); + + /* record check result info */ + check_result_info.exited_ok = FALSE; + check_result_info.return_code = pclose_result; + check_result_info.finish_time = end_time; + + /* write check result to file */ + if(check_result_info.output_file_fp) { + + fprintf(check_result_info.output_file_fp, "finish_time=%lu.%lu\n", check_result_info.finish_time.tv_sec, check_result_info.finish_time.tv_usec); + fprintf(check_result_info.output_file_fp, "early_timeout=%d\n", check_result_info.early_timeout); + fprintf(check_result_info.output_file_fp, "exited_ok=%d\n", check_result_info.exited_ok); + fprintf(check_result_info.output_file_fp, "return_code=%d\n", check_result_info.return_code); + fprintf(check_result_info.output_file_fp, "output=%s\n", (checkresult_dbuf.buf == NULL) ? "(null)" : checkresult_dbuf.buf); + + /* close the temp file */ + fclose(check_result_info.output_file_fp); + + /* move check result to queue directory */ + move_check_result_to_queue(check_result_info.output_file); + } + + /* free memory */ + dbuf_free(&checkresult_dbuf); + + /* free check result memory */ + free_check_result(&check_result_info); + + return OK; + } + else { + + plugin_hndlr_cr = newSVsv(POPs); + + log_debug_info(DEBUGL_CHECKS, 1, "Embedded Perl successfully compiled %s and returned code ref to plugin handler\n", fname); + + PUTBACK ; + FREETMPS ; + LEAVE ; + } + } +#endif + + /* plugin is a C plugin or a Perl plugin _without_ compilation errors */ + + /* fork a child process */ + pid = fork(); + + /* an error occurred while trying to fork */ + if(pid == -1) { + + fork_error = TRUE; + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: The check of service '%s' on host '%s' could not be performed due to a fork() error: '%s'. The check will be rescheduled.\n", svc->description, svc->host_name, strerror(errno)); + + log_debug_info(DEBUGL_CHECKS, 0, "Check of service '%s' on host '%s' could not be performed due to a fork() error: '%s'!\n", svc->description, svc->host_name, strerror(errno)); + } + + /* if we are in the child process... */ + else if(pid == 0) { + + /* set environment variables */ + set_all_macro_environment_vars_r(&mac, TRUE); + + /* ADDED 11/12/07 EG */ + /* close external command file and shut down worker thread */ + close_command_file(); + + /* fork again if we're not in a large installation */ + if(child_processes_fork_twice == TRUE) { + + /* fork again... */ + pid = fork(); + + /* an error occurred while trying to fork again */ + if(pid == -1) + exit(STATE_UNKNOWN); + } + + /* the grandchild (or child if large install tweaks are enabled) process should run the service check... */ + if(pid == 0 || child_processes_fork_twice == FALSE) { + + /* reset signal handling */ + reset_sighandler(); + + /* become the process group leader */ + setpgid(0, 0); + + /* exit on term signals at this process level */ + signal(SIGTERM, SIG_DFL); + + /* catch plugins that don't finish in a timely manner */ + signal(SIGALRM, service_check_sighandler); + alarm(service_check_timeout); + + /* disable rotation of the debug file */ + max_debug_file_size = 0L; + + /******** BEGIN EMBEDDED PERL INTERPRETER EXECUTION ********/ +#ifdef EMBEDDEDPERL + if(use_epn == TRUE) { + + /* execute our previously compiled script - from call_pv("Embed::Persistent::eval_file",..) */ + /* NB. args[2] is _now_ a code ref (to the Perl subroutine corresp to the plugin) returned by eval_file() */ + + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(plugin_hndlr_cr); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + count = call_pv("Embed::Persistent::run_package", G_ARRAY); + + SPAGAIN; + + perl_plugin_output = POPpx ; + pclose_result = POPi ; + + /* NOTE: 07/16/07 This has to be done before FREETMPS statement below, or the POPpx pointer will be invalid (Hendrik B.) */ + /* get perl plugin output - escape newlines */ + if(perl_plugin_output != NULL) { + temp_buffer = escape_newlines(perl_plugin_output); + dbuf_strcat(&checkresult_dbuf, temp_buffer); + my_free(temp_buffer); + } + + PUTBACK; + FREETMPS; + LEAVE; + + log_debug_info(DEBUGL_CHECKS, 1, "Embedded Perl ran %s: return code=%d, plugin output=%s\n", fname, pclose_result, (perl_plugin_output == NULL) ? "NULL" : checkresult_dbuf.buf); + + /* reset the alarm */ + alarm(0); + + /* get the check finish time */ + gettimeofday(&end_time, NULL); + + /* record check result info */ + check_result_info.return_code = pclose_result; + check_result_info.finish_time = end_time; + + /* write check result to file */ + if(check_result_info.output_file_fp) { + + fprintf(check_result_info.output_file_fp, "finish_time=%lu.%lu\n", check_result_info.finish_time.tv_sec, check_result_info.finish_time.tv_usec); + fprintf(check_result_info.output_file_fp, "early_timeout=%d\n", check_result_info.early_timeout); + fprintf(check_result_info.output_file_fp, "exited_ok=%d\n", check_result_info.exited_ok); + fprintf(check_result_info.output_file_fp, "return_code=%d\n", check_result_info.return_code); + fprintf(check_result_info.output_file_fp, "output=%s\n", (checkresult_dbuf.buf == NULL) ? "(null)" : checkresult_dbuf.buf); + + /* close the temp file */ + fclose(check_result_info.output_file_fp); + + /* move check result to queue directory */ + move_check_result_to_queue(check_result_info.output_file); + } + + /* free memory */ + dbuf_free(&checkresult_dbuf); + + /* free check result memory */ + free_check_result(&check_result_info); + + /* return with plugin exit status - not really necessary... */ + _exit(pclose_result); + } +#endif + /******** END EMBEDDED PERL INTERPRETER EXECUTION ********/ + + + /* run the plugin check command */ + fp = popen(processed_command, "r"); + if(fp == NULL) + _exit(STATE_UNKNOWN); + + /* initialize buffer */ + strcpy(output_buffer, ""); + + /* get all lines of plugin output - escape newlines */ + while(fgets(output_buffer, sizeof(output_buffer) - 1, fp)) { + temp_buffer = escape_newlines(output_buffer); + dbuf_strcat(&checkresult_dbuf, temp_buffer); + my_free(temp_buffer); + } + + /* close the process */ + pclose_result = pclose(fp); + + /* reset the alarm and ignore SIGALRM */ + signal(SIGALRM, SIG_IGN); + alarm(0); + + /* get the check finish time */ + gettimeofday(&end_time, NULL); + + /* record check result info */ + check_result_info.finish_time = end_time; + check_result_info.early_timeout = FALSE; + + /* test for execution error */ + if(pclose_result == -1) { + pclose_result = STATE_UNKNOWN; + check_result_info.return_code = STATE_CRITICAL; + check_result_info.exited_ok = FALSE; + } + else { + if(WEXITSTATUS(pclose_result) == 0 && WIFSIGNALED(pclose_result)) + check_result_info.return_code = 128 + WTERMSIG(pclose_result); + else + check_result_info.return_code = WEXITSTATUS(pclose_result); + } + + /* write check result to file */ + if(check_result_info.output_file_fp) { + FILE *fp; + + /* avoid races with signal handling */ + fp = check_result_info.output_file_fp; + check_result_info.output_file_fp = NULL; + + fprintf(fp, "finish_time=%lu.%lu\n", check_result_info.finish_time.tv_sec, check_result_info.finish_time.tv_usec); + fprintf(fp, "early_timeout=%d\n", check_result_info.early_timeout); + fprintf(fp, "exited_ok=%d\n", check_result_info.exited_ok); + fprintf(fp, "return_code=%d\n", check_result_info.return_code); + fprintf(fp, "output=%s\n", (checkresult_dbuf.buf == NULL) ? "(null)" : checkresult_dbuf.buf); + + /* close the temp file */ + fclose(fp); + + /* move check result to queue directory */ + move_check_result_to_queue(check_result_info.output_file); + } + + /* free memory */ + dbuf_free(&checkresult_dbuf); + my_free(processed_command); + + /* free check result memory */ + free_check_result(&check_result_info); + + /* return with plugin exit status - not really necessary... */ + _exit(pclose_result); + } + + /* NOTE: this code is never reached if large install tweaks are enabled... */ + + /* unset environment variables */ + set_all_macro_environment_vars_r(&mac, FALSE); + + /* free allocated memory */ + /* this needs to be done last, so we don't free memory for variables before they're used above */ + if(free_child_process_memory == TRUE) + free_memory(&mac); + + /* parent exits immediately - grandchild process is inherited by the INIT process, so we have no zombie problem... */ + _exit(STATE_OK); + } + + /* else the parent should wait for the first child to return... */ + else if(pid > 0) { + clear_volatile_macros_r(&mac); + + log_debug_info(DEBUGL_CHECKS, 2, "Service check is executing in child process (pid=%lu)\n", (unsigned long)pid); + + /* parent should close output file */ + if(check_result_info.output_file_fp) + fclose(check_result_info.output_file_fp); + + /* should this be done in first child process (after spawning grandchild) as well? */ + /* free memory allocated for IPC functionality */ + free_check_result(&check_result_info); + + /* free memory */ + my_free(processed_command); + + /* wait for the first child to return */ + /* don't do this if large install tweaks are enabled - we'll clean up children in event loop */ + if(child_processes_fork_twice == TRUE) + wait_result = waitpid(pid, NULL, 0); + } + + /* see if we were able to run the check... */ + if(fork_error == TRUE) + return ERROR; + + return OK; + } + + + +/* handles asynchronous service check results */ +int handle_async_service_check_result(service *temp_service, check_result *queued_check_result) { + host *temp_host = NULL; + time_t next_service_check = 0L; + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + int reschedule_check = FALSE; + int state_change = FALSE; + int hard_state_change = FALSE; + int first_host_check_initiated = FALSE; + int route_result = HOST_UP; + time_t current_time = 0L; + int state_was_logged = FALSE; + char *old_plugin_output = NULL; + char *temp_plugin_output = NULL; + char *temp_ptr = NULL; + servicedependency *temp_dependency = NULL; + objectlist *check_servicelist = NULL; + objectlist *servicelist_item = NULL; + service *master_service = NULL; + int run_async_check = TRUE; + int state_changes_use_cached_state = TRUE; /* TODO - 09/23/07 move this to a global variable */ + int flapping_check_done = FALSE; + void *ptr = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_async_service_check_result()\n"); + + /* make sure we have what we need */ + if(temp_service == NULL || queued_check_result == NULL) + return ERROR; + + /* get the current time */ + time(¤t_time); + + log_debug_info(DEBUGL_CHECKS, 0, "** Handling check result for service '%s' on host '%s'...\n", temp_service->description, temp_service->host_name); + log_debug_info(DEBUGL_CHECKS, 1, "HOST: %s, SERVICE: %s, CHECK TYPE: %s, OPTIONS: %d, SCHEDULED: %s, RESCHEDULE: %s, EXITED OK: %s, RETURN CODE: %d, OUTPUT: %s\n", temp_service->host_name, temp_service->description, (queued_check_result->check_type == SERVICE_CHECK_ACTIVE) ? "Active" : "Passive", queued_check_result->check_options, (queued_check_result->scheduled_check == TRUE) ? "Yes" : "No", (queued_check_result->reschedule_check == TRUE) ? "Yes" : "No", (queued_check_result->exited_ok == TRUE) ? "Yes" : "No", queued_check_result->return_code, queued_check_result->output); + + /* decrement the number of service checks still out there... */ + if(queued_check_result->check_type == SERVICE_CHECK_ACTIVE && currently_running_service_checks > 0) + currently_running_service_checks--; + + /* skip this service check results if its passive and we aren't accepting passive check results */ + if(queued_check_result->check_type == SERVICE_CHECK_PASSIVE) { + if(accept_passive_service_checks == FALSE) { + log_debug_info(DEBUGL_CHECKS, 0, "Discarding passive service check result because passive service checks are disabled globally.\n"); + return ERROR; + } + if(temp_service->accept_passive_service_checks == FALSE) { + log_debug_info(DEBUGL_CHECKS, 0, "Discarding passive service check result because passive checks are disabled for this service.\n"); + return ERROR; + } + } + + /* clear the freshening flag (it would have been set if this service was determined to be stale) */ + if(queued_check_result->check_options & CHECK_OPTION_FRESHNESS_CHECK) + temp_service->is_being_freshened = FALSE; + + /* clear the execution flag if this was an active check */ + if(queued_check_result->check_type == SERVICE_CHECK_ACTIVE) + temp_service->is_executing = FALSE; + + /* DISCARD INVALID FRESHNESS CHECK RESULTS */ + /* If a services goes stale, Nagios will initiate a forced check in order to freshen it. There is a race condition whereby a passive check + could arrive between the 1) initiation of the forced check and 2) the time when the forced check result is processed here. This would + make the service fresh again, so we do a quick check to make sure the service is still stale before we accept the check result. */ + if((queued_check_result->check_options & CHECK_OPTION_FRESHNESS_CHECK) && is_service_result_fresh(temp_service, current_time, FALSE) == TRUE) { + log_debug_info(DEBUGL_CHECKS, 0, "Discarding service freshness check result because the service is currently fresh (race condition avoided).\n"); + return OK; + } + + /* check latency is passed to us */ + temp_service->latency = queued_check_result->latency; + + /* update the execution time for this check (millisecond resolution) */ + temp_service->execution_time = (double)((double)(queued_check_result->finish_time.tv_sec - queued_check_result->start_time.tv_sec) + (double)((queued_check_result->finish_time.tv_usec - queued_check_result->start_time.tv_usec) / 1000.0) / 1000.0); + if(temp_service->execution_time < 0.0) + temp_service->execution_time = 0.0; + + /* get the last check time */ + temp_service->last_check = queued_check_result->start_time.tv_sec; + + /* was this check passive or active? */ + temp_service->check_type = (queued_check_result->check_type == SERVICE_CHECK_ACTIVE) ? SERVICE_CHECK_ACTIVE : SERVICE_CHECK_PASSIVE; + + /* update check statistics for passive checks */ + if(queued_check_result->check_type == SERVICE_CHECK_PASSIVE) + update_check_stats(PASSIVE_SERVICE_CHECK_STATS, queued_check_result->start_time.tv_sec); + + /* should we reschedule the next service check? NOTE: This may be overridden later... */ + reschedule_check = queued_check_result->reschedule_check; + + /* save the old service status info */ + temp_service->last_state = temp_service->current_state; + + /* save old plugin output */ + if(temp_service->plugin_output) + old_plugin_output = (char *)strdup(temp_service->plugin_output); + + /* clear the old plugin output and perf data buffers */ + my_free(temp_service->plugin_output); + my_free(temp_service->long_plugin_output); + my_free(temp_service->perf_data); + + /* if there was some error running the command, just skip it (this shouldn't be happening) */ + if(queued_check_result->exited_ok == FALSE) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Check of service '%s' on host '%s' did not exit properly!\n", temp_service->description, temp_service->host_name); + + temp_service->plugin_output = (char *)strdup("(Service check did not exit properly)"); + + temp_service->current_state = STATE_CRITICAL; + } + + /* make sure the return code is within bounds */ + else if(queued_check_result->return_code < 0 || queued_check_result->return_code > 3) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Return code of %d for check of service '%s' on host '%s' was out of bounds.%s\n", queued_check_result->return_code, temp_service->description, temp_service->host_name, (queued_check_result->return_code == 126 ? "Make sure the plugin you're trying to run is executable." : (queued_check_result->return_code == 127 ? " Make sure the plugin you're trying to run actually exists." : ""))); + + asprintf(&temp_plugin_output, "\x73\x6f\x69\x67\x61\x6e\x20\x74\x68\x67\x69\x72\x79\x70\x6f\x63\x20\x6e\x61\x68\x74\x65\x20\x64\x61\x74\x73\x6c\x61\x67"); + my_free(temp_plugin_output); + asprintf(&temp_service->plugin_output, "(Return code of %d is out of bounds%s)", queued_check_result->return_code, (queued_check_result->return_code == 126 ? " - plugin may not be executable" : (queued_check_result->return_code == 127 ? " - plugin may be missing" : ""))); + + temp_service->current_state = STATE_CRITICAL; + } + + /* else the return code is okay... */ + else { + + /* parse check output to get: (1) short output, (2) long output, (3) perf data */ + parse_check_output(queued_check_result->output, &temp_service->plugin_output, &temp_service->long_plugin_output, &temp_service->perf_data, TRUE, TRUE); + + /* make sure the plugin output isn't null */ + if(temp_service->plugin_output == NULL) + temp_service->plugin_output = (char *)strdup("(No output returned from plugin)"); + + /* replace semicolons in plugin output (but not performance data) with colons */ + else if((temp_ptr = temp_service->plugin_output)) { + while((temp_ptr = strchr(temp_ptr, ';'))) + * temp_ptr = ':'; + } + + log_debug_info(DEBUGL_CHECKS, 2, "Parsing check output...\n"); + log_debug_info(DEBUGL_CHECKS, 2, "Short Output: %s\n", (temp_service->plugin_output == NULL) ? "NULL" : temp_service->plugin_output); + log_debug_info(DEBUGL_CHECKS, 2, "Long Output: %s\n", (temp_service->long_plugin_output == NULL) ? "NULL" : temp_service->long_plugin_output); + log_debug_info(DEBUGL_CHECKS, 2, "Perf Data: %s\n", (temp_service->perf_data == NULL) ? "NULL" : temp_service->perf_data); + + /* grab the return code */ + temp_service->current_state = queued_check_result->return_code; + } + + + /* record the last state time */ + switch(temp_service->current_state) { + case STATE_OK: + temp_service->last_time_ok = temp_service->last_check; + break; + case STATE_WARNING: + temp_service->last_time_warning = temp_service->last_check; + break; + case STATE_UNKNOWN: + temp_service->last_time_unknown = temp_service->last_check; + break; + case STATE_CRITICAL: + temp_service->last_time_critical = temp_service->last_check; + break; + default: + break; + } + + /* log passive checks - we need to do this here, as some my bypass external commands by getting dropped in checkresults dir */ + if(temp_service->check_type == SERVICE_CHECK_PASSIVE) { + if(log_passive_checks == TRUE) + logit(NSLOG_PASSIVE_CHECK, FALSE, "PASSIVE SERVICE CHECK: %s;%s;%d;%s\n", temp_service->host_name, temp_service->description, temp_service->current_state, temp_service->plugin_output); + } + + /* get the host that this service runs on */ + temp_host = (host *)temp_service->host_ptr; + + /* if the service check was okay... */ + if(temp_service->current_state == STATE_OK) { + + /* if the host has never been checked before, verify its status */ + /* only do this if 1) the initial state was set to non-UP or 2) the host is not scheduled to be checked soon (next 5 minutes) */ + if(temp_host->has_been_checked == FALSE && (temp_host->initial_state != HOST_UP || (unsigned long)temp_host->next_check == 0L || (unsigned long)(temp_host->next_check - current_time) > 300)) { + + /* set a flag to remember that we launched a check */ + first_host_check_initiated = TRUE; + + /* 08/04/07 EG launch an async (parallel) host check unless aggressive host checking is enabled */ + /* previous logic was to simply run a sync (serial) host check */ + /* do NOT allow cached check results to happen here - we need the host to be checked for real... */ + if(use_aggressive_host_checking == TRUE) + perform_on_demand_host_check(temp_host, NULL, CHECK_OPTION_NONE, FALSE, 0L); + else + run_async_host_check_3x(temp_host, CHECK_OPTION_NONE, 0.0, FALSE, FALSE, NULL, NULL); + } + } + + + /**** NOTE - THIS WAS MOVED UP FROM LINE 1049 BELOW TO FIX PROBLEMS WHERE CURRENT ATTEMPT VALUE WAS ACTUALLY "LEADING" REAL VALUE ****/ + /* increment the current attempt number if this is a soft state (service was rechecked) */ + if(temp_service->state_type == SOFT_STATE && (temp_service->current_attempt < temp_service->max_attempts)) + temp_service->current_attempt = temp_service->current_attempt + 1; + + + log_debug_info(DEBUGL_CHECKS, 2, "ST: %s CA: %d MA: %d CS: %d LS: %d LHS: %d\n", (temp_service->state_type == SOFT_STATE) ? "SOFT" : "HARD", temp_service->current_attempt, temp_service->max_attempts, temp_service->current_state, temp_service->last_state, temp_service->last_hard_state); + + /* check for a state change (either soft or hard) */ + if(temp_service->current_state != temp_service->last_state) { + log_debug_info(DEBUGL_CHECKS, 2, "Service has changed state since last check!\n"); + state_change = TRUE; + } + + /* checks for a hard state change where host was down at last service check */ + /* this occurs in the case where host goes down and service current attempt gets reset to 1 */ + /* if this check is not made, the service recovery looks like a soft recovery instead of a hard one */ + if(temp_service->host_problem_at_last_check == TRUE && temp_service->current_state == STATE_OK) { + log_debug_info(DEBUGL_CHECKS, 2, "Service had a HARD STATE CHANGE!!\n"); + hard_state_change = TRUE; + } + + /* check for a "normal" hard state change where max check attempts is reached */ + if(temp_service->current_attempt >= temp_service->max_attempts && temp_service->current_state != temp_service->last_hard_state) { + log_debug_info(DEBUGL_CHECKS, 2, "Service had a HARD STATE CHANGE!!\n"); + hard_state_change = TRUE; + } + + /* a state change occurred... */ + /* reset last and next notification times and acknowledgement flag if necessary, misc other stuff */ + if(state_change == TRUE || hard_state_change == TRUE) { + + /* reschedule the service check */ + reschedule_check = TRUE; + + /* reset notification times */ + temp_service->last_notification = (time_t)0; + temp_service->next_notification = (time_t)0; + + /* reset notification suppression option */ + temp_service->no_more_notifications = FALSE; + + if(temp_service->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL && (state_change == TRUE || hard_state_change == FALSE)) { + + temp_service->problem_has_been_acknowledged = FALSE; + temp_service->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + + /* remove any non-persistant comments associated with the ack */ + delete_service_acknowledgement_comments(temp_service); + } + else if(temp_service->acknowledgement_type == ACKNOWLEDGEMENT_STICKY && temp_service->current_state == STATE_OK) { + + temp_service->problem_has_been_acknowledged = FALSE; + temp_service->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + + /* remove any non-persistant comments associated with the ack */ + delete_service_acknowledgement_comments(temp_service); + } + + /* do NOT reset current notification number!!! */ + /* hard changes between non-OK states should continue to be escalated, so don't reset current notification number */ + /*temp_service->current_notification_number=0;*/ + } + + /* initialize the last host and service state change times if necessary */ + if(temp_service->last_state_change == (time_t)0) + temp_service->last_state_change = temp_service->last_check; + if(temp_service->last_hard_state_change == (time_t)0) + temp_service->last_hard_state_change = temp_service->last_check; + if(temp_host->last_state_change == (time_t)0) + temp_host->last_state_change = temp_service->last_check; + if(temp_host->last_hard_state_change == (time_t)0) + temp_host->last_hard_state_change = temp_service->last_check; + + /* update last service state change times */ + if(state_change == TRUE) + temp_service->last_state_change = temp_service->last_check; + if(hard_state_change == TRUE) + temp_service->last_hard_state_change = temp_service->last_check; + + /* update the event and problem ids */ + if(state_change == TRUE) { + + /* always update the event id on a state change */ + temp_service->last_event_id = temp_service->current_event_id; + temp_service->current_event_id = next_event_id; + next_event_id++; + + /* update the problem id when transitioning to a problem state */ + if(temp_service->last_state == STATE_OK) { + /* don't reset last problem id, or it will be zero the next time a problem is encountered */ + /* temp_service->last_problem_id=temp_service->current_problem_id;*/ + temp_service->current_problem_id = next_problem_id; + next_problem_id++; + } + + /* clear the problem id when transitioning from a problem state to an OK state */ + if(temp_service->current_state == STATE_OK) { + temp_service->last_problem_id = temp_service->current_problem_id; + temp_service->current_problem_id = 0L; + } + } + + + /**************************************/ + /******* SERVICE CHECK OK LOGIC *******/ + /**************************************/ + + /* if the service is up and running OK... */ + if(temp_service->current_state == STATE_OK) { + + log_debug_info(DEBUGL_CHECKS, 1, "Service is OK.\n"); + + /* reset the acknowledgement flag (this should already have been done, but just in case...) */ + temp_service->problem_has_been_acknowledged = FALSE; + temp_service->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + + /* verify the route to the host and send out host recovery notifications */ + if(temp_host->current_state != HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is NOT UP, so we'll check it to see if it recovered...\n"); + + /* 08/04/07 EG launch an async (parallel) host check (possibly cached) unless aggressive host checking is enabled */ + /* previous logic was to simply run a sync (serial) host check */ + if(use_aggressive_host_checking == TRUE) + perform_on_demand_host_check(temp_host, NULL, CHECK_OPTION_NONE, TRUE, cached_host_check_horizon); + /* 09/23/07 EG don't launch a new host check if we already did so earlier */ + else if(first_host_check_initiated == TRUE) + log_debug_info(DEBUGL_CHECKS, 1, "First host check was already initiated, so we'll skip a new host check.\n"); + else { + /* can we use the last cached host state? */ + /* usually only use cached host state if no service state change has occurred */ + if((state_change == FALSE || state_changes_use_cached_state == TRUE) && temp_host->has_been_checked == TRUE && ((current_time - temp_host->last_check) <= cached_host_check_horizon)) { + log_debug_info(DEBUGL_CHECKS, 1, "* Using cached host state: %d\n", temp_host->current_state); + update_check_stats(ACTIVE_ONDEMAND_HOST_CHECK_STATS, current_time); + update_check_stats(ACTIVE_CACHED_HOST_CHECK_STATS, current_time); + } + + /* else launch an async (parallel) check of the host */ + else + run_async_host_check_3x(temp_host, CHECK_OPTION_NONE, 0.0, FALSE, FALSE, NULL, NULL); + } + } + + /* if a hard service recovery has occurred... */ + if(hard_state_change == TRUE) { + + log_debug_info(DEBUGL_CHECKS, 1, "Service experienced a HARD RECOVERY.\n"); + + /* set the state type macro */ + temp_service->state_type = HARD_STATE; + + /* log the service recovery */ + log_service_event(temp_service); + state_was_logged = TRUE; + + /* 10/04/07 check to see if the service and/or associate host is flapping */ + /* this should be done before a notification is sent out to ensure the host didn't just start flapping */ + check_for_service_flapping(temp_service, TRUE, TRUE); + check_for_host_flapping(temp_host, TRUE, FALSE, TRUE); + flapping_check_done = TRUE; + + /* notify contacts about the service recovery */ + service_notification(temp_service, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); + + /* run the service event handler to handle the hard state change */ + handle_service_event(temp_service); + } + + /* else if a soft service recovery has occurred... */ + else if(state_change == TRUE) { + + log_debug_info(DEBUGL_CHECKS, 1, "Service experienced a SOFT RECOVERY.\n"); + + /* this is a soft recovery */ + temp_service->state_type = SOFT_STATE; + + /* log the soft recovery */ + log_service_event(temp_service); + state_was_logged = TRUE; + + /* run the service event handler to handle the soft state change */ + handle_service_event(temp_service); + } + + /* else no service state change has occurred... */ + else { + log_debug_info(DEBUGL_CHECKS, 1, "Service did not change state.\n"); + } + + /* should we obsessive over service checks? */ + if(obsess_over_services == TRUE) + obsessive_compulsive_service_check_processor(temp_service); + + /* reset all service variables because its okay now... */ + temp_service->host_problem_at_last_check = FALSE; + temp_service->current_attempt = 1; + temp_service->state_type = HARD_STATE; + temp_service->last_hard_state = STATE_OK; + temp_service->last_notification = (time_t)0; + temp_service->next_notification = (time_t)0; + temp_service->current_notification_number = 0; + temp_service->problem_has_been_acknowledged = FALSE; + temp_service->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + temp_service->notified_on_unknown = FALSE; + temp_service->notified_on_warning = FALSE; + temp_service->notified_on_critical = FALSE; + temp_service->no_more_notifications = FALSE; + + if(reschedule_check == TRUE) + next_service_check = (time_t)(temp_service->last_check + (temp_service->check_interval * interval_length)); + } + + + /*******************************************/ + /******* SERVICE CHECK PROBLEM LOGIC *******/ + /*******************************************/ + + /* hey, something's not working quite like it should... */ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Service is in a non-OK state!\n"); + + /* check the route to the host if its up right now... */ + if(temp_host->current_state == HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is currently UP, so we'll recheck its state to make sure...\n"); + + /* 08/04/07 EG launch an async (parallel) host check (possibly cached) unless aggressive host checking is enabled */ + /* previous logic was to simply run a sync (serial) host check */ + if(use_aggressive_host_checking == TRUE) + perform_on_demand_host_check(temp_host, &route_result, CHECK_OPTION_NONE, TRUE, cached_host_check_horizon); + else { + /* can we use the last cached host state? */ + /* only use cached host state if no service state change has occurred */ + if((state_change == FALSE || state_changes_use_cached_state == TRUE) && temp_host->has_been_checked == TRUE && ((current_time - temp_host->last_check) <= cached_host_check_horizon)) { + /* use current host state as route result */ + route_result = temp_host->current_state; + log_debug_info(DEBUGL_CHECKS, 1, "* Using cached host state: %d\n", temp_host->current_state); + update_check_stats(ACTIVE_ONDEMAND_HOST_CHECK_STATS, current_time); + update_check_stats(ACTIVE_CACHED_HOST_CHECK_STATS, current_time); + } + + /* else launch an async (parallel) check of the host */ + /* CHANGED 02/15/08 only if service changed state since service was last checked */ + else if(state_change == TRUE) { + /* use current host state as route result */ + route_result = temp_host->current_state; + run_async_host_check_3x(temp_host, CHECK_OPTION_NONE, 0.0, FALSE, FALSE, NULL, NULL); + } + + /* ADDED 02/15/08 */ + /* else assume same host state */ + else { + route_result = temp_host->current_state; + log_debug_info(DEBUGL_CHECKS, 1, "* Using last known host state: %d\n", temp_host->current_state); + update_check_stats(ACTIVE_ONDEMAND_HOST_CHECK_STATS, current_time); + update_check_stats(ACTIVE_CACHED_HOST_CHECK_STATS, current_time); + } + } + } + + /* else the host is either down or unreachable, so recheck it if necessary */ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is currently DOWN/UNREACHABLE.\n"); + + /* we're using aggressive host checking, so really do recheck the host... */ + if(use_aggressive_host_checking == TRUE) { + log_debug_info(DEBUGL_CHECKS, 1, "Agressive host checking is enabled, so we'll recheck the host state...\n"); + perform_on_demand_host_check(temp_host, &route_result, CHECK_OPTION_NONE, TRUE, cached_host_check_horizon); + } + + /* the service wobbled between non-OK states, so check the host... */ + else if((state_change == TRUE && state_changes_use_cached_state == FALSE) && temp_service->last_hard_state != STATE_OK) { + log_debug_info(DEBUGL_CHECKS, 1, "Service wobbled between non-OK states, so we'll recheck the host state...\n"); + /* 08/04/07 EG launch an async (parallel) host check unless aggressive host checking is enabled */ + /* previous logic was to simply run a sync (serial) host check */ + /* use current host state as route result */ + route_result = temp_host->current_state; + run_async_host_check_3x(temp_host, CHECK_OPTION_NONE, 0.0, FALSE, FALSE, NULL, NULL); + /*perform_on_demand_host_check(temp_host,&route_result,CHECK_OPTION_NONE,TRUE,cached_host_check_horizon);*/ + } + + /* else fake the host check, but (possibly) resend host notifications to contacts... */ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Assuming host is in same state as before...\n"); + + /* if the host has never been checked before, set the checked flag and last check time */ + /* 03/11/06 EG Note: This probably never evaluates to FALSE, present for historical reasons only, can probably be removed in the future */ + if(temp_host->has_been_checked == FALSE) { + temp_host->has_been_checked = TRUE; + temp_host->last_check = temp_service->last_check; + } + + /* fake the route check result */ + route_result = temp_host->current_state; + + /* possibly re-send host notifications... */ + host_notification(temp_host, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); + } + } + + /* if the host is down or unreachable ... */ + /* 05/29/2007 NOTE: The host might be in a SOFT problem state due to host check retries/caching. Not sure if we should take that into account and do something different or not... */ + if(route_result != HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 2, "Host is not UP, so we mark state changes if appropriate\n"); + + /* "fake" a hard state change for the service - well, its not really fake, but it didn't get caught earlier... */ + if(temp_service->last_hard_state != temp_service->current_state) + hard_state_change = TRUE; + + /* update last state change times */ + if(state_change == TRUE || hard_state_change == TRUE) + temp_service->last_state_change = temp_service->last_check; + if(hard_state_change == TRUE) { + temp_service->last_hard_state_change = temp_service->last_check; + temp_service->state_type = HARD_STATE; + temp_service->last_hard_state = temp_service->current_state; + } + + /* put service into a hard state without attempting check retries and don't send out notifications about it */ + temp_service->host_problem_at_last_check = TRUE; + /* Below removed 08/04/2010 EG - http://tracker.nagios.org/view.php?id=128 */ + /* + temp_service->state_type=HARD_STATE; + temp_service->last_hard_state=temp_service->current_state; + temp_service->current_attempt=1; + */ + } + + /* the host is up - it recovered since the last time the service was checked... */ + else if(temp_service->host_problem_at_last_check == TRUE) { + + /* next time the service is checked we shouldn't get into this same case... */ + temp_service->host_problem_at_last_check = FALSE; + + /* reset the current check counter, so we give the service a chance */ + /* this helps prevent the case where service has N max check attempts, N-1 of which have already occurred. */ + /* if we didn't do this, the next check might fail and result in a hard problem - we should really give it more time */ + /* ADDED IF STATEMENT 01-17-05 EG */ + /* 01-17-05: Services in hard problem states before hosts went down would sometimes come back as soft problem states after */ + /* the hosts recovered. This caused problems, so hopefully this will fix it */ + if(temp_service->state_type == SOFT_STATE) + temp_service->current_attempt = 1; + } + + log_debug_info(DEBUGL_CHECKS, 1, "Current/Max Attempt(s): %d/%d\n", temp_service->current_attempt, temp_service->max_attempts); + + /* if we should retry the service check, do so (except it the host is down or unreachable!) */ + if(temp_service->current_attempt < temp_service->max_attempts) { + + /* the host is down or unreachable, so don't attempt to retry the service check */ + if(route_result != HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 1, "Host isn't UP, so we won't retry the service check...\n"); + + /* the host is not up, so reschedule the next service check at regular interval */ + if(reschedule_check == TRUE) + next_service_check = (time_t)(temp_service->last_check + (temp_service->check_interval * interval_length)); + + /* log the problem as a hard state if the host just went down */ + if(hard_state_change == TRUE) { + log_service_event(temp_service); + state_was_logged = TRUE; + + /* run the service event handler to handle the hard state */ + handle_service_event(temp_service); + } + } + + /* the host is up, so continue to retry the service check */ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is UP, so we'll retry the service check...\n"); + + /* this is a soft state */ + temp_service->state_type = SOFT_STATE; + + /* log the service check retry */ + log_service_event(temp_service); + state_was_logged = TRUE; + + /* run the service event handler to handle the soft state */ + handle_service_event(temp_service); + + if(reschedule_check == TRUE) + next_service_check = (time_t)(temp_service->last_check + (temp_service->retry_interval * interval_length)); + } + + /* perform dependency checks on the second to last check of the service */ + if(enable_predictive_service_dependency_checks == TRUE && temp_service->current_attempt == (temp_service->max_attempts - 1)) { + + log_debug_info(DEBUGL_CHECKS, 1, "Looking for services to check for predictive dependency checks...\n"); + + /* check services that THIS ONE depends on for notification AND execution */ + /* we do this because we might be sending out a notification soon and we want the dependency logic to be accurate */ + for(temp_dependency = get_first_servicedependency_by_dependent_service(temp_service->host_name, temp_service->description, &ptr); temp_dependency != NULL; temp_dependency = get_next_servicedependency_by_dependent_service(temp_service->host_name, temp_service->description, &ptr)) { + if(temp_dependency->dependent_service_ptr == temp_service && temp_dependency->master_service_ptr != NULL) { + master_service = (service *)temp_dependency->master_service_ptr; + log_debug_info(DEBUGL_CHECKS, 2, "Predictive check of service '%s' on host '%s' queued.\n", master_service->description, master_service->host_name); + add_object_to_objectlist(&check_servicelist, (void *)master_service); + } + } + } + } + + + /* we've reached the maximum number of service rechecks, so handle the error */ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Service has reached max number of rechecks, so we'll handle the error...\n"); + + /* this is a hard state */ + temp_service->state_type = HARD_STATE; + + /* if we've hard a hard state change... */ + if(hard_state_change == TRUE) { + + /* log the service problem (even if host is not up, which is new in 0.0.5) */ + log_service_event(temp_service); + state_was_logged = TRUE; + } + + /* else log the problem (again) if this service is flagged as being volatile */ + else if(temp_service->is_volatile == TRUE) { + log_service_event(temp_service); + state_was_logged = TRUE; + } + + /* check for start of flexible (non-fixed) scheduled downtime if we just had a hard error */ + /* we need to check for both, state_change (SOFT) and hard_state_change (HARD) values */ + if((hard_state_change == TRUE || state_change == TRUE) && temp_service->pending_flex_downtime > 0) + check_pending_flex_service_downtime(temp_service); + + /* 10/04/07 check to see if the service and/or associate host is flapping */ + /* this should be done before a notification is sent out to ensure the host didn't just start flapping */ + check_for_service_flapping(temp_service, TRUE, TRUE); + check_for_host_flapping(temp_host, TRUE, FALSE, TRUE); + flapping_check_done = TRUE; + + /* (re)send notifications out about this service problem if the host is up (and was at last check also) and the dependencies were okay... */ + service_notification(temp_service, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); + + /* run the service event handler if we changed state from the last hard state or if this service is flagged as being volatile */ + if(hard_state_change == TRUE || temp_service->is_volatile == TRUE) + handle_service_event(temp_service); + + /* save the last hard state */ + temp_service->last_hard_state = temp_service->current_state; + + /* reschedule the next check at the regular interval */ + if(reschedule_check == TRUE) + next_service_check = (time_t)(temp_service->last_check + (temp_service->check_interval * interval_length)); + } + + + /* should we obsessive over service checks? */ + if(obsess_over_services == TRUE) + obsessive_compulsive_service_check_processor(temp_service); + } + + /* reschedule the next service check ONLY for active, scheduled checks */ + if(reschedule_check == TRUE) { + + log_debug_info(DEBUGL_CHECKS, 1, "Rescheduling next check of service at %s", ctime(&next_service_check)); + + /* default is to reschedule service check unless a test below fails... */ + temp_service->should_be_scheduled = TRUE; + + /* next check time was calculated above */ + temp_service->next_check = next_service_check; + + /* make sure we don't get ourselves into too much trouble... */ + if(current_time > temp_service->next_check) + temp_service->next_check = current_time; + + /* make sure we rescheduled the next service check at a valid time */ + preferred_time = temp_service->next_check; + get_next_valid_time(preferred_time, &next_valid_time, temp_service->check_period_ptr); + temp_service->next_check = next_valid_time; + + /* services with non-recurring intervals do not get rescheduled */ + if(temp_service->check_interval == 0) + temp_service->should_be_scheduled = FALSE; + + /* services with active checks disabled do not get rescheduled */ + if(temp_service->checks_enabled == FALSE) + temp_service->should_be_scheduled = FALSE; + + /* schedule a non-forced check if we can */ + if(temp_service->should_be_scheduled == TRUE) + schedule_service_check(temp_service, temp_service->next_check, CHECK_OPTION_NONE); + } + + /* if we're stalking this state type and state was not already logged AND the plugin output changed since last check, log it now.. */ + if(temp_service->state_type == HARD_STATE && state_change == FALSE && state_was_logged == FALSE && compare_strings(old_plugin_output, temp_service->plugin_output)) { + + if((temp_service->current_state == STATE_OK && temp_service->stalk_on_ok == TRUE)) + log_service_event(temp_service); + + else if((temp_service->current_state == STATE_WARNING && temp_service->stalk_on_warning == TRUE)) + log_service_event(temp_service); + + else if((temp_service->current_state == STATE_UNKNOWN && temp_service->stalk_on_unknown == TRUE)) + log_service_event(temp_service); + + else if((temp_service->current_state == STATE_CRITICAL && temp_service->stalk_on_critical == TRUE)) + log_service_event(temp_service); + } + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_service_check(NEBTYPE_SERVICECHECK_PROCESSED, NEBFLAG_NONE, NEBATTR_NONE, temp_service, temp_service->check_type, queued_check_result->start_time, queued_check_result->finish_time, NULL, temp_service->latency, temp_service->execution_time, service_check_timeout, queued_check_result->early_timeout, queued_check_result->return_code, NULL, NULL); +#endif + + /* set the checked flag */ + temp_service->has_been_checked = TRUE; + + /* update the current service status log */ + update_service_status(temp_service, FALSE); + + /* check to see if the service and/or associate host is flapping */ + if(flapping_check_done == FALSE) { + check_for_service_flapping(temp_service, TRUE, TRUE); + check_for_host_flapping(temp_host, TRUE, FALSE, TRUE); + } + + /* update service performance info */ + update_service_performance_data(temp_service); + + /* free allocated memory */ + my_free(temp_plugin_output); + my_free(old_plugin_output); + + + /* run async checks of all services we added above */ + /* don't run a check if one is already executing or we can get by with a cached state */ + for(servicelist_item = check_servicelist; servicelist_item != NULL; servicelist_item = servicelist_item->next) { + run_async_check = TRUE; + temp_service = (service *)servicelist_item->object_ptr; + + /* we can get by with a cached state, so don't check the service */ + if((current_time - temp_service->last_check) <= cached_service_check_horizon) { + run_async_check = FALSE; + + /* update check statistics */ + update_check_stats(ACTIVE_CACHED_SERVICE_CHECK_STATS, current_time); + } + + if(temp_service->is_executing == TRUE) + run_async_check = FALSE; + + if(run_async_check == TRUE) + run_async_service_check(temp_service, CHECK_OPTION_NONE, 0.0, FALSE, FALSE, NULL, NULL); + } + free_objectlist(&check_servicelist); + + return OK; + } + + + +/* schedules an immediate or delayed service check */ +void schedule_service_check(service *svc, time_t check_time, int options) { + timed_event *temp_event = NULL; + timed_event *new_event = NULL; + int use_original_event = TRUE; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "schedule_service_check()\n"); + + if(svc == NULL) + return; + + log_debug_info(DEBUGL_CHECKS, 0, "Scheduling a %s, active check of service '%s' on host '%s' @ %s", (options & CHECK_OPTION_FORCE_EXECUTION) ? "forced" : "non-forced", svc->description, svc->host_name, ctime(&check_time)); + + /* don't schedule a check if active checks of this service are disabled */ + if(svc->checks_enabled == FALSE && !(options & CHECK_OPTION_FORCE_EXECUTION)) { + log_debug_info(DEBUGL_CHECKS, 0, "Active checks of this service are disabled.\n"); + return; + } + + /* default is to use the new event */ + use_original_event = FALSE; + + temp_event = (timed_event *)svc->next_check_event; + + /* + * If the service already has a check scheduled, + * we need to decide which of the events to use + */ + if(temp_event != NULL) { + + log_debug_info(DEBUGL_CHECKS, 2, "Found another service check event for this service @ %s", ctime(&temp_event->run_time)); + + /* use the originally scheduled check unless we decide otherwise */ + use_original_event = TRUE; + + /* the original event is a forced check... */ + if((temp_event->event_options & CHECK_OPTION_FORCE_EXECUTION)) { + + /* the new event is also forced and its execution time is earlier than the original, so use it instead */ + if((options & CHECK_OPTION_FORCE_EXECUTION) && (check_time < temp_event->run_time)) { + use_original_event = FALSE; + log_debug_info(DEBUGL_CHECKS, 2, "New service check event is forced and occurs before the existing event, so the new event will be used instead.\n"); + } + } + + /* the original event is not a forced check... */ + else { + + /* the new event is a forced check, so use it instead */ + if((options & CHECK_OPTION_FORCE_EXECUTION)) { + use_original_event = FALSE; + log_debug_info(DEBUGL_CHECKS, 2, "New service check event is forced, so it will be used instead of the existing event.\n"); + } + + /* the new event is not forced either and its execution time is earlier than the original, so use it instead */ + else if(check_time < temp_event->run_time) { + use_original_event = FALSE; + log_debug_info(DEBUGL_CHECKS, 2, "New service check event occurs before the existing (older) event, so it will be used instead.\n"); + } + + /* the new event is older, so override the existing one */ + else { + log_debug_info(DEBUGL_CHECKS, 2, "New service check event occurs after the existing event, so we'll ignore it.\n"); + } + } + } + + /* schedule a new event */ + if(use_original_event == FALSE) { + + /* allocate memory for a new event item */ + new_event = (timed_event *)malloc(sizeof(timed_event)); + if(new_event == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not reschedule check of service '%s' on host '%s'!\n", svc->description, svc->host_name); + return; + } + + /* make sure we kill off the old event */ + if(temp_event) { + remove_event(temp_event, &event_list_low, &event_list_low_tail); + my_free(temp_event); + } + log_debug_info(DEBUGL_CHECKS, 2, "Scheduling new service check event.\n"); + + /* set the next service check event and time */ + svc->next_check_event = new_event; + svc->next_check = check_time; + + /* save check options for retention purposes */ + svc->check_options = options; + + /* place the new event in the event queue */ + new_event->event_type = EVENT_SERVICE_CHECK; + new_event->event_data = (void *)svc; + new_event->event_args = (void *)NULL; + new_event->event_options = options; + new_event->run_time = svc->next_check; + new_event->recurring = FALSE; + new_event->event_interval = 0L; + new_event->timing_func = NULL; + new_event->compensate_for_time_change = TRUE; + reschedule_event(new_event, &event_list_low, &event_list_low_tail); + } + + else { + /* reset the next check time (it may be out of sync) */ + if(temp_event != NULL) + svc->next_check = temp_event->run_time; + + log_debug_info(DEBUGL_CHECKS, 2, "Keeping original service check event (ignoring the new one).\n"); + } + + + /* update the status log */ + update_service_status(svc, FALSE); + + return; + } + + + +/* checks viability of performing a service check */ +int check_service_check_viability(service *svc, int check_options, int *time_is_valid, time_t *new_time) { + int result = OK; + int perform_check = TRUE; + time_t current_time = 0L; + time_t preferred_time = 0L; + int check_interval = 0; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_service_check_viability()\n"); + + /* make sure we have a service */ + if(svc == NULL) + return ERROR; + + /* get the check interval to use if we need to reschedule the check */ + if(svc->state_type == SOFT_STATE && svc->current_state != STATE_OK) + check_interval = (svc->retry_interval * interval_length); + else + check_interval = (svc->check_interval * interval_length); + + /* get the current time */ + time(¤t_time); + + /* initialize the next preferred check time */ + preferred_time = current_time; + + /* can we check the host right now? */ + if(!(check_options & CHECK_OPTION_FORCE_EXECUTION)) { + + /* if checks of the service are currently disabled... */ + if(svc->checks_enabled == FALSE) { + preferred_time = current_time + check_interval; + perform_check = FALSE; + + log_debug_info(DEBUGL_CHECKS, 2, "Active checks of the service are currently disabled.\n"); + } + + /* make sure this is a valid time to check the service */ + if(check_time_against_period((unsigned long)current_time, svc->check_period_ptr) == ERROR) { + preferred_time = current_time; + if(time_is_valid) + *time_is_valid = FALSE; + perform_check = FALSE; + + log_debug_info(DEBUGL_CHECKS, 2, "This is not a valid time for this service to be actively checked.\n"); + } + + /* check service dependencies for execution */ + if(check_service_dependencies(svc, EXECUTION_DEPENDENCY) == DEPENDENCIES_FAILED) { + preferred_time = current_time + check_interval; + perform_check = FALSE; + + log_debug_info(DEBUGL_CHECKS, 2, "Execution dependencies for this service failed, so it will not be actively checked.\n"); + } + } + + /* pass back the next viable check time */ + if(new_time) + *new_time = preferred_time; + + result = (perform_check == TRUE) ? OK : ERROR; + + return result; + } + + + +/* checks service dependencies */ +int check_service_dependencies(service *svc, int dependency_type) { + servicedependency *temp_dependency = NULL; + service *temp_service = NULL; + int state = STATE_OK; + time_t current_time = 0L; + void *ptr = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_service_dependencies()\n"); + + /* check all dependencies... */ + for(temp_dependency = get_first_servicedependency_by_dependent_service(svc->host_name, svc->description, &ptr); temp_dependency != NULL; temp_dependency = get_next_servicedependency_by_dependent_service(svc->host_name, svc->description, &ptr)) { + + /* only check dependencies of the desired type (notification or execution) */ + if(temp_dependency->dependency_type != dependency_type) + continue; + + /* find the service we depend on... */ + if((temp_service = temp_dependency->master_service_ptr) == NULL) + continue; + + /* skip this dependency if it has a timeperiod and the current time isn't valid */ + time(¤t_time); + if(temp_dependency->dependency_period != NULL && check_time_against_period(current_time, temp_dependency->dependency_period_ptr) == ERROR) + return FALSE; + + /* get the status to use (use last hard state if its currently in a soft state) */ + if(temp_service->state_type == SOFT_STATE && soft_state_dependencies == FALSE) + state = temp_service->last_hard_state; + else + state = temp_service->current_state; + + /* is the service we depend on in state that fails the dependency tests? */ + if(state == STATE_OK && temp_dependency->fail_on_ok == TRUE) + return DEPENDENCIES_FAILED; + if(state == STATE_WARNING && temp_dependency->fail_on_warning == TRUE) + return DEPENDENCIES_FAILED; + if(state == STATE_UNKNOWN && temp_dependency->fail_on_unknown == TRUE) + return DEPENDENCIES_FAILED; + if(state == STATE_CRITICAL && temp_dependency->fail_on_critical == TRUE) + return DEPENDENCIES_FAILED; + if((state == STATE_OK && temp_service->has_been_checked == FALSE) && temp_dependency->fail_on_pending == TRUE) + return DEPENDENCIES_FAILED; + + /* immediate dependencies ok at this point - check parent dependencies if necessary */ + if(temp_dependency->inherits_parent == TRUE) { + if(check_service_dependencies(temp_service, dependency_type) != DEPENDENCIES_OK) + return DEPENDENCIES_FAILED; + } + } + + return DEPENDENCIES_OK; + } + + + +/* check for services that never returned from a check... */ +void check_for_orphaned_services(void) { + service *temp_service = NULL; + time_t current_time = 0L; + time_t expected_time = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_orphaned_services()\n"); + + /* get the current time */ + time(¤t_time); + + /* check all services... */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* skip services that are not currently executing */ + if(temp_service->is_executing == FALSE) + continue; + + /* determine the time at which the check results should have come in (allow 10 minutes slack time) */ + expected_time = (time_t)(temp_service->next_check + temp_service->latency + service_check_timeout + check_reaper_interval + 600); + + /* this service was supposed to have executed a while ago, but for some reason the results haven't come back in... */ + if(expected_time < current_time) { + + /* log a warning */ + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: The check of service '%s' on host '%s' looks like it was orphaned (results never came back). I'm scheduling an immediate check of the service...\n", temp_service->description, temp_service->host_name); + + log_debug_info(DEBUGL_CHECKS, 1, "Service '%s' on host '%s' was orphaned, so we're scheduling an immediate check...\n", temp_service->description, temp_service->host_name); + + /* decrement the number of running service checks */ + if(currently_running_service_checks > 0) + currently_running_service_checks--; + + /* disable the executing flag */ + temp_service->is_executing = FALSE; + + /* schedule an immediate check of the service */ + schedule_service_check(temp_service, current_time, CHECK_OPTION_ORPHAN_CHECK); + } + + } + + return; + } + + + +/* check freshness of service results */ +void check_service_result_freshness(void) { + service *temp_service = NULL; + time_t current_time = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_service_result_freshness()\n"); + log_debug_info(DEBUGL_CHECKS, 1, "Checking the freshness of service check results...\n"); + + /* bail out if we're not supposed to be checking freshness */ + if(check_service_freshness == FALSE) { + log_debug_info(DEBUGL_CHECKS, 1, "Service freshness checking is disabled.\n"); + return; + } + + /* get the current time */ + time(¤t_time); + + /* check all services... */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* skip services we shouldn't be checking for freshness */ + if(temp_service->check_freshness == FALSE) + continue; + + /* skip services that are currently executing (problems here will be caught by orphaned service check) */ + if(temp_service->is_executing == TRUE) + continue; + + /* skip services that have both active and passive checks disabled */ + if(temp_service->checks_enabled == FALSE && temp_service->accept_passive_service_checks == FALSE) + continue; + + /* skip services that are already being freshened */ + if(temp_service->is_being_freshened == TRUE) + continue; + + /* see if the time is right... */ + if(check_time_against_period(current_time, temp_service->check_period_ptr) == ERROR) + continue; + + /* EXCEPTION */ + /* don't check freshness of services without regular check intervals if we're using auto-freshness threshold */ + if(temp_service->check_interval == 0 && temp_service->freshness_threshold == 0) + continue; + + /* the results for the last check of this service are stale! */ + if(is_service_result_fresh(temp_service, current_time, TRUE) == FALSE) { + + /* set the freshen flag */ + temp_service->is_being_freshened = TRUE; + + /* schedule an immediate forced check of the service */ + schedule_service_check(temp_service, current_time, CHECK_OPTION_FORCE_EXECUTION | CHECK_OPTION_FRESHNESS_CHECK); + } + + } + + return; + } + + + +/* tests whether or not a service's check results are fresh */ +int is_service_result_fresh(service *temp_service, time_t current_time, int log_this) { + int freshness_threshold = 0; + time_t expiration_time = 0L; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + int tdays = 0; + int thours = 0; + int tminutes = 0; + int tseconds = 0; + + log_debug_info(DEBUGL_CHECKS, 2, "Checking freshness of service '%s' on host '%s'...\n", temp_service->description, temp_service->host_name); + + /* use user-supplied freshness threshold or auto-calculate a freshness threshold to use? */ + if(temp_service->freshness_threshold == 0) { + if(temp_service->state_type == HARD_STATE || temp_service->current_state == STATE_OK) + freshness_threshold = (temp_service->check_interval * interval_length) + temp_service->latency + additional_freshness_latency; + else + freshness_threshold = (temp_service->retry_interval * interval_length) + temp_service->latency + additional_freshness_latency; + } + else + freshness_threshold = temp_service->freshness_threshold; + + log_debug_info(DEBUGL_CHECKS, 2, "Freshness thresholds: service=%d, use=%d\n", temp_service->freshness_threshold, freshness_threshold); + + /* calculate expiration time */ + /* + * CHANGED 11/10/05 EG - + * program start is only used in expiration time calculation + * if > last check AND active checks are enabled, so active checks + * can become stale immediately upon program startup + */ + /* + * CHANGED 02/25/06 SG - + * passive checks also become stale, so remove dependence on active + * check logic + */ + if(temp_service->has_been_checked == FALSE) + expiration_time = (time_t)(event_start + freshness_threshold); + /* + * CHANGED 06/19/07 EG - + * Per Ton's suggestion (and user requests), only use program start + * time over last check if no specific threshold has been set by user. + * Problems can occur if Nagios is restarted more frequently that + * freshness threshold intervals (services never go stale). + */ + /* + * CHANGED 10/07/07 EG: + * Only match next condition for services that + * have active checks enabled... + */ + /* + * CHANGED 10/07/07 EG: + * Added max_service_check_spread to expiration time as suggested + * by Altinity + */ + else if(temp_service->checks_enabled == TRUE && event_start > temp_service->last_check && temp_service->freshness_threshold == 0) + expiration_time = (time_t)(event_start + freshness_threshold + (max_service_check_spread * interval_length)); + else + expiration_time = (time_t)(temp_service->last_check + freshness_threshold); + + /* + * If the check was last done passively, we assume it's going + * to continue that way and we need to handle the fact that + * Nagios might have been shut off for quite a long time. If so, + * we mustn't spam freshness notifications but use event_start + * instead of last_check to determine freshness expiration time. + * The threshold for "long time" is determined as 61.8% of the normal + * freshness threshold based on vast heuristical research (ie, "some + * guy once told me the golden ratio is good for loads of stuff"). + */ + if(temp_service->check_type == SERVICE_CHECK_PASSIVE) { + if(temp_service->last_check < event_start && + event_start - last_program_stop > freshness_threshold * 0.618) { + expiration_time = event_start + freshness_threshold; + } + } + log_debug_info(DEBUGL_CHECKS, 2, "HBC: %d, PS: %lu, ES: %lu, LC: %lu, CT: %lu, ET: %lu\n", temp_service->has_been_checked, (unsigned long)program_start, (unsigned long)event_start, (unsigned long)temp_service->last_check, (unsigned long)current_time, (unsigned long)expiration_time); + + /* the results for the last check of this service are stale */ + if(expiration_time < current_time) { + + get_time_breakdown((current_time - expiration_time), &days, &hours, &minutes, &seconds); + get_time_breakdown(freshness_threshold, &tdays, &thours, &tminutes, &tseconds); + + /* log a warning */ + if(log_this == TRUE) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: The results of service '%s' on host '%s' are stale by %dd %dh %dm %ds (threshold=%dd %dh %dm %ds). I'm forcing an immediate check of the service.\n", temp_service->description, temp_service->host_name, days, hours, minutes, seconds, tdays, thours, tminutes, tseconds); + + log_debug_info(DEBUGL_CHECKS, 1, "Check results for service '%s' on host '%s' are stale by %dd %dh %dm %ds (threshold=%dd %dh %dm %ds). Forcing an immediate check of the service...\n", temp_service->description, temp_service->host_name, days, hours, minutes, seconds, tdays, thours, tminutes, tseconds); + + return FALSE; + } + + log_debug_info(DEBUGL_CHECKS, 1, "Check results for service '%s' on host '%s' are fresh.\n", temp_service->description, temp_service->host_name); + + return TRUE; + } + + + + +/******************************************************************/ +/*************** COMMON ROUTE/HOST CHECK FUNCTIONS ****************/ +/******************************************************************/ + +/* execute an on-demand check */ +int perform_on_demand_host_check(host *hst, int *check_return_code, int check_options, int use_cached_result, unsigned long check_timestamp_horizon) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "perform_on_demand_host_check()\n"); + + perform_on_demand_host_check_3x(hst, check_return_code, check_options, use_cached_result, check_timestamp_horizon); + + return OK; + } + + + +/* execute a scheduled host check using either the 2.x or 3.x logic */ +int perform_scheduled_host_check(host *hst, int check_options, double latency) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "perform_scheduled_host_check()\n"); + + run_scheduled_host_check_3x(hst, check_options, latency); + + return OK; + } + + + +/* schedules an immediate or delayed host check */ +void schedule_host_check(host *hst, time_t check_time, int options) { + timed_event *temp_event = NULL; + timed_event *new_event = NULL; + int use_original_event = TRUE; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "schedule_host_check()\n"); + + if(hst == NULL) + return; + + log_debug_info(DEBUGL_CHECKS, 0, "Scheduling a %s, active check of host '%s' @ %s", (options & CHECK_OPTION_FORCE_EXECUTION) ? "forced" : "non-forced", hst->name, ctime(&check_time)); + + /* don't schedule a check if active checks of this host are disabled */ + if(hst->checks_enabled == FALSE && !(options & CHECK_OPTION_FORCE_EXECUTION)) { + log_debug_info(DEBUGL_CHECKS, 0, "Active checks are disabled for this host.\n"); + return; + } + + /* default is to use the new event */ + use_original_event = FALSE; + + temp_event = (timed_event *)hst->next_check_event; + + /* + * If the host already had a check scheduled we need + * to decide which check event to use + */ + if(temp_event != NULL) { + + log_debug_info(DEBUGL_CHECKS, 2, "Found another host check event for this host @ %s", ctime(&temp_event->run_time)); + + /* use the originally scheduled check unless we decide otherwise */ + use_original_event = TRUE; + + /* the original event is a forced check... */ + if((temp_event->event_options & CHECK_OPTION_FORCE_EXECUTION)) { + + /* the new event is also forced and its execution time is earlier than the original, so use it instead */ + if((options & CHECK_OPTION_FORCE_EXECUTION) && (check_time < temp_event->run_time)) { + log_debug_info(DEBUGL_CHECKS, 2, "New host check event is forced and occurs before the existing event, so the new event be used instead.\n"); + use_original_event = FALSE; + } + } + + /* the original event is not a forced check... */ + else { + + /* the new event is a forced check, so use it instead */ + if((options & CHECK_OPTION_FORCE_EXECUTION)) { + use_original_event = FALSE; + log_debug_info(DEBUGL_CHECKS, 2, "New host check event is forced, so it will be used instead of the existing event.\n"); + } + + /* the new event is not forced either and its execution time is earlier than the original, so use it instead */ + else if(check_time < temp_event->run_time) { + use_original_event = FALSE; + log_debug_info(DEBUGL_CHECKS, 2, "New host check event occurs before the existing (older) event, so it will be used instead.\n"); + } + + /* the new event is older, so override the existing one */ + else { + log_debug_info(DEBUGL_CHECKS, 2, "New host check event occurs after the existing event, so we'll ignore it.\n"); + } + } + } + + /* use the new event */ + if(use_original_event == FALSE) { + + log_debug_info(DEBUGL_CHECKS, 2, "Scheduling new host check event.\n"); + + /* allocate memory for a new event item */ + if((new_event = (timed_event *)malloc(sizeof(timed_event))) == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not reschedule check of host '%s'!\n", hst->name); + return; + } + + if(temp_event) { + remove_event(temp_event, &event_list_low, &event_list_low_tail); + my_free(temp_event); + } + + /* set the next host check event and time */ + hst->next_check_event = new_event; + hst->next_check = check_time; + + /* save check options for retention purposes */ + hst->check_options = options; + + /* place the new event in the event queue */ + new_event->event_type = EVENT_HOST_CHECK; + new_event->event_data = (void *)hst; + new_event->event_args = (void *)NULL; + new_event->event_options = options; + new_event->run_time = hst->next_check; + new_event->recurring = FALSE; + new_event->event_interval = 0L; + new_event->timing_func = NULL; + new_event->compensate_for_time_change = TRUE; + reschedule_event(new_event, &event_list_low, &event_list_low_tail); + } + + else { + /* reset the next check time (it may be out of sync) */ + if(temp_event != NULL) + hst->next_check = temp_event->run_time; + + log_debug_info(DEBUGL_CHECKS, 2, "Keeping original host check event (ignoring the new one).\n"); + } + + /* update the status log */ + update_host_status(hst, FALSE); + + return; + } + + + +/* checks host dependencies */ +int check_host_dependencies(host *hst, int dependency_type) { + hostdependency *temp_dependency = NULL; + host *temp_host = NULL; + int state = HOST_UP; + time_t current_time = 0L; + void *ptr = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_host_dependencies()\n"); + + /* check all dependencies... */ + for(temp_dependency = get_first_hostdependency_by_dependent_host(hst->name, &ptr); temp_dependency != NULL; temp_dependency = get_next_hostdependency_by_dependent_host(hst->name, &ptr)) { + + /* only check dependencies of the desired type (notification or execution) */ + if(temp_dependency->dependency_type != dependency_type) + continue; + + /* find the host we depend on... */ + if((temp_host = temp_dependency->master_host_ptr) == NULL) + continue; + + /* skip this dependency if it has a timeperiod and the current time isn't valid */ + time(¤t_time); + if(temp_dependency->dependency_period != NULL && check_time_against_period(current_time, temp_dependency->dependency_period_ptr) == ERROR) + return FALSE; + + /* get the status to use (use last hard state if its currently in a soft state) */ + if(temp_host->state_type == SOFT_STATE && soft_state_dependencies == FALSE) + state = temp_host->last_hard_state; + else + state = temp_host->current_state; + + /* is the host we depend on in state that fails the dependency tests? */ + if(state == HOST_UP && temp_dependency->fail_on_up == TRUE) + return DEPENDENCIES_FAILED; + if(state == HOST_DOWN && temp_dependency->fail_on_down == TRUE) + return DEPENDENCIES_FAILED; + if(state == HOST_UNREACHABLE && temp_dependency->fail_on_unreachable == TRUE) + return DEPENDENCIES_FAILED; + if((state == HOST_UP && temp_host->has_been_checked == FALSE) && temp_dependency->fail_on_pending == TRUE) + return DEPENDENCIES_FAILED; + + /* immediate dependencies ok at this point - check parent dependencies if necessary */ + if(temp_dependency->inherits_parent == TRUE) { + if(check_host_dependencies(temp_host, dependency_type) != DEPENDENCIES_OK) + return DEPENDENCIES_FAILED; + } + } + + return DEPENDENCIES_OK; + } + + + +/* check for hosts that never returned from a check... */ +void check_for_orphaned_hosts(void) { + host *temp_host = NULL; + time_t current_time = 0L; + time_t expected_time = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_orphaned_hosts()\n"); + + /* get the current time */ + time(¤t_time); + + /* check all hosts... */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* skip hosts that don't have a set check interval (on-demand checks are missed by the orphan logic) */ + if(temp_host->next_check == (time_t)0L) + continue; + + /* skip hosts that are not currently executing */ + if(temp_host->is_executing == FALSE) + continue; + + /* determine the time at which the check results should have come in (allow 10 minutes slack time) */ + expected_time = (time_t)(temp_host->next_check + temp_host->latency + host_check_timeout + check_reaper_interval + 600); + + /* this host was supposed to have executed a while ago, but for some reason the results haven't come back in... */ + if(expected_time < current_time) { + + /* log a warning */ + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: The check of host '%s' looks like it was orphaned (results never came back). I'm scheduling an immediate check of the host...\n", temp_host->name); + + log_debug_info(DEBUGL_CHECKS, 1, "Host '%s' was orphaned, so we're scheduling an immediate check...\n", temp_host->name); + + /* decrement the number of running host checks */ + if(currently_running_host_checks > 0) + currently_running_host_checks--; + + /* disable the executing flag */ + temp_host->is_executing = FALSE; + + /* schedule an immediate check of the host */ + schedule_host_check(temp_host, current_time, CHECK_OPTION_ORPHAN_CHECK); + } + + } + + return; + } + + + +/* check freshness of host results */ +void check_host_result_freshness(void) { + host *temp_host = NULL; + time_t current_time = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_host_result_freshness()\n"); + log_debug_info(DEBUGL_CHECKS, 2, "Attempting to check the freshness of host check results...\n"); + + /* bail out if we're not supposed to be checking freshness */ + if(check_host_freshness == FALSE) { + log_debug_info(DEBUGL_CHECKS, 2, "Host freshness checking is disabled.\n"); + return; + } + + /* get the current time */ + time(¤t_time); + + /* check all hosts... */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* skip hosts we shouldn't be checking for freshness */ + if(temp_host->check_freshness == FALSE) + continue; + + /* skip hosts that have both active and passive checks disabled */ + if(temp_host->checks_enabled == FALSE && temp_host->accept_passive_host_checks == FALSE) + continue; + + /* skip hosts that are currently executing (problems here will be caught by orphaned host check) */ + if(temp_host->is_executing == TRUE) + continue; + + /* skip hosts that are already being freshened */ + if(temp_host->is_being_freshened == TRUE) + continue; + + /* see if the time is right... */ + if(check_time_against_period(current_time, temp_host->check_period_ptr) == ERROR) + continue; + + /* the results for the last check of this host are stale */ + if(is_host_result_fresh(temp_host, current_time, TRUE) == FALSE) { + + /* set the freshen flag */ + temp_host->is_being_freshened = TRUE; + + /* schedule an immediate forced check of the host */ + schedule_host_check(temp_host, current_time, CHECK_OPTION_FORCE_EXECUTION | CHECK_OPTION_FRESHNESS_CHECK); + } + } + + return; + } + + + +/* checks to see if a hosts's check results are fresh */ +int is_host_result_fresh(host *temp_host, time_t current_time, int log_this) { + time_t expiration_time = 0L; + int freshness_threshold = 0; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + int tdays = 0; + int thours = 0; + int tminutes = 0; + int tseconds = 0; + double interval = 0; + + log_debug_info(DEBUGL_CHECKS, 2, "Checking freshness of host '%s'...\n", temp_host->name); + + /* use user-supplied freshness threshold or auto-calculate a freshness threshold to use? */ + if(temp_host->freshness_threshold == 0) { + if(temp_host->state_type == HARD_STATE || temp_host->current_state == STATE_OK) { + interval = temp_host->check_interval; + } + else { + interval = temp_host->retry_interval; + } + freshness_threshold = (interval * interval_length) + temp_host->latency + additional_freshness_latency; + } + else + freshness_threshold = temp_host->freshness_threshold; + + log_debug_info(DEBUGL_CHECKS, 2, "Freshness thresholds: host=%d, use=%d\n", temp_host->freshness_threshold, freshness_threshold); + + /* calculate expiration time */ + /* + * CHANGED 11/10/05 EG: + * program start is only used in expiration time calculation + * if > last check AND active checks are enabled, so active checks + * can become stale immediately upon program startup + */ + if(temp_host->has_been_checked == FALSE) + expiration_time = (time_t)(event_start + freshness_threshold); + /* + * CHANGED 06/19/07 EG: + * Per Ton's suggestion (and user requests), only use program start + * time over last check if no specific threshold has been set by user. + * Problems can occur if Nagios is restarted more frequently that + * freshness threshold intervals (hosts never go stale). + */ + /* + * CHANGED 10/07/07 EG: + * Added max_host_check_spread to expiration time as suggested by + * Altinity + */ + else if(temp_host->checks_enabled == TRUE && event_start > temp_host->last_check && temp_host->freshness_threshold == 0) + expiration_time = (time_t)(event_start + freshness_threshold + (max_host_check_spread * interval_length)); + else + expiration_time = (time_t)(temp_host->last_check + freshness_threshold); + + /* + * If the check was last done passively, we assume it's going + * to continue that way and we need to handle the fact that + * Nagios might have been shut off for quite a long time. If so, + * we mustn't spam freshness notifications but use event_start + * instead of last_check to determine freshness expiration time. + * The threshold for "long time" is determined as 61.8% of the normal + * freshness threshold based on vast heuristical research (ie, "some + * guy once told me the golden ratio is good for loads of stuff"). + */ + if(temp_host->check_type == HOST_CHECK_PASSIVE) { + if(temp_host->last_check < event_start && + event_start - last_program_stop > freshness_threshold * 0.618) { + expiration_time = event_start + freshness_threshold; + } + } + + log_debug_info(DEBUGL_CHECKS, 2, "HBC: %d, PS: %lu, ES: %lu, LC: %lu, CT: %lu, ET: %lu\n", temp_host->has_been_checked, (unsigned long)program_start, (unsigned long)event_start, (unsigned long)temp_host->last_check, (unsigned long)current_time, (unsigned long)expiration_time); + + /* the results for the last check of this host are stale */ + if(expiration_time < current_time) { + + get_time_breakdown((current_time - expiration_time), &days, &hours, &minutes, &seconds); + get_time_breakdown(freshness_threshold, &tdays, &thours, &tminutes, &tseconds); + + /* log a warning */ + if(log_this == TRUE) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: The results of host '%s' are stale by %dd %dh %dm %ds (threshold=%dd %dh %dm %ds). I'm forcing an immediate check of the host.\n", temp_host->name, days, hours, minutes, seconds, tdays, thours, tminutes, tseconds); + + log_debug_info(DEBUGL_CHECKS, 1, "Check results for host '%s' are stale by %dd %dh %dm %ds (threshold=%dd %dh %dm %ds). Forcing an immediate check of the host...\n", temp_host->name, days, hours, minutes, seconds, tdays, thours, tminutes, tseconds); + + return FALSE; + } + else + log_debug_info(DEBUGL_CHECKS, 1, "Check results for host '%s' are fresh.\n", temp_host->name); + + return TRUE; + } + + + +/******************************************************************/ +/************* NAGIOS 3.X ROUTE/HOST CHECK FUNCTIONS **************/ +/******************************************************************/ + + +/*** ON-DEMAND HOST CHECKS USE THIS FUNCTION ***/ +/* check to see if we can reach the host */ +int perform_on_demand_host_check_3x(host *hst, int *check_result_code, int check_options, int use_cached_result, unsigned long check_timestamp_horizon) { + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "perform_on_demand_host_check_3x()\n"); + + /* make sure we have a host */ + if(hst == NULL) + return ERROR; + + log_debug_info(DEBUGL_CHECKS, 0, "** On-demand check for host '%s'...\n", hst->name); + + /* check the status of the host */ + result = run_sync_host_check_3x(hst, check_result_code, check_options, use_cached_result, check_timestamp_horizon); + + return result; + } + + + +/* perform a synchronous check of a host */ +/* on-demand host checks will use this... */ +int run_sync_host_check_3x(host *hst, int *check_result_code, int check_options, int use_cached_result, unsigned long check_timestamp_horizon) { + int result = OK; + time_t current_time = 0L; + int host_result = HOST_UP; + char *old_plugin_output = NULL; + struct timeval start_time; + struct timeval end_time; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_sync_host_check_3x()\n"); + + /* make sure we have a host */ + if(hst == NULL) + return ERROR; + + log_debug_info(DEBUGL_CHECKS, 0, "** Run sync check of host '%s'...\n", hst->name); + + /* is the host check viable at this time? */ + /* if not, return current state and bail out */ + if(check_host_check_viability_3x(hst, check_options, NULL, NULL) == ERROR) { + if(check_result_code) + *check_result_code = hst->current_state; + log_debug_info(DEBUGL_CHECKS, 0, "Host check is not viable at this time.\n"); + return OK; + } + + /* get the current time */ + time(¤t_time); + + /* high resolution start time for event broker */ + gettimeofday(&start_time, NULL); + + /* can we use the last cached host state? */ + if(use_cached_result == TRUE && !(check_options & CHECK_OPTION_FORCE_EXECUTION)) { + + /* we can used the cached result, so return it and get out of here... */ + if(hst->has_been_checked == TRUE && ((current_time - hst->last_check) <= check_timestamp_horizon)) { + if(check_result_code) + *check_result_code = hst->current_state; + + log_debug_info(DEBUGL_CHECKS, 1, "* Using cached host state: %d\n", hst->current_state); + + /* update check statistics */ + update_check_stats(ACTIVE_ONDEMAND_HOST_CHECK_STATS, current_time); + update_check_stats(ACTIVE_CACHED_HOST_CHECK_STATS, current_time); + + return OK; + } + } + + + log_debug_info(DEBUGL_CHECKS, 1, "* Running actual host check: old state=%d\n", hst->current_state); + + + /******** GOOD TO GO FOR A REAL HOST CHECK AT THIS POINT ********/ + + /* update check statistics */ + update_check_stats(ACTIVE_ONDEMAND_HOST_CHECK_STATS, current_time); + update_check_stats(SERIAL_HOST_CHECK_STATS, start_time.tv_sec); + + /* reset host check latency, since on-demand checks have none */ + hst->latency = 0.0; + + /* adjust host check attempt */ + adjust_host_check_attempt_3x(hst, TRUE); + + /* save old host state */ + hst->last_state = hst->current_state; + if(hst->state_type == HARD_STATE) + hst->last_hard_state = hst->current_state; + + /* save old plugin output for state stalking */ + if(hst->plugin_output) + old_plugin_output = (char *)strdup(hst->plugin_output); + + /* set the checked flag */ + hst->has_been_checked = TRUE; + + /* clear the freshness flag */ + hst->is_being_freshened = FALSE; + + /* clear check options - we don't want old check options retained */ + hst->check_options = CHECK_OPTION_NONE; + + /* set the check type */ + hst->check_type = HOST_CHECK_ACTIVE; + + + /*********** EXECUTE THE CHECK AND PROCESS THE RESULTS **********/ + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + broker_host_check(NEBTYPE_HOSTCHECK_INITIATE, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, hst->current_state, hst->state_type, start_time, end_time, hst->host_check_command, hst->latency, 0.0, host_check_timeout, FALSE, 0, NULL, NULL, NULL, NULL, NULL); +#endif + + /* execute the host check */ + host_result = execute_sync_host_check_3x(hst); + + /* process the host check result */ + process_host_check_result_3x(hst, host_result, old_plugin_output, check_options, FALSE, use_cached_result, check_timestamp_horizon); + + /* free memory */ + my_free(old_plugin_output); + + log_debug_info(DEBUGL_CHECKS, 1, "* Sync host check done: new state=%d\n", hst->current_state); + + /* high resolution end time for event broker */ + gettimeofday(&end_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_host_check(NEBTYPE_HOSTCHECK_PROCESSED, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, hst->current_state, hst->state_type, start_time, end_time, hst->host_check_command, hst->latency, hst->execution_time, host_check_timeout, FALSE, hst->current_state, NULL, hst->plugin_output, hst->long_plugin_output, hst->perf_data, NULL); +#endif + + return result; + } + + + +/* run an "alive" check on a host */ +/* on-demand host checks will use this... */ +int execute_sync_host_check_3x(host *hst) { + nagios_macros mac; + int result = STATE_OK; + int return_result = HOST_UP; + char *processed_command = NULL; + char *raw_command = NULL; + struct timeval start_time; + struct timeval end_time; + char *temp_ptr; + int early_timeout = FALSE; + double exectime; + char *temp_plugin_output = NULL; +#ifdef USE_EVENT_BROKER + int neb_result = OK; +#endif + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "execute_sync_host_check_3x()\n"); + + if(hst == NULL) + return HOST_DOWN; + + log_debug_info(DEBUGL_CHECKS, 0, "** Executing sync check of host '%s'...\n", hst->name); + +#ifdef USE_EVENT_BROKER + /* initialize start/end times */ + start_time.tv_sec = 0L; + start_time.tv_usec = 0L; + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + + /* send data to event broker */ + neb_result = broker_host_check(NEBTYPE_HOSTCHECK_SYNC_PRECHECK, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, hst->current_state, hst->state_type, start_time, end_time, hst->host_check_command, hst->latency, 0.0, host_check_timeout, FALSE, 0, NULL, NULL, NULL, NULL, NULL); + + /* neb module wants to cancel the host check - return the current state of the host */ + if(neb_result == NEBERROR_CALLBACKCANCEL) + return hst->current_state; + + /* neb module wants to override the host check - perhaps it will check the host itself */ + /* NOTE: if a module does this, it must check the status of the host and populate the data structures BEFORE it returns from the callback! */ + if(neb_result == NEBERROR_CALLBACKOVERRIDE) + return hst->current_state; +#endif + + /* grab the host macros */ + memset(&mac, 0, sizeof(mac)); + grab_host_macros_r(&mac, hst); + + /* high resolution start time for event broker */ + gettimeofday(&start_time, NULL); + + /* get the last host check time */ + time(&hst->last_check); + + /* get the raw command line */ + get_raw_command_line_r(&mac, hst->check_command_ptr, hst->host_check_command, &raw_command, 0); + if(raw_command == NULL) { + clear_volatile_macros_r(&mac); + return ERROR; + } + + /* process any macros contained in the argument */ + process_macros_r(&mac, raw_command, &processed_command, 0); + if(processed_command == NULL) { + my_free(raw_command); + clear_volatile_macros_r(&mac); + return ERROR; + } + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + broker_host_check(NEBTYPE_HOSTCHECK_RAW_START, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, return_result, hst->state_type, start_time, end_time, hst->host_check_command, 0.0, 0.0, host_check_timeout, early_timeout, result, processed_command, hst->plugin_output, hst->long_plugin_output, hst->perf_data, NULL); +#endif + + log_debug_info(DEBUGL_COMMANDS, 1, "Raw host check command: %s\n", raw_command); + log_debug_info(DEBUGL_COMMANDS, 0, "Processed host check ommand: %s\n", processed_command); + my_free(raw_command); + + /* clear plugin output and performance data buffers */ + my_free(hst->plugin_output); + my_free(hst->long_plugin_output); + my_free(hst->perf_data); + + /* run the host check command */ + result = my_system_r(&mac, processed_command, host_check_timeout, &early_timeout, &exectime, &temp_plugin_output, MAX_PLUGIN_OUTPUT_LENGTH); + clear_volatile_macros_r(&mac); + + /* if the check timed out, report an error */ + if(early_timeout == TRUE) { + + my_free(temp_plugin_output); + asprintf(&temp_plugin_output, "Host check timed out after %d seconds\n", host_check_timeout); + + /* log the timeout */ + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host check command '%s' for host '%s' timed out after %d seconds\n", processed_command, hst->name, host_check_timeout); + } + + /* calculate total execution time */ + hst->execution_time = exectime; + + /* record check type */ + hst->check_type = HOST_CHECK_ACTIVE; + + /* parse the output: short and long output, and perf data */ + parse_check_output(temp_plugin_output, &hst->plugin_output, &hst->long_plugin_output, &hst->perf_data, TRUE, TRUE); + + /* free memory */ + my_free(temp_plugin_output); + my_free(processed_command); + + /* a NULL host check command means we should assume the host is UP */ + if(hst->host_check_command == NULL) { + my_free(hst->plugin_output); + hst->plugin_output = (char *)strdup("(Host assumed to be UP)"); + result = STATE_OK; + } + + /* make sure we have some data */ + if(hst->plugin_output == NULL || !strcmp(hst->plugin_output, "")) { + my_free(hst->plugin_output); + hst->plugin_output = (char *)strdup("(No output returned from host check)"); + } + + /* replace semicolons in plugin output (but not performance data) with colons */ + if((temp_ptr = hst->plugin_output)) { + while((temp_ptr = strchr(temp_ptr, ';'))) + * temp_ptr = ':'; + } + + /* if we're not doing aggressive host checking, let WARNING states indicate the host is up (fake the result to be STATE_OK) */ + if(use_aggressive_host_checking == FALSE && result == STATE_WARNING) + result = STATE_OK; + + + if(result == STATE_OK) + return_result = HOST_UP; + else + return_result = HOST_DOWN; + + /* high resolution end time for event broker */ + gettimeofday(&end_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_host_check(NEBTYPE_HOSTCHECK_RAW_END, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, return_result, hst->state_type, start_time, end_time, hst->host_check_command, 0.0, exectime, host_check_timeout, early_timeout, result, processed_command, hst->plugin_output, hst->long_plugin_output, hst->perf_data, NULL); +#endif + + log_debug_info(DEBUGL_CHECKS, 0, "** Sync host check done: state=%d\n", return_result); + + return return_result; + } + + + +/* run a scheduled host check asynchronously */ +int run_scheduled_host_check_3x(host *hst, int check_options, double latency) { + int result = OK; + time_t current_time = 0L; + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + int time_is_valid = TRUE; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_scheduled_host_check_3x()\n"); + + if(hst == NULL) + return ERROR; + + log_debug_info(DEBUGL_CHECKS, 0, "Attempting to run scheduled check of host '%s': check options=%d, latency=%lf\n", hst->name, check_options, latency); + + /* + * reset the next_check_event so we know this host + * check is no longer in the scheduling queue + */ + hst->next_check_event = NULL; + + /* attempt to run the check */ + result = run_async_host_check_3x(hst, check_options, latency, TRUE, TRUE, &time_is_valid, &preferred_time); + + /* an error occurred, so reschedule the check */ + if(result == ERROR) { + + log_debug_info(DEBUGL_CHECKS, 1, "Unable to run scheduled host check at this time\n"); + + /* only attempt to (re)schedule checks that should get checked... */ + if(hst->should_be_scheduled == TRUE) { + + /* get current time */ + time(¤t_time); + + /* determine next time we should check the host if needed */ + /* if host has no check interval, schedule it again for 5 minutes from now */ + if(current_time >= preferred_time) + preferred_time = current_time + ((hst->check_interval <= 0) ? 300 : (hst->check_interval * interval_length)); + + /* make sure we rescheduled the next host check at a valid time */ + get_next_valid_time(preferred_time, &next_valid_time, hst->check_period_ptr); + + /* the host could not be rescheduled properly - set the next check time for next week */ + if(time_is_valid == FALSE && next_valid_time == preferred_time) { + + /* + hst->next_check=(time_t)(next_valid_time+(60*60*24*365)); + hst->should_be_scheduled=FALSE; + */ + + hst->next_check = (time_t)(next_valid_time + (60 * 60 * 24 * 7)); + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Check of host '%s' could not be rescheduled properly. Scheduling check for next week...\n", hst->name); + + log_debug_info(DEBUGL_CHECKS, 1, "Unable to find any valid times to reschedule the next host check!\n"); + } + + /* this service could be rescheduled... */ + else { + hst->next_check = next_valid_time; + hst->should_be_scheduled = TRUE; + + log_debug_info(DEBUGL_CHECKS, 1, "Rescheduled next host check for %s", ctime(&next_valid_time)); + } + } + + /* update the status log */ + update_host_status(hst, FALSE); + + /* reschedule the next host check - unless we couldn't find a valid next check time */ + /* 10/19/07 EG - keep original check options */ + if(hst->should_be_scheduled == TRUE) + schedule_host_check(hst, hst->next_check, check_options); + + return ERROR; + } + + return OK; + } + + + +/* perform an asynchronous check of a host */ +/* scheduled host checks will use this, as will some checks that result from on-demand checks... */ +int run_async_host_check_3x(host *hst, int check_options, double latency, int scheduled_check, int reschedule_check, int *time_is_valid, time_t *preferred_time) { + nagios_macros mac; + char *raw_command = NULL; + char *processed_command = NULL; + char output_buffer[MAX_INPUT_BUFFER] = ""; + char *temp_buffer = NULL; + struct timeval start_time, end_time; + pid_t pid = 0; + int fork_error = FALSE; + int wait_result = 0; + FILE *fp = NULL; + int pclose_result = 0; + mode_t new_umask = 077; + mode_t old_umask; + char *output_file = NULL; + double old_latency = 0.0; + dbuf checkresult_dbuf; + int dbuf_chunk = 1024; +#ifdef USE_EVENT_BROKER + int neb_result = OK; +#endif + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_async_host_check_3x()\n"); + + /* make sure we have a host */ + if(hst == NULL) + return ERROR; + + log_debug_info(DEBUGL_CHECKS, 0, "** Running async check of host '%s'...\n", hst->name); + + /* is the host check viable at this time? */ + if(check_host_check_viability_3x(hst, check_options, time_is_valid, preferred_time) == ERROR) + return ERROR; + + /* 08/04/07 EG don't execute a new host check if one is already running */ + if(hst->is_executing == TRUE && !(check_options & CHECK_OPTION_FORCE_EXECUTION)) { + log_debug_info(DEBUGL_CHECKS, 1, "A check of this host is already being executed, so we'll pass for the moment...\n"); + return ERROR; + } + + /******** GOOD TO GO FOR A REAL HOST CHECK AT THIS POINT ********/ + +#ifdef USE_EVENT_BROKER + /* initialize start/end times */ + start_time.tv_sec = 0L; + start_time.tv_usec = 0L; + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + + /* send data to event broker */ + neb_result = broker_host_check(NEBTYPE_HOSTCHECK_ASYNC_PRECHECK, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, hst->current_state, hst->state_type, start_time, end_time, hst->host_check_command, hst->latency, 0.0, host_check_timeout, FALSE, 0, NULL, NULL, NULL, NULL, NULL); + + /* neb module wants to cancel the host check - the check will be rescheduled for a later time by the scheduling logic */ + if(neb_result == NEBERROR_CALLBACKCANCEL) + return ERROR; + + /* neb module wants to override the host check - perhaps it will check the host itself */ + /* NOTE: if a module does this, it has to do a lot of the stuff found below to make sure things don't get whacked out of shape! */ + if(neb_result == NEBERROR_CALLBACKOVERRIDE) + return OK; +#endif + + log_debug_info(DEBUGL_CHECKS, 0, "Checking host '%s'...\n", hst->name); + + /* clear check options - we don't want old check options retained */ + /* only clear options if this was a scheduled check - on demand check options shouldn't affect retained info */ + if(scheduled_check == TRUE) + hst->check_options = CHECK_OPTION_NONE; + + /* adjust host check attempt */ + adjust_host_check_attempt_3x(hst, TRUE); + + /* set latency (temporarily) for macros and event broker */ + old_latency = hst->latency; + hst->latency = latency; + + /* grab the host macro variables */ + memset(&mac, 0, sizeof(mac)); + grab_host_macros_r(&mac, hst); + + /* get the raw command line */ + get_raw_command_line_r(&mac, hst->check_command_ptr, hst->host_check_command, &raw_command, 0); + if(raw_command == NULL) { + clear_volatile_macros_r(&mac); + log_debug_info(DEBUGL_CHECKS, 0, "Raw check command for host '%s' was NULL - aborting.\n", hst->name); + return ERROR; + } + + /* process any macros contained in the argument */ + process_macros_r(&mac, raw_command, &processed_command, 0); + my_free(raw_command); + if(processed_command == NULL) { + clear_volatile_macros_r(&mac); + log_debug_info(DEBUGL_CHECKS, 0, "Processed check command for host '%s' was NULL - aborting.\n", hst->name); + return ERROR; + } + + /* get the command start time */ + gettimeofday(&start_time, NULL); + + /* set check time for on-demand checks, so they're not incorrectly detected as being orphaned - Luke Ross 5/16/08 */ + /* NOTE: 06/23/08 EG not sure if there will be side effects to this or not.... */ + if(scheduled_check == FALSE) + hst->next_check = start_time.tv_sec; + + /* increment number of host checks that are currently running... */ + currently_running_host_checks++; + + /* set the execution flag */ + hst->is_executing = TRUE; + + /* open a temp file for storing check output */ + old_umask = umask(new_umask); + asprintf(&output_file, "%s/checkXXXXXX", temp_path); + check_result_info.output_file_fd = mkstemp(output_file); + if(check_result_info.output_file_fd >= 0) + check_result_info.output_file_fp = fdopen(check_result_info.output_file_fd, "w"); + else { + check_result_info.output_file_fp = NULL; + check_result_info.output_file_fd = -1; + } + umask(old_umask); + + log_debug_info(DEBUGL_CHECKS | DEBUGL_IPC, 1, "Check result output will be written to '%s' (fd=%d)\n", output_file, check_result_info.output_file_fd); + + /* save check info */ + check_result_info.object_check_type = HOST_CHECK; + check_result_info.host_name = (char *)strdup(hst->name); + check_result_info.service_description = NULL; + check_result_info.check_type = HOST_CHECK_ACTIVE; + check_result_info.check_options = check_options; + check_result_info.scheduled_check = scheduled_check; + check_result_info.reschedule_check = reschedule_check; + check_result_info.output_file = (check_result_info.output_file_fd < 0 || output_file == NULL) ? NULL : strdup(output_file); + check_result_info.latency = latency; + check_result_info.start_time = start_time; + check_result_info.finish_time = start_time; + check_result_info.early_timeout = FALSE; + check_result_info.exited_ok = TRUE; + check_result_info.return_code = STATE_OK; + check_result_info.output = NULL; + + /* free memory */ + my_free(output_file); + + /* write initial check info to file */ + /* if things go bad later on, the user will at least have something to go on when debugging... */ + if(check_result_info.output_file_fp) { + + fprintf(check_result_info.output_file_fp, "### Active Check Result File ###\n"); + fprintf(check_result_info.output_file_fp, "file_time=%lu\n", (unsigned long)check_result_info.start_time.tv_sec); + fprintf(check_result_info.output_file_fp, "\n"); + + fprintf(check_result_info.output_file_fp, "### Nagios Host Check Result ###\n"); + fprintf(check_result_info.output_file_fp, "# Time: %s", ctime(&check_result_info.start_time.tv_sec)); + fprintf(check_result_info.output_file_fp, "host_name=%s\n", check_result_info.host_name); + fprintf(check_result_info.output_file_fp, "check_type=%d\n", check_result_info.check_type); + fprintf(check_result_info.output_file_fp, "check_options=%d\n", check_result_info.check_options); + fprintf(check_result_info.output_file_fp, "scheduled_check=%d\n", check_result_info.scheduled_check); + fprintf(check_result_info.output_file_fp, "reschedule_check=%d\n", check_result_info.reschedule_check); + fprintf(check_result_info.output_file_fp, "latency=%f\n", hst->latency); + fprintf(check_result_info.output_file_fp, "start_time=%lu.%lu\n", check_result_info.start_time.tv_sec, check_result_info.start_time.tv_usec); + + /* flush buffer or we'll end up writing twice when we fork() */ + fflush(check_result_info.output_file_fp); + } + + /* initialize dynamic buffer for storing plugin output */ + dbuf_init(&checkresult_dbuf, dbuf_chunk); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_host_check(NEBTYPE_HOSTCHECK_INITIATE, NEBFLAG_NONE, NEBATTR_NONE, hst, HOST_CHECK_ACTIVE, hst->current_state, hst->state_type, start_time, end_time, hst->host_check_command, hst->latency, 0.0, host_check_timeout, FALSE, 0, processed_command, NULL, NULL, NULL, NULL); +#endif + + /* reset latency (permanent value for this check will get set later) */ + hst->latency = old_latency; + + /* update check statistics */ + update_check_stats((scheduled_check == TRUE) ? ACTIVE_SCHEDULED_HOST_CHECK_STATS : ACTIVE_ONDEMAND_HOST_CHECK_STATS, start_time.tv_sec); + update_check_stats(PARALLEL_HOST_CHECK_STATS, start_time.tv_sec); + + /* fork a child process */ + pid = fork(); + + /* an error occurred while trying to fork */ + if(pid == -1) { + + fork_error = TRUE; + + /* log an error */ + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: The check of host '%s' could not be performed due to a fork() error: '%s'.\n", hst->name, strerror(errno)); + + log_debug_info(DEBUGL_CHECKS, 0, "Check of host '%s' could not be performed due to a fork() error: '%s'!\n", hst->name, strerror(errno)); + } + + /* if we are in the child process... */ + else if(pid == 0) { + + /* set environment variables */ + set_all_macro_environment_vars_r(&mac, TRUE); + + /* ADDED 11/12/07 EG */ + /* close external command file and shut down worker thread */ + close_command_file(); + + /* fork again if we're not in a large installation */ + if(child_processes_fork_twice == TRUE) { + + /* fork again... */ + pid = fork(); + + /* an error occurred while trying to fork again */ + if(pid == -1) + exit(STATE_UNKNOWN); + } + + /* the grandchild (or child if large install tweaks are enabled) process should run the host check... */ + if(pid == 0 || child_processes_fork_twice == FALSE) { + + /* reset signal handling */ + reset_sighandler(); + + /* become the process group leader */ + setpgid(0, 0); + + /* exit on term signals at this process level */ + signal(SIGTERM, SIG_DFL); + + /* catch plugins that don't finish in a timely manner */ + signal(SIGALRM, host_check_sighandler); + alarm(host_check_timeout); + + /* disable rotation of the debug file */ + max_debug_file_size = 0L; + + /* run the plugin check command */ + fp = popen(processed_command, "r"); + if(fp == NULL) + _exit(STATE_UNKNOWN); + + /* initialize buffer */ + strcpy(output_buffer, ""); + + /* get all lines of plugin output - escape newlines */ + while(fgets(output_buffer, sizeof(output_buffer) - 1, fp)) { + temp_buffer = escape_newlines(output_buffer); + dbuf_strcat(&checkresult_dbuf, temp_buffer); + my_free(temp_buffer); + } + + /* close the process */ + pclose_result = pclose(fp); + + /* reset the alarm and signal handling here */ + signal(SIGALRM, SIG_IGN); + alarm(0); + + /* get the check finish time */ + gettimeofday(&end_time, NULL); + + /* record check result info */ + check_result_info.finish_time = end_time; + check_result_info.early_timeout = FALSE; + + /* test for execution error */ + if(pclose_result == -1) { + pclose_result = STATE_UNKNOWN; + check_result_info.return_code = STATE_CRITICAL; + check_result_info.exited_ok = FALSE; + } + else { + if(WEXITSTATUS(pclose_result) == 0 && WIFSIGNALED(pclose_result)) + check_result_info.return_code = 128 + WTERMSIG(pclose_result); + else + check_result_info.return_code = WEXITSTATUS(pclose_result); + } + + /* write check result to file */ + if(check_result_info.output_file_fp) { + FILE *fp; + + /* protect against signal races */ + fp = check_result_info.output_file_fp; + check_result_info.output_file_fp = NULL; + + fprintf(fp, "finish_time=%lu.%lu\n", check_result_info.finish_time.tv_sec, check_result_info.finish_time.tv_usec); + fprintf(fp, "early_timeout=%d\n", check_result_info.early_timeout); + fprintf(fp, "exited_ok=%d\n", check_result_info.exited_ok); + fprintf(fp, "return_code=%d\n", check_result_info.return_code); + fprintf(fp, "output=%s\n", (checkresult_dbuf.buf == NULL) ? "(null)" : checkresult_dbuf.buf); + + /* close the temp file */ + fclose(fp); + + /* move check result to queue directory */ + move_check_result_to_queue(check_result_info.output_file); + } + + /* free memory */ + dbuf_free(&checkresult_dbuf); + my_free(processed_command); + + /* free check result memory */ + free_check_result(&check_result_info); + + /* return with plugin exit status - not really necessary... */ + _exit(pclose_result); + } + + /* NOTE: this code is never reached if large install tweaks are enabled... */ + + /* unset environment variables */ + set_all_macro_environment_vars_r(&mac, FALSE); + + /* free allocated memory */ + /* this needs to be done last, so we don't free memory for variables before they're used above */ + if(free_child_process_memory == TRUE) + free_memory(&mac); + + /* parent exits immediately - grandchild process is inherited by the INIT process, so we have no zombie problem... */ + _exit(STATE_OK); + } + + /* else the parent should wait for the first child to return... */ + else if(pid > 0) { + clear_volatile_macros_r(&mac); + + log_debug_info(DEBUGL_CHECKS, 2, "Host check is executing in child process (pid=%lu)\n", (unsigned long)pid); + + /* parent should close output file */ + if(check_result_info.output_file_fp) + fclose(check_result_info.output_file_fp); + + /* should this be done in first child process (after spawning grandchild) as well? */ + /* free memory allocated for IPC functionality */ + free_check_result(&check_result_info); + + /* free memory */ + my_free(processed_command); + + /* wait for the first child to return */ + /* if large install tweaks are enabled, we'll clean up the zombie process later */ + if(child_processes_fork_twice == TRUE) + wait_result = waitpid(pid, NULL, 0); + } + + /* see if we were able to run the check... */ + if(fork_error == TRUE) + return ERROR; + + return OK; + } + + + +/* process results of an asynchronous host check */ +int handle_async_host_check_result_3x(host *temp_host, check_result *queued_check_result) { + time_t current_time; + int result = STATE_OK; + int reschedule_check = FALSE; + char *old_plugin_output = NULL; + char *temp_ptr = NULL; + struct timeval start_time_hires; + struct timeval end_time_hires; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_async_host_check_result_3x()\n"); + + /* make sure we have what we need */ + if(temp_host == NULL || queued_check_result == NULL) + return ERROR; + + time(¤t_time); + + log_debug_info(DEBUGL_CHECKS, 1, "** Handling async check result for host '%s'...\n", temp_host->name); + + log_debug_info(DEBUGL_CHECKS, 2, "\tCheck Type: %s\n", (queued_check_result->check_type == HOST_CHECK_ACTIVE) ? "Active" : "Passive"); + log_debug_info(DEBUGL_CHECKS, 2, "\tCheck Options: %d\n", queued_check_result->check_options); + log_debug_info(DEBUGL_CHECKS, 2, "\tScheduled Check?: %s\n", (queued_check_result->scheduled_check == TRUE) ? "Yes" : "No"); + log_debug_info(DEBUGL_CHECKS, 2, "\tReschedule Check?: %s\n", (queued_check_result->reschedule_check == TRUE) ? "Yes" : "No"); + log_debug_info(DEBUGL_CHECKS, 2, "\tExited OK?: %s\n", (queued_check_result->exited_ok == TRUE) ? "Yes" : "No"); + log_debug_info(DEBUGL_CHECKS, 2, "\tExec Time: %.3f\n", temp_host->execution_time); + log_debug_info(DEBUGL_CHECKS, 2, "\tLatency: %.3f\n", temp_host->latency); + log_debug_info(DEBUGL_CHECKS, 2, "\tReturn Status: %d\n", queued_check_result->return_code); + log_debug_info(DEBUGL_CHECKS, 2, "\tOutput: %s\n", (queued_check_result == NULL) ? "NULL" : queued_check_result->output); + + /* decrement the number of host checks still out there... */ + if(queued_check_result->check_type == HOST_CHECK_ACTIVE && currently_running_host_checks > 0) + currently_running_host_checks--; + + /* skip this host check results if its passive and we aren't accepting passive check results */ + if(queued_check_result->check_type == HOST_CHECK_PASSIVE) { + if(accept_passive_host_checks == FALSE) { + log_debug_info(DEBUGL_CHECKS, 0, "Discarding passive host check result because passive host checks are disabled globally.\n"); + return ERROR; + } + if(temp_host->accept_passive_host_checks == FALSE) { + log_debug_info(DEBUGL_CHECKS, 0, "Discarding passive host check result because passive checks are disabled for this host.\n"); + return ERROR; + } + } + + /* clear the freshening flag (it would have been set if this host was determined to be stale) */ + if(queued_check_result->check_options & CHECK_OPTION_FRESHNESS_CHECK) + temp_host->is_being_freshened = FALSE; + + /* DISCARD INVALID FRESHNESS CHECK RESULTS */ + /* If a host goes stale, Nagios will initiate a forced check in order to freshen it. There is a race condition whereby a passive check + could arrive between the 1) initiation of the forced check and 2) the time when the forced check result is processed here. This would + make the host fresh again, so we do a quick check to make sure the host is still stale before we accept the check result. */ + if((queued_check_result->check_options & CHECK_OPTION_FRESHNESS_CHECK) && is_host_result_fresh(temp_host, current_time, FALSE) == TRUE) { + log_debug_info(DEBUGL_CHECKS, 0, "Discarding host freshness check result because the host is currently fresh (race condition avoided).\n"); + return OK; + } + + /* was this check passive or active? */ + temp_host->check_type = (queued_check_result->check_type == HOST_CHECK_ACTIVE) ? HOST_CHECK_ACTIVE : HOST_CHECK_PASSIVE; + + /* update check statistics for passive results */ + if(queued_check_result->check_type == HOST_CHECK_PASSIVE) + update_check_stats(PASSIVE_HOST_CHECK_STATS, queued_check_result->start_time.tv_sec); + + /* should we reschedule the next check of the host? NOTE: this might be overridden later... */ + reschedule_check = queued_check_result->reschedule_check; + + /* check latency is passed to us for both active and passive checks */ + temp_host->latency = queued_check_result->latency; + + /* update the execution time for this check (millisecond resolution) */ + temp_host->execution_time = (double)((double)(queued_check_result->finish_time.tv_sec - queued_check_result->start_time.tv_sec) + (double)((queued_check_result->finish_time.tv_usec - queued_check_result->start_time.tv_usec) / 1000.0) / 1000.0); + if(temp_host->execution_time < 0.0) + temp_host->execution_time = 0.0; + + /* set the checked flag */ + temp_host->has_been_checked = TRUE; + + /* clear the execution flag if this was an active check */ + if(queued_check_result->check_type == HOST_CHECK_ACTIVE) + temp_host->is_executing = FALSE; + + /* get the last check time */ + temp_host->last_check = queued_check_result->start_time.tv_sec; + + /* was this check passive or active? */ + temp_host->check_type = (queued_check_result->check_type == HOST_CHECK_ACTIVE) ? HOST_CHECK_ACTIVE : HOST_CHECK_PASSIVE; + + /* save the old host state */ + temp_host->last_state = temp_host->current_state; + if(temp_host->state_type == HARD_STATE) + temp_host->last_hard_state = temp_host->current_state; + + /* save old plugin output */ + if(temp_host->plugin_output) + old_plugin_output = (char *)strdup(temp_host->plugin_output); + + /* clear the old plugin output and perf data buffers */ + my_free(temp_host->plugin_output); + my_free(temp_host->long_plugin_output); + my_free(temp_host->perf_data); + + /* parse check output to get: (1) short output, (2) long output, (3) perf data */ + parse_check_output(queued_check_result->output, &temp_host->plugin_output, &temp_host->long_plugin_output, &temp_host->perf_data, TRUE, TRUE); + + /* make sure we have some data */ + if(temp_host->plugin_output == NULL || !strcmp(temp_host->plugin_output, "")) { + my_free(temp_host->plugin_output); + temp_host->plugin_output = (char *)strdup("(No output returned from host check)"); + } + + /* replace semicolons in plugin output (but not performance data) with colons */ + if((temp_ptr = temp_host->plugin_output)) { + while((temp_ptr = strchr(temp_ptr, ';'))) + * temp_ptr = ':'; + } + + log_debug_info(DEBUGL_CHECKS, 2, "Parsing check output...\n"); + log_debug_info(DEBUGL_CHECKS, 2, "Short Output: %s\n", (temp_host->plugin_output == NULL) ? "NULL" : temp_host->plugin_output); + log_debug_info(DEBUGL_CHECKS, 2, "Long Output: %s\n", (temp_host->long_plugin_output == NULL) ? "NULL" : temp_host->long_plugin_output); + log_debug_info(DEBUGL_CHECKS, 2, "Perf Data: %s\n", (temp_host->perf_data == NULL) ? "NULL" : temp_host->perf_data); + + /* get the unprocessed return code */ + /* NOTE: for passive checks, this is the final/processed state */ + result = queued_check_result->return_code; + + /* adjust return code (active checks only) */ + if(queued_check_result->check_type == HOST_CHECK_ACTIVE) { + + /* if there was some error running the command, just skip it (this shouldn't be happening) */ + if(queued_check_result->exited_ok == FALSE) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Check of host '%s' did not exit properly!\n", temp_host->name); + + my_free(temp_host->plugin_output); + my_free(temp_host->long_plugin_output); + my_free(temp_host->perf_data); + + temp_host->plugin_output = (char *)strdup("(Host check did not exit properly)"); + + result = STATE_CRITICAL; + } + + /* make sure the return code is within bounds */ + else if(queued_check_result->return_code < 0 || queued_check_result->return_code > 3) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Return code of %d for check of host '%s' was out of bounds.%s\n", queued_check_result->return_code, temp_host->name, (queued_check_result->return_code == 126 || queued_check_result->return_code == 127) ? " Make sure the plugin you're trying to run actually exists." : ""); + + my_free(temp_host->plugin_output); + my_free(temp_host->long_plugin_output); + my_free(temp_host->perf_data); + + asprintf(&temp_host->plugin_output, "(Return code of %d is out of bounds%s)", queued_check_result->return_code, (queued_check_result->return_code == 126 || queued_check_result->return_code == 127) ? " - plugin may be missing" : ""); + + result = STATE_CRITICAL; + } + + /* a NULL host check command means we should assume the host is UP */ + if(temp_host->host_check_command == NULL) { + my_free(temp_host->plugin_output); + temp_host->plugin_output = (char *)strdup("(Host assumed to be UP)"); + result = STATE_OK; + } + } + + /* translate return code to basic UP/DOWN state - the DOWN/UNREACHABLE state determination is made later */ + /* NOTE: only do this for active checks - passive check results already have the final state */ + if(queued_check_result->check_type == HOST_CHECK_ACTIVE) { + + /* if we're not doing aggressive host checking, let WARNING states indicate the host is up (fake the result to be STATE_OK) */ + if(use_aggressive_host_checking == FALSE && result == STATE_WARNING) + result = STATE_OK; + + /* OK states means the host is UP */ + if(result == STATE_OK) + result = HOST_UP; + + /* any problem state indicates the host is not UP */ + else + result = HOST_DOWN; + } + + + /******************* PROCESS THE CHECK RESULTS ******************/ + + /* process the host check result */ + process_host_check_result_3x(temp_host, result, old_plugin_output, CHECK_OPTION_NONE, reschedule_check, TRUE, cached_host_check_horizon); + + /* free memory */ + my_free(old_plugin_output); + + log_debug_info(DEBUGL_CHECKS, 1, "** Async check result for host '%s' handled: new state=%d\n", temp_host->name, temp_host->current_state); + + /* high resolution start time for event broker */ + start_time_hires = queued_check_result->start_time; + + /* high resolution end time for event broker */ + gettimeofday(&end_time_hires, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_host_check(NEBTYPE_HOSTCHECK_PROCESSED, NEBFLAG_NONE, NEBATTR_NONE, temp_host, temp_host->check_type, temp_host->current_state, temp_host->state_type, start_time_hires, end_time_hires, temp_host->host_check_command, temp_host->latency, temp_host->execution_time, host_check_timeout, queued_check_result->early_timeout, queued_check_result->return_code, NULL, temp_host->plugin_output, temp_host->long_plugin_output, temp_host->perf_data, NULL); +#endif + + return OK; + } + + + +/* processes the result of a synchronous or asynchronous host check */ +int process_host_check_result_3x(host *hst, int new_state, char *old_plugin_output, int check_options, int reschedule_check, int use_cached_result, unsigned long check_timestamp_horizon) { + hostsmember *temp_hostsmember = NULL; + host *child_host = NULL; + host *parent_host = NULL; + host *master_host = NULL; + host *temp_host = NULL; + hostdependency *temp_dependency = NULL; + objectlist *check_hostlist = NULL; + objectlist *hostlist_item = NULL; + int parent_state = HOST_UP; + time_t current_time = 0L; + time_t next_check = 0L; + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + int run_async_check = TRUE; + void *ptr = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_host_check_result_3x()\n"); + + log_debug_info(DEBUGL_CHECKS, 1, "HOST: %s, ATTEMPT=%d/%d, CHECK TYPE=%s, STATE TYPE=%s, OLD STATE=%d, NEW STATE=%d\n", hst->name, hst->current_attempt, hst->max_attempts, (hst->check_type == HOST_CHECK_ACTIVE) ? "ACTIVE" : "PASSIVE", (hst->state_type == HARD_STATE) ? "HARD" : "SOFT", hst->current_state, new_state); + + /* get the current time */ + time(¤t_time); + + /* default next check time */ + next_check = (unsigned long)(current_time + (hst->check_interval * interval_length)); + + /* we have to adjust current attempt # for passive checks, as it isn't done elsewhere */ + if(hst->check_type == HOST_CHECK_PASSIVE && passive_host_checks_are_soft == TRUE) + adjust_host_check_attempt_3x(hst, FALSE); + + /* log passive checks - we need to do this here, as some my bypass external commands by getting dropped in checkresults dir */ + if(hst->check_type == HOST_CHECK_PASSIVE) { + if(log_passive_checks == TRUE) + logit(NSLOG_PASSIVE_CHECK, FALSE, "PASSIVE HOST CHECK: %s;%d;%s\n", hst->name, new_state, hst->plugin_output); + } + + + /******* HOST WAS DOWN/UNREACHABLE INITIALLY *******/ + if(hst->current_state != HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 1, "Host was DOWN/UNREACHABLE.\n"); + + /***** HOST IS NOW UP *****/ + /* the host just recovered! */ + if(new_state == HOST_UP) { + + /* set the current state */ + hst->current_state = HOST_UP; + + /* set the state type */ + /* set state type to HARD for passive checks and active checks that were previously in a HARD STATE */ + if(hst->state_type == HARD_STATE || (hst->check_type == HOST_CHECK_PASSIVE && passive_host_checks_are_soft == FALSE)) + hst->state_type = HARD_STATE; + else + hst->state_type = SOFT_STATE; + + log_debug_info(DEBUGL_CHECKS, 1, "Host experienced a %s recovery (it's now UP).\n", (hst->state_type == HARD_STATE) ? "HARD" : "SOFT"); + + /* reschedule the next check of the host at the normal interval */ + reschedule_check = TRUE; + next_check = (unsigned long)(current_time + (hst->check_interval * interval_length)); + + /* propagate checks to immediate parents if they are not already UP */ + /* we do this because a parent host (or grandparent) may have recovered somewhere and we should catch the recovery as soon as possible */ + log_debug_info(DEBUGL_CHECKS, 1, "Propagating checks to parent host(s)...\n"); + + for(temp_hostsmember = hst->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if((parent_host = temp_hostsmember->host_ptr) == NULL) + continue; + if(parent_host->current_state != HOST_UP) { + log_debug_info(DEBUGL_CHECKS, 1, "Check of parent host '%s' queued.\n", parent_host->name); + add_object_to_objectlist(&check_hostlist, (void *)parent_host); + } + } + + /* propagate checks to immediate children if they are not already UP */ + /* we do this because children may currently be UNREACHABLE, but may (as a result of this recovery) switch to UP or DOWN states */ + log_debug_info(DEBUGL_CHECKS, 1, "Propagating checks to child host(s)...\n"); + + for(temp_hostsmember = hst->child_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if((child_host = temp_hostsmember->host_ptr) == NULL) + continue; + if(child_host->current_state != HOST_UP) { + log_debug_info(DEBUGL_CHECKS, 1, "Check of child host '%s' queued.\n", child_host->name); + add_object_to_objectlist(&check_hostlist, (void *)child_host); + } + } + } + + /***** HOST IS STILL DOWN/UNREACHABLE *****/ + /* we're still in a problem state... */ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is still DOWN/UNREACHABLE.\n"); + + /* passive checks are treated as HARD states by default... */ + if(hst->check_type == HOST_CHECK_PASSIVE && passive_host_checks_are_soft == FALSE) { + + /* set the state type */ + hst->state_type = HARD_STATE; + + /* reset the current attempt */ + hst->current_attempt = 1; + } + + /* active checks and passive checks (treated as SOFT states) */ + else { + + /* set the state type */ + /* we've maxed out on the retries */ + if(hst->current_attempt == hst->max_attempts) + hst->state_type = HARD_STATE; + /* the host was in a hard problem state before, so it still is now */ + else if(hst->current_attempt == 1) + hst->state_type = HARD_STATE; + /* the host is in a soft state and the check will be retried */ + else + hst->state_type = SOFT_STATE; + } + + /* make a determination of the host's state */ + /* translate host state between DOWN/UNREACHABLE (only for passive checks if enabled) */ + hst->current_state = new_state; + if(hst->check_type == HOST_CHECK_ACTIVE || translate_passive_host_checks == TRUE) + hst->current_state = determine_host_reachability(hst); + + /* reschedule the next check if the host state changed */ + if(hst->last_state != hst->current_state || hst->last_hard_state != hst->current_state) { + + reschedule_check = TRUE; + + /* schedule a re-check of the host at the retry interval because we can't determine its final state yet... */ + if(hst->state_type == SOFT_STATE) + next_check = (unsigned long)(current_time + (hst->retry_interval * interval_length)); + + /* host has maxed out on retries (or was previously in a hard problem state), so reschedule the next check at the normal interval */ + else + next_check = (unsigned long)(current_time + (hst->check_interval * interval_length)); + } + + } + + } + + /******* HOST WAS UP INITIALLY *******/ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Host was UP.\n"); + + /***** HOST IS STILL UP *****/ + /* either the host never went down since last check */ + if(new_state == HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is still UP.\n"); + + /* set the current state */ + hst->current_state = HOST_UP; + + /* set the state type */ + hst->state_type = HARD_STATE; + + /* reschedule the next check at the normal interval */ + if(reschedule_check == TRUE) + next_check = (unsigned long)(current_time + (hst->check_interval * interval_length)); + } + + /***** HOST IS NOW DOWN/UNREACHABLE *****/ + else { + + log_debug_info(DEBUGL_CHECKS, 1, "Host is now DOWN/UNREACHABLE.\n"); + + /***** SPECIAL CASE FOR HOSTS WITH MAX_ATTEMPTS==1 *****/ + if(hst->max_attempts == 1) { + + log_debug_info(DEBUGL_CHECKS, 1, "Max attempts = 1!.\n"); + + /* set the state type */ + hst->state_type = HARD_STATE; + + /* host has maxed out on retries, so reschedule the next check at the normal interval */ + reschedule_check = TRUE; + next_check = (unsigned long)(current_time + (hst->check_interval * interval_length)); + + /* we need to run SYNCHRONOUS checks of all parent hosts to accurately determine the state of this host */ + /* this is extremely inefficient (reminiscent of Nagios 2.x logic), but there's no other good way around it */ + /* check all parent hosts to see if we're DOWN or UNREACHABLE */ + /* only do this for ACTIVE checks, as PASSIVE checks contain a pre-determined state */ + if(hst->check_type == HOST_CHECK_ACTIVE) { + + log_debug_info(DEBUGL_CHECKS, 1, "** WARNING: Max attempts = 1, so we have to run serial checks of all parent hosts!\n"); + + for(temp_hostsmember = hst->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if((parent_host = temp_hostsmember->host_ptr) == NULL) + continue; + + log_debug_info(DEBUGL_CHECKS, 1, "Running serial check parent host '%s'...\n", parent_host->name); + + /* run an immediate check of the parent host */ + run_sync_host_check_3x(parent_host, &parent_state, check_options, use_cached_result, check_timestamp_horizon); + + /* bail out as soon as we find one parent host that is UP */ + if(parent_state == HOST_UP) { + + log_debug_info(DEBUGL_CHECKS, 1, "Parent host is UP, so this one is DOWN.\n"); + + /* set the current state */ + hst->current_state = HOST_DOWN; + break; + } + } + + if(temp_hostsmember == NULL) { + /* host has no parents, so its up */ + if(hst->parent_hosts == NULL) { + log_debug_info(DEBUGL_CHECKS, 1, "Host has no parents, so it's DOWN.\n"); + hst->current_state = HOST_DOWN; + } + else { + /* no parents were up, so this host is UNREACHABLE */ + log_debug_info(DEBUGL_CHECKS, 1, "No parents were UP, so this host is UNREACHABLE.\n"); + hst->current_state = HOST_UNREACHABLE; + } + } + } + + /* set the host state for passive checks */ + else { + /* set the state */ + hst->current_state = new_state; + + /* translate host state between DOWN/UNREACHABLE for passive checks (if enabled) */ + /* make a determination of the host's state */ + if(translate_passive_host_checks == TRUE) + hst->current_state = determine_host_reachability(hst); + + } + + /* propagate checks to immediate children if they are not UNREACHABLE */ + /* we do this because we may now be blocking the route to child hosts */ + log_debug_info(DEBUGL_CHECKS, 1, "Propagating check to immediate non-UNREACHABLE child hosts...\n"); + + for(temp_hostsmember = hst->child_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if((child_host = temp_hostsmember->host_ptr) == NULL) + continue; + if(child_host->current_state != HOST_UNREACHABLE) { + log_debug_info(DEBUGL_CHECKS, 1, "Check of child host '%s' queued.\n", child_host->name); + add_object_to_objectlist(&check_hostlist, (void *)child_host); + } + } + } + + /***** MAX ATTEMPTS > 1 *****/ + else { + + /* active and (in some cases) passive check results are treated as SOFT states */ + if(hst->check_type == HOST_CHECK_ACTIVE || passive_host_checks_are_soft == TRUE) { + + /* set the state type */ + hst->state_type = SOFT_STATE; + } + + /* by default, passive check results are treated as HARD states */ + else { + + /* set the state type */ + hst->state_type = HARD_STATE; + + /* reset the current attempt */ + hst->current_attempt = 1; + } + + /* make a (in some cases) preliminary determination of the host's state */ + /* translate host state between DOWN/UNREACHABLE (for passive checks only if enabled) */ + hst->current_state = new_state; + if(hst->check_type == HOST_CHECK_ACTIVE || translate_passive_host_checks == TRUE) + hst->current_state = determine_host_reachability(hst); + + /* reschedule a check of the host */ + reschedule_check = TRUE; + + /* schedule a re-check of the host at the retry interval because we can't determine its final state yet... */ + if(hst->check_type == HOST_CHECK_ACTIVE || passive_host_checks_are_soft == TRUE) + next_check = (unsigned long)(current_time + (hst->retry_interval * interval_length)); + + /* schedule a re-check of the host at the normal interval */ + else + next_check = (unsigned long)(current_time + (hst->check_interval * interval_length)); + + /* propagate checks to immediate parents if they are UP */ + /* we do this because a parent host (or grandparent) may have gone down and blocked our route */ + /* checking the parents ASAP will allow us to better determine the final state (DOWN/UNREACHABLE) of this host later */ + log_debug_info(DEBUGL_CHECKS, 1, "Propagating checks to immediate parent hosts that are UP...\n"); + + for(temp_hostsmember = hst->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if((parent_host = temp_hostsmember->host_ptr) == NULL) + continue; + if(parent_host->current_state == HOST_UP) { + add_object_to_objectlist(&check_hostlist, (void *)parent_host); + log_debug_info(DEBUGL_CHECKS, 1, "Check of host '%s' queued.\n", parent_host->name); + } + } + + /* propagate checks to immediate children if they are not UNREACHABLE */ + /* we do this because we may now be blocking the route to child hosts */ + log_debug_info(DEBUGL_CHECKS, 1, "Propagating checks to immediate non-UNREACHABLE child hosts...\n"); + + for(temp_hostsmember = hst->child_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if((child_host = temp_hostsmember->host_ptr) == NULL) + continue; + if(child_host->current_state != HOST_UNREACHABLE) { + log_debug_info(DEBUGL_CHECKS, 1, "Check of child host '%s' queued.\n", child_host->name); + add_object_to_objectlist(&check_hostlist, (void *)child_host); + } + } + + /* check dependencies on second to last host check */ + if(enable_predictive_host_dependency_checks == TRUE && hst->current_attempt == (hst->max_attempts - 1)) { + + /* propagate checks to hosts that THIS ONE depends on for notifications AND execution */ + /* we do to help ensure that the dependency checks are accurate before it comes time to notify */ + log_debug_info(DEBUGL_CHECKS, 1, "Propagating predictive dependency checks to hosts this one depends on...\n"); + + for(temp_dependency = get_first_hostdependency_by_dependent_host(hst->name, &ptr); temp_dependency != NULL; temp_dependency = get_next_hostdependency_by_dependent_host(hst->name, &ptr)) { + if(temp_dependency->dependent_host_ptr == hst && temp_dependency->master_host_ptr != NULL) { + master_host = (host *)temp_dependency->master_host_ptr; + log_debug_info(DEBUGL_CHECKS, 1, "Check of host '%s' queued.\n", master_host->name); + add_object_to_objectlist(&check_hostlist, (void *)master_host); + } + } + } + } + } + } + + log_debug_info(DEBUGL_CHECKS, 1, "Pre-handle_host_state() Host: %s, Attempt=%d/%d, Type=%s, Final State=%d\n", hst->name, hst->current_attempt, hst->max_attempts, (hst->state_type == HARD_STATE) ? "HARD" : "SOFT", hst->current_state); + + /* handle the host state */ + handle_host_state(hst); + + log_debug_info(DEBUGL_CHECKS, 1, "Post-handle_host_state() Host: %s, Attempt=%d/%d, Type=%s, Final State=%d\n", hst->name, hst->current_attempt, hst->max_attempts, (hst->state_type == HARD_STATE) ? "HARD" : "SOFT", hst->current_state); + + + /******************** POST-PROCESSING STUFF *********************/ + + /* if the plugin output differs from previous check and no state change, log the current state/output if state stalking is enabled */ + if(hst->last_state == hst->current_state && compare_strings(old_plugin_output, hst->plugin_output)) { + + if(hst->current_state == HOST_UP && hst->stalk_on_up == TRUE) + log_host_event(hst); + + else if(hst->current_state == HOST_DOWN && hst->stalk_on_down == TRUE) + log_host_event(hst); + + else if(hst->current_state == HOST_UNREACHABLE && hst->stalk_on_unreachable == TRUE) + log_host_event(hst); + } + + /* check to see if the associated host is flapping */ + check_for_host_flapping(hst, TRUE, TRUE, TRUE); + + /* reschedule the next check of the host (usually ONLY for scheduled, active checks, unless overridden above) */ + if(reschedule_check == TRUE) { + + log_debug_info(DEBUGL_CHECKS, 1, "Rescheduling next check of host at %s", ctime(&next_check)); + + /* default is to reschedule host check unless a test below fails... */ + hst->should_be_scheduled = TRUE; + + /* get the new current time */ + time(¤t_time); + + /* make sure we don't get ourselves into too much trouble... */ + if(current_time > next_check) + hst->next_check = current_time; + else + hst->next_check = next_check; + + /* make sure we rescheduled the next service check at a valid time */ + preferred_time = hst->next_check; + get_next_valid_time(preferred_time, &next_valid_time, hst->check_period_ptr); + hst->next_check = next_valid_time; + + /* hosts with non-recurring intervals do not get rescheduled if we're in a HARD or UP state */ + if(hst->check_interval == 0 && (hst->state_type == HARD_STATE || hst->current_state == HOST_UP)) + hst->should_be_scheduled = FALSE; + + /* host with active checks disabled do not get rescheduled */ + if(hst->checks_enabled == FALSE) + hst->should_be_scheduled = FALSE; + + /* schedule a non-forced check if we can */ + if(hst->should_be_scheduled == TRUE) { + schedule_host_check(hst, hst->next_check, CHECK_OPTION_NONE); + } + } + + /* update host status - for both active (scheduled) and passive (non-scheduled) hosts */ + update_host_status(hst, FALSE); + + /* run async checks of all hosts we added above */ + /* don't run a check if one is already executing or we can get by with a cached state */ + for(hostlist_item = check_hostlist; hostlist_item != NULL; hostlist_item = hostlist_item->next) { + run_async_check = TRUE; + temp_host = (host *)hostlist_item->object_ptr; + + log_debug_info(DEBUGL_CHECKS, 2, "ASYNC CHECK OF HOST: %s, CURRENTTIME: %lu, LASTHOSTCHECK: %lu, CACHEDTIMEHORIZON: %lu, USECACHEDRESULT: %d, ISEXECUTING: %d\n", temp_host->name, current_time, temp_host->last_check, check_timestamp_horizon, use_cached_result, temp_host->is_executing); + + if(use_cached_result == TRUE && ((current_time - temp_host->last_check) <= check_timestamp_horizon)) + run_async_check = FALSE; + if(temp_host->is_executing == TRUE) + run_async_check = FALSE; + if(run_async_check == TRUE) + run_async_host_check_3x(temp_host, CHECK_OPTION_NONE, 0.0, FALSE, FALSE, NULL, NULL); + } + free_objectlist(&check_hostlist); + + return OK; + } + + + +/* checks viability of performing a host check */ +int check_host_check_viability_3x(host *hst, int check_options, int *time_is_valid, time_t *new_time) { + int result = OK; + int perform_check = TRUE; + time_t current_time = 0L; + time_t preferred_time = 0L; + int check_interval = 0; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_host_check_viability_3x()\n"); + + /* make sure we have a host */ + if(hst == NULL) + return ERROR; + + /* get the check interval to use if we need to reschedule the check */ + if(hst->state_type == SOFT_STATE && hst->current_state != HOST_UP) + check_interval = (hst->retry_interval * interval_length); + else + check_interval = (hst->check_interval * interval_length); + + /* make sure check interval is positive - otherwise use 5 minutes out for next check */ + if(check_interval <= 0) + check_interval = 300; + + /* get the current time */ + time(¤t_time); + + /* initialize the next preferred check time */ + preferred_time = current_time; + + /* can we check the host right now? */ + if(!(check_options & CHECK_OPTION_FORCE_EXECUTION)) { + + /* if checks of the host are currently disabled... */ + if(hst->checks_enabled == FALSE) { + preferred_time = current_time + check_interval; + perform_check = FALSE; + } + + /* make sure this is a valid time to check the host */ + if(check_time_against_period((unsigned long)current_time, hst->check_period_ptr) == ERROR) { + preferred_time = current_time; + if(time_is_valid) + *time_is_valid = FALSE; + perform_check = FALSE; + } + + /* check host dependencies for execution */ + if(check_host_dependencies(hst, EXECUTION_DEPENDENCY) == DEPENDENCIES_FAILED) { + preferred_time = current_time + check_interval; + perform_check = FALSE; + } + } + + /* pass back the next viable check time */ + if(new_time) + *new_time = preferred_time; + + result = (perform_check == TRUE) ? OK : ERROR; + + return result; + } + + + +/* adjusts current host check attempt before a new check is performed */ +int adjust_host_check_attempt_3x(host *hst, int is_active) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "adjust_host_check_attempt_3x()\n"); + + if(hst == NULL) + return ERROR; + + log_debug_info(DEBUGL_CHECKS, 2, "Adjusting check attempt number for host '%s': current attempt=%d/%d, state=%d, state type=%d\n", hst->name, hst->current_attempt, hst->max_attempts, hst->current_state, hst->state_type); + + /* if host is in a hard state, reset current attempt number */ + if(hst->state_type == HARD_STATE) + hst->current_attempt = 1; + + /* if host is in a soft UP state, reset current attempt number (active checks only) */ + else if(is_active == TRUE && hst->state_type == SOFT_STATE && hst->current_state == HOST_UP) + hst->current_attempt = 1; + + /* increment current attempt number */ + else if(hst->current_attempt < hst->max_attempts) + hst->current_attempt++; + + log_debug_info(DEBUGL_CHECKS, 2, "New check attempt number = %d\n", hst->current_attempt); + + return OK; + } + + + +/* determination of the host's state based on route availability*/ +/* used only to determine difference between DOWN and UNREACHABLE states */ +int determine_host_reachability(host *hst) { + int state = HOST_DOWN; + host *parent_host = NULL; + hostsmember *temp_hostsmember = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "determine_host_reachability()\n"); + + if(hst == NULL) + return HOST_DOWN; + + log_debug_info(DEBUGL_CHECKS, 2, "Determining state of host '%s': current state=%d\n", hst->name, hst->current_state); + + /* host is UP - no translation needed */ + if(hst->current_state == HOST_UP) { + state = HOST_UP; + log_debug_info(DEBUGL_CHECKS, 2, "Host is UP, no state translation needed.\n"); + } + + /* host has no parents, so it is DOWN */ + else if(hst->parent_hosts == NULL) { + state = HOST_DOWN; + log_debug_info(DEBUGL_CHECKS, 2, "Host has no parents, so it is DOWN.\n"); + } + + /* check all parent hosts to see if we're DOWN or UNREACHABLE */ + else { + + for(temp_hostsmember = hst->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if((parent_host = temp_hostsmember->host_ptr) == NULL) + continue; + + /* bail out as soon as we find one parent host that is UP */ + if(parent_host->current_state == HOST_UP) { + /* set the current state */ + state = HOST_DOWN; + log_debug_info(DEBUGL_CHECKS, 2, "At least one parent (%s) is up, so host is DOWN.\n", parent_host->name); + break; + } + } + /* no parents were up, so this host is UNREACHABLE */ + if(temp_hostsmember == NULL) { + state = HOST_UNREACHABLE; + log_debug_info(DEBUGL_CHECKS, 2, "No parents were up, so host is UNREACHABLE.\n"); + } + } + + return state; + } + + + +/******************************************************************/ +/****************** HOST STATE HANDLER FUNCTIONS ******************/ +/******************************************************************/ + + +/* top level host state handler - occurs after every host check (soft/hard and active/passive) */ +int handle_host_state(host *hst) { + int state_change = FALSE; + int hard_state_change = FALSE; + time_t current_time = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_host_state()\n"); + + /* get current time */ + time(¤t_time); + + /* obsess over this host check */ + obsessive_compulsive_host_check_processor(hst); + + /* update performance data */ + update_host_performance_data(hst); + + /* record latest time for current state */ + switch(hst->current_state) { + case HOST_UP: + hst->last_time_up = current_time; + break; + case HOST_DOWN: + hst->last_time_down = current_time; + break; + case HOST_UNREACHABLE: + hst->last_time_unreachable = current_time; + break; + default: + break; + } + + /* has the host state changed? */ + if(hst->last_state != hst->current_state || (hst->current_state == HOST_UP && hst->state_type == SOFT_STATE)) + state_change = TRUE; + + if(hst->current_attempt >= hst->max_attempts && hst->last_hard_state != hst->current_state) + hard_state_change = TRUE; + + /* if the host state has changed... */ + if(state_change == TRUE || hard_state_change == TRUE) { + + /* reset the next and last notification times */ + hst->last_host_notification = (time_t)0; + hst->next_host_notification = (time_t)0; + + /* reset notification suppression option */ + hst->no_more_notifications = FALSE; + + /* reset the acknowledgement flag if necessary */ + if(hst->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL && (state_change == TRUE || hard_state_change == FALSE)) { + + hst->problem_has_been_acknowledged = FALSE; + hst->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + + /* remove any non-persistant comments associated with the ack */ + delete_host_acknowledgement_comments(hst); + } + else if(hst->acknowledgement_type == ACKNOWLEDGEMENT_STICKY && hst->current_state == HOST_UP) { + + hst->problem_has_been_acknowledged = FALSE; + hst->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + + /* remove any non-persistant comments associated with the ack */ + delete_host_acknowledgement_comments(hst); + } + + } + + /* Not sure about this, but is old behaviour */ + if(hst->last_hard_state != hst->current_state) + hard_state_change = TRUE; + + if(state_change == TRUE || hard_state_change == TRUE) { + + /* update last state change times */ + hst->last_state_change = current_time; + if(hst->state_type == HARD_STATE) + hst->last_hard_state_change = current_time; + + /* update the event id */ + hst->last_event_id = hst->current_event_id; + hst->current_event_id = next_event_id; + next_event_id++; + + /* update the problem id when transitioning to a problem state */ + if(hst->last_state == HOST_UP) { + /* don't reset last problem id, or it will be zero the next time a problem is encountered */ + /*hst->last_problem_id=hst->current_problem_id;*/ + hst->current_problem_id = next_problem_id; + next_problem_id++; + } + + /* clear the problem id when transitioning from a problem state to an UP state */ + if(hst->current_state == HOST_UP) { + hst->last_problem_id = hst->current_problem_id; + hst->current_problem_id = 0L; + } + + /* write the host state change to the main log file */ + if(hst->state_type == HARD_STATE || (hst->state_type == SOFT_STATE && log_host_retries == TRUE)) + log_host_event(hst); + + /* check for start of flexible (non-fixed) scheduled downtime */ + /* CHANGED 08-05-2010 EG flex downtime can now start on soft states */ + /*if(hst->state_type==HARD_STATE)*/ + check_pending_flex_host_downtime(hst); + + /* notify contacts about the recovery or problem if its a "hard" state */ + if(hst->state_type == HARD_STATE) + host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); + + /* handle the host state change */ + handle_host_event(hst); + + /* the host just recovered, so reset the current host attempt */ + if(hst->current_state == HOST_UP) + hst->current_attempt = 1; + + /* the host recovered, so reset the current notification number and state flags (after the recovery notification has gone out) */ + if(hst->current_state == HOST_UP) { + hst->current_notification_number = 0; + hst->notified_on_down = FALSE; + hst->notified_on_unreachable = FALSE; + } + } + + /* else the host state has not changed */ + else { + + /* notify contacts if host is still down or unreachable */ + if(hst->current_state != HOST_UP && hst->state_type == HARD_STATE) + host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); + + /* if we're in a soft state and we should log host retries, do so now... */ + if(hst->state_type == SOFT_STATE && log_host_retries == TRUE) + log_host_event(hst); + } + + return OK; + } + + +/* parse raw plugin output and return: short and long output, perf data */ +int parse_check_output(char *buf, char **short_output, char **long_output, char **perf_data, int escape_newlines_please, int newlines_are_escaped) { + int current_line = 0; + int found_newline = FALSE; + int eof = FALSE; + int used_buf = 0; + int dbuf_chunk = 1024; + dbuf db1; + dbuf db2; + char *ptr = NULL; + int in_perf_data = FALSE; + char *tempbuf = NULL; + register int x = 0; + register int y = 0; + + /* initialize values */ + if(short_output) + *short_output = NULL; + if(long_output) + *long_output = NULL; + if(perf_data) + *perf_data = NULL; + + /* nothing to do */ + if(buf == NULL || !strcmp(buf, "")) + return OK; + + used_buf = strlen(buf) + 1; + + /* initialize dynamic buffers (1KB chunk size) */ + dbuf_init(&db1, dbuf_chunk); + dbuf_init(&db2, dbuf_chunk); + + /* unescape newlines and escaped backslashes first */ + if(newlines_are_escaped == TRUE) { + for(x = 0, y = 0; buf[x] != '\x0'; x++) { + if(buf[x] == '\\' && buf[x + 1] == '\\') { + x++; + buf[y++] = buf[x]; + } + else if(buf[x] == '\\' && buf[x + 1] == 'n') { + x++; + buf[y++] = '\n'; + } + else + buf[y++] = buf[x]; + } + buf[y] = '\x0'; + } + + /* process each line of input */ + for(x = 0; eof == FALSE; x++) { + + /* we found the end of a line */ + if(buf[x] == '\n') + found_newline = TRUE; + else if(buf[x] == '\\' && buf[x + 1] == 'n' && newlines_are_escaped == TRUE) { + found_newline = TRUE; + buf[x] = '\x0'; + x++; + } + else if(buf[x] == '\x0') { + found_newline = TRUE; + eof = TRUE; + } + else + found_newline = FALSE; + + if(found_newline == TRUE) { + + current_line++; + + /* handle this line of input */ + buf[x] = '\x0'; + if((tempbuf = (char *)strdup(buf))) { + + /* first line contains short plugin output and optional perf data */ + if(current_line == 1) { + + /* get the short plugin output */ + if((ptr = strtok(tempbuf, "|"))) { + if(short_output) + *short_output = (char *)strdup(ptr); + + /* get the optional perf data */ + if((ptr = strtok(NULL, "\n"))) + dbuf_strcat(&db2, ptr); + } + } + + /* additional lines contain long plugin output and optional perf data */ + else { + + /* rest of the output is perf data */ + if(in_perf_data == TRUE) { + dbuf_strcat(&db2, tempbuf); + dbuf_strcat(&db2, " "); + } + + /* we're still in long output */ + else { + + /* perf data separator has been found */ + if(strstr(tempbuf, "|")) { + + /* NOTE: strtok() causes problems if first character of tempbuf='|', so use my_strtok() instead */ + /* get the remaining long plugin output */ + if((ptr = my_strtok(tempbuf, "|"))) { + + if(current_line > 2) + dbuf_strcat(&db1, "\n"); + dbuf_strcat(&db1, ptr); + + /* get the perf data */ + if((ptr = my_strtok(NULL, "\n"))) { + dbuf_strcat(&db2, ptr); + dbuf_strcat(&db2, " "); + } + } + + /* set the perf data flag */ + in_perf_data = TRUE; + } + + /* just long output */ + else { + if(current_line > 2) + dbuf_strcat(&db1, "\n"); + dbuf_strcat(&db1, tempbuf); + } + } + } + + my_free(tempbuf); + tempbuf = NULL; + } + + + /* shift data back to front of buffer and adjust counters */ + memmove((void *)&buf[0], (void *)&buf[x + 1], (size_t)((int)used_buf - x - 1)); + used_buf -= (x + 1); + buf[used_buf] = '\x0'; + x = -1; + } + } + + /* save long output */ + if(long_output && (db1.buf && strcmp(db1.buf, ""))) { + + if(escape_newlines_please == FALSE) + *long_output = (char *)strdup(db1.buf); + + else { + + /* escape newlines (and backslashes) in long output */ + if((tempbuf = (char *)malloc((strlen(db1.buf) * 2) + 1))) { + + for(x = 0, y = 0; db1.buf[x] != '\x0'; x++) { + + if(db1.buf[x] == '\n') { + tempbuf[y++] = '\\'; + tempbuf[y++] = 'n'; + } + else if(db1.buf[x] == '\\') { + tempbuf[y++] = '\\'; + tempbuf[y++] = '\\'; + } + else + tempbuf[y++] = db1.buf[x]; + } + + tempbuf[y] = '\x0'; + *long_output = (char *)strdup(tempbuf); + my_free(tempbuf); + } + } + } + + /* save perf data */ + if(perf_data && (db2.buf && strcmp(db2.buf, ""))) + *perf_data = (char *)strdup(db2.buf); + + /* strip short output and perf data */ + if(short_output) + strip(*short_output); + if(perf_data) + strip(*perf_data); + + /* free dynamic buffers */ + dbuf_free(&db1); + dbuf_free(&db2); + + return OK; + } + + diff --git a/base/commands.c b/base/commands.c new file mode 100644 index 0000000..48640d5 --- /dev/null +++ b/base/commands.c @@ -0,0 +1,5223 @@ +/***************************************************************************** + * + * COMMANDS.C - External command functions for Nagios + * + * 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/comments.h" +#include "../include/downtime.h" +#include "../include/statusdata.h" +#include "../include/perfdata.h" +#include "../include/sretention.h" +#include "../include/broker.h" +#include "../include/nagios.h" + +extern char *config_file; +extern char *log_file; +extern char *command_file; +extern char *temp_file; +extern char *temp_path; + +extern int sigshutdown; +extern int sigrestart; + +extern int check_external_commands; + +extern int ipc_pipe[2]; + +extern time_t last_command_check; +extern time_t last_command_status_update; + +extern int command_check_interval; + +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int enable_failure_prediction; +extern int process_performance_data; + +extern int log_external_commands; +extern int log_passive_checks; + +extern unsigned long modified_host_process_attributes; +extern unsigned long modified_service_process_attributes; + +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 host *host_list; +extern service *service_list; + +extern FILE *command_file_fp; +extern int command_file_fd; + +passive_check_result *passive_check_result_list = NULL; +passive_check_result *passive_check_result_list_tail = NULL; + +extern pthread_t worker_threads[TOTAL_WORKER_THREADS]; +extern circular_buffer external_command_buffer; +extern int external_command_buffer_slots; + + + +/******************************************************************/ +/****************** EXTERNAL COMMAND PROCESSING *******************/ +/******************************************************************/ + + +/* checks for the existence of the external command file and processes all commands found in it */ +int check_for_external_commands(void) { + char *buffer = NULL; + int update_status = FALSE; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_external_commands()\n"); + + /* bail out if we shouldn't be checking for external commands */ + if(check_external_commands == FALSE) + return ERROR; + + /* update last command check time */ + last_command_check = time(NULL); + + /* update the status log with new program information */ + /* go easy on the frequency of this if we're checking often - only update program status every 10 seconds.... */ + if(last_command_check < (last_command_status_update + 10)) + update_status = FALSE; + else + update_status = TRUE; + if(update_status == TRUE) { + last_command_status_update = last_command_check; + update_program_status(FALSE); + } + + /* reset passive check result list pointers */ + passive_check_result_list = NULL; + passive_check_result_list_tail = NULL; + + /* process all commands found in the buffer */ + while(1) { + + /* get a lock on the buffer */ + pthread_mutex_lock(&external_command_buffer.buffer_lock); + + /* if no items present, bail out */ + if(external_command_buffer.items <= 0) { + pthread_mutex_unlock(&external_command_buffer.buffer_lock); + break; + } + + if(external_command_buffer.buffer[external_command_buffer.tail]) + buffer = strdup(((char **)external_command_buffer.buffer)[external_command_buffer.tail]); + + /* free memory allocated for buffer slot */ + my_free(((char **)external_command_buffer.buffer)[external_command_buffer.tail]); + + /* adjust tail counter and number of items */ + external_command_buffer.tail = (external_command_buffer.tail + 1) % external_command_buffer_slots; + external_command_buffer.items--; + + /* release the lock on the buffer */ + pthread_mutex_unlock(&external_command_buffer.buffer_lock); + + /* process the command */ + process_external_command1(buffer); + + /* free memory */ + my_free(buffer); + } + + /**** PROCESS ALL PASSIVE HOST AND SERVICE CHECK RESULTS AT ONE TIME ****/ + if(passive_check_result_list != NULL) + process_passive_checks(); + + return OK; + } + + + +/* processes all external commands in a (regular) file */ +int process_external_commands_from_file(char *fname, int delete_file) { + mmapfile *thefile = NULL; + char *input = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_external_commands_from_file()\n"); + + if(fname == NULL) + return ERROR; + + log_debug_info(DEBUGL_EXTERNALCOMMANDS, 1, "Processing commands from file '%s'. File will %s deleted after processing.\n", fname, (delete_file == TRUE) ? "be" : "NOT be"); + + /* open the config file for reading */ + if((thefile = mmap_fopen(fname)) == NULL) { + logit(NSLOG_INFO_MESSAGE, FALSE, "Error: Cannot open file '%s' to process external commands!", fname); + return ERROR; + } + + /* process all commands in the file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets(thefile)) == NULL) + break; + + /* process the command */ + process_external_command1(input); + } + + /* close the file */ + mmap_fclose(thefile); + + /* delete the file */ + if(delete_file == TRUE) + unlink(fname); + + return OK; + } + + + +/* top-level external command processor */ +int process_external_command1(char *cmd) { + char *temp_buffer = NULL; + char *command_id = NULL; + char *args = NULL; + time_t entry_time = 0L; + int command_type = CMD_NONE; + char *temp_ptr = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_external_command1()\n"); + + if(cmd == NULL) + return ERROR; + + /* strip the command of newlines and carriage returns */ + strip(cmd); + + log_debug_info(DEBUGL_EXTERNALCOMMANDS, 2, "Raw command entry: %s\n", cmd); + + /* get the command entry time */ + if((temp_ptr = my_strtok(cmd, "[")) == NULL) + return ERROR; + if((temp_ptr = my_strtok(NULL, "]")) == NULL) + return ERROR; + entry_time = (time_t)strtoul(temp_ptr, NULL, 10); + + /* get the command identifier */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + if((command_id = (char *)strdup(temp_ptr + 1)) == NULL) + return ERROR; + + /* get the command arguments */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) + args = (char *)strdup(""); + else + args = (char *)strdup(temp_ptr); + if(args == NULL) { + my_free(command_id); + return ERROR; + } + + /* decide what type of command this is... */ + + /**************************/ + /**** PROCESS COMMANDS ****/ + /**************************/ + + if(!strcmp(command_id, "ENTER_STANDBY_MODE") || !strcmp(command_id, "DISABLE_NOTIFICATIONS")) + command_type = CMD_DISABLE_NOTIFICATIONS; + else if(!strcmp(command_id, "ENTER_ACTIVE_MODE") || !strcmp(command_id, "ENABLE_NOTIFICATIONS")) + command_type = CMD_ENABLE_NOTIFICATIONS; + + else if(!strcmp(command_id, "SHUTDOWN_PROGRAM") || !strcmp(command_id, "SHUTDOWN_PROCESS")) + command_type = CMD_SHUTDOWN_PROCESS; + else if(!strcmp(command_id, "RESTART_PROGRAM") || !strcmp(command_id, "RESTART_PROCESS")) + command_type = CMD_RESTART_PROCESS; + + else if(!strcmp(command_id, "SAVE_STATE_INFORMATION")) + command_type = CMD_SAVE_STATE_INFORMATION; + else if(!strcmp(command_id, "READ_STATE_INFORMATION")) + command_type = CMD_READ_STATE_INFORMATION; + + else if(!strcmp(command_id, "ENABLE_EVENT_HANDLERS")) + command_type = CMD_ENABLE_EVENT_HANDLERS; + else if(!strcmp(command_id, "DISABLE_EVENT_HANDLERS")) + command_type = CMD_DISABLE_EVENT_HANDLERS; + + else if(!strcmp(command_id, "FLUSH_PENDING_COMMANDS")) + command_type = CMD_FLUSH_PENDING_COMMANDS; + + else if(!strcmp(command_id, "ENABLE_FAILURE_PREDICTION")) + command_type = CMD_ENABLE_FAILURE_PREDICTION; + else if(!strcmp(command_id, "DISABLE_FAILURE_PREDICTION")) + command_type = CMD_DISABLE_FAILURE_PREDICTION; + + else if(!strcmp(command_id, "ENABLE_PERFORMANCE_DATA")) + command_type = CMD_ENABLE_PERFORMANCE_DATA; + else if(!strcmp(command_id, "DISABLE_PERFORMANCE_DATA")) + command_type = CMD_DISABLE_PERFORMANCE_DATA; + + else if(!strcmp(command_id, "START_EXECUTING_HOST_CHECKS")) + command_type = CMD_START_EXECUTING_HOST_CHECKS; + else if(!strcmp(command_id, "STOP_EXECUTING_HOST_CHECKS")) + command_type = CMD_STOP_EXECUTING_HOST_CHECKS; + + else if(!strcmp(command_id, "START_EXECUTING_SVC_CHECKS")) + command_type = CMD_START_EXECUTING_SVC_CHECKS; + else if(!strcmp(command_id, "STOP_EXECUTING_SVC_CHECKS")) + command_type = CMD_STOP_EXECUTING_SVC_CHECKS; + + else if(!strcmp(command_id, "START_ACCEPTING_PASSIVE_HOST_CHECKS")) + command_type = CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS; + else if(!strcmp(command_id, "STOP_ACCEPTING_PASSIVE_HOST_CHECKS")) + command_type = CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS; + + else if(!strcmp(command_id, "START_ACCEPTING_PASSIVE_SVC_CHECKS")) + command_type = CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS; + else if(!strcmp(command_id, "STOP_ACCEPTING_PASSIVE_SVC_CHECKS")) + command_type = CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS; + + else if(!strcmp(command_id, "START_OBSESSING_OVER_HOST_CHECKS")) + command_type = CMD_START_OBSESSING_OVER_HOST_CHECKS; + else if(!strcmp(command_id, "STOP_OBSESSING_OVER_HOST_CHECKS")) + command_type = CMD_STOP_OBSESSING_OVER_HOST_CHECKS; + + else if(!strcmp(command_id, "START_OBSESSING_OVER_SVC_CHECKS")) + command_type = CMD_START_OBSESSING_OVER_SVC_CHECKS; + else if(!strcmp(command_id, "STOP_OBSESSING_OVER_SVC_CHECKS")) + command_type = CMD_STOP_OBSESSING_OVER_SVC_CHECKS; + + else if(!strcmp(command_id, "ENABLE_FLAP_DETECTION")) + command_type = CMD_ENABLE_FLAP_DETECTION; + else if(!strcmp(command_id, "DISABLE_FLAP_DETECTION")) + command_type = CMD_DISABLE_FLAP_DETECTION; + + else if(!strcmp(command_id, "CHANGE_GLOBAL_HOST_EVENT_HANDLER")) + command_type = CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER; + else if(!strcmp(command_id, "CHANGE_GLOBAL_SVC_EVENT_HANDLER")) + command_type = CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER; + + else if(!strcmp(command_id, "ENABLE_SERVICE_FRESHNESS_CHECKS")) + command_type = CMD_ENABLE_SERVICE_FRESHNESS_CHECKS; + else if(!strcmp(command_id, "DISABLE_SERVICE_FRESHNESS_CHECKS")) + command_type = CMD_DISABLE_SERVICE_FRESHNESS_CHECKS; + + else if(!strcmp(command_id, "ENABLE_HOST_FRESHNESS_CHECKS")) + command_type = CMD_ENABLE_HOST_FRESHNESS_CHECKS; + else if(!strcmp(command_id, "DISABLE_HOST_FRESHNESS_CHECKS")) + command_type = CMD_DISABLE_HOST_FRESHNESS_CHECKS; + + + /*******************************/ + /**** HOST-RELATED COMMANDS ****/ + /*******************************/ + + else if(!strcmp(command_id, "ADD_HOST_COMMENT")) + command_type = CMD_ADD_HOST_COMMENT; + else if(!strcmp(command_id, "DEL_HOST_COMMENT")) + command_type = CMD_DEL_HOST_COMMENT; + else if(!strcmp(command_id, "DEL_ALL_HOST_COMMENTS")) + command_type = CMD_DEL_ALL_HOST_COMMENTS; + + else if(!strcmp(command_id, "DELAY_HOST_NOTIFICATION")) + command_type = CMD_DELAY_HOST_NOTIFICATION; + + else if(!strcmp(command_id, "ENABLE_HOST_NOTIFICATIONS")) + command_type = CMD_ENABLE_HOST_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_HOST_NOTIFICATIONS")) + command_type = CMD_DISABLE_HOST_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST")) + command_type = CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST; + else if(!strcmp(command_id, "DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST")) + command_type = CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST; + + else if(!strcmp(command_id, "ENABLE_HOST_AND_CHILD_NOTIFICATIONS")) + command_type = CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_HOST_AND_CHILD_NOTIFICATIONS")) + command_type = CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_HOST_SVC_NOTIFICATIONS")) + command_type = CMD_ENABLE_HOST_SVC_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_HOST_SVC_NOTIFICATIONS")) + command_type = CMD_DISABLE_HOST_SVC_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_HOST_SVC_CHECKS")) + command_type = CMD_ENABLE_HOST_SVC_CHECKS; + else if(!strcmp(command_id, "DISABLE_HOST_SVC_CHECKS")) + command_type = CMD_DISABLE_HOST_SVC_CHECKS; + + else if(!strcmp(command_id, "ENABLE_PASSIVE_HOST_CHECKS")) + command_type = CMD_ENABLE_PASSIVE_HOST_CHECKS; + else if(!strcmp(command_id, "DISABLE_PASSIVE_HOST_CHECKS")) + command_type = CMD_DISABLE_PASSIVE_HOST_CHECKS; + + else if(!strcmp(command_id, "SCHEDULE_HOST_SVC_CHECKS")) + command_type = CMD_SCHEDULE_HOST_SVC_CHECKS; + else if(!strcmp(command_id, "SCHEDULE_FORCED_HOST_SVC_CHECKS")) + command_type = CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS; + + else if(!strcmp(command_id, "ACKNOWLEDGE_HOST_PROBLEM")) + command_type = CMD_ACKNOWLEDGE_HOST_PROBLEM; + else if(!strcmp(command_id, "REMOVE_HOST_ACKNOWLEDGEMENT")) + command_type = CMD_REMOVE_HOST_ACKNOWLEDGEMENT; + + else if(!strcmp(command_id, "ENABLE_HOST_EVENT_HANDLER")) + command_type = CMD_ENABLE_HOST_EVENT_HANDLER; + else if(!strcmp(command_id, "DISABLE_HOST_EVENT_HANDLER")) + command_type = CMD_DISABLE_HOST_EVENT_HANDLER; + + else if(!strcmp(command_id, "ENABLE_HOST_CHECK")) + command_type = CMD_ENABLE_HOST_CHECK; + else if(!strcmp(command_id, "DISABLE_HOST_CHECK")) + command_type = CMD_DISABLE_HOST_CHECK; + + else if(!strcmp(command_id, "SCHEDULE_HOST_CHECK")) + command_type = CMD_SCHEDULE_HOST_CHECK; + else if(!strcmp(command_id, "SCHEDULE_FORCED_HOST_CHECK")) + command_type = CMD_SCHEDULE_FORCED_HOST_CHECK; + + else if(!strcmp(command_id, "SCHEDULE_HOST_DOWNTIME")) + command_type = CMD_SCHEDULE_HOST_DOWNTIME; + else if(!strcmp(command_id, "SCHEDULE_HOST_SVC_DOWNTIME")) + command_type = CMD_SCHEDULE_HOST_SVC_DOWNTIME; + else if(!strcmp(command_id, "DEL_HOST_DOWNTIME")) + command_type = CMD_DEL_HOST_DOWNTIME; + else if(!strcmp(command_id, "DEL_DOWNTIME_BY_HOST_NAME")) + command_type = CMD_DEL_DOWNTIME_BY_HOST_NAME; + else if(!strcmp(command_id, "DEL_DOWNTIME_BY_HOSTGROUP_NAME")) + command_type = CMD_DEL_DOWNTIME_BY_HOSTGROUP_NAME; + else if(!strcmp(command_id, "DEL_DOWNTIME_BY_START_TIME_COMMENT")) + command_type = CMD_DEL_DOWNTIME_BY_START_TIME_COMMENT; + + else if(!strcmp(command_id, "ENABLE_HOST_FLAP_DETECTION")) + command_type = CMD_ENABLE_HOST_FLAP_DETECTION; + else if(!strcmp(command_id, "DISABLE_HOST_FLAP_DETECTION")) + command_type = CMD_DISABLE_HOST_FLAP_DETECTION; + + else if(!strcmp(command_id, "START_OBSESSING_OVER_HOST")) + command_type = CMD_START_OBSESSING_OVER_HOST; + else if(!strcmp(command_id, "STOP_OBSESSING_OVER_HOST")) + command_type = CMD_STOP_OBSESSING_OVER_HOST; + + else if(!strcmp(command_id, "CHANGE_HOST_EVENT_HANDLER")) + command_type = CMD_CHANGE_HOST_EVENT_HANDLER; + else if(!strcmp(command_id, "CHANGE_HOST_CHECK_COMMAND")) + command_type = CMD_CHANGE_HOST_CHECK_COMMAND; + + else if(!strcmp(command_id, "CHANGE_NORMAL_HOST_CHECK_INTERVAL")) + command_type = CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL; + else if(!strcmp(command_id, "CHANGE_RETRY_HOST_CHECK_INTERVAL")) + command_type = CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL; + + else if(!strcmp(command_id, "CHANGE_MAX_HOST_CHECK_ATTEMPTS")) + command_type = CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS; + + else if(!strcmp(command_id, "SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME")) + command_type = CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME; + + else if(!strcmp(command_id, "SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME")) + command_type = CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME; + + else if(!strcmp(command_id, "SET_HOST_NOTIFICATION_NUMBER")) + command_type = CMD_SET_HOST_NOTIFICATION_NUMBER; + + else if(!strcmp(command_id, "CHANGE_HOST_CHECK_TIMEPERIOD")) + command_type = CMD_CHANGE_HOST_CHECK_TIMEPERIOD; + + else if(!strcmp(command_id, "CHANGE_CUSTOM_HOST_VAR")) + command_type = CMD_CHANGE_CUSTOM_HOST_VAR; + + else if(!strcmp(command_id, "SEND_CUSTOM_HOST_NOTIFICATION")) + command_type = CMD_SEND_CUSTOM_HOST_NOTIFICATION; + + else if(!strcmp(command_id, "CHANGE_HOST_NOTIFICATION_TIMEPERIOD")) + command_type = CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD; + + else if(!strcmp(command_id, "CHANGE_HOST_MODATTR")) + command_type = CMD_CHANGE_HOST_MODATTR; + + + /************************************/ + /**** HOSTGROUP-RELATED COMMANDS ****/ + /************************************/ + + else if(!strcmp(command_id, "ENABLE_HOSTGROUP_HOST_NOTIFICATIONS")) + command_type = CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_HOSTGROUP_HOST_NOTIFICATIONS")) + command_type = CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_HOSTGROUP_SVC_NOTIFICATIONS")) + command_type = CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_HOSTGROUP_SVC_NOTIFICATIONS")) + command_type = CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_HOSTGROUP_HOST_CHECKS")) + command_type = CMD_ENABLE_HOSTGROUP_HOST_CHECKS; + else if(!strcmp(command_id, "DISABLE_HOSTGROUP_HOST_CHECKS")) + command_type = CMD_DISABLE_HOSTGROUP_HOST_CHECKS; + + else if(!strcmp(command_id, "ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")) + command_type = CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS; + else if(!strcmp(command_id, "DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")) + command_type = CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS; + + else if(!strcmp(command_id, "ENABLE_HOSTGROUP_SVC_CHECKS")) + command_type = CMD_ENABLE_HOSTGROUP_SVC_CHECKS; + else if(!strcmp(command_id, "DISABLE_HOSTGROUP_SVC_CHECKS")) + command_type = CMD_DISABLE_HOSTGROUP_SVC_CHECKS; + + else if(!strcmp(command_id, "ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")) + command_type = CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS; + else if(!strcmp(command_id, "DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")) + command_type = CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS; + + else if(!strcmp(command_id, "SCHEDULE_HOSTGROUP_HOST_DOWNTIME")) + command_type = CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME; + else if(!strcmp(command_id, "SCHEDULE_HOSTGROUP_SVC_DOWNTIME")) + command_type = CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME; + + + /**********************************/ + /**** SERVICE-RELATED COMMANDS ****/ + /**********************************/ + + else if(!strcmp(command_id, "ADD_SVC_COMMENT")) + command_type = CMD_ADD_SVC_COMMENT; + else if(!strcmp(command_id, "DEL_SVC_COMMENT")) + command_type = CMD_DEL_SVC_COMMENT; + else if(!strcmp(command_id, "DEL_ALL_SVC_COMMENTS")) + command_type = CMD_DEL_ALL_SVC_COMMENTS; + + else if(!strcmp(command_id, "SCHEDULE_SVC_CHECK")) + command_type = CMD_SCHEDULE_SVC_CHECK; + else if(!strcmp(command_id, "SCHEDULE_FORCED_SVC_CHECK")) + command_type = CMD_SCHEDULE_FORCED_SVC_CHECK; + + else if(!strcmp(command_id, "ENABLE_SVC_CHECK")) + command_type = CMD_ENABLE_SVC_CHECK; + else if(!strcmp(command_id, "DISABLE_SVC_CHECK")) + command_type = CMD_DISABLE_SVC_CHECK; + + else if(!strcmp(command_id, "ENABLE_PASSIVE_SVC_CHECKS")) + command_type = CMD_ENABLE_PASSIVE_SVC_CHECKS; + else if(!strcmp(command_id, "DISABLE_PASSIVE_SVC_CHECKS")) + command_type = CMD_DISABLE_PASSIVE_SVC_CHECKS; + + else if(!strcmp(command_id, "DELAY_SVC_NOTIFICATION")) + command_type = CMD_DELAY_SVC_NOTIFICATION; + else if(!strcmp(command_id, "ENABLE_SVC_NOTIFICATIONS")) + command_type = CMD_ENABLE_SVC_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_SVC_NOTIFICATIONS")) + command_type = CMD_DISABLE_SVC_NOTIFICATIONS; + + else if(!strcmp(command_id, "PROCESS_SERVICE_CHECK_RESULT")) + command_type = CMD_PROCESS_SERVICE_CHECK_RESULT; + else if(!strcmp(command_id, "PROCESS_HOST_CHECK_RESULT")) + command_type = CMD_PROCESS_HOST_CHECK_RESULT; + + else if(!strcmp(command_id, "ENABLE_SVC_EVENT_HANDLER")) + command_type = CMD_ENABLE_SVC_EVENT_HANDLER; + else if(!strcmp(command_id, "DISABLE_SVC_EVENT_HANDLER")) + command_type = CMD_DISABLE_SVC_EVENT_HANDLER; + + else if(!strcmp(command_id, "ENABLE_SVC_FLAP_DETECTION")) + command_type = CMD_ENABLE_SVC_FLAP_DETECTION; + else if(!strcmp(command_id, "DISABLE_SVC_FLAP_DETECTION")) + command_type = CMD_DISABLE_SVC_FLAP_DETECTION; + + else if(!strcmp(command_id, "SCHEDULE_SVC_DOWNTIME")) + command_type = CMD_SCHEDULE_SVC_DOWNTIME; + else if(!strcmp(command_id, "DEL_SVC_DOWNTIME")) + command_type = CMD_DEL_SVC_DOWNTIME; + + else if(!strcmp(command_id, "ACKNOWLEDGE_SVC_PROBLEM")) + command_type = CMD_ACKNOWLEDGE_SVC_PROBLEM; + else if(!strcmp(command_id, "REMOVE_SVC_ACKNOWLEDGEMENT")) + command_type = CMD_REMOVE_SVC_ACKNOWLEDGEMENT; + + else if(!strcmp(command_id, "START_OBSESSING_OVER_SVC")) + command_type = CMD_START_OBSESSING_OVER_SVC; + else if(!strcmp(command_id, "STOP_OBSESSING_OVER_SVC")) + command_type = CMD_STOP_OBSESSING_OVER_SVC; + + else if(!strcmp(command_id, "CHANGE_SVC_EVENT_HANDLER")) + command_type = CMD_CHANGE_SVC_EVENT_HANDLER; + else if(!strcmp(command_id, "CHANGE_SVC_CHECK_COMMAND")) + command_type = CMD_CHANGE_SVC_CHECK_COMMAND; + + else if(!strcmp(command_id, "CHANGE_NORMAL_SVC_CHECK_INTERVAL")) + command_type = CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL; + else if(!strcmp(command_id, "CHANGE_RETRY_SVC_CHECK_INTERVAL")) + command_type = CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL; + + else if(!strcmp(command_id, "CHANGE_MAX_SVC_CHECK_ATTEMPTS")) + command_type = CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS; + + else if(!strcmp(command_id, "SET_SVC_NOTIFICATION_NUMBER")) + command_type = CMD_SET_SVC_NOTIFICATION_NUMBER; + + else if(!strcmp(command_id, "CHANGE_SVC_CHECK_TIMEPERIOD")) + command_type = CMD_CHANGE_SVC_CHECK_TIMEPERIOD; + + else if(!strcmp(command_id, "CHANGE_CUSTOM_SVC_VAR")) + command_type = CMD_CHANGE_CUSTOM_SVC_VAR; + + else if(!strcmp(command_id, "CHANGE_CUSTOM_CONTACT_VAR")) + command_type = CMD_CHANGE_CUSTOM_CONTACT_VAR; + + else if(!strcmp(command_id, "SEND_CUSTOM_SVC_NOTIFICATION")) + command_type = CMD_SEND_CUSTOM_SVC_NOTIFICATION; + + else if(!strcmp(command_id, "CHANGE_SVC_NOTIFICATION_TIMEPERIOD")) + command_type = CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD; + + else if(!strcmp(command_id, "CHANGE_SVC_MODATTR")) + command_type = CMD_CHANGE_SVC_MODATTR; + + + /***************************************/ + /**** SERVICEGROUP-RELATED COMMANDS ****/ + /***************************************/ + + else if(!strcmp(command_id, "ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS")) + command_type = CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS")) + command_type = CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS")) + command_type = CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS")) + command_type = CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_SERVICEGROUP_HOST_CHECKS")) + command_type = CMD_ENABLE_SERVICEGROUP_HOST_CHECKS; + else if(!strcmp(command_id, "DISABLE_SERVICEGROUP_HOST_CHECKS")) + command_type = CMD_DISABLE_SERVICEGROUP_HOST_CHECKS; + + else if(!strcmp(command_id, "ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")) + command_type = CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS; + else if(!strcmp(command_id, "DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")) + command_type = CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS; + + else if(!strcmp(command_id, "ENABLE_SERVICEGROUP_SVC_CHECKS")) + command_type = CMD_ENABLE_SERVICEGROUP_SVC_CHECKS; + else if(!strcmp(command_id, "DISABLE_SERVICEGROUP_SVC_CHECKS")) + command_type = CMD_DISABLE_SERVICEGROUP_SVC_CHECKS; + + else if(!strcmp(command_id, "ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")) + command_type = CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS; + else if(!strcmp(command_id, "DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")) + command_type = CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS; + + else if(!strcmp(command_id, "SCHEDULE_SERVICEGROUP_HOST_DOWNTIME")) + command_type = CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME; + else if(!strcmp(command_id, "SCHEDULE_SERVICEGROUP_SVC_DOWNTIME")) + command_type = CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME; + + + /**********************************/ + /**** CONTACT-RELATED COMMANDS ****/ + /**********************************/ + + else if(!strcmp(command_id, "ENABLE_CONTACT_HOST_NOTIFICATIONS")) + command_type = CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_CONTACT_HOST_NOTIFICATIONS")) + command_type = CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_CONTACT_SVC_NOTIFICATIONS")) + command_type = CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_CONTACT_SVC_NOTIFICATIONS")) + command_type = CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS; + + else if(!strcmp(command_id, "CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD")) + command_type = CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD; + + else if(!strcmp(command_id, "CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD")) + command_type = CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD; + + else if(!strcmp(command_id, "CHANGE_CONTACT_MODATTR")) + command_type = CMD_CHANGE_CONTACT_MODATTR; + else if(!strcmp(command_id, "CHANGE_CONTACT_MODHATTR")) + command_type = CMD_CHANGE_CONTACT_MODHATTR; + else if(!strcmp(command_id, "CHANGE_CONTACT_MODSATTR")) + command_type = CMD_CHANGE_CONTACT_MODSATTR; + + /***************************************/ + /**** CONTACTGROUP-RELATED COMMANDS ****/ + /***************************************/ + + else if(!strcmp(command_id, "ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS")) + command_type = CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS")) + command_type = CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS; + + else if(!strcmp(command_id, "ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS")) + command_type = CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS; + else if(!strcmp(command_id, "DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS")) + command_type = CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS; + + + /**************************/ + /****** MISC COMMANDS *****/ + /**************************/ + + else if(!strcmp(command_id, "PROCESS_FILE")) + command_type = CMD_PROCESS_FILE; + + + + /****************************/ + /****** CUSTOM COMMANDS *****/ + /****************************/ + + else if(command_id[0] == '_') + command_type = CMD_CUSTOM_COMMAND; + + + + /**** UNKNOWN COMMAND ****/ + else { + /* log the bad external command */ + logit(NSLOG_EXTERNAL_COMMAND | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Unrecognized external command -> %s;%s\n", command_id, args); + + /* free memory */ + my_free(command_id); + my_free(args); + + return ERROR; + } + + /* update statistics for external commands */ + update_check_stats(EXTERNAL_COMMAND_STATS, time(NULL)); + + /* log the external command */ + asprintf(&temp_buffer, "EXTERNAL COMMAND: %s;%s\n", command_id, args); + if(command_type == CMD_PROCESS_SERVICE_CHECK_RESULT || command_type == CMD_PROCESS_HOST_CHECK_RESULT) { + /* passive checks are logged in checks.c as well, as some my bypass external commands by getting dropped in checkresults dir */ + if(log_passive_checks == TRUE) + write_to_all_logs(temp_buffer, NSLOG_PASSIVE_CHECK); + } + else { + if(log_external_commands == TRUE) + write_to_all_logs(temp_buffer, NSLOG_EXTERNAL_COMMAND); + } + my_free(temp_buffer); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_external_command(NEBTYPE_EXTERNALCOMMAND_START, NEBFLAG_NONE, NEBATTR_NONE, command_type, entry_time, command_id, args, NULL); +#endif + + /* process the command */ + process_external_command2(command_type, entry_time, args); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_external_command(NEBTYPE_EXTERNALCOMMAND_END, NEBFLAG_NONE, NEBATTR_NONE, command_type, entry_time, command_id, args, NULL); +#endif + + /* free memory */ + my_free(command_id); + my_free(args); + + return OK; + } + + + +/* top-level processor for a single external command */ +int process_external_command2(int cmd, time_t entry_time, char *args) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_external_command2()\n"); + + log_debug_info(DEBUGL_EXTERNALCOMMANDS, 1, "External Command Type: %d\n", cmd); + log_debug_info(DEBUGL_EXTERNALCOMMANDS, 1, "Command Entry Time: %lu\n", (unsigned long)entry_time); + log_debug_info(DEBUGL_EXTERNALCOMMANDS, 1, "Command Arguments: %s\n", (args == NULL) ? "" : args); + + /* how shall we execute the command? */ + switch(cmd) { + + /***************************/ + /***** SYSTEM COMMANDS *****/ + /***************************/ + + case CMD_SHUTDOWN_PROCESS: + case CMD_RESTART_PROCESS: + cmd_signal_process(cmd, args); + break; + + case CMD_SAVE_STATE_INFORMATION: + save_state_information(FALSE); + break; + + case CMD_READ_STATE_INFORMATION: + read_initial_state_information(); + break; + + case CMD_ENABLE_NOTIFICATIONS: + enable_all_notifications(); + break; + + case CMD_DISABLE_NOTIFICATIONS: + disable_all_notifications(); + break; + + case CMD_START_EXECUTING_SVC_CHECKS: + start_executing_service_checks(); + break; + + case CMD_STOP_EXECUTING_SVC_CHECKS: + stop_executing_service_checks(); + break; + + case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: + start_accepting_passive_service_checks(); + break; + + case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: + stop_accepting_passive_service_checks(); + break; + + case CMD_START_OBSESSING_OVER_SVC_CHECKS: + start_obsessing_over_service_checks(); + break; + + case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: + stop_obsessing_over_service_checks(); + break; + + case CMD_START_EXECUTING_HOST_CHECKS: + start_executing_host_checks(); + break; + + case CMD_STOP_EXECUTING_HOST_CHECKS: + stop_executing_host_checks(); + break; + + case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: + start_accepting_passive_host_checks(); + break; + + case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: + stop_accepting_passive_host_checks(); + break; + + case CMD_START_OBSESSING_OVER_HOST_CHECKS: + start_obsessing_over_host_checks(); + break; + + case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: + stop_obsessing_over_host_checks(); + break; + + case CMD_ENABLE_EVENT_HANDLERS: + start_using_event_handlers(); + break; + + case CMD_DISABLE_EVENT_HANDLERS: + stop_using_event_handlers(); + break; + + case CMD_ENABLE_FLAP_DETECTION: + enable_flap_detection_routines(); + break; + + case CMD_DISABLE_FLAP_DETECTION: + disable_flap_detection_routines(); + break; + + case CMD_ENABLE_SERVICE_FRESHNESS_CHECKS: + enable_service_freshness_checks(); + break; + + case CMD_DISABLE_SERVICE_FRESHNESS_CHECKS: + disable_service_freshness_checks(); + break; + + case CMD_ENABLE_HOST_FRESHNESS_CHECKS: + enable_host_freshness_checks(); + break; + + case CMD_DISABLE_HOST_FRESHNESS_CHECKS: + disable_host_freshness_checks(); + break; + + case CMD_ENABLE_FAILURE_PREDICTION: + enable_all_failure_prediction(); + break; + + case CMD_DISABLE_FAILURE_PREDICTION: + disable_all_failure_prediction(); + break; + + case CMD_ENABLE_PERFORMANCE_DATA: + enable_performance_data(); + break; + + case CMD_DISABLE_PERFORMANCE_DATA: + disable_performance_data(); + break; + + + /***************************/ + /***** HOST COMMANDS *****/ + /***************************/ + + case CMD_ENABLE_HOST_CHECK: + case CMD_DISABLE_HOST_CHECK: + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + case CMD_ENABLE_HOST_SVC_CHECKS: + case CMD_DISABLE_HOST_SVC_CHECKS: + case CMD_ENABLE_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOST_NOTIFICATIONS: + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS: + case CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS: + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + case CMD_ENABLE_HOST_FLAP_DETECTION: + case CMD_DISABLE_HOST_FLAP_DETECTION: + case CMD_ENABLE_HOST_EVENT_HANDLER: + case CMD_DISABLE_HOST_EVENT_HANDLER: + case CMD_START_OBSESSING_OVER_HOST: + case CMD_STOP_OBSESSING_OVER_HOST: + case CMD_SET_HOST_NOTIFICATION_NUMBER: + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + process_host_command(cmd, entry_time, args); + break; + + + /*****************************/ + /***** HOSTGROUP COMMANDS ****/ + /*****************************/ + + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_HOSTGROUP_HOST_CHECKS: + case CMD_DISABLE_HOSTGROUP_HOST_CHECKS: + case CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + case CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: + process_hostgroup_command(cmd, entry_time, args); + break; + + + /***************************/ + /***** SERVICE COMMANDS ****/ + /***************************/ + + case CMD_ENABLE_SVC_CHECK: + case CMD_DISABLE_SVC_CHECK: + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + case CMD_ENABLE_SVC_NOTIFICATIONS: + case CMD_DISABLE_SVC_NOTIFICATIONS: + case CMD_ENABLE_SVC_FLAP_DETECTION: + case CMD_DISABLE_SVC_FLAP_DETECTION: + case CMD_ENABLE_SVC_EVENT_HANDLER: + case CMD_DISABLE_SVC_EVENT_HANDLER: + case CMD_START_OBSESSING_OVER_SVC: + case CMD_STOP_OBSESSING_OVER_SVC: + case CMD_SET_SVC_NOTIFICATION_NUMBER: + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + process_service_command(cmd, entry_time, args); + break; + + + /********************************/ + /***** SERVICEGROUP COMMANDS ****/ + /********************************/ + + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS: + case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS: + case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: + process_servicegroup_command(cmd, entry_time, args); + break; + + + /**********************************/ + /**** CONTACT-RELATED COMMANDS ****/ + /**********************************/ + + case CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS: + case CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS: + case CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS: + case CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS: + process_contact_command(cmd, entry_time, args); + break; + + + /***************************************/ + /**** CONTACTGROUP-RELATED COMMANDS ****/ + /***************************************/ + + case CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS: + process_contactgroup_command(cmd, entry_time, args); + break; + + + /***************************/ + /**** UNSORTED COMMANDS ****/ + /***************************/ + + + case CMD_ADD_HOST_COMMENT: + case CMD_ADD_SVC_COMMENT: + cmd_add_comment(cmd, entry_time, args); + break; + + case CMD_DEL_HOST_COMMENT: + case CMD_DEL_SVC_COMMENT: + cmd_delete_comment(cmd, args); + break; + + case CMD_DELAY_HOST_NOTIFICATION: + case CMD_DELAY_SVC_NOTIFICATION: + cmd_delay_notification(cmd, args); + break; + + case CMD_SCHEDULE_SVC_CHECK: + case CMD_SCHEDULE_FORCED_SVC_CHECK: + cmd_schedule_check(cmd, args); + break; + + case CMD_SCHEDULE_HOST_SVC_CHECKS: + case CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS: + cmd_schedule_check(cmd, args); + break; + + case CMD_DEL_ALL_HOST_COMMENTS: + case CMD_DEL_ALL_SVC_COMMENTS: + cmd_delete_all_comments(cmd, args); + break; + + case CMD_PROCESS_SERVICE_CHECK_RESULT: + cmd_process_service_check_result(cmd, entry_time, args); + break; + + case CMD_PROCESS_HOST_CHECK_RESULT: + cmd_process_host_check_result(cmd, entry_time, args); + break; + + case CMD_ACKNOWLEDGE_HOST_PROBLEM: + case CMD_ACKNOWLEDGE_SVC_PROBLEM: + cmd_acknowledge_problem(cmd, args); + break; + + case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: + case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: + cmd_remove_acknowledgement(cmd, args); + break; + + case CMD_SCHEDULE_HOST_DOWNTIME: + case CMD_SCHEDULE_SVC_DOWNTIME: + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + case CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME: + case CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME: + cmd_schedule_downtime(cmd, entry_time, args); + break; + + case CMD_DEL_HOST_DOWNTIME: + case CMD_DEL_SVC_DOWNTIME: + cmd_delete_downtime(cmd, args); + break; + + case CMD_DEL_DOWNTIME_BY_HOST_NAME: + cmd_delete_downtime_by_host_name(cmd, args); + break; + + case CMD_DEL_DOWNTIME_BY_HOSTGROUP_NAME: + cmd_delete_downtime_by_hostgroup_name(cmd, args); + break; + + case CMD_DEL_DOWNTIME_BY_START_TIME_COMMENT: + cmd_delete_downtime_by_start_time_comment(cmd, args); + break; + + case CMD_CANCEL_ACTIVE_HOST_SVC_DOWNTIME: + case CMD_CANCEL_PENDING_HOST_SVC_DOWNTIME: + break; + + case CMD_SCHEDULE_HOST_CHECK: + case CMD_SCHEDULE_FORCED_HOST_CHECK: + cmd_schedule_check(cmd, args); + break; + + case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: + case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: + case CMD_CHANGE_HOST_EVENT_HANDLER: + case CMD_CHANGE_SVC_EVENT_HANDLER: + case CMD_CHANGE_HOST_CHECK_COMMAND: + case CMD_CHANGE_SVC_CHECK_COMMAND: + case CMD_CHANGE_HOST_CHECK_TIMEPERIOD: + case CMD_CHANGE_SVC_CHECK_TIMEPERIOD: + case CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD: + cmd_change_object_char_var(cmd, args); + break; + + case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL: + case CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL: + case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL: + case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL: + case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS: + case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS: + case CMD_CHANGE_HOST_MODATTR: + case CMD_CHANGE_SVC_MODATTR: + case CMD_CHANGE_CONTACT_MODATTR: + case CMD_CHANGE_CONTACT_MODHATTR: + case CMD_CHANGE_CONTACT_MODSATTR: + cmd_change_object_int_var(cmd, args); + break; + + case CMD_CHANGE_CUSTOM_HOST_VAR: + case CMD_CHANGE_CUSTOM_SVC_VAR: + case CMD_CHANGE_CUSTOM_CONTACT_VAR: + cmd_change_object_custom_var(cmd, args); + break; + + + /***********************/ + /**** MISC COMMANDS ****/ + /***********************/ + + + case CMD_PROCESS_FILE: + cmd_process_external_commands_from_file(cmd, args); + break; + + + /*************************/ + /**** CUSTOM COMMANDS ****/ + /*************************/ + + + case CMD_CUSTOM_COMMAND: + /* custom commands aren't handled internally by Nagios, but may be by NEB modules */ + break; + + default: + return ERROR; + break; + } + + return OK; + } + + +/* processes an external host command */ +int process_host_command(int cmd, time_t entry_time, char *args) { + char *host_name = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + servicesmember *temp_servicesmember = NULL; + char *str = NULL; + char *buf[2] = {NULL, NULL}; + int intval = 0; + + printf("ARGS: %s\n", args); + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* find the host */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + switch(cmd) { + + case CMD_ENABLE_HOST_NOTIFICATIONS: + enable_host_notifications(temp_host); + break; + + case CMD_DISABLE_HOST_NOTIFICATIONS: + disable_host_notifications(temp_host); + break; + + case CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS: + enable_and_propagate_notifications(temp_host, 0, TRUE, TRUE, FALSE); + break; + + case CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS: + disable_and_propagate_notifications(temp_host, 0, TRUE, TRUE, FALSE); + break; + + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + enable_and_propagate_notifications(temp_host, 0, FALSE, TRUE, TRUE); + break; + + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + disable_and_propagate_notifications(temp_host, 0, FALSE, TRUE, TRUE); + break; + + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + if(cmd == CMD_ENABLE_HOST_SVC_NOTIFICATIONS) + enable_service_notifications(temp_service); + else + disable_service_notifications(temp_service); + } + break; + + case CMD_ENABLE_HOST_SVC_CHECKS: + case CMD_DISABLE_HOST_SVC_CHECKS: + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + if(cmd == CMD_ENABLE_HOST_SVC_CHECKS) + enable_service_checks(temp_service); + else + disable_service_checks(temp_service); + } + break; + + case CMD_ENABLE_HOST_CHECK: + enable_host_checks(temp_host); + break; + + case CMD_DISABLE_HOST_CHECK: + disable_host_checks(temp_host); + break; + + case CMD_ENABLE_HOST_EVENT_HANDLER: + enable_host_event_handler(temp_host); + break; + + case CMD_DISABLE_HOST_EVENT_HANDLER: + disable_host_event_handler(temp_host); + break; + + case CMD_ENABLE_HOST_FLAP_DETECTION: + enable_host_flap_detection(temp_host); + break; + + case CMD_DISABLE_HOST_FLAP_DETECTION: + disable_host_flap_detection(temp_host); + break; + + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + enable_passive_host_checks(temp_host); + break; + + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + disable_passive_host_checks(temp_host); + break; + + case CMD_START_OBSESSING_OVER_HOST: + start_obsessing_over_host(temp_host); + break; + + case CMD_STOP_OBSESSING_OVER_HOST: + stop_obsessing_over_host(temp_host); + break; + + case CMD_SET_HOST_NOTIFICATION_NUMBER: + if((str = my_strtok(NULL, ";"))) { + intval = atoi(str); + set_host_notification_number(temp_host, intval); + } + break; + + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + if((str = my_strtok(NULL, ";"))) + intval = atoi(str); + str = my_strtok(NULL, ";"); + if(str) + buf[0] = strdup(str); + str = my_strtok(NULL, ";"); + if(str) + buf[1] = strdup(str); + if(buf[0] && buf[1]) + host_notification(temp_host, NOTIFICATION_CUSTOM, buf[0], buf[1], intval); + break; + + default: + break; + } + + return OK; + } + + +/* processes an external hostgroup command */ +int process_hostgroup_command(int cmd, time_t entry_time, char *args) { + char *hostgroup_name = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_member = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + servicesmember *temp_servicesmember = NULL; + + /* get the hostgroup name */ + if((hostgroup_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* find the hostgroup */ + if((temp_hostgroup = find_hostgroup(hostgroup_name)) == NULL) + return ERROR; + + /* loop through all hosts in the hostgroup */ + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + + if((temp_host = (host *)temp_member->host_ptr) == NULL) + continue; + + switch(cmd) { + + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + enable_host_notifications(temp_host); + break; + + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + disable_host_notifications(temp_host); + break; + + case CMD_ENABLE_HOSTGROUP_HOST_CHECKS: + enable_host_checks(temp_host); + break; + + case CMD_DISABLE_HOSTGROUP_HOST_CHECKS: + disable_host_checks(temp_host); + break; + + case CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: + enable_passive_host_checks(temp_host); + break; + + case CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: + disable_passive_host_checks(temp_host); + break; + + default: + + /* loop through all services on the host */ + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + + switch(cmd) { + + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + enable_service_notifications(temp_service); + break; + + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + disable_service_notifications(temp_service); + break; + + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + enable_service_checks(temp_service); + break; + + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + disable_service_checks(temp_service); + break; + + case CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: + enable_passive_service_checks(temp_service); + break; + + case CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: + disable_passive_service_checks(temp_service); + break; + + default: + break; + } + } + + break; + } + + } + + return OK; + } + + + +/* processes an external service command */ +int process_service_command(int cmd, time_t entry_time, char *args) { + char *host_name = NULL; + char *svc_description = NULL; + service *temp_service = NULL; + char *str = NULL; + char *buf[2] = {NULL, NULL}; + int intval = 0; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* get the service description */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* find the service */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + + switch(cmd) { + + case CMD_ENABLE_SVC_NOTIFICATIONS: + enable_service_notifications(temp_service); + break; + + case CMD_DISABLE_SVC_NOTIFICATIONS: + disable_service_notifications(temp_service); + break; + + case CMD_ENABLE_SVC_CHECK: + enable_service_checks(temp_service); + break; + + case CMD_DISABLE_SVC_CHECK: + disable_service_checks(temp_service); + break; + + case CMD_ENABLE_SVC_EVENT_HANDLER: + enable_service_event_handler(temp_service); + break; + + case CMD_DISABLE_SVC_EVENT_HANDLER: + disable_service_event_handler(temp_service); + break; + + case CMD_ENABLE_SVC_FLAP_DETECTION: + enable_service_flap_detection(temp_service); + break; + + case CMD_DISABLE_SVC_FLAP_DETECTION: + disable_service_flap_detection(temp_service); + break; + + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + enable_passive_service_checks(temp_service); + break; + + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + disable_passive_service_checks(temp_service); + break; + + case CMD_START_OBSESSING_OVER_SVC: + start_obsessing_over_service(temp_service); + break; + + case CMD_STOP_OBSESSING_OVER_SVC: + stop_obsessing_over_service(temp_service); + break; + + case CMD_SET_SVC_NOTIFICATION_NUMBER: + if((str = my_strtok(NULL, ";"))) { + intval = atoi(str); + set_service_notification_number(temp_service, intval); + } + break; + + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + if((str = my_strtok(NULL, ";"))) + intval = atoi(str); + str = my_strtok(NULL, ";"); + if(str) + buf[0] = strdup(str); + str = my_strtok(NULL, ";"); + if(str) + buf[1] = strdup(str); + if(buf[0] && buf[1]) + service_notification(temp_service, NOTIFICATION_CUSTOM, buf[0], buf[1], intval); + break; + + default: + break; + } + + return OK; + } + + +/* processes an external servicegroup command */ +int process_servicegroup_command(int cmd, time_t entry_time, char *args) { + char *servicegroup_name = NULL; + servicegroup *temp_servicegroup = NULL; + servicesmember *temp_member = NULL; + host *temp_host = NULL; + host *last_host = NULL; + service *temp_service = NULL; + + /* get the servicegroup name */ + if((servicegroup_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* find the servicegroup */ + if((temp_servicegroup = find_servicegroup(servicegroup_name)) == NULL) + return ERROR; + + switch(cmd) { + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: + + /* loop through all servicegroup members */ + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + temp_service = find_service(temp_member->host_name, temp_member->service_description); + if(temp_service == NULL) + continue; + + switch(cmd) { + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + enable_service_notifications(temp_service); + break; + + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + disable_service_notifications(temp_service); + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + enable_service_checks(temp_service); + break; + + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + disable_service_checks(temp_service); + break; + + case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: + enable_passive_service_checks(temp_service); + break; + + case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: + disable_passive_service_checks(temp_service); + break; + + default: + break; + } + } + + break; + + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS: + case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS: + case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: + + /* loop through all hosts that have services belonging to the servicegroup */ + last_host = NULL; + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + if((temp_host = find_host(temp_member->host_name)) == NULL) + continue; + + if(temp_host == last_host) + continue; + + switch(cmd) { + + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + enable_host_notifications(temp_host); + break; + + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + disable_host_notifications(temp_host); + break; + + case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS: + enable_host_checks(temp_host); + break; + + case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS: + disable_host_checks(temp_host); + break; + + case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: + enable_passive_host_checks(temp_host); + break; + + case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: + disable_passive_host_checks(temp_host); + break; + + default: + break; + } + + last_host = temp_host; + } + + break; + + default: + break; + } + + return OK; + } + + + +/* processes an external contact command */ +int process_contact_command(int cmd, time_t entry_time, char *args) { + char *contact_name = NULL; + contact *temp_contact = NULL; + + /* get the contact name */ + if((contact_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* find the contact */ + if((temp_contact = find_contact(contact_name)) == NULL) + return ERROR; + + switch(cmd) { + + case CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS: + enable_contact_host_notifications(temp_contact); + break; + + case CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS: + disable_contact_host_notifications(temp_contact); + break; + + case CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS: + enable_contact_service_notifications(temp_contact); + break; + + case CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS: + disable_contact_service_notifications(temp_contact); + break; + + default: + break; + } + + return OK; + } + + +/* processes an external contactgroup command */ +int process_contactgroup_command(int cmd, time_t entry_time, char *args) { + char *contactgroup_name = NULL; + contactgroup *temp_contactgroup = NULL; + contactsmember *temp_member = NULL; + contact *temp_contact = NULL; + + /* get the contactgroup name */ + if((contactgroup_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* find the contactgroup */ + if((temp_contactgroup = find_contactgroup(contactgroup_name)) == NULL) + return ERROR; + + switch(cmd) { + + case CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS: + + /* loop through all contactgroup members */ + for(temp_member = temp_contactgroup->members; temp_member != NULL; temp_member = temp_member->next) { + + if((temp_contact = temp_member->contact_ptr) == NULL) + continue; + + switch(cmd) { + + case CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS: + enable_contact_host_notifications(temp_contact); + break; + + case CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS: + disable_contact_host_notifications(temp_contact); + break; + + case CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS: + enable_contact_service_notifications(temp_contact); + break; + + case CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS: + disable_contact_service_notifications(temp_contact); + break; + + default: + break; + } + } + + break; + + default: + break; + } + + return OK; + } + + + +/******************************************************************/ +/*************** EXTERNAL COMMAND IMPLEMENTATIONS ****************/ +/******************************************************************/ + +/* adds a host or service comment to the status log */ +int cmd_add_comment(int cmd, time_t entry_time, char *args) { + char *temp_ptr = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + char *host_name = NULL; + char *svc_description = NULL; + char *user = NULL; + char *comment_data = NULL; + int persistent = 0; + int result = 0; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* if we're adding a service comment... */ + if(cmd == CMD_ADD_SVC_COMMENT) { + + /* get the service description */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + } + + /* else verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + /* get the persistent flag */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + persistent = atoi(temp_ptr); + if(persistent > 1) + persistent = 1; + else if(persistent < 0) + persistent = 0; + + /* get the name of the user who entered the comment */ + if((user = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* get the comment */ + if((comment_data = my_strtok(NULL, "\n")) == NULL) + return ERROR; + + /* add the comment */ + result = add_new_comment((cmd == CMD_ADD_HOST_COMMENT) ? HOST_COMMENT : SERVICE_COMMENT, USER_COMMENT, host_name, svc_description, entry_time, user, comment_data, persistent, COMMENTSOURCE_EXTERNAL, FALSE, (time_t)0, NULL); + + if(result < 0) + return ERROR; + + return OK; + } + + + +/* removes a host or service comment from the status log */ +int cmd_delete_comment(int cmd, char *args) { + unsigned long comment_id = 0L; + + /* get the comment id we should delete */ + if((comment_id = strtoul(args, NULL, 10)) == 0) + return ERROR; + + /* delete the specified comment */ + if(cmd == CMD_DEL_HOST_COMMENT) + delete_host_comment(comment_id); + else + delete_service_comment(comment_id); + + return OK; + } + + + +/* removes all comments associated with a host or service from the status log */ +int cmd_delete_all_comments(int cmd, char *args) { + service *temp_service = NULL; + host *temp_host = NULL; + char *host_name = NULL; + char *svc_description = NULL; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* if we're deleting service comments... */ + if(cmd == CMD_DEL_ALL_SVC_COMMENTS) { + + /* get the service description */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + } + + /* else verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + /* delete comments */ + delete_all_comments((cmd == CMD_DEL_ALL_HOST_COMMENTS) ? HOST_COMMENT : SERVICE_COMMENT, host_name, svc_description); + + return OK; + } + + + +/* delays a host or service notification for given number of minutes */ +int cmd_delay_notification(int cmd, char *args) { + char *temp_ptr = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + char *host_name = NULL; + char *svc_description = NULL; + time_t delay_time = 0L; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* if this is a service notification delay... */ + if(cmd == CMD_DELAY_SVC_NOTIFICATION) { + + /* get the service description */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + } + + /* else verify that the host is valid */ + else { + + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + } + + /* get the time that we should delay until... */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) + return ERROR; + delay_time = strtoul(temp_ptr, NULL, 10); + + /* delay the next notification... */ + if(cmd == CMD_DELAY_HOST_NOTIFICATION) + temp_host->next_host_notification = delay_time; + else + temp_service->next_notification = delay_time; + + return OK; + } + + + +/* schedules a host check at a particular time */ +int cmd_schedule_check(int cmd, char *args) { + char *temp_ptr = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + servicesmember *temp_servicesmember = NULL; + char *host_name = NULL; + char *svc_description = NULL; + time_t delay_time = 0L; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + if(cmd == CMD_SCHEDULE_HOST_CHECK || cmd == CMD_SCHEDULE_FORCED_HOST_CHECK || cmd == CMD_SCHEDULE_HOST_SVC_CHECKS || cmd == CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS) { + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + } + + else { + + /* get the service description */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + } + + /* get the next check time */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) + return ERROR; + delay_time = strtoul(temp_ptr, NULL, 10); + + /* schedule the host check */ + if(cmd == CMD_SCHEDULE_HOST_CHECK || cmd == CMD_SCHEDULE_FORCED_HOST_CHECK) + schedule_host_check(temp_host, delay_time, (cmd == CMD_SCHEDULE_FORCED_HOST_CHECK) ? CHECK_OPTION_FORCE_EXECUTION : CHECK_OPTION_NONE); + + /* schedule service checks */ + else if(cmd == CMD_SCHEDULE_HOST_SVC_CHECKS || cmd == CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS) { + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + schedule_service_check(temp_service, delay_time, (cmd == CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS) ? CHECK_OPTION_FORCE_EXECUTION : CHECK_OPTION_NONE); + } + } + else + schedule_service_check(temp_service, delay_time, (cmd == CMD_SCHEDULE_FORCED_SVC_CHECK) ? CHECK_OPTION_FORCE_EXECUTION : CHECK_OPTION_NONE); + + return OK; + } + + + +/* schedules all service checks on a host for a particular time */ +int cmd_schedule_host_service_checks(int cmd, char *args, int force) { + char *temp_ptr = NULL; + service *temp_service = NULL; + servicesmember *temp_servicesmember = NULL; + host *temp_host = NULL; + char *host_name = NULL; + time_t delay_time = 0L; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + /* get the next check time */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) + return ERROR; + delay_time = strtoul(temp_ptr, NULL, 10); + + /* reschedule all services on the specified host */ + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + schedule_service_check(temp_service, delay_time, (force == TRUE) ? CHECK_OPTION_FORCE_EXECUTION : CHECK_OPTION_NONE); + } + + return OK; + } + + + + +/* schedules a program shutdown or restart */ +int cmd_signal_process(int cmd, char *args) { + time_t scheduled_time = 0L; + char *temp_ptr = NULL; + int result = OK; + + /* get the time to schedule the event */ + if((temp_ptr = my_strtok(args, "\n")) == NULL) + scheduled_time = 0L; + else + scheduled_time = strtoul(temp_ptr, NULL, 10); + + /* add a scheduled program shutdown or restart to the event list */ + result = schedule_new_event((cmd == CMD_SHUTDOWN_PROCESS) ? EVENT_PROGRAM_SHUTDOWN : EVENT_PROGRAM_RESTART, TRUE, scheduled_time, FALSE, 0, NULL, FALSE, NULL, NULL, 0); + + return result; + } + + + +/* processes results of an external service check */ +int cmd_process_service_check_result(int cmd, time_t check_time, char *args) { + char *temp_ptr = NULL; + char *host_name = NULL; + char *svc_description = NULL; + int return_code = 0; + char *output = NULL; + int result = 0; + + /* get the host name */ + if((temp_ptr = my_strtok(args, ";")) == NULL) + return ERROR; + host_name = (char *)strdup(temp_ptr); + + /* get the service description */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) { + my_free(host_name); + return ERROR; + } + svc_description = (char *)strdup(temp_ptr); + + /* get the service check return code */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) { + my_free(host_name); + my_free(svc_description); + return ERROR; + } + return_code = atoi(temp_ptr); + + /* get the plugin output (may be empty) */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) + output = (char *)strdup(""); + else + output = (char *)strdup(temp_ptr); + + /* submit the passive check result */ + result = process_passive_service_check(check_time, host_name, svc_description, return_code, output); + + /* free memory */ + my_free(host_name); + my_free(svc_description); + my_free(output); + + return result; + } + + + +/* submits a passive service check result for later processing */ +int process_passive_service_check(time_t check_time, char *host_name, char *svc_description, int return_code, char *output) { + passive_check_result *new_pcr = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + char *real_host_name = NULL; + struct timeval tv; + int result = OK; + + /* skip this service check result if we aren't accepting passive service checks */ + if(accept_passive_service_checks == FALSE) + return ERROR; + + /* make sure we have all required data */ + if(host_name == NULL || svc_description == NULL || output == NULL) + return ERROR; + + /* find the host by its name or address */ + if(find_host(host_name) != NULL) + real_host_name = host_name; + else { + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(!strcmp(host_name, temp_host->address)) { + real_host_name = temp_host->name; + break; + } + } + } + + /* we couldn't find the host */ + if(real_host_name == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Passive check result was received for service '%s' on host '%s', but the host could not be found!\n", svc_description, host_name); + return ERROR; + } + + /* make sure the service exists */ + if((temp_service = find_service(real_host_name, svc_description)) == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Passive check result was received for service '%s' on host '%s', but the service could not be found!\n", svc_description, host_name); + return ERROR; + } + + /* skip this is we aren't accepting passive checks for this service */ + if(temp_service->accept_passive_service_checks == FALSE) + return ERROR; + + /* allocate memory for the passive check result */ + new_pcr = (passive_check_result *)malloc(sizeof(passive_check_result)); + if(new_pcr == NULL) + return ERROR; + + /* initialize vars */ + new_pcr->object_check_type = SERVICE_CHECK; + new_pcr->host_name = NULL; + new_pcr->service_description = NULL; + new_pcr->output = NULL; + new_pcr->next = NULL; + + /* save string vars */ + if((new_pcr->host_name = (char *)strdup(real_host_name)) == NULL) + result = ERROR; + if((new_pcr->service_description = (char *)strdup(svc_description)) == NULL) + result = ERROR; + if((new_pcr->output = (char *)strdup(output)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_pcr->output); + my_free(new_pcr->service_description); + my_free(new_pcr->host_name); + my_free(new_pcr); + return ERROR; + } + + /* save the return code */ + new_pcr->return_code = return_code; + + /* make sure the return code is within bounds */ + if(new_pcr->return_code < 0 || new_pcr->return_code > 3) + new_pcr->return_code = STATE_UNKNOWN; + + new_pcr->check_time = check_time; + + /* calculate latency */ + gettimeofday(&tv, NULL); + new_pcr->latency = (double)((double)(tv.tv_sec - check_time) + (double)(tv.tv_usec / 1000.0) / 1000.0); + if(new_pcr->latency < 0.0) + new_pcr->latency = 0.0; + + /* add the passive check result to the end of the list in memory */ + if(passive_check_result_list == NULL) + passive_check_result_list = new_pcr; + else + passive_check_result_list_tail->next = new_pcr; + passive_check_result_list_tail = new_pcr; + + return OK; + } + + + +/* process passive host check result */ +int cmd_process_host_check_result(int cmd, time_t check_time, char *args) { + char *temp_ptr = NULL; + char *host_name = NULL; + int return_code = 0; + char *output = NULL; + int result = 0; + + /* get the host name */ + if((temp_ptr = my_strtok(args, ";")) == NULL) + return ERROR; + host_name = (char *)strdup(temp_ptr); + + /* get the host check return code */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) { + my_free(host_name); + return ERROR; + } + return_code = atoi(temp_ptr); + + /* get the plugin output (may be empty) */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) + output = (char *)strdup(""); + else + output = (char *)strdup(temp_ptr); + + /* submit the check result */ + result = process_passive_host_check(check_time, host_name, return_code, output); + + /* free memory */ + my_free(host_name); + my_free(output); + + return result; + } + + +/* process passive host check result */ +int process_passive_host_check(time_t check_time, char *host_name, int return_code, char *output) { + passive_check_result *new_pcr = NULL; + host *temp_host = NULL; + char *real_host_name = NULL; + struct timeval tv; + int result = OK; + + /* skip this host check result if we aren't accepting passive host checks */ + if(accept_passive_service_checks == FALSE) + return ERROR; + + /* make sure we have all required data */ + if(host_name == NULL || output == NULL) + return ERROR; + + /* make sure we have a reasonable return code */ + if(return_code < 0 || return_code > 2) + return ERROR; + + /* find the host by its name or address */ + if((temp_host = find_host(host_name)) != NULL) + real_host_name = host_name; + else { + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(!strcmp(host_name, temp_host->address)) { + real_host_name = temp_host->name; + break; + } + } + } + + /* we couldn't find the host */ + if(temp_host == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Passive check result was received for host '%s', but the host could not be found!\n", host_name); + return ERROR; + } + + /* skip this is we aren't accepting passive checks for this host */ + if(temp_host->accept_passive_host_checks == FALSE) + return ERROR; + + /* allocate memory for the passive check result */ + new_pcr = (passive_check_result *)malloc(sizeof(passive_check_result)); + if(new_pcr == NULL) + return ERROR; + + /* initialize vars */ + new_pcr->object_check_type = HOST_CHECK; + new_pcr->host_name = NULL; + new_pcr->service_description = NULL; + new_pcr->output = NULL; + new_pcr->next = NULL; + + /* save string vars */ + if((new_pcr->host_name = (char *)strdup(real_host_name)) == NULL) + result = ERROR; + if((new_pcr->output = (char *)strdup(output)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_pcr->output); + my_free(new_pcr->service_description); + my_free(new_pcr->host_name); + my_free(new_pcr); + return ERROR; + } + + /* save the return code */ + new_pcr->return_code = return_code; + + /* make sure the return code is within bounds */ + if(new_pcr->return_code < 0 || new_pcr->return_code > 3) + new_pcr->return_code = STATE_UNKNOWN; + + new_pcr->check_time = check_time; + + /* calculate latency */ + gettimeofday(&tv, NULL); + new_pcr->latency = (double)((double)(tv.tv_sec - check_time) + (double)(tv.tv_usec / 1000.0) / 1000.0); + if(new_pcr->latency < 0.0) + new_pcr->latency = 0.0; + + /* add the passive check result to the end of the list in memory */ + if(passive_check_result_list == NULL) + passive_check_result_list = new_pcr; + else + passive_check_result_list_tail->next = new_pcr; + passive_check_result_list_tail = new_pcr; + + return OK; + } + + + +/* acknowledges a host or service problem */ +int cmd_acknowledge_problem(int cmd, char *args) { + service *temp_service = NULL; + host *temp_host = NULL; + char *host_name = NULL; + char *svc_description = NULL; + char *ack_author = NULL; + char *ack_data = NULL; + char *temp_ptr = NULL; + int type = ACKNOWLEDGEMENT_NORMAL; + int notify = TRUE; + int persistent = TRUE; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + /* this is a service acknowledgement */ + if(cmd == CMD_ACKNOWLEDGE_SVC_PROBLEM) { + + /* get the service name */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(temp_host->name, svc_description)) == NULL) + return ERROR; + } + + /* get the type */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + type = atoi(temp_ptr); + + /* get the notification option */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + notify = (atoi(temp_ptr) > 0) ? TRUE : FALSE; + + /* get the persistent option */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + persistent = (atoi(temp_ptr) > 0) ? TRUE : FALSE; + + /* get the acknowledgement author */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + ack_author = (char *)strdup(temp_ptr); + + /* get the acknowledgement data */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + my_free(ack_author); + return ERROR; + } + ack_data = (char *)strdup(temp_ptr); + + /* acknowledge the host problem */ + if(cmd == CMD_ACKNOWLEDGE_HOST_PROBLEM) + acknowledge_host_problem(temp_host, ack_author, ack_data, type, notify, persistent); + + /* acknowledge the service problem */ + else + acknowledge_service_problem(temp_service, ack_author, ack_data, type, notify, persistent); + + /* free memory */ + my_free(ack_author); + my_free(ack_data); + + return OK; + } + + + +/* removes a host or service acknowledgement */ +int cmd_remove_acknowledgement(int cmd, char *args) { + service *temp_service = NULL; + host *temp_host = NULL; + char *host_name = NULL; + char *svc_description = NULL; + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + /* we are removing a service acknowledgement */ + if(cmd == CMD_REMOVE_SVC_ACKNOWLEDGEMENT) { + + /* get the service name */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(temp_host->name, svc_description)) == NULL) + return ERROR; + } + + /* acknowledge the host problem */ + if(cmd == CMD_REMOVE_HOST_ACKNOWLEDGEMENT) + remove_host_acknowledgement(temp_host); + + /* acknowledge the service problem */ + else + remove_service_acknowledgement(temp_service); + + return OK; + } + + + +/* schedules downtime for a specific host or service */ +int cmd_schedule_downtime(int cmd, time_t entry_time, char *args) { + servicesmember *temp_servicesmember = NULL; + service *temp_service = NULL; + host *temp_host = NULL; + host *last_host = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_hgmember = NULL; + servicegroup *temp_servicegroup = NULL; + servicesmember *temp_sgmember = NULL; + char *host_name = NULL; + char *hostgroup_name = NULL; + char *servicegroup_name = NULL; + char *svc_description = NULL; + char *temp_ptr = NULL; + time_t start_time = 0L; + time_t end_time = 0L; + int fixed = 0; + unsigned long triggered_by = 0L; + unsigned long duration = 0L; + char *author = NULL; + char *comment_data = NULL; + unsigned long downtime_id = 0L; + + if(cmd == CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) { + + /* get the hostgroup name */ + if((hostgroup_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the hostgroup is valid */ + if((temp_hostgroup = find_hostgroup(hostgroup_name)) == NULL) + return ERROR; + } + + else if(cmd == CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) { + + /* get the servicegroup name */ + if((servicegroup_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the servicegroup is valid */ + if((temp_servicegroup = find_servicegroup(servicegroup_name)) == NULL) + return ERROR; + } + + else { + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + /* this is a service downtime */ + if(cmd == CMD_SCHEDULE_SVC_DOWNTIME) { + + /* get the service name */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(temp_host->name, svc_description)) == NULL) + return ERROR; + } + } + + /* get the start time */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + start_time = (time_t)strtoul(temp_ptr, NULL, 10); + + /* get the end time */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + end_time = (time_t)strtoul(temp_ptr, NULL, 10); + + /* get the fixed flag */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + fixed = atoi(temp_ptr); + + /* get the trigger id */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + triggered_by = strtoul(temp_ptr, NULL, 10); + + /* get the duration */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + duration = strtoul(temp_ptr, NULL, 10); + + /* get the author */ + if((author = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* get the comment */ + if((comment_data = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* check if flexible downtime demanded and duration set + to non-zero. + according to the documentation, a flexible downtime is + started between start and end time and will last for + "duration" seconds. strtoul converts a NULL value to 0 + so if set to 0, bail out as a duration>0 is needed. */ + + if(fixed == 0 && duration == 0) + return ERROR; + + + /* duration should be auto-calculated, not user-specified */ + if(fixed > 0) + duration = (unsigned long)(end_time - start_time); + + /* schedule downtime */ + switch(cmd) { + + case CMD_SCHEDULE_HOST_DOWNTIME: + schedule_downtime(HOST_DOWNTIME, host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + break; + + case CMD_SCHEDULE_SVC_DOWNTIME: + schedule_downtime(SERVICE_DOWNTIME, host_name, svc_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + break; + + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + schedule_downtime(SERVICE_DOWNTIME, host_name, temp_service->description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + } + break; + + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next) + schedule_downtime(HOST_DOWNTIME, temp_hgmember->host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + break; + + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next) { + if((temp_host = temp_hgmember->host_ptr) == NULL) + continue; + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + schedule_downtime(SERVICE_DOWNTIME, temp_service->host_name, temp_service->description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + } + } + break; + + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + last_host = NULL; + for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) { + temp_host = find_host(temp_sgmember->host_name); + if(temp_host == NULL) + continue; + if(last_host == temp_host) + continue; + schedule_downtime(HOST_DOWNTIME, temp_sgmember->host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + last_host = temp_host; + } + break; + + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) + schedule_downtime(SERVICE_DOWNTIME, temp_sgmember->host_name, temp_sgmember->service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + break; + + case CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME: + + /* schedule downtime for "parent" host */ + schedule_downtime(HOST_DOWNTIME, host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + + /* schedule (non-triggered) downtime for all child hosts */ + schedule_and_propagate_downtime(temp_host, entry_time, author, comment_data, start_time, end_time, fixed, 0, duration); + break; + + case CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME: + + /* schedule downtime for "parent" host */ + schedule_downtime(HOST_DOWNTIME, host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id); + + /* schedule triggered downtime for all child hosts */ + schedule_and_propagate_downtime(temp_host, entry_time, author, comment_data, start_time, end_time, fixed, downtime_id, duration); + break; + + default: + break; + } + + return OK; + } + + + +/* deletes scheduled host or service downtime */ +int cmd_delete_downtime(int cmd, char *args) { + unsigned long downtime_id = 0L; + char *temp_ptr = NULL; + + /* get the id of the downtime to delete */ + if((temp_ptr = my_strtok(args, "\n")) == NULL) + return ERROR; + downtime_id = strtoul(temp_ptr, NULL, 10); + + if(cmd == CMD_DEL_HOST_DOWNTIME) + unschedule_downtime(HOST_DOWNTIME, downtime_id); + else + unschedule_downtime(SERVICE_DOWNTIME, downtime_id); + + return OK; + } + + +/* Opsview enhancements: some of these commands are now "distributable" as no downtime ids are used */ +/* Deletes scheduled host and service downtime based on hostname and optionally other filter arguments */ +int cmd_delete_downtime_by_host_name(int cmd, char *args) { + char *temp_ptr = NULL; + char *end_ptr = NULL; + char *hostname = NULL; + char *service_description = NULL; + char *downtime_comment = NULL; + time_t downtime_start_time = 0L; + int deleted = 0; + + /* get the host name of the downtime to delete */ + temp_ptr = my_strtok(args, ";"); + if(temp_ptr == NULL) + return ERROR; + hostname = temp_ptr; + + /* get the optional service name */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + service_description = temp_ptr; + + /* get the optional start time */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + downtime_start_time = strtoul(temp_ptr, &end_ptr, 10); + + /* get the optional comment */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + downtime_comment = temp_ptr; + + } + } + } + + deleted = delete_downtime_by_hostname_service_description_start_time_comment(hostname, service_description, downtime_start_time, downtime_comment); + + if(deleted == 0) + return ERROR; + + return OK; + } + +/* Opsview enhancement: Deletes scheduled host and service downtime based on hostgroup and optionally other filter arguments */ +int cmd_delete_downtime_by_hostgroup_name(int cmd, char *args) { + char *temp_ptr = NULL; + char *end_ptr = NULL; + host *temp_host = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_member = NULL; + char *service_description = NULL; + char *downtime_comment = NULL; + char *host_name = NULL; + time_t downtime_start_time = 0L; + int deleted = 0; + + /* get the host group name of the downtime to delete */ + temp_ptr = my_strtok(args, ";"); + if(temp_ptr == NULL) + return ERROR; + + temp_hostgroup = find_hostgroup(temp_ptr); + if(temp_hostgroup == NULL) + return ERROR; + + /* get the optional host name */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + host_name = temp_ptr; + + /* get the optional service name */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + service_description = temp_ptr; + + /* get the optional start time */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + downtime_start_time = strtoul(temp_ptr, &end_ptr, 10); + + /* get the optional comment */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + downtime_comment = temp_ptr; + + } + } + } + + /* get the optional service name */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + service_description = temp_ptr; + + /* get the optional start time */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + downtime_start_time = strtoul(temp_ptr, &end_ptr, 10); + + /* get the optional comment */ + temp_ptr = my_strtok(NULL, ";"); + if(temp_ptr != NULL) { + if(*temp_ptr != '\0') + downtime_comment = temp_ptr; + } + } + } + } + + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + if((temp_host = (host *)temp_member->host_ptr) == NULL) + continue; + if(host_name != NULL && strcmp(temp_host->name, host_name) != 0) + continue; + deleted = +delete_downtime_by_hostname_service_description_start_time_comment(temp_host->name, service_description, downtime_start_time, downtime_comment); + } + + if(deleted == 0) + return ERROR; + + return OK; + } + +/* Opsview enhancement: Delete downtimes based on start time and/or comment */ +int cmd_delete_downtime_by_start_time_comment(int cmd, char *args) { + time_t downtime_start_time = 0L; + char *downtime_comment = NULL; + char *temp_ptr = NULL; + char *end_ptr = NULL; + int deleted = 0; + + /* Get start time if set */ + temp_ptr = my_strtok(args, ";"); + if(temp_ptr != NULL) { + /* This will be set to 0 if no start_time is entered or data is bad */ + downtime_start_time = strtoul(temp_ptr, &end_ptr, 10); + } + + /* Get comment - not sure if this should be also tokenised by ; */ + temp_ptr = my_strtok(NULL, "\n"); + if(temp_ptr != NULL && *temp_ptr != '\0') { + downtime_comment = temp_ptr; + } + + /* No args should give an error */ + if(downtime_start_time == 0 && downtime_comment == NULL) + return ERROR; + + deleted = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, downtime_start_time, downtime_comment); + + if(deleted == 0) + return ERROR; + + return OK; + } + + +/* changes a host or service (integer) variable */ +int cmd_change_object_int_var(int cmd, char *args) { + service *temp_service = NULL; + host *temp_host = NULL; + contact *temp_contact = NULL; + char *host_name = NULL; + char *svc_description = NULL; + char *contact_name = NULL; + char *temp_ptr = NULL; + int intval = 0; + double dval = 0.0; + double old_dval = 0.0; + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + unsigned long attr = MODATTR_NONE; + unsigned long hattr = MODATTR_NONE; + unsigned long sattr = MODATTR_NONE; + + switch(cmd) { + + case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL: + case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL: + case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS: + case CMD_CHANGE_SVC_MODATTR: + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* get the service name */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + + break; + + case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL: + case CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL: + case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS: + case CMD_CHANGE_HOST_MODATTR: + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + break; + + case CMD_CHANGE_CONTACT_MODATTR: + case CMD_CHANGE_CONTACT_MODHATTR: + case CMD_CHANGE_CONTACT_MODSATTR: + + /* get the contact name */ + if((contact_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the contact is valid */ + if((temp_contact = find_contact(contact_name)) == NULL) + return ERROR; + break; + + default: + /* unknown command */ + return ERROR; + break; + } + + /* get the value */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) + return ERROR; + intval = (int)strtol(temp_ptr, NULL, 0); + if(intval < 0 || (intval == 0 && errno == EINVAL)) + return ERROR; + dval = (int)strtod(temp_ptr, NULL); + + switch(cmd) { + + case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL: + + /* save the old check interval */ + old_dval = temp_host->check_interval; + + /* modify the check interval */ + temp_host->check_interval = dval; + attr = MODATTR_NORMAL_CHECK_INTERVAL; + + /* schedule a host check if previous interval was 0 (checks were not regularly scheduled) */ + if(old_dval == 0 && temp_host->checks_enabled == TRUE) { + + /* set the host check flag */ + temp_host->should_be_scheduled = TRUE; + + /* schedule a check for right now (or as soon as possible) */ + time(&preferred_time); + if(check_time_against_period(preferred_time, temp_host->check_period_ptr) == ERROR) { + get_next_valid_time(preferred_time, &next_valid_time, temp_host->check_period_ptr); + temp_host->next_check = next_valid_time; + } + else + temp_host->next_check = preferred_time; + + /* schedule a check if we should */ + if(temp_host->should_be_scheduled == TRUE) + schedule_host_check(temp_host, temp_host->next_check, CHECK_OPTION_NONE); + } + + break; + + case CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL: + + temp_host->retry_interval = dval; + attr = MODATTR_RETRY_CHECK_INTERVAL; + + break; + + case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS: + + temp_host->max_attempts = intval; + attr = MODATTR_MAX_CHECK_ATTEMPTS; + + /* adjust current attempt number if in a hard state */ + if(temp_host->state_type == HARD_STATE && temp_host->current_state != HOST_UP && temp_host->current_attempt > 1) + temp_host->current_attempt = temp_host->max_attempts; + + break; + + case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL: + + /* save the old check interval */ + old_dval = temp_service->check_interval; + + /* modify the check interval */ + temp_service->check_interval = dval; + attr = MODATTR_NORMAL_CHECK_INTERVAL; + + /* schedule a service check if previous interval was 0 (checks were not regularly scheduled) */ + if(old_dval == 0 && temp_service->checks_enabled == TRUE && temp_service->check_interval != 0) { + + /* set the service check flag */ + temp_service->should_be_scheduled = TRUE; + + /* schedule a check for right now (or as soon as possible) */ + time(&preferred_time); + if(check_time_against_period(preferred_time, temp_service->check_period_ptr) == ERROR) { + get_next_valid_time(preferred_time, &next_valid_time, temp_service->check_period_ptr); + temp_service->next_check = next_valid_time; + } + else + temp_service->next_check = preferred_time; + + /* schedule a check if we should */ + if(temp_service->should_be_scheduled == TRUE) + schedule_service_check(temp_service, temp_service->next_check, CHECK_OPTION_NONE); + } + + break; + + case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL: + + temp_service->retry_interval = dval; + attr = MODATTR_RETRY_CHECK_INTERVAL; + + break; + + case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS: + + temp_service->max_attempts = intval; + attr = MODATTR_MAX_CHECK_ATTEMPTS; + + /* adjust current attempt number if in a hard state */ + if(temp_service->state_type == HARD_STATE && temp_service->current_state != STATE_OK && temp_service->current_attempt > 1) + temp_service->current_attempt = temp_service->max_attempts; + + break; + + case CMD_CHANGE_HOST_MODATTR: + case CMD_CHANGE_SVC_MODATTR: + case CMD_CHANGE_CONTACT_MODATTR: + + attr = intval; + break; + + case CMD_CHANGE_CONTACT_MODHATTR: + + hattr = intval; + break; + + case CMD_CHANGE_CONTACT_MODSATTR: + + sattr = intval; + break; + + + default: + break; + } + + + /* send data to event broker and update status file */ + switch(cmd) { + + case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL: + case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL: + case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS: + case CMD_CHANGE_SVC_MODATTR: + + /* set the modified service attribute */ + if(cmd == CMD_CHANGE_SVC_MODATTR) + temp_service->modified_attributes = attr; + else + temp_service->modified_attributes |= attr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, temp_service, cmd, attr, temp_service->modified_attributes, NULL); +#endif + + /* update the status log with the service info */ + update_service_status(temp_service, FALSE); + + break; + + case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL: + case CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL: + case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS: + case CMD_CHANGE_HOST_MODATTR: + + /* set the modified host attribute */ + if(cmd == CMD_CHANGE_HOST_MODATTR) + temp_host->modified_attributes = attr; + else + temp_host->modified_attributes |= attr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, temp_host, cmd, attr, temp_host->modified_attributes, NULL); +#endif + + /* update the status log with the host info */ + update_host_status(temp_host, FALSE); + break; + + case CMD_CHANGE_CONTACT_MODATTR: + case CMD_CHANGE_CONTACT_MODHATTR: + case CMD_CHANGE_CONTACT_MODSATTR: + + /* set the modified attribute */ + switch(cmd) { + case CMD_CHANGE_CONTACT_MODATTR: + temp_contact->modified_attributes = attr; + break; + case CMD_CHANGE_CONTACT_MODHATTR: + temp_contact->modified_host_attributes = hattr; + break; + case CMD_CHANGE_CONTACT_MODSATTR: + temp_contact->modified_service_attributes = sattr; + break; + default: + break; + } + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_contact_data(NEBTYPE_ADAPTIVECONTACT_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, temp_contact, cmd, attr, temp_contact->modified_attributes, hattr, temp_contact->modified_host_attributes, sattr, temp_contact->modified_service_attributes, NULL); +#endif + + /* update the status log with the contact info */ + update_contact_status(temp_contact, FALSE); + break; + + default: + break; + } + + return OK; + } + + + +/* changes a host or service (char) variable */ +int cmd_change_object_char_var(int cmd, char *args) { + service *temp_service = NULL; + host *temp_host = NULL; + contact *temp_contact = NULL; + timeperiod *temp_timeperiod = NULL; + command *temp_command = NULL; + char *host_name = NULL; + char *svc_description = NULL; + char *contact_name = NULL; + char *charval = NULL; + char *temp_ptr = NULL; + char *temp_ptr2 = NULL; + unsigned long attr = MODATTR_NONE; + unsigned long hattr = MODATTR_NONE; + unsigned long sattr = MODATTR_NONE; + + + /* SECURITY PATCH - disable these for the time being */ + switch(cmd) { + case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: + case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: + case CMD_CHANGE_HOST_EVENT_HANDLER: + case CMD_CHANGE_SVC_EVENT_HANDLER: + case CMD_CHANGE_HOST_CHECK_COMMAND: + case CMD_CHANGE_SVC_CHECK_COMMAND: + return ERROR; + } + + + /* get the command arguments */ + switch(cmd) { + + case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: + case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: + + if((charval = my_strtok(args, "\n")) == NULL) + return ERROR; + + break; + + case CMD_CHANGE_HOST_EVENT_HANDLER: + case CMD_CHANGE_HOST_CHECK_COMMAND: + case CMD_CHANGE_HOST_CHECK_TIMEPERIOD: + case CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD: + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the host is valid */ + if((temp_host = find_host(host_name)) == NULL) + return ERROR; + + if((charval = my_strtok(NULL, "\n")) == NULL) + return ERROR; + + break; + + case CMD_CHANGE_SVC_EVENT_HANDLER: + case CMD_CHANGE_SVC_CHECK_COMMAND: + case CMD_CHANGE_SVC_CHECK_TIMEPERIOD: + case CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD: + + /* get the host name */ + if((host_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* get the service name */ + if((svc_description = my_strtok(NULL, ";")) == NULL) + return ERROR; + + /* verify that the service is valid */ + if((temp_service = find_service(host_name, svc_description)) == NULL) + return ERROR; + + if((charval = my_strtok(NULL, "\n")) == NULL) + return ERROR; + + break; + + + case CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD: + + /* get the contact name */ + if((contact_name = my_strtok(args, ";")) == NULL) + return ERROR; + + /* verify that the contact is valid */ + if((temp_contact = find_contact(contact_name)) == NULL) + return ERROR; + + if((charval = my_strtok(NULL, "\n")) == NULL) + return ERROR; + + break; + + default: + /* invalid command */ + return ERROR; + break; + + } + + if((temp_ptr = (char *)strdup(charval)) == NULL) + return ERROR; + + + /* do some validation */ + switch(cmd) { + + case CMD_CHANGE_HOST_CHECK_TIMEPERIOD: + case CMD_CHANGE_SVC_CHECK_TIMEPERIOD: + case CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD: + + /* make sure the timeperiod is valid */ + if((temp_timeperiod = find_timeperiod(temp_ptr)) == NULL) { + my_free(temp_ptr); + return ERROR; + } + + break; + + case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: + case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: + case CMD_CHANGE_HOST_EVENT_HANDLER: + case CMD_CHANGE_SVC_EVENT_HANDLER: + case CMD_CHANGE_HOST_CHECK_COMMAND: + case CMD_CHANGE_SVC_CHECK_COMMAND: + + /* make sure the command exists */ + temp_ptr2 = my_strtok(temp_ptr, "!"); + if((temp_command = find_command(temp_ptr2)) == NULL) { + my_free(temp_ptr); + return ERROR; + } + + my_free(temp_ptr); + if((temp_ptr = (char *)strdup(charval)) == NULL) + return ERROR; + + break; + + default: + break; + } + + + /* update the variable */ + switch(cmd) { + + case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: + + my_free(global_host_event_handler); + global_host_event_handler = temp_ptr; + global_host_event_handler_ptr = temp_command; + attr = MODATTR_EVENT_HANDLER_COMMAND; + break; + + case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: + + my_free(global_service_event_handler); + global_service_event_handler = temp_ptr; + global_service_event_handler_ptr = temp_command; + attr = MODATTR_EVENT_HANDLER_COMMAND; + break; + + case CMD_CHANGE_HOST_EVENT_HANDLER: + + my_free(temp_host->event_handler); + temp_host->event_handler = temp_ptr; + temp_host->event_handler_ptr = temp_command; + attr = MODATTR_EVENT_HANDLER_COMMAND; + break; + + case CMD_CHANGE_HOST_CHECK_COMMAND: + + my_free(temp_host->host_check_command); + temp_host->host_check_command = temp_ptr; + temp_host->check_command_ptr = temp_command; + attr = MODATTR_CHECK_COMMAND; + break; + + case CMD_CHANGE_HOST_CHECK_TIMEPERIOD: + + my_free(temp_host->check_period); + temp_host->check_period = temp_ptr; + temp_host->check_period_ptr = temp_timeperiod; + attr = MODATTR_CHECK_TIMEPERIOD; + break; + + case CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD: + + my_free(temp_host->notification_period); + temp_host->notification_period = temp_ptr; + temp_host->notification_period_ptr = temp_timeperiod; + attr = MODATTR_NOTIFICATION_TIMEPERIOD; + break; + + case CMD_CHANGE_SVC_EVENT_HANDLER: + + my_free(temp_service->event_handler); + temp_service->event_handler = temp_ptr; + temp_service->event_handler_ptr = temp_command; + attr = MODATTR_EVENT_HANDLER_COMMAND; + break; + + case CMD_CHANGE_SVC_CHECK_COMMAND: + + my_free(temp_service->service_check_command); + temp_service->service_check_command = temp_ptr; + temp_service->check_command_ptr = temp_command; + attr = MODATTR_CHECK_COMMAND; + break; + + case CMD_CHANGE_SVC_CHECK_TIMEPERIOD: + + my_free(temp_service->check_period); + temp_service->check_period = temp_ptr; + temp_service->check_period_ptr = temp_timeperiod; + attr = MODATTR_CHECK_TIMEPERIOD; + break; + + case CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD: + + my_free(temp_service->notification_period); + temp_service->notification_period = temp_ptr; + temp_service->notification_period_ptr = temp_timeperiod; + attr = MODATTR_NOTIFICATION_TIMEPERIOD; + break; + + case CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD: + + my_free(temp_contact->host_notification_period); + temp_contact->host_notification_period = temp_ptr; + temp_contact->host_notification_period_ptr = temp_timeperiod; + hattr = MODATTR_NOTIFICATION_TIMEPERIOD; + break; + + case CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD: + + my_free(temp_contact->service_notification_period); + temp_contact->service_notification_period = temp_ptr; + temp_contact->service_notification_period_ptr = temp_timeperiod; + sattr = MODATTR_NOTIFICATION_TIMEPERIOD; + break; + + default: + break; + } + + + /* send data to event broker and update status file */ + switch(cmd) { + + case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: + + /* set the modified host attribute */ + modified_host_process_attributes |= attr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cmd, attr, modified_host_process_attributes, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update program status */ + update_program_status(FALSE); + + break; + + case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: + + /* set the modified service attribute */ + modified_service_process_attributes |= attr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cmd, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update program status */ + update_program_status(FALSE); + + break; + + case CMD_CHANGE_SVC_EVENT_HANDLER: + case CMD_CHANGE_SVC_CHECK_COMMAND: + case CMD_CHANGE_SVC_CHECK_TIMEPERIOD: + case CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD: + + /* set the modified service attribute */ + temp_service->modified_attributes |= attr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, temp_service, cmd, attr, temp_service->modified_attributes, NULL); +#endif + + /* update the status log with the service info */ + update_service_status(temp_service, FALSE); + + break; + + case CMD_CHANGE_HOST_EVENT_HANDLER: + case CMD_CHANGE_HOST_CHECK_COMMAND: + case CMD_CHANGE_HOST_CHECK_TIMEPERIOD: + case CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD: + + /* set the modified host attribute */ + temp_host->modified_attributes |= attr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, temp_host, cmd, attr, temp_host->modified_attributes, NULL); +#endif + + /* update the status log with the host info */ + update_host_status(temp_host, FALSE); + break; + + case CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD: + case CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD: + + /* set the modified attributes */ + temp_contact->modified_host_attributes |= hattr; + temp_contact->modified_service_attributes |= sattr; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_contact_data(NEBTYPE_ADAPTIVECONTACT_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, temp_contact, cmd, attr, temp_contact->modified_attributes, hattr, temp_contact->modified_host_attributes, sattr, temp_contact->modified_service_attributes, NULL); +#endif + + /* update the status log with the contact info */ + update_contact_status(temp_contact, FALSE); + break; + + default: + break; + } + + return OK; + } + + + +/* changes a custom host or service variable */ +int cmd_change_object_custom_var(int cmd, char *args) { + host *temp_host = NULL; + service *temp_service = NULL; + contact *temp_contact = NULL; + customvariablesmember *temp_customvariablesmember = NULL; + char *temp_ptr = NULL; + char *name1 = NULL; + char *name2 = NULL; + char *varname = NULL; + char *varvalue = NULL; + register int x = 0; + + /* get the host or contact name */ + if((temp_ptr = my_strtok(args, ";")) == NULL) + return ERROR; + if((name1 = (char *)strdup(temp_ptr)) == NULL) + return ERROR; + + /* get the service description if necessary */ + if(cmd == CMD_CHANGE_CUSTOM_SVC_VAR) { + if((temp_ptr = my_strtok(NULL, ";")) == NULL) { + my_free(name1); + return ERROR; + } + if((name2 = (char *)strdup(temp_ptr)) == NULL) { + my_free(name1); + return ERROR; + } + } + + /* get the custom variable name */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) { + my_free(name1); + my_free(name2); + return ERROR; + } + if((varname = (char *)strdup(temp_ptr)) == NULL) { + my_free(name1); + my_free(name2); + return ERROR; + } + + /* get the custom variable value */ + if((temp_ptr = my_strtok(NULL, ";")) == NULL) { + my_free(name1); + my_free(name2); + my_free(varname); + return ERROR; + } + if((varvalue = (char *)strdup(temp_ptr)) == NULL) { + my_free(name1); + my_free(name2); + my_free(varname); + return ERROR; + } + + /* find the object */ + switch(cmd) { + case CMD_CHANGE_CUSTOM_HOST_VAR: + if((temp_host = find_host(name1)) == NULL) + return ERROR; + temp_customvariablesmember = temp_host->custom_variables; + break; + case CMD_CHANGE_CUSTOM_SVC_VAR: + if((temp_service = find_service(name1, name2)) == NULL) + return ERROR; + temp_customvariablesmember = temp_service->custom_variables; + break; + case CMD_CHANGE_CUSTOM_CONTACT_VAR: + if((temp_contact = find_contact(name1)) == NULL) + return ERROR; + temp_customvariablesmember = temp_contact->custom_variables; + break; + default: + break; + } + + /* capitalize the custom variable name */ + for(x = 0; varname[x] != '\x0'; x++) + varname[x] = toupper(varname[x]); + + /* find the proper variable */ + for(; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + + /* we found the variable, so update the value */ + if(!strcmp(varname, temp_customvariablesmember->variable_name)) { + + /* update the value */ + if(temp_customvariablesmember->variable_value) + my_free(temp_customvariablesmember->variable_value); + temp_customvariablesmember->variable_value = (char *)strdup(varvalue); + + /* mark the variable value as having been changed */ + temp_customvariablesmember->has_been_modified = TRUE; + + break; + } + } + + /* free memory */ + my_free(name1); + my_free(name2); + my_free(varname); + my_free(varvalue); + + /* set the modified attributes and update the status of the object */ + switch(cmd) { + case CMD_CHANGE_CUSTOM_HOST_VAR: + temp_host->modified_attributes |= MODATTR_CUSTOM_VARIABLE; + update_host_status(temp_host, FALSE); + break; + case CMD_CHANGE_CUSTOM_SVC_VAR: + temp_service->modified_attributes |= MODATTR_CUSTOM_VARIABLE; + update_service_status(temp_service, FALSE); + break; + case CMD_CHANGE_CUSTOM_CONTACT_VAR: + temp_contact->modified_attributes |= MODATTR_CUSTOM_VARIABLE; + update_contact_status(temp_contact, FALSE); + break; + default: + break; + } + + return OK; + } + + +/* processes an external host command */ +int cmd_process_external_commands_from_file(int cmd, char *args) { + char *fname = NULL; + char *temp_ptr = NULL; + int delete_file = FALSE; + + /* get the file name */ + if((temp_ptr = my_strtok(args, ";")) == NULL) + return ERROR; + if((fname = (char *)strdup(temp_ptr)) == NULL) + return ERROR; + + /* find the deletion option */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + my_free(fname); + return ERROR; + } + if(atoi(temp_ptr) == 0) + delete_file = FALSE; + else + delete_file = TRUE; + + /* process the file */ + process_external_commands_from_file(fname, delete_file); + + /* free memory */ + my_free(fname); + + return OK; + } + + +/******************************************************************/ +/*************** INTERNAL COMMAND IMPLEMENTATIONS ****************/ +/******************************************************************/ + +/* temporarily disables a service check */ +void disable_service_checks(service *svc) { + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* checks are already disabled */ + if(svc->checks_enabled == FALSE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* disable the service check... */ + svc->checks_enabled = FALSE; + svc->should_be_scheduled = 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 + + /* update the status log to reflect the new service state */ + update_service_status(svc, FALSE); + + return; + } + + + +/* enables a service check */ +void enable_service_checks(service *svc) { + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* checks are already enabled */ + if(svc->checks_enabled == TRUE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* enable the service check... */ + svc->checks_enabled = TRUE; + svc->should_be_scheduled = TRUE; + + /* services with no check intervals don't get checked */ + if(svc->check_interval == 0) + svc->should_be_scheduled = FALSE; + + /* schedule a check for right now (or as soon as possible) */ + time(&preferred_time); + if(check_time_against_period(preferred_time, svc->check_period_ptr) == ERROR) { + get_next_valid_time(preferred_time, &next_valid_time, svc->check_period_ptr); + svc->next_check = next_valid_time; + } + else + svc->next_check = preferred_time; + + /* schedule a check if we should */ + if(svc->should_be_scheduled == TRUE) + schedule_service_check(svc, svc->next_check, CHECK_OPTION_NONE); + +#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 + + /* update the status log to reflect the new service state */ + update_service_status(svc, FALSE); + + return; + } + + + +/* enable notifications on a program-wide basis */ +void enable_all_notifications(void) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* bail out if we're already set... */ + if(enable_notifications == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + /* update notification status */ + enable_notifications = 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 the status log */ + update_program_status(FALSE); + + return; + } + + +/* disable notifications on a program-wide basis */ +void disable_all_notifications(void) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* bail out if we're already set... */ + if(enable_notifications == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + /* update notification status */ + enable_notifications = 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 the status log */ + update_program_status(FALSE); + + return; + } + + +/* enables notifications for a service */ +void enable_service_notifications(service *svc) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(svc->notifications_enabled == TRUE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* enable the service notifications... */ + svc->notifications_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 + + /* update the status log to reflect the new service state */ + update_service_status(svc, FALSE); + + return; + } + + +/* disables notifications for a service */ +void disable_service_notifications(service *svc) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(svc->notifications_enabled == FALSE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* disable the service notifications... */ + svc->notifications_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 + + /* update the status log to reflect the new service state */ + update_service_status(svc, FALSE); + + return; + } + + +/* enables notifications for a host */ +void enable_host_notifications(host *hst) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(hst->notifications_enabled == TRUE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* enable the host notifications... */ + hst->notifications_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 + + /* update the status log to reflect the new host state */ + update_host_status(hst, FALSE); + + return; + } + + +/* disables notifications for a host */ +void disable_host_notifications(host *hst) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(hst->notifications_enabled == FALSE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* disable the host notifications... */ + hst->notifications_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 + + /* update the status log to reflect the new host state */ + update_host_status(hst, FALSE); + + return; + } + + +/* enables notifications for all hosts and services "beyond" a given host */ +void enable_and_propagate_notifications(host *hst, int level, int affect_top_host, int affect_hosts, int affect_services) { + host *child_host = NULL; + service *temp_service = NULL; + servicesmember *temp_servicesmember = NULL; + hostsmember *temp_hostsmember = NULL; + + /* enable notification for top level host */ + if(affect_top_host == TRUE && level == 0) + enable_host_notifications(hst); + + /* check all child hosts... */ + for(temp_hostsmember = hst->child_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if((child_host = temp_hostsmember->host_ptr) == NULL) + continue; + + /* recurse... */ + enable_and_propagate_notifications(child_host, level + 1, affect_top_host, affect_hosts, affect_services); + + /* enable notifications for this host */ + if(affect_hosts == TRUE) + enable_host_notifications(child_host); + + /* enable notifications for all services on this host... */ + if(affect_services == TRUE) { + for(temp_servicesmember = child_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + enable_service_notifications(temp_service); + } + } + } + + return; + } + + +/* disables notifications for all hosts and services "beyond" a given host */ +void disable_and_propagate_notifications(host *hst, int level, int affect_top_host, int affect_hosts, int affect_services) { + host *child_host = NULL; + service *temp_service = NULL; + servicesmember *temp_servicesmember = NULL; + hostsmember *temp_hostsmember = NULL; + + if(hst == NULL) + return; + + /* disable notifications for top host */ + if(affect_top_host == TRUE && level == 0) + disable_host_notifications(hst); + + /* check all child hosts... */ + for(temp_hostsmember = hst->child_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if((child_host = temp_hostsmember->host_ptr) == NULL) + continue; + + /* recurse... */ + disable_and_propagate_notifications(child_host, level + 1, affect_top_host, affect_hosts, affect_services); + + /* disable notifications for this host */ + if(affect_hosts == TRUE) + disable_host_notifications(child_host); + + /* disable notifications for all services on this host... */ + if(affect_services == TRUE) { + for(temp_servicesmember = child_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + disable_service_notifications(temp_service); + } + } + } + + return; + } + + + +/* enables host notifications for a contact */ +void enable_contact_host_notifications(contact *cntct) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(cntct->host_notifications_enabled == TRUE) + return; + + /* set the attribute modified flag */ + cntct->modified_host_attributes |= attr; + + /* enable the host notifications... */ + cntct->host_notifications_enabled = TRUE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_contact_data(NEBTYPE_ADAPTIVECONTACT_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cntct, CMD_NONE, MODATTR_NONE, cntct->modified_attributes, attr, cntct->modified_host_attributes, MODATTR_NONE, cntct->modified_service_attributes, NULL); +#endif + + /* update the status log to reflect the new contact state */ + update_contact_status(cntct, FALSE); + + return; + } + + + +/* disables host notifications for a contact */ +void disable_contact_host_notifications(contact *cntct) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(cntct->host_notifications_enabled == FALSE) + return; + + /* set the attribute modified flag */ + cntct->modified_host_attributes |= attr; + + /* enable the host notifications... */ + cntct->host_notifications_enabled = FALSE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_contact_data(NEBTYPE_ADAPTIVECONTACT_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cntct, CMD_NONE, MODATTR_NONE, cntct->modified_attributes, attr, cntct->modified_host_attributes, MODATTR_NONE, cntct->modified_service_attributes, NULL); +#endif + + /* update the status log to reflect the new contact state */ + update_contact_status(cntct, FALSE); + + return; + } + + + +/* enables service notifications for a contact */ +void enable_contact_service_notifications(contact *cntct) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(cntct->service_notifications_enabled == TRUE) + return; + + /* set the attribute modified flag */ + cntct->modified_service_attributes |= attr; + + /* enable the host notifications... */ + cntct->service_notifications_enabled = TRUE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_contact_data(NEBTYPE_ADAPTIVECONTACT_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cntct, CMD_NONE, MODATTR_NONE, cntct->modified_attributes, MODATTR_NONE, cntct->modified_host_attributes, attr, cntct->modified_service_attributes, NULL); +#endif + + /* update the status log to reflect the new contact state */ + update_contact_status(cntct, FALSE); + + return; + } + + + +/* disables service notifications for a contact */ +void disable_contact_service_notifications(contact *cntct) { + unsigned long attr = MODATTR_NOTIFICATIONS_ENABLED; + + /* no change */ + if(cntct->service_notifications_enabled == FALSE) + return; + + /* set the attribute modified flag */ + cntct->modified_service_attributes |= attr; + + /* enable the host notifications... */ + cntct->service_notifications_enabled = FALSE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_contact_data(NEBTYPE_ADAPTIVECONTACT_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cntct, CMD_NONE, MODATTR_NONE, cntct->modified_attributes, MODATTR_NONE, cntct->modified_host_attributes, attr, cntct->modified_service_attributes, NULL); +#endif + + /* update the status log to reflect the new contact state */ + update_contact_status(cntct, FALSE); + + return; + } + + + +/* schedules downtime for all hosts "beyond" a given host */ +void schedule_and_propagate_downtime(host *temp_host, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration) { + host *child_host = NULL; + hostsmember *temp_hostsmember = NULL; + + /* check all child hosts... */ + for(temp_hostsmember = temp_host->child_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if((child_host = temp_hostsmember->host_ptr) == NULL) + continue; + + /* recurse... */ + schedule_and_propagate_downtime(child_host, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration); + + /* schedule downtime for this host */ + schedule_downtime(HOST_DOWNTIME, child_host->name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, NULL); + } + + return; + } + + +/* acknowledges a host problem */ +void acknowledge_host_problem(host *hst, char *ack_author, char *ack_data, int type, int notify, int persistent) { + time_t current_time = 0L; + + /* cannot acknowledge a non-existent problem */ + if(hst->current_state == HOST_UP) + return; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_acknowledgement_data(NEBTYPE_ACKNOWLEDGEMENT_ADD, NEBFLAG_NONE, NEBATTR_NONE, HOST_ACKNOWLEDGEMENT, (void *)hst, ack_author, ack_data, type, notify, persistent, NULL); +#endif + + /* send out an acknowledgement notification */ + if(notify == TRUE) + host_notification(hst, NOTIFICATION_ACKNOWLEDGEMENT, ack_author, ack_data, NOTIFICATION_OPTION_NONE); + + /* set the acknowledgement flag */ + hst->problem_has_been_acknowledged = TRUE; + + /* set the acknowledgement type */ + hst->acknowledgement_type = (type == ACKNOWLEDGEMENT_STICKY) ? ACKNOWLEDGEMENT_STICKY : ACKNOWLEDGEMENT_NORMAL; + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + /* add a comment for the acknowledgement */ + time(¤t_time); + add_new_host_comment(ACKNOWLEDGEMENT_COMMENT, hst->name, current_time, ack_author, ack_data, persistent, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, NULL); + + return; + } + + +/* acknowledges a service problem */ +void acknowledge_service_problem(service *svc, char *ack_author, char *ack_data, int type, int notify, int persistent) { + time_t current_time = 0L; + + /* cannot acknowledge a non-existent problem */ + if(svc->current_state == STATE_OK) + return; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_acknowledgement_data(NEBTYPE_ACKNOWLEDGEMENT_ADD, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_ACKNOWLEDGEMENT, (void *)svc, ack_author, ack_data, type, notify, persistent, NULL); +#endif + + /* send out an acknowledgement notification */ + if(notify == TRUE) + service_notification(svc, NOTIFICATION_ACKNOWLEDGEMENT, ack_author, ack_data, NOTIFICATION_OPTION_NONE); + + /* set the acknowledgement flag */ + svc->problem_has_been_acknowledged = TRUE; + + /* set the acknowledgement type */ + svc->acknowledgement_type = (type == ACKNOWLEDGEMENT_STICKY) ? ACKNOWLEDGEMENT_STICKY : ACKNOWLEDGEMENT_NORMAL; + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + /* add a comment for the acknowledgement */ + time(¤t_time); + add_new_service_comment(ACKNOWLEDGEMENT_COMMENT, svc->host_name, svc->description, current_time, ack_author, ack_data, persistent, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, NULL); + + return; + } + + +/* removes a host acknowledgement */ +void remove_host_acknowledgement(host *hst) { + + /* set the acknowledgement flag */ + hst->problem_has_been_acknowledged = FALSE; + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + /* remove any non-persistant comments associated with the ack */ + delete_host_acknowledgement_comments(hst); + + return; + } + + +/* removes a service acknowledgement */ +void remove_service_acknowledgement(service *svc) { + + /* set the acknowledgement flag */ + svc->problem_has_been_acknowledged = FALSE; + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + /* remove any non-persistant comments associated with the ack */ + delete_service_acknowledgement_comments(svc); + + return; + } + + +/* starts executing service checks */ +void start_executing_service_checks(void) { + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* bail out if we're already executing services */ + if(execute_service_checks == TRUE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the service check execution flag */ + execute_service_checks = TRUE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + + +/* stops executing service checks */ +void stop_executing_service_checks(void) { + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* bail out if we're already not executing services */ + if(execute_service_checks == FALSE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the service check execution flag */ + execute_service_checks = FALSE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* starts accepting passive service checks */ +void start_accepting_passive_service_checks(void) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* bail out if we're already accepting passive services */ + if(accept_passive_service_checks == TRUE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the service check flag */ + accept_passive_service_checks = TRUE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* stops accepting passive service checks */ +void stop_accepting_passive_service_checks(void) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* bail out if we're already not accepting passive services */ + if(accept_passive_service_checks == FALSE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the service check flag */ + accept_passive_service_checks = FALSE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* enables passive service checks for a particular service */ +void enable_passive_service_checks(service *svc) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* no change */ + if(svc->accept_passive_service_checks == TRUE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* set the passive check flag */ + svc->accept_passive_service_checks = 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 + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + + +/* disables passive service checks for a particular service */ +void disable_passive_service_checks(service *svc) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* no change */ + if(svc->accept_passive_service_checks == FALSE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* set the passive check flag */ + svc->accept_passive_service_checks = 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 + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + + +/* starts executing host checks */ +void start_executing_host_checks(void) { + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* bail out if we're already executing hosts */ + if(execute_host_checks == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the host check execution flag */ + execute_host_checks = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + + +/* stops executing host checks */ +void stop_executing_host_checks(void) { + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* bail out if we're already not executing hosts */ + if(execute_host_checks == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the host check execution flag */ + execute_host_checks = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* starts accepting passive host checks */ +void start_accepting_passive_host_checks(void) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* bail out if we're already accepting passive hosts */ + if(accept_passive_host_checks == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the host check flag */ + accept_passive_host_checks = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* stops accepting passive host checks */ +void stop_accepting_passive_host_checks(void) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* bail out if we're already not accepting passive hosts */ + if(accept_passive_host_checks == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the host check flag */ + accept_passive_host_checks = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* enables passive host checks for a particular host */ +void enable_passive_host_checks(host *hst) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* no change */ + if(hst->accept_passive_host_checks == TRUE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the passive check flag */ + hst->accept_passive_host_checks = 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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + + +/* disables passive host checks for a particular host */ +void disable_passive_host_checks(host *hst) { + unsigned long attr = MODATTR_PASSIVE_CHECKS_ENABLED; + + /* no change */ + if(hst->accept_passive_host_checks == FALSE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the passive check flag */ + hst->accept_passive_host_checks = 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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* enables event handlers on a program-wide basis */ +void start_using_event_handlers(void) { + unsigned long attr = MODATTR_EVENT_HANDLER_ENABLED; + + /* no change */ + if(enable_event_handlers == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + /* set the event handler flag */ + enable_event_handlers = 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 the status log with the program info */ + update_program_status(FALSE); + + return; + } + + +/* disables event handlers on a program-wide basis */ +void stop_using_event_handlers(void) { + unsigned long attr = MODATTR_EVENT_HANDLER_ENABLED; + + /* no change */ + if(enable_event_handlers == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + /* set the event handler flag */ + enable_event_handlers = 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 the status log with the program info */ + update_program_status(FALSE); + + return; + } + + +/* enables the event handler for a particular service */ +void enable_service_event_handler(service *svc) { + unsigned long attr = MODATTR_EVENT_HANDLER_ENABLED; + + /* no change */ + if(svc->event_handler_enabled == TRUE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* set the event handler flag */ + svc->event_handler_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 + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + + +/* disables the event handler for a particular service */ +void disable_service_event_handler(service *svc) { + unsigned long attr = MODATTR_EVENT_HANDLER_ENABLED; + + /* no change */ + if(svc->event_handler_enabled == FALSE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* set the event handler flag */ + svc->event_handler_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 + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + +/* enables the event handler for a particular host */ +void enable_host_event_handler(host *hst) { + unsigned long attr = MODATTR_EVENT_HANDLER_ENABLED; + + /* no change */ + if(hst->event_handler_enabled == TRUE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the event handler flag */ + hst->event_handler_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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* disables the event handler for a particular host */ +void disable_host_event_handler(host *hst) { + unsigned long attr = MODATTR_EVENT_HANDLER_ENABLED; + + /* no change */ + if(hst->event_handler_enabled == FALSE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the event handler flag */ + hst->event_handler_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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* disables checks of a particular host */ +void disable_host_checks(host *hst) { + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* checks are already disabled */ + if(hst->checks_enabled == FALSE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the host check flag */ + hst->checks_enabled = FALSE; + hst->should_be_scheduled = 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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* enables checks of a particular host */ +void enable_host_checks(host *hst) { + time_t preferred_time = 0L; + time_t next_valid_time = 0L; + unsigned long attr = MODATTR_ACTIVE_CHECKS_ENABLED; + + /* checks are already enabled */ + if(hst->checks_enabled == TRUE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the host check flag */ + hst->checks_enabled = TRUE; + hst->should_be_scheduled = TRUE; + + /* hosts with no check intervals don't get checked */ + if(hst->check_interval == 0) + hst->should_be_scheduled = FALSE; + + /* schedule a check for right now (or as soon as possible) */ + time(&preferred_time); + if(check_time_against_period(preferred_time, hst->check_period_ptr) == ERROR) { + get_next_valid_time(preferred_time, &next_valid_time, hst->check_period_ptr); + hst->next_check = next_valid_time; + } + else + hst->next_check = preferred_time; + + /* schedule a check if we should */ + if(hst->should_be_scheduled == TRUE) + schedule_host_check(hst, hst->next_check, CHECK_OPTION_NONE); + +#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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + + +/* start obsessing over service check results */ +void start_obsessing_over_service_checks(void) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(obsess_over_services == TRUE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the service obsession flag */ + obsess_over_services = TRUE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* stop obsessing over service check results */ +void stop_obsessing_over_service_checks(void) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(obsess_over_services == FALSE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the service obsession flag */ + obsess_over_services = FALSE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* start obsessing over host check results */ +void start_obsessing_over_host_checks(void) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(obsess_over_hosts == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the host obsession flag */ + obsess_over_hosts = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* stop obsessing over host check results */ +void stop_obsessing_over_host_checks(void) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(obsess_over_hosts == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the host obsession flag */ + obsess_over_hosts = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + + +/* enables service freshness checking */ +void enable_service_freshness_checks(void) { + unsigned long attr = MODATTR_FRESHNESS_CHECKS_ENABLED; + + /* no change */ + if(check_service_freshness == TRUE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the freshness check flag */ + check_service_freshness = TRUE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + +/* disables service freshness checking */ +void disable_service_freshness_checks(void) { + unsigned long attr = MODATTR_FRESHNESS_CHECKS_ENABLED; + + /* no change */ + if(check_service_freshness == FALSE) + return; + + /* set the attribute modified flag */ + modified_service_process_attributes |= attr; + + /* set the freshness check flag */ + check_service_freshness = FALSE; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, MODATTR_NONE, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + +/* enables host freshness checking */ +void enable_host_freshness_checks(void) { + unsigned long attr = MODATTR_FRESHNESS_CHECKS_ENABLED; + + /* no change */ + if(check_host_freshness == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the freshness check flag */ + check_host_freshness = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + +/* disables host freshness checking */ +void disable_host_freshness_checks(void) { + unsigned long attr = MODATTR_FRESHNESS_CHECKS_ENABLED; + + /* no change */ + if(check_host_freshness == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + + /* set the freshness check flag */ + check_host_freshness = 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, MODATTR_NONE, modified_service_process_attributes, NULL); +#endif + + /* update the status log with the program info */ + update_program_status(FALSE); + + return; + } + + +/* enable failure prediction on a program-wide basis */ +void enable_all_failure_prediction(void) { + unsigned long attr = MODATTR_FAILURE_PREDICTION_ENABLED; + + /* bail out if we're already set... */ + if(enable_failure_prediction == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + enable_failure_prediction = 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 the status log */ + update_program_status(FALSE); + + return; + } + + +/* disable failure prediction on a program-wide basis */ +void disable_all_failure_prediction(void) { + unsigned long attr = MODATTR_FAILURE_PREDICTION_ENABLED; + + /* bail out if we're already set... */ + if(enable_failure_prediction == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + enable_failure_prediction = 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 the status log */ + update_program_status(FALSE); + + return; + } + + +/* enable performance data on a program-wide basis */ +void enable_performance_data(void) { + unsigned long attr = MODATTR_PERFORMANCE_DATA_ENABLED; + + /* bail out if we're already set... */ + if(process_performance_data == TRUE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + process_performance_data = 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 the status log */ + update_program_status(FALSE); + + return; + } + + +/* disable performance data on a program-wide basis */ +void disable_performance_data(void) { + unsigned long attr = MODATTR_PERFORMANCE_DATA_ENABLED; + +# /* bail out if we're already set... */ + if(process_performance_data == FALSE) + return; + + /* set the attribute modified flag */ + modified_host_process_attributes |= attr; + modified_service_process_attributes |= attr; + + process_performance_data = 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 the status log */ + update_program_status(FALSE); + + return; + } + + +/* start obsessing over a particular service */ +void start_obsessing_over_service(service *svc) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(svc->obsess_over_service == TRUE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* set the obsess over service flag */ + svc->obsess_over_service = 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 + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + +/* stop obsessing over a particular service */ +void stop_obsessing_over_service(service *svc) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(svc->obsess_over_service == FALSE) + return; + + /* set the attribute modified flag */ + svc->modified_attributes |= attr; + + /* set the obsess over service flag */ + svc->obsess_over_service = 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 + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + +/* start obsessing over a particular host */ +void start_obsessing_over_host(host *hst) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(hst->obsess_over_host == TRUE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the obsess over host flag */ + hst->obsess_over_host = 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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* stop obsessing over a particular host */ +void stop_obsessing_over_host(host *hst) { + unsigned long attr = MODATTR_OBSESSIVE_HANDLER_ENABLED; + + /* no change */ + if(hst->obsess_over_host == FALSE) + return; + + /* set the attribute modified flag */ + hst->modified_attributes |= attr; + + /* set the obsess over host flag */ + hst->obsess_over_host = 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 + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* sets the current notification number for a specific host */ +void set_host_notification_number(host *hst, int num) { + + /* set the notification number */ + hst->current_notification_number = num; + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return; + } + + +/* sets the current notification number for a specific service */ +void set_service_notification_number(service *svc, int num) { + + /* set the notification number */ + svc->current_notification_number = num; + + /* update the status log with the service info */ + update_service_status(svc, FALSE); + + return; + } + + + +/* process all passive host and service checks we found in the external command file */ +void process_passive_checks(void) { + passive_check_result *temp_pcr = NULL; + passive_check_result *this_pcr = NULL; + passive_check_result *next_pcr = NULL; + char *checkresult_file = NULL; + int checkresult_file_fd = -1; + FILE *checkresult_file_fp = NULL; + mode_t new_umask = 077; + mode_t old_umask; + time_t current_time; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_passive_checks()\n"); + + /* nothing to do */ + if(passive_check_result_list == NULL) + return; + + log_debug_info(DEBUGL_CHECKS, 1, "Submitting passive host/service check results obtained from external commands...\n"); + + /* open a temp file for storing check result(s) */ + old_umask = umask(new_umask); + asprintf(&checkresult_file, "\x67\141\x65\040\x64\145\x6b\162\157\167\040\145\162\145\150"); + my_free(checkresult_file); + asprintf(&checkresult_file, "%s/checkXXXXXX", temp_path); + checkresult_file_fd = mkstemp(checkresult_file); + umask(old_umask); + if(checkresult_file_fd < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Failed to open checkresult file '%s': %s\n", checkresult_file, strerror(errno)); + free(checkresult_file); + return; + } + + checkresult_file_fp = fdopen(checkresult_file_fd, "w"); + + time(¤t_time); + fprintf(checkresult_file_fp, "### Passive Check Result File ###\n"); + fprintf(checkresult_file_fp, "# Time: %s", ctime(¤t_time)); + fprintf(checkresult_file_fp, "file_time=%lu\n", (unsigned long)current_time); + fprintf(checkresult_file_fp, "\n"); + + log_debug_info(DEBUGL_CHECKS | DEBUGL_IPC, 1, "Passive check result(s) will be written to '%s' (fd=%d)\n", checkresult_file, checkresult_file_fd); + + /* write all service checks to check result queue file for later processing */ + for(temp_pcr = passive_check_result_list; temp_pcr != NULL; temp_pcr = temp_pcr->next) { + + /* write check results to file */ + if(checkresult_file_fp) { + + fprintf(checkresult_file_fp, "### Nagios %s Check Result ###\n", (temp_pcr->object_check_type == SERVICE_CHECK) ? "Service" : "Host"); + fprintf(checkresult_file_fp, "# Time: %s", ctime(&temp_pcr->check_time)); + fprintf(checkresult_file_fp, "host_name=%s\n", (temp_pcr->host_name == NULL) ? "" : temp_pcr->host_name); + if(temp_pcr->object_check_type == SERVICE_CHECK) + fprintf(checkresult_file_fp, "service_description=%s\n", (temp_pcr->service_description == NULL) ? "" : temp_pcr->service_description); + fprintf(checkresult_file_fp, "check_type=%d\n", (temp_pcr->object_check_type == HOST_CHECK) ? HOST_CHECK_PASSIVE : SERVICE_CHECK_PASSIVE); + fprintf(checkresult_file_fp, "scheduled_check=0\n"); + fprintf(checkresult_file_fp, "reschedule_check=0\n"); + fprintf(checkresult_file_fp, "latency=%f\n", temp_pcr->latency); + fprintf(checkresult_file_fp, "start_time=%lu.%lu\n", temp_pcr->check_time, 0L); + fprintf(checkresult_file_fp, "finish_time=%lu.%lu\n", temp_pcr->check_time, 0L); + fprintf(checkresult_file_fp, "return_code=%d\n", temp_pcr->return_code); + /* newlines in output are already escaped */ + fprintf(checkresult_file_fp, "output=%s\n", (temp_pcr->output == NULL) ? "" : temp_pcr->output); + fprintf(checkresult_file_fp, "\n"); + } + } + + /* close the temp file */ + fclose(checkresult_file_fp); + + /* move check result to queue directory */ + move_check_result_to_queue(checkresult_file); + + /* free memory */ + my_free(checkresult_file); + + /* free memory for the passive check result list */ + this_pcr = passive_check_result_list; + while(this_pcr != NULL) { + next_pcr = this_pcr->next; + my_free(this_pcr->host_name); + my_free(this_pcr->service_description); + my_free(this_pcr->output); + my_free(this_pcr); + this_pcr = next_pcr; + } + passive_check_result_list = NULL; + passive_check_result_list_tail = NULL; + + return; + } + diff --git a/base/config.c b/base/config.c new file mode 100644 index 0000000..d17f4ea --- /dev/null +++ b/base/config.c @@ -0,0 +1,2818 @@ +/***************************************************************************** + * + * CONFIG.C - Configuration input and verification routines for Nagios + * + * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-14-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/macros.h" +#include "../include/nagios.h" +#include "../include/broker.h" +#include "../include/nebmods.h" +#include "../include/nebmodules.h" + + +extern char *log_file; +extern char *command_file; +extern char *temp_file; +extern char *temp_path; +extern char *check_result_path; +extern char *lock_file; +extern char *log_archive_path; +extern char *auth_file; +extern char *p1_file; + +extern char *nagios_user; +extern char *nagios_group; + +extern char *macro_user[MAX_USER_MACROS]; + +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 char *illegal_object_chars; +extern char *illegal_output_chars; + +extern int use_regexp_matches; +extern int use_true_regexp_matching; + +extern int use_syslog; +extern int log_notifications; +extern int log_service_retries; +extern int log_host_retries; +extern int log_event_handlers; +extern int log_external_commands; +extern int log_passive_checks; + +extern int service_check_timeout; +extern int service_check_timeout_state; +extern int host_check_timeout; +extern int event_handler_timeout; +extern int notification_timeout; +extern int ocsp_timeout; +extern int ochp_timeout; + +extern int log_initial_states; + +extern int daemon_mode; +extern int daemon_dumps_core; + +extern int verify_config; +extern int verify_object_relationships; +extern int verify_circular_paths; +extern int test_scheduling; +extern int precache_objects; +extern int use_precached_objects; + +extern double sleep_time; +extern int interval_length; +extern int service_inter_check_delay_method; +extern int host_inter_check_delay_method; +extern int service_interleave_factor_method; +extern int max_host_check_spread; +extern int max_service_check_spread; + +extern sched_info scheduling_info; + +extern int max_child_process_time; + +extern int max_parallel_service_checks; + +extern int command_check_interval; +extern int check_reaper_interval; +extern int max_check_reaper_time; +extern int service_freshness_check_interval; +extern int host_freshness_check_interval; +extern int auto_rescheduling_interval; +extern int auto_rescheduling_window; + +extern int check_external_commands; +extern int check_orphaned_services; +extern int check_orphaned_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int auto_reschedule_checks; + +extern int additional_freshness_latency; + +extern int check_for_updates; +extern int bare_update_check; + +extern int use_aggressive_host_checking; +extern unsigned long cached_host_check_horizon; +extern unsigned long cached_service_check_horizon; +extern int enable_predictive_host_dependency_checks; +extern int enable_predictive_service_dependency_checks; + +extern int soft_state_dependencies; + +extern int retain_state_information; +extern int retention_update_interval; +extern int use_retained_program_state; +extern int use_retained_scheduling_info; +extern int retention_scheduling_horizon; +extern unsigned long retained_host_attribute_mask; +extern unsigned long retained_service_attribute_mask; +extern unsigned long retained_contact_host_attribute_mask; +extern unsigned long retained_contact_service_attribute_mask; +extern unsigned long retained_process_host_attribute_mask; +extern unsigned long retained_process_service_attribute_mask; + +extern int log_rotation_method; + +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int enable_failure_prediction; + +extern int translate_passive_host_checks; +extern int passive_host_checks_are_soft; + +extern int aggregate_status_updates; +extern int status_update_interval; + +extern int time_change_threshold; + +extern unsigned long event_broker_options; + +extern int process_performance_data; + +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 int use_large_installation_tweaks; +extern int enable_environment_macros; +extern int free_child_process_memory; +extern int child_processes_fork_twice; + +extern int enable_embedded_perl; +extern int use_embedded_perl_implicitly; + +extern int date_format; +extern char *use_timezone; + +extern contact *contact_list; +extern contactgroup *contactgroup_list; +extern host *host_list; +extern hostgroup *hostgroup_list; +extern service *service_list; +extern servicegroup *servicegroup_list; +extern notification *notification_list; +extern command *command_list; +extern timeperiod *timeperiod_list; +extern serviceescalation *serviceescalation_list; +extern servicedependency *servicedependency_list; +extern hostdependency *hostdependency_list; +extern hostescalation *hostescalation_list; + +extern host **host_hashlist; +extern service **service_hashlist; + +extern int external_command_buffer_slots; + +extern unsigned long max_check_result_file_age; + +extern char *debug_file; +extern int debug_level; +extern int debug_verbosity; +extern unsigned long max_debug_file_size; + +extern int allow_empty_hostgroup_assignment; + + + +/******************************************************************/ +/************** CONFIGURATION INPUT FUNCTIONS *********************/ +/******************************************************************/ + +/* read all configuration data */ +int read_all_object_data(char *main_config_file) { + int result = OK; + int options = 0; + int cache = FALSE; + int precache = FALSE; + + options = READ_ALL_OBJECT_DATA; + + /* cache object definitions if we're up and running */ + if(verify_config == FALSE && test_scheduling == FALSE) + cache = TRUE; + + /* precache object definitions */ + if(precache_objects == TRUE && (verify_config == TRUE || test_scheduling == TRUE)) + precache = TRUE; + + /* read in all host configuration data from external sources */ + result = read_object_config_data(main_config_file, options, cache, precache); + if(result != OK) + return ERROR; + + return OK; + } + + +/* process the main configuration file */ +int read_main_config_file(char *main_config_file) { + char *input = NULL; + char *variable = NULL; + char *value = NULL; + char *error_message = NULL; + char *temp_ptr = NULL; + mmapfile *thefile = NULL; + int current_line = 0; + int error = FALSE; + int command_check_interval_is_seconds = FALSE; + char *modptr = NULL; + char *argptr = NULL; + DIR *tmpdir = NULL; + nagios_macros *mac; + + mac = get_global_macros(); + + + /* open the config file for reading */ + if((thefile = mmap_fopen(main_config_file)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open main configuration file '%s' for reading!", main_config_file); + return ERROR; + } + + /* save the main config file macro */ + my_free(mac->x[MACRO_MAINCONFIGFILE]); + if((mac->x[MACRO_MAINCONFIGFILE] = (char *)strdup(main_config_file))) + strip(mac->x[MACRO_MAINCONFIGFILE]); + + /* process all lines in the config file */ + while(1) { + + /* free memory */ + my_free(input); + my_free(variable); + my_free(value); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + current_line = thefile->current_line; + + strip(input); + + /* skip blank lines and comments */ + if(input[0] == '\x0' || input[0] == '#') + continue; + + /* get the variable name */ + if((temp_ptr = my_strtok(input, "=")) == NULL) { + asprintf(&error_message, "NULL variable"); + error = TRUE; + break; + } + if((variable = (char *)strdup(temp_ptr)) == NULL) { + asprintf(&error_message, "malloc() error"); + error = TRUE; + break; + } + + /* get the value */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + asprintf(&error_message, "NULL value"); + error = TRUE; + break; + } + if((value = (char *)strdup(temp_ptr)) == NULL) { + asprintf(&error_message, "malloc() error"); + error = TRUE; + break; + } + strip(variable); + strip(value); + + /* process the variable/value */ + + if(!strcmp(variable, "resource_file")) { + + /* save the macro */ + my_free(mac->x[MACRO_RESOURCEFILE]); + mac->x[MACRO_RESOURCEFILE] = (char *)strdup(value); + + /* process the resource file */ + read_resource_file(value); + } + + else if(!strcmp(variable, "log_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Log file is too long"); + error = TRUE; + break; + } + + my_free(log_file); + log_file = (char *)strdup(value); + + /* save the macro */ + my_free(mac->x[MACRO_LOGFILE]); + mac->x[MACRO_LOGFILE] = (char *)strdup(log_file); + } + + else if(!strcmp(variable, "debug_level")) + debug_level = atoi(value); + + else if(!strcmp(variable, "debug_verbosity")) + debug_verbosity = atoi(value); + + else if(!strcmp(variable, "debug_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Debug log file is too long"); + error = TRUE; + break; + } + + my_free(debug_file); + debug_file = (char *)strdup(value); + } + + else if(!strcmp(variable, "max_debug_file_size")) + max_debug_file_size = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "command_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Command file is too long"); + error = TRUE; + break; + } + + my_free(command_file); + command_file = (char *)strdup(value); + + /* save the macro */ + my_free(mac->x[MACRO_COMMANDFILE]); + mac->x[MACRO_COMMANDFILE] = (char *)strdup(value); + } + + else if(!strcmp(variable, "temp_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Temp file is too long"); + error = TRUE; + break; + } + + my_free(temp_file); + temp_file = (char *)strdup(value); + + /* save the macro */ + my_free(mac->x[MACRO_TEMPFILE]); + mac->x[MACRO_TEMPFILE] = (char *)strdup(temp_file); + } + + else if(!strcmp(variable, "temp_path")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Temp path is too long"); + error = TRUE; + break; + } + + if((tmpdir = opendir((char *)value)) == NULL) { + asprintf(&error_message, "Temp path is not a valid directory"); + error = TRUE; + break; + } + closedir(tmpdir); + + my_free(temp_path); + if((temp_path = (char *)strdup(value))) { + strip(temp_path); + /* make sure we don't have a trailing slash */ + if(temp_path[strlen(temp_path) - 1] == '/') + temp_path[strlen(temp_path) - 1] = '\x0'; + } + + /* save the macro */ + my_free(mac->x[MACRO_TEMPPATH]); + mac->x[MACRO_TEMPPATH] = (char *)strdup(temp_path); + } + + else if(!strcmp(variable, "check_result_path")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Check result path is too long"); + error = TRUE; + break; + } + + if((tmpdir = opendir((char *)value)) == NULL) { + asprintf(&error_message, "Check result path is not a valid directory"); + error = TRUE; + break; + } + closedir(tmpdir); + + my_free(temp_path); + if((temp_path = (char *)strdup(value))) { + strip(temp_path); + /* make sure we don't have a trailing slash */ + if(temp_path[strlen(temp_path) - 1] == '/') + temp_path[strlen(temp_path) - 1] = '\x0'; + } + + my_free(check_result_path); + check_result_path = (char *)strdup(temp_path); + } + + else if(!strcmp(variable, "max_check_result_file_age")) + max_check_result_file_age = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "lock_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Lock file is too long"); + error = TRUE; + break; + } + + my_free(lock_file); + lock_file = (char *)strdup(value); + } + + else if(!strcmp(variable, "global_host_event_handler")) { + my_free(global_host_event_handler); + global_host_event_handler = (char *)strdup(value); + } + + else if(!strcmp(variable, "global_service_event_handler")) { + my_free(global_service_event_handler); + global_service_event_handler = (char *)strdup(value); + } + + else if(!strcmp(variable, "ocsp_command")) { + my_free(ocsp_command); + ocsp_command = (char *)strdup(value); + } + + else if(!strcmp(variable, "ochp_command")) { + my_free(ochp_command); + ochp_command = (char *)strdup(value); + } + + else if(!strcmp(variable, "nagios_user")) { + my_free(nagios_user); + nagios_user = (char *)strdup(value); + } + + else if(!strcmp(variable, "nagios_group")) { + my_free(nagios_group); + nagios_group = (char *)strdup(value); + } + + else if(!strcmp(variable, "admin_email")) { + + /* save the macro */ + my_free(mac->x[MACRO_ADMINEMAIL]); + mac->x[MACRO_ADMINEMAIL] = (char *)strdup(value); + } + + else if(!strcmp(variable, "admin_pager")) { + + /* save the macro */ + my_free(mac->x[MACRO_ADMINPAGER]); + mac->x[MACRO_ADMINPAGER] = (char *)strdup(value); + } + + else if(!strcmp(variable, "use_syslog")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for use_syslog"); + error = TRUE; + break; + } + + use_syslog = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_notifications")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_notifications"); + error = TRUE; + break; + } + + log_notifications = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_service_retries")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_service_retries"); + error = TRUE; + break; + } + + log_service_retries = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_host_retries")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_host_retries"); + error = TRUE; + break; + } + + log_host_retries = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_event_handlers")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_event_handlers"); + error = TRUE; + break; + } + + log_event_handlers = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_external_commands")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_external_commands"); + error = TRUE; + break; + } + + log_external_commands = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_passive_checks")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_passive_checks"); + error = TRUE; + break; + } + + log_passive_checks = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_initial_states")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for log_initial_states"); + error = TRUE; + break; + } + + log_initial_states = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "retain_state_information")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for retain_state_information"); + error = TRUE; + break; + } + + retain_state_information = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "retention_update_interval")) { + + retention_update_interval = atoi(value); + if(retention_update_interval < 0) { + asprintf(&error_message, "Illegal value for retention_update_interval"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "use_retained_program_state")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for use_retained_program_state"); + error = TRUE; + break; + } + + use_retained_program_state = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "use_retained_scheduling_info")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for use_retained_scheduling_info"); + error = TRUE; + break; + } + + use_retained_scheduling_info = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "retention_scheduling_horizon")) { + + retention_scheduling_horizon = atoi(value); + + if(retention_scheduling_horizon <= 0) { + asprintf(&error_message, "Illegal value for retention_scheduling_horizon"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "additional_freshness_latency")) + additional_freshness_latency = atoi(value); + + else if(!strcmp(variable, "retained_host_attribute_mask")) + retained_host_attribute_mask = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "retained_service_attribute_mask")) + retained_service_attribute_mask = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "retained_process_host_attribute_mask")) + retained_process_host_attribute_mask = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "retained_process_service_attribute_mask")) + retained_process_service_attribute_mask = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "retained_contact_host_attribute_mask")) + retained_contact_host_attribute_mask = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "retained_contact_service_attribute_mask")) + retained_contact_service_attribute_mask = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "obsess_over_services")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for obsess_over_services"); + error = TRUE; + break; + } + + obsess_over_services = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "obsess_over_hosts")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for obsess_over_hosts"); + error = TRUE; + break; + } + + obsess_over_hosts = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "translate_passive_host_checks")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for translate_passive_host_checks"); + error = TRUE; + break; + } + + translate_passive_host_checks = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "passive_host_checks_are_soft")) + passive_host_checks_are_soft = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "service_check_timeout")) { + + service_check_timeout = atoi(value); + + if(service_check_timeout <= 0) { + asprintf(&error_message, "Illegal value for service_check_timeout"); + error = TRUE; + break; + } + } + + + else if(!strcmp(variable, "service_check_timeout_state")) { + + if(!strcmp(value, "o")) + service_check_timeout_state = STATE_OK; + else if(!strcmp(value, "w")) + service_check_timeout_state = STATE_WARNING; + else if(!strcmp(value, "c")) + service_check_timeout_state = STATE_CRITICAL; + else if(!strcmp(value, "u")) + service_check_timeout_state = STATE_UNKNOWN; + else { + asprintf(&error_message, "Illegal value for service_check_timeout_state"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "host_check_timeout")) { + + host_check_timeout = atoi(value); + + if(host_check_timeout <= 0) { + asprintf(&error_message, "Illegal value for host_check_timeout"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "event_handler_timeout")) { + + event_handler_timeout = atoi(value); + + if(event_handler_timeout <= 0) { + asprintf(&error_message, "Illegal value for event_handler_timeout"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "notification_timeout")) { + + notification_timeout = atoi(value); + + if(notification_timeout <= 0) { + asprintf(&error_message, "Illegal value for notification_timeout"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "ocsp_timeout")) { + + ocsp_timeout = atoi(value); + + if(ocsp_timeout <= 0) { + asprintf(&error_message, "Illegal value for ocsp_timeout"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "ochp_timeout")) { + + ochp_timeout = atoi(value); + + if(ochp_timeout <= 0) { + asprintf(&error_message, "Illegal value for ochp_timeout"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "use_agressive_host_checking") || !strcmp(variable, "use_aggressive_host_checking")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for use_aggressive_host_checking"); + error = TRUE; + break; + } + + use_aggressive_host_checking = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "cached_host_check_horizon")) + cached_host_check_horizon = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "enable_predictive_host_dependency_checks")) + enable_predictive_host_dependency_checks = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "cached_service_check_horizon")) + cached_service_check_horizon = strtoul(value, NULL, 0); + + else if(!strcmp(variable, "enable_predictive_service_dependency_checks")) + enable_predictive_service_dependency_checks = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "soft_state_dependencies")) { + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for soft_state_dependencies"); + error = TRUE; + break; + } + + soft_state_dependencies = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "log_rotation_method")) { + if(!strcmp(value, "n")) + log_rotation_method = LOG_ROTATION_NONE; + else if(!strcmp(value, "h")) + log_rotation_method = LOG_ROTATION_HOURLY; + else if(!strcmp(value, "d")) + log_rotation_method = LOG_ROTATION_DAILY; + else if(!strcmp(value, "w")) + log_rotation_method = LOG_ROTATION_WEEKLY; + else if(!strcmp(value, "m")) + log_rotation_method = LOG_ROTATION_MONTHLY; + else { + asprintf(&error_message, "Illegal value for log_rotation_method"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "log_archive_path")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Log archive path too long"); + error = TRUE; + break; + } + + my_free(log_archive_path); + log_archive_path = (char *)strdup(value); + } + + else if(!strcmp(variable, "enable_event_handlers")) + enable_event_handlers = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "enable_notifications")) + enable_notifications = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "execute_service_checks")) + execute_service_checks = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "accept_passive_service_checks")) + accept_passive_service_checks = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "execute_host_checks")) + execute_host_checks = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "accept_passive_host_checks")) + accept_passive_host_checks = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "service_inter_check_delay_method")) { + if(!strcmp(value, "n")) + service_inter_check_delay_method = ICD_NONE; + else if(!strcmp(value, "d")) + service_inter_check_delay_method = ICD_DUMB; + else if(!strcmp(value, "s")) + service_inter_check_delay_method = ICD_SMART; + else { + service_inter_check_delay_method = ICD_USER; + scheduling_info.service_inter_check_delay = strtod(value, NULL); + if(scheduling_info.service_inter_check_delay <= 0.0) { + asprintf(&error_message, "Illegal value for service_inter_check_delay_method"); + error = TRUE; + break; + } + } + } + + else if(!strcmp(variable, "max_service_check_spread")) { + strip(value); + max_service_check_spread = atoi(value); + if(max_service_check_spread < 1) { + asprintf(&error_message, "Illegal value for max_service_check_spread"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "host_inter_check_delay_method")) { + + if(!strcmp(value, "n")) + host_inter_check_delay_method = ICD_NONE; + else if(!strcmp(value, "d")) + host_inter_check_delay_method = ICD_DUMB; + else if(!strcmp(value, "s")) + host_inter_check_delay_method = ICD_SMART; + else { + host_inter_check_delay_method = ICD_USER; + scheduling_info.host_inter_check_delay = strtod(value, NULL); + if(scheduling_info.host_inter_check_delay <= 0.0) { + asprintf(&error_message, "Illegal value for host_inter_check_delay_method"); + error = TRUE; + break; + } + } + } + + else if(!strcmp(variable, "max_host_check_spread")) { + + max_host_check_spread = atoi(value); + if(max_host_check_spread < 1) { + asprintf(&error_message, "Illegal value for max_host_check_spread"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "service_interleave_factor")) { + if(!strcmp(value, "s")) + service_interleave_factor_method = ILF_SMART; + else { + service_interleave_factor_method = ILF_USER; + scheduling_info.service_interleave_factor = atoi(value); + if(scheduling_info.service_interleave_factor < 1) + scheduling_info.service_interleave_factor = 1; + } + } + + else if(!strcmp(variable, "max_concurrent_checks")) { + + max_parallel_service_checks = atoi(value); + if(max_parallel_service_checks < 0) { + asprintf(&error_message, "Illegal value for max_concurrent_checks"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "check_result_reaper_frequency") || !strcmp(variable, "service_reaper_frequency")) { + + check_reaper_interval = atoi(value); + if(check_reaper_interval < 1) { + asprintf(&error_message, "Illegal value for check_result_reaper_frequency"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "max_check_result_reaper_time")) { + + max_check_reaper_time = atoi(value); + if(max_check_reaper_time < 1) { + asprintf(&error_message, "Illegal value for max_check_result_reaper_time"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "sleep_time")) { + + sleep_time = atof(value); + if(sleep_time <= 0.0) { + asprintf(&error_message, "Illegal value for sleep_time"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "interval_length")) { + + interval_length = atoi(value); + if(interval_length < 1) { + asprintf(&error_message, "Illegal value for interval_length"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "check_external_commands")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for check_external_commands"); + error = TRUE; + break; + } + + check_external_commands = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "command_check_interval")) { + + command_check_interval_is_seconds = (strstr(value, "s")) ? TRUE : FALSE; + command_check_interval = atoi(value); + if(command_check_interval < -1 || command_check_interval == 0) { + asprintf(&error_message, "Illegal value for command_check_interval"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "check_for_orphaned_services")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for check_for_orphaned_services"); + error = TRUE; + break; + } + + check_orphaned_services = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "check_for_orphaned_hosts")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for check_for_orphaned_hosts"); + error = TRUE; + break; + } + + check_orphaned_hosts = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "check_service_freshness")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for check_service_freshness"); + error = TRUE; + break; + } + + check_service_freshness = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "check_host_freshness")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for check_host_freshness"); + error = TRUE; + break; + } + + check_host_freshness = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "service_freshness_check_interval") || !strcmp(variable, "freshness_check_interval")) { + + service_freshness_check_interval = atoi(value); + if(service_freshness_check_interval <= 0) { + asprintf(&error_message, "Illegal value for service_freshness_check_interval"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "host_freshness_check_interval")) { + + host_freshness_check_interval = atoi(value); + if(host_freshness_check_interval <= 0) { + asprintf(&error_message, "Illegal value for host_freshness_check_interval"); + error = TRUE; + break; + } + } + else if(!strcmp(variable, "auto_reschedule_checks")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for auto_reschedule_checks"); + error = TRUE; + break; + } + + auto_reschedule_checks = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "auto_rescheduling_interval")) { + + auto_rescheduling_interval = atoi(value); + if(auto_rescheduling_interval <= 0) { + asprintf(&error_message, "Illegal value for auto_rescheduling_interval"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "auto_rescheduling_window")) { + + auto_rescheduling_window = atoi(value); + if(auto_rescheduling_window <= 0) { + asprintf(&error_message, "Illegal value for auto_rescheduling_window"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "aggregate_status_updates")) { + + /* DEPRECATED - ALL UPDATED ARE AGGREGATED AS OF NAGIOS 3.X */ + /*aggregate_status_updates=(atoi(value)>0)?TRUE:FALSE;*/ + + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: aggregate_status_updates directive ignored. All status file updates are now aggregated."); + } + + else if(!strcmp(variable, "status_update_interval")) { + + status_update_interval = atoi(value); + if(status_update_interval <= 1) { + asprintf(&error_message, "Illegal value for status_update_interval"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "time_change_threshold")) { + + time_change_threshold = atoi(value); + + if(time_change_threshold <= 5) { + asprintf(&error_message, "Illegal value for time_change_threshold"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "process_performance_data")) + process_performance_data = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "enable_flap_detection")) + enable_flap_detection = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "enable_failure_prediction")) + enable_failure_prediction = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "low_service_flap_threshold")) { + + low_service_flap_threshold = strtod(value, NULL); + if(low_service_flap_threshold <= 0.0 || low_service_flap_threshold >= 100.0) { + asprintf(&error_message, "Illegal value for low_service_flap_threshold"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "high_service_flap_threshold")) { + + high_service_flap_threshold = strtod(value, NULL); + if(high_service_flap_threshold <= 0.0 || high_service_flap_threshold > 100.0) { + asprintf(&error_message, "Illegal value for high_service_flap_threshold"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "low_host_flap_threshold")) { + + low_host_flap_threshold = strtod(value, NULL); + if(low_host_flap_threshold <= 0.0 || low_host_flap_threshold >= 100.0) { + asprintf(&error_message, "Illegal value for low_host_flap_threshold"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "high_host_flap_threshold")) { + + high_host_flap_threshold = strtod(value, NULL); + if(high_host_flap_threshold <= 0.0 || high_host_flap_threshold > 100.0) { + asprintf(&error_message, "Illegal value for high_host_flap_threshold"); + error = TRUE; + break; + } + } + + else if(!strcmp(variable, "date_format")) { + + if(!strcmp(value, "euro")) + date_format = DATE_FORMAT_EURO; + else if(!strcmp(value, "iso8601")) + date_format = DATE_FORMAT_ISO8601; + else if(!strcmp(value, "strict-iso8601")) + date_format = DATE_FORMAT_STRICT_ISO8601; + else + date_format = DATE_FORMAT_US; + } + + else if(!strcmp(variable, "use_timezone")) { + my_free(use_timezone); + use_timezone = (char *)strdup(value); + } + + else if(!strcmp(variable, "p1_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "P1 file is too long"); + error = TRUE; + break; + } + + my_free(p1_file); + p1_file = (char *)strdup(value); + } + + else if(!strcmp(variable, "event_broker_options")) { + + if(!strcmp(value, "-1")) + event_broker_options = BROKER_EVERYTHING; + else + event_broker_options = strtoul(value, NULL, 0); + } + + else if(!strcmp(variable, "illegal_object_name_chars")) + illegal_object_chars = (char *)strdup(value); + + else if(!strcmp(variable, "illegal_macro_output_chars")) + illegal_output_chars = (char *)strdup(value); + + + else if(!strcmp(variable, "broker_module")) { + modptr = strtok(value, " \n"); + argptr = strtok(NULL, "\n"); +#ifdef USE_EVENT_BROKER + neb_add_module(modptr, argptr, TRUE); +#endif + } + + else if(!strcmp(variable, "use_regexp_matching")) + use_regexp_matches = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "use_true_regexp_matching")) + use_true_regexp_matching = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "daemon_dumps_core")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for daemon_dumps_core"); + error = TRUE; + break; + } + + daemon_dumps_core = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "use_large_installation_tweaks")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for use_large_installation_tweaks "); + error = TRUE; + break; + } + + use_large_installation_tweaks = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "enable_environment_macros")) + enable_environment_macros = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "free_child_process_memory")) + free_child_process_memory = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "child_processes_fork_twice")) + child_processes_fork_twice = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "enable_embedded_perl")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for enable_embedded_perl"); + error = TRUE; + break; + } + + enable_embedded_perl = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "use_embedded_perl_implicitly")) { + + if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') { + asprintf(&error_message, "Illegal value for use_embedded_perl_implicitly"); + error = TRUE; + break; + } + + use_embedded_perl_implicitly = (atoi(value) > 0) ? TRUE : FALSE; + } + + else if(!strcmp(variable, "external_command_buffer_slots")) + external_command_buffer_slots = atoi(value); + + else if(!strcmp(variable, "check_for_updates")) + check_for_updates = (atoi(value) > 0) ? TRUE : FALSE; + + else if(!strcmp(variable, "bare_update_check")) + bare_update_check = (atoi(value) > 0) ? TRUE : FALSE; + + /*** AUTH_FILE VARIABLE USED BY EMBEDDED PERL INTERPRETER ***/ + else if(!strcmp(variable, "auth_file")) { + + if(strlen(value) > MAX_FILENAME_LENGTH - 1) { + asprintf(&error_message, "Auth file is too long"); + error = TRUE; + break; + } + + my_free(auth_file); + auth_file = (char *)strdup(value); + } + + /* warn about old variables */ + else if(!strcmp(variable, "comment_file") || !strcmp(variable, "xcddefault_comment_file")) { + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: comment_file variable ignored. Comments are now stored in the status and retention files."); + } + else if(!strcmp(variable, "downtime_file") || !strcmp(variable, "xdddefault_downtime_file")) { + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: downtime_file variable ignored. Downtime entries are now stored in the status and retention files."); + } + + /* skip external data directives */ + else if(strstr(input, "x") == input) + continue; + + /* ignore external variables */ + else if(!strcmp(variable, "status_file")) + continue; + else if(!strcmp(variable, "perfdata_timeout")) + continue; + else if(strstr(variable, "host_perfdata") == variable) + continue; + else if(strstr(variable, "service_perfdata") == variable) + continue; + else if(strstr(input, "cfg_file=") == input || strstr(input, "cfg_dir=") == input) + continue; + else if(strstr(input, "state_retention_file=") == input) + continue; + else if(strstr(input, "object_cache_file=") == input) + continue; + else if(strstr(input, "precached_object_file=") == input) + continue; + else if(!strcmp(variable, "allow_empty_hostgroup_assignment")) { + allow_empty_hostgroup_assignment = (atoi(value) > 0) ? TRUE : FALSE; + } + + /* we don't know what this variable is... */ + else { + asprintf(&error_message, "UNKNOWN VARIABLE"); + error = TRUE; + break; + } + + } + + /* adjust timezone values */ + if(use_timezone != NULL) + set_environment_var("TZ", use_timezone, 1); + tzset(); + + /* adjust command check interval */ + if(command_check_interval_is_seconds == FALSE && command_check_interval != -1) + command_check_interval *= interval_length; + + /* adjust tweaks */ + if(free_child_process_memory == -1) + free_child_process_memory = (use_large_installation_tweaks == TRUE) ? FALSE : TRUE; + if(child_processes_fork_twice == -1) + child_processes_fork_twice = (use_large_installation_tweaks == TRUE) ? FALSE : TRUE; + + + /* handle errors */ + if(error == TRUE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error in configuration file '%s' - Line %d (%s)", main_config_file, current_line, (error_message == NULL) ? "NULL" : error_message); + return ERROR; + } + + /* free leftover memory and close the file */ + my_free(input); + mmap_fclose(thefile); + + /* free memory */ + my_free(error_message); + my_free(input); + my_free(variable); + my_free(value); + + /* make sure a log file has been specified */ + strip(log_file); + if(!strcmp(log_file, "")) { + if(daemon_mode == FALSE) + printf("Error: Log file is not specified anywhere in main config file '%s'!\n", main_config_file); + return ERROR; + } + + return OK; + } + + + +/* processes macros in resource file */ +int read_resource_file(char *resource_file) { + char *input = NULL; + char *variable = NULL; + char *value = NULL; + char *temp_ptr = NULL; + mmapfile *thefile = NULL; + int current_line = 1; + int error = FALSE; + int user_index = 0; + + if((thefile = mmap_fopen(resource_file)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open resource file '%s' for reading!", resource_file); + return ERROR; + } + + /* process all lines in the resource file */ + while(1) { + + /* free memory */ + my_free(input); + my_free(variable); + my_free(value); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + current_line = thefile->current_line; + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == '\x0' || input[0] == '\n' || input[0] == '\r') + continue; + + strip(input); + + /* get the variable name */ + if((temp_ptr = my_strtok(input, "=")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL variable - Line %d of resource file '%s'", current_line, resource_file); + error = TRUE; + break; + } + if((variable = (char *)strdup(temp_ptr)) == NULL) { + error = TRUE; + break; + } + + /* get the value */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL variable value - Line %d of resource file '%s'", current_line, resource_file); + error = TRUE; + break; + } + if((value = (char *)strdup(temp_ptr)) == NULL) { + error = TRUE; + break; + } + + /* what should we do with the variable/value pair? */ + + /* check for macro declarations */ + if(variable[0] == '$' && variable[strlen(variable) - 1] == '$') { + + /* $USERx$ macro declarations */ + if(strstr(variable, "$USER") == variable && strlen(variable) > 5) { + user_index = atoi(variable + 5) - 1; + if(user_index >= 0 && user_index < MAX_USER_MACROS) { + my_free(macro_user[user_index]); + macro_user[user_index] = (char *)strdup(value); + } + } + } + } + + /* free leftover memory and close the file */ + my_free(input); + mmap_fclose(thefile); + + /* free memory */ + my_free(variable); + my_free(value); + + if(error == TRUE) + return ERROR; + + return OK; + } + + + + + + +/****************************************************************/ +/**************** CONFIG VERIFICATION FUNCTIONS *****************/ +/****************************************************************/ + +/* do a pre-flight check to make sure object relationships, etc. make sense */ +int pre_flight_check(void) { + host *temp_host = NULL; + char *buf = NULL; + service *temp_service = NULL; + command *temp_command = NULL; + char *temp_command_name = ""; + int warnings = 0; + int errors = 0; + struct timeval tv[4]; + double runtime[4]; + int temp_path_fd = -1; + + + if(test_scheduling == TRUE) + gettimeofday(&tv[0], NULL); + + /********************************************/ + /* check object relationships */ + /********************************************/ + pre_flight_object_check(&warnings, &errors); + if(test_scheduling == TRUE) + gettimeofday(&tv[1], NULL); + + + /********************************************/ + /* check for circular paths between hosts */ + /********************************************/ + pre_flight_circular_check(&warnings, &errors); + if(test_scheduling == TRUE) + gettimeofday(&tv[2], NULL); + + + /********************************************/ + /* check global event handler commands... */ + /********************************************/ + if(verify_config == TRUE) + printf("Checking global event handlers...\n"); + if(global_host_event_handler != NULL) { + + /* check the event handler command */ + buf = (char *)strdup(global_host_event_handler); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Global host event handler command '%s' is not defined anywhere!", temp_command_name); + errors++; + } + + /* save the pointer to the command for later */ + global_host_event_handler_ptr = temp_command; + + my_free(buf); + } + if(global_service_event_handler != NULL) { + + /* check the event handler command */ + buf = (char *)strdup(global_service_event_handler); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Global service event handler command '%s' is not defined anywhere!", temp_command_name); + errors++; + } + + /* save the pointer to the command for later */ + global_service_event_handler_ptr = temp_command; + + my_free(buf); + } + + + /**************************************************/ + /* check obsessive processor commands... */ + /**************************************************/ + if(verify_config == TRUE) + printf("Checking obsessive compulsive processor commands...\n"); + if(ocsp_command != NULL) { + + buf = (char *)strdup(ocsp_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Obsessive compulsive service processor command '%s' is not defined anywhere!", temp_command_name); + errors++; + } + + /* save the pointer to the command for later */ + ocsp_command_ptr = temp_command; + + my_free(buf); + } + if(ochp_command != NULL) { + + buf = (char *)strdup(ochp_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Obsessive compulsive host processor command '%s' is not defined anywhere!", temp_command_name); + errors++; + } + + /* save the pointer to the command for later */ + ochp_command_ptr = temp_command; + + my_free(buf); + } + + + /**************************************************/ + /* check various settings... */ + /**************************************************/ + if(verify_config == TRUE) + printf("Checking misc settings...\n"); + + /* check if we can write to temp_path */ + asprintf(&buf, "%s/nagiosXXXXXX", temp_path); + if((temp_path_fd = mkstemp(buf)) == -1) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "\tError: Unable to write to temp_path ('%s') - %s\n", temp_path, strerror(errno)); + errors++; + } + else { + close(temp_path_fd); + remove(buf); + } + my_free(buf); + + /* check if we can write to check_result_path */ + asprintf(&buf, "%s/nagiosXXXXXX", check_result_path); + if((temp_path_fd = mkstemp(buf)) == -1) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "\tError: Unable to write to check_result_path ('%s') - %s\n", check_result_path, strerror(errno)); + errors++; + } + else { + close(temp_path_fd); + remove(buf); + } + my_free(buf); + + /* warn if user didn't specify any illegal macro output chars */ + if(illegal_output_chars == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "%s", "Warning: Nothing specified for illegal_macro_output_chars variable!\n"); + warnings++; + } + + /* count number of services associated with each host (we need this for flap detection)... */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + if((temp_host = find_host(temp_service->host_name))) { + temp_host->total_services++; + temp_host->total_service_check_interval += temp_service->check_interval; + } + } + + if(verify_config == TRUE) { + printf("\n"); + printf("Total Warnings: %d\n", warnings); + printf("Total Errors: %d\n", errors); + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[3], NULL); + + if(test_scheduling == TRUE) { + + if(verify_object_relationships == TRUE) + runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + else + runtime[0] = 0.0; + if(verify_circular_paths == TRUE) + runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0); + else + runtime[1] = 0.0; + runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0); + runtime[3] = runtime[0] + runtime[1] + runtime[2]; + + printf("Timing information on configuration verification is listed below.\n\n"); + + printf("CONFIG VERIFICATION TIMES (* = Potential for speedup with -x option)\n"); + printf("----------------------------------\n"); + printf("Object Relationships: %.6lf sec\n", runtime[0]); + printf("Circular Paths: %.6lf sec *\n", runtime[1]); + printf("Misc: %.6lf sec\n", runtime[2]); + printf(" ============\n"); + printf("TOTAL: %.6lf sec * = %.6lf sec (%.1f%%) estimated savings\n", runtime[3], runtime[1], (runtime[1] / runtime[3]) * 100.0); + printf("\n\n"); + } + + return (errors > 0) ? ERROR : OK; + } + + + +/* do a pre-flight check to make sure object relationships make sense */ +int pre_flight_object_check(int *w, int *e) { + contact *temp_contact = NULL; + commandsmember *temp_commandsmember = NULL; + contactgroup *temp_contactgroup = NULL; + contactsmember *temp_contactsmember = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + host *temp_host = NULL; + host *temp_host2 = NULL; + hostsmember *temp_hostsmember = NULL; + hostgroup *temp_hostgroup = NULL; + servicegroup *temp_servicegroup = NULL; + servicesmember *temp_servicesmember = NULL; + service *temp_service = NULL; + service *temp_service2 = NULL; + command *temp_command = NULL; + timeperiod *temp_timeperiod = NULL; + timeperiod *temp_timeperiod2 = NULL; + timeperiodexclusion *temp_timeperiodexclusion = NULL; + serviceescalation *temp_se = NULL; + hostescalation *temp_he = NULL; + servicedependency *temp_sd = NULL; + hostdependency *temp_hd = NULL; + char *buf = NULL; + char *temp_command_name = ""; + int found = FALSE; + int total_objects = 0; + int warnings = 0; + int errors = 0; + + +#ifdef TEST + void *ptr = NULL; + char *buf1 = ""; + char *buf2 = ""; + buf1 = "temptraxe1"; + buf2 = "Probe 2"; + for(temp_se = get_first_serviceescalation_by_service(buf1, buf2, &ptr); temp_se != NULL; temp_se = get_next_serviceescalation_by_service(buf1, buf2, &ptr)) { + printf("FOUND ESCALATION FOR SVC '%s'/'%s': %d-%d/%.3f, PTR=%p\n", buf1, buf2, temp_se->first_notification, temp_se->last_notification, temp_se->notification_interval, ptr); + } + for(temp_he = get_first_hostescalation_by_host(buf1, &ptr); temp_he != NULL; temp_he = get_next_hostescalation_by_host(buf1, &ptr)) { + printf("FOUND ESCALATION FOR HOST '%s': %d-%d/%d, PTR=%p\n", buf1, temp_he->first_notification, temp_he->last_notification, temp_he->notification_interval, ptr); + } +#endif + + /* bail out if we aren't supposed to verify object relationships */ + if(verify_object_relationships == FALSE) + return OK; + + + /*****************************************/ + /* check each service... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking services...\n"); + if(get_service_count() == 0) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: There are no services defined!"); + errors++; + } + total_objects = 0; + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + total_objects++; + found = FALSE; + + /* check for a valid host */ + temp_host = find_host(temp_service->host_name); + + /* we couldn't find an associated host! */ + if(!temp_host) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host '%s' specified in service '%s' not defined anywhere!", temp_service->host_name, temp_service->description); + errors++; + } + + /* save the host pointer for later */ + temp_service->host_ptr = temp_host; + + /* add a reverse link from the host to the service for faster lookups later */ + add_service_link_to_host(temp_host, temp_service); + + /* check the event handler command */ + if(temp_service->event_handler != NULL) { + + /* check the event handler command */ + buf = (char *)strdup(temp_service->event_handler); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Event handler command '%s' specified in service '%s' for host '%s' not defined anywhere", temp_command_name, temp_service->description, temp_service->host_name); + errors++; + } + + my_free(buf); + + /* save the pointer to the event handler for later */ + temp_service->event_handler_ptr = temp_command; + } + + /* check the service check_command */ + buf = (char *)strdup(temp_service->service_check_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service check command '%s' specified in service '%s' for host '%s' not defined anywhere!", temp_command_name, temp_service->description, temp_service->host_name); + errors++; + } + + my_free(buf); + + /* save the pointer to the check command for later */ + temp_service->check_command_ptr = temp_command; + + /* check for sane recovery options */ + if(temp_service->notify_on_recovery == TRUE && temp_service->notify_on_warning == FALSE && temp_service->notify_on_critical == FALSE) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Recovery notification option in service '%s' for host '%s' doesn't make any sense - specify warning and/or critical options as well", temp_service->description, temp_service->host_name); + warnings++; + } + + /* reset the found flag */ + found = FALSE; + + /* check for valid contacts */ + for(temp_contactsmember = temp_service->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + + temp_contact = find_contact(temp_contactsmember->contact_name); + + if(temp_contact == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in service '%s' for host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_service->description, temp_service->host_name); + errors++; + } + + /* save the contact pointer for later */ + temp_contactsmember->contact_ptr = temp_contact; + } + + /* check all contact groupss */ + for(temp_contactgroupsmember = temp_service->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); + + if(temp_contactgroup == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in service '%s' for host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_service->description, temp_service->host_name); + errors++; + } + + /* save the contact group pointer for later */ + temp_contactgroupsmember->group_ptr = temp_contactgroup; + } + + /* check to see if there is at least one contact/group */ + if(temp_service->contacts == NULL && temp_service->contact_groups == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has no default contacts or contactgroups defined!", temp_service->description, temp_service->host_name); + warnings++; + } + + /* verify service check timeperiod */ + if(temp_service->check_period == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has no check time period defined!", temp_service->description, temp_service->host_name); + warnings++; + } + else { + temp_timeperiod = find_timeperiod(temp_service->check_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Check period '%s' specified for service '%s' on host '%s' is not defined anywhere!", temp_service->check_period, temp_service->description, temp_service->host_name); + errors++; + } + + /* save the pointer to the check timeperiod for later */ + temp_service->check_period_ptr = temp_timeperiod; + } + + /* check service notification timeperiod */ + if(temp_service->notification_period == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has no notification time period defined!", temp_service->description, temp_service->host_name); + warnings++; + } + + else { + temp_timeperiod = find_timeperiod(temp_service->notification_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Notification period '%s' specified for service '%s' on host '%s' is not defined anywhere!", temp_service->notification_period, temp_service->description, temp_service->host_name); + errors++; + } + + /* save the pointer to the notification timeperiod for later */ + temp_service->notification_period_ptr = temp_timeperiod; + } + + /* see if the notification interval is less than the check interval */ + if(temp_service->notification_interval < temp_service->check_interval && temp_service->notification_interval != 0) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has a notification interval less than its check interval! Notifications are only re-sent after checks are made, so the effective notification interval will be that of the check interval.", temp_service->description, temp_service->host_name); + warnings++; + } + + /* check for illegal characters in service description */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_service->description) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The description string for service '%s' on host '%s' contains one or more illegal characters.", temp_service->description, temp_service->host_name); + errors++; + } + } + } + + if(verify_config == TRUE) + printf("\tChecked %d services.\n", total_objects); + + + + /*****************************************/ + /* check all hosts... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking hosts...\n"); + + if(get_host_count() == 0) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: There are no hosts defined!"); + errors++; + } + + total_objects = 0; + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + total_objects++; + found = FALSE; + + /* make sure each host has at least one service associated with it */ + /* 02/21/08 NOTE: this is extremely inefficient */ + if(use_precached_objects == FALSE && use_large_installation_tweaks == FALSE) { + + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + if(!strcmp(temp_service->host_name, temp_host->name)) { + found = TRUE; + break; + } + } + + /* we couldn't find a service associated with this host! */ + if(found == FALSE) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Host '%s' has no services associated with it!", temp_host->name); + warnings++; + } + + found = FALSE; + } + + /* check the event handler command */ + if(temp_host->event_handler != NULL) { + + /* check the event handler command */ + buf = (char *)strdup(temp_host->event_handler); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Event handler command '%s' specified for host '%s' not defined anywhere", temp_command_name, temp_host->name); + errors++; + } + + my_free(buf); + + /* save the pointer to the event handler command for later */ + temp_host->event_handler_ptr = temp_command; + } + + /* hosts that don't have check commands defined shouldn't ever be checked... */ + if(temp_host->host_check_command != NULL) { + + /* check the host check_command */ + buf = (char *)strdup(temp_host->host_check_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host check command '%s' specified for host '%s' is not defined anywhere!", temp_command_name, temp_host->name); + errors++; + } + + /* save the pointer to the check command for later */ + temp_host->check_command_ptr = temp_command; + + my_free(buf); + } + + /* check host check timeperiod */ + if(temp_host->check_period != NULL) { + temp_timeperiod = find_timeperiod(temp_host->check_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Check period '%s' specified for host '%s' is not defined anywhere!", temp_host->check_period, temp_host->name); + errors++; + } + + /* save the pointer to the check timeperiod for later */ + temp_host->check_period_ptr = temp_timeperiod; + } + + /* check all contacts */ + for(temp_contactsmember = temp_host->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + + temp_contact = find_contact(temp_contactsmember->contact_name); + + if(temp_contact == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_host->name); + errors++; + } + + /* save the contact pointer for later */ + temp_contactsmember->contact_ptr = temp_contact; + } + + /* check all contact groups */ + for(temp_contactgroupsmember = temp_host->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); + + if(temp_contactgroup == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_host->name); + errors++; + } + + /* save the contact group pointer for later */ + temp_contactgroupsmember->group_ptr = temp_contactgroup; + } + + /* check to see if there is at least one contact/group */ + if(temp_host->contacts == NULL && temp_host->contact_groups == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Host '%s' has no default contacts or contactgroups defined!", temp_host->name); + warnings++; + } + + /* check notification timeperiod */ + if(temp_host->notification_period != NULL) { + temp_timeperiod = find_timeperiod(temp_host->notification_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Notification period '%s' specified for host '%s' is not defined anywhere!", temp_host->notification_period, temp_host->name); + errors++; + } + + /* save the pointer to the notification timeperiod for later */ + temp_host->notification_period_ptr = temp_timeperiod; + } + + /* check all parent parent host */ + for(temp_hostsmember = temp_host->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if((temp_host2 = find_host(temp_hostsmember->host_name)) == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: '%s' is not a valid parent for host '%s'!", temp_hostsmember->host_name, temp_host->name); + errors++; + } + + /* save the parent host pointer for later */ + temp_hostsmember->host_ptr = temp_host2; + + /* add a reverse (child) link to make searches faster later on */ + add_child_link_to_host(temp_host2, temp_host); + } + + /* check for sane recovery options */ + if(temp_host->notify_on_recovery == TRUE && temp_host->notify_on_down == FALSE && temp_host->notify_on_unreachable == FALSE) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Recovery notification option in host '%s' definition doesn't make any sense - specify down and/or unreachable options as well", temp_host->name); + warnings++; + } + + /* check for illegal characters in host name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_host->name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of host '%s' contains one or more illegal characters.", temp_host->name); + errors++; + } + } + } + + + if(verify_config == TRUE) + printf("\tChecked %d hosts.\n", total_objects); + + + /*****************************************/ + /* check each host group... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking host groups...\n"); + for(temp_hostgroup = hostgroup_list, total_objects = 0; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next, total_objects++) { + + /* check all group members */ + for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + temp_host = find_host(temp_hostsmember->host_name); + if(temp_host == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host '%s' specified in host group '%s' is not defined anywhere!", temp_hostsmember->host_name, temp_hostgroup->group_name); + errors++; + } + + /* save a pointer to this hostgroup for faster host/group membership lookups later */ + else + add_object_to_objectlist(&temp_host->hostgroups_ptr, (void *)temp_hostgroup); + + /* save host pointer for later */ + temp_hostsmember->host_ptr = temp_host; + } + + /* check for illegal characters in hostgroup name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_hostgroup->group_name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of hostgroup '%s' contains one or more illegal characters.", temp_hostgroup->group_name); + errors++; + } + } + } + + if(verify_config == TRUE) + printf("\tChecked %d host groups.\n", total_objects); + + + /*****************************************/ + /* check each service group... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking service groups...\n"); + for(temp_servicegroup = servicegroup_list, total_objects = 0; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next, total_objects++) { + + /* check all group members */ + for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + + temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description); + if(temp_service == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service '%s' on host '%s' specified in service group '%s' is not defined anywhere!", temp_servicesmember->service_description, temp_servicesmember->host_name, temp_servicegroup->group_name); + errors++; + } + + /* save a pointer to this servicegroup for faster service/group membership lookups later */ + else + add_object_to_objectlist(&temp_service->servicegroups_ptr, (void *)temp_servicegroup); + + /* save service pointer for later */ + temp_servicesmember->service_ptr = temp_service; + } + + /* check for illegal characters in servicegroup name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_servicegroup->group_name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of servicegroup '%s' contains one or more illegal characters.", temp_servicegroup->group_name); + errors++; + } + } + } + + if(verify_config == TRUE) + printf("\tChecked %d service groups.\n", total_objects); + + + + /*****************************************/ + /* check all contacts... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking contacts...\n"); + if(contact_list == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: There are no contacts defined!"); + errors++; + } + for(temp_contact = contact_list, total_objects = 0; temp_contact != NULL; temp_contact = temp_contact->next, total_objects++) { + + /* check service notification commands */ + if(temp_contact->service_notification_commands == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' has no service notification commands defined!", temp_contact->name); + errors++; + } + else for(temp_commandsmember = temp_contact->service_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) { + + /* check the host notification command */ + buf = (char *)strdup(temp_commandsmember->command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service notification command '%s' specified for contact '%s' is not defined anywhere!", temp_command_name, temp_contact->name); + errors++; + } + + /* save pointer to the command for later */ + temp_commandsmember->command_ptr = temp_command; + + my_free(buf); + } + + /* check host notification commands */ + if(temp_contact->host_notification_commands == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' has no host notification commands defined!", temp_contact->name); + errors++; + } + else for(temp_commandsmember = temp_contact->host_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) { + + /* check the host notification command */ + buf = (char *)strdup(temp_commandsmember->command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(buf, "!"); + + temp_command = find_command(temp_command_name); + if(temp_command == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host notification command '%s' specified for contact '%s' is not defined anywhere!", temp_command_name, temp_contact->name); + errors++; + } + + /* save pointer to the command for later */ + temp_commandsmember->command_ptr = temp_command; + + my_free(buf); + } + + /* check service notification timeperiod */ + if(temp_contact->service_notification_period == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Contact '%s' has no service notification time period defined!", temp_contact->name); + warnings++; + } + + else { + temp_timeperiod = find_timeperiod(temp_contact->service_notification_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service notification period '%s' specified for contact '%s' is not defined anywhere!", temp_contact->service_notification_period, temp_contact->name); + errors++; + } + + /* save the pointer to the service notification timeperiod for later */ + temp_contact->service_notification_period_ptr = temp_timeperiod; + } + + /* check host notification timeperiod */ + if(temp_contact->host_notification_period == NULL) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Contact '%s' has no host notification time period defined!", temp_contact->name); + warnings++; + } + + else { + temp_timeperiod = find_timeperiod(temp_contact->host_notification_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host notification period '%s' specified for contact '%s' is not defined anywhere!", temp_contact->host_notification_period, temp_contact->name); + errors++; + } + + /* save the pointer to the host notification timeperiod for later */ + temp_contact->host_notification_period_ptr = temp_timeperiod; + } + + /* check for sane host recovery options */ + if(temp_contact->notify_on_host_recovery == TRUE && temp_contact->notify_on_host_down == FALSE && temp_contact->notify_on_host_unreachable == FALSE) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Host recovery notification option for contact '%s' doesn't make any sense - specify down and/or unreachable options as well", temp_contact->name); + warnings++; + } + + /* check for sane service recovery options */ + if(temp_contact->notify_on_service_recovery == TRUE && temp_contact->notify_on_service_critical == FALSE && temp_contact->notify_on_service_warning == FALSE) { + logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service recovery notification option for contact '%s' doesn't make any sense - specify critical and/or warning options as well", temp_contact->name); + warnings++; + } + + /* check for illegal characters in contact name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_contact->name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of contact '%s' contains one or more illegal characters.", temp_contact->name); + errors++; + } + } + } + + if(verify_config == TRUE) + printf("\tChecked %d contacts.\n", total_objects); + + + + /*****************************************/ + /* check each contact group... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking contact groups...\n"); + for(temp_contactgroup = contactgroup_list, total_objects = 0; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next, total_objects++) { + + found = FALSE; + + /* check all the group members */ + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + + temp_contact = find_contact(temp_contactsmember->contact_name); + if(temp_contact == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in contact group '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_contactgroup->group_name); + errors++; + } + + /* save a pointer to this contactgroup for faster contact/group membership lookups later */ + else + add_object_to_objectlist(&temp_contact->contactgroups_ptr, (void *)temp_contactgroup); + + /* save the contact pointer for later */ + temp_contactsmember->contact_ptr = temp_contact; + } + + /* check for illegal characters in contactgroup name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_contactgroup->group_name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of contact group '%s' contains one or more illegal characters.", temp_contactgroup->group_name); + errors++; + } + } + } + + if(verify_config == TRUE) + printf("\tChecked %d contact groups.\n", total_objects); + + + + /*****************************************/ + /* check all service escalations... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking service escalations...\n"); + + for(temp_se = serviceescalation_list, total_objects = 0; temp_se != NULL; temp_se = temp_se->next, total_objects++) { + + /* find the service */ + temp_service = find_service(temp_se->host_name, temp_se->description); + if(temp_service == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service '%s' on host '%s' specified in service escalation is not defined anywhere!", temp_se->description, temp_se->host_name); + errors++; + } + + /* save the service pointer for later */ + temp_se->service_ptr = temp_service; + + /* find the timeperiod */ + if(temp_se->escalation_period != NULL) { + temp_timeperiod = find_timeperiod(temp_se->escalation_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Escalation period '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!", temp_se->escalation_period, temp_se->description, temp_se->host_name); + errors++; + } + + /* save the timeperiod pointer for later */ + temp_se->escalation_period_ptr = temp_timeperiod; + } + + /* find the contacts */ + for(temp_contactsmember = temp_se->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + + /* find the contact */ + temp_contact = find_contact(temp_contactsmember->contact_name); + if(temp_contact == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_se->description, temp_se->host_name); + errors++; + } + + /* save the contact pointer for later */ + temp_contactsmember->contact_ptr = temp_contact; + } + + /* check all contact groups */ + for(temp_contactgroupsmember = temp_se->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); + + if(temp_contactgroup == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_se->description, temp_se->host_name); + errors++; + } + + /* save the contact group pointer for later */ + temp_contactgroupsmember->group_ptr = temp_contactgroup; + } + } + + if(verify_config == TRUE) + printf("\tChecked %d service escalations.\n", total_objects); + + + + /*****************************************/ + /* check all service dependencies... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking service dependencies...\n"); + + for(temp_sd = servicedependency_list, total_objects = 0; temp_sd != NULL; temp_sd = temp_sd->next, total_objects++) { + + /* find the dependent service */ + temp_service = find_service(temp_sd->dependent_host_name, temp_sd->dependent_service_description); + if(temp_service == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependent service '%s' on host '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!", temp_sd->dependent_service_description, temp_sd->dependent_host_name, temp_sd->service_description, temp_sd->host_name); + errors++; + } + + /* save pointer for later */ + temp_sd->dependent_service_ptr = temp_service; + + /* find the service we're depending on */ + temp_service2 = find_service(temp_sd->host_name, temp_sd->service_description); + if(temp_service2 == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service '%s' on host '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!", temp_sd->service_description, temp_sd->host_name, temp_sd->dependent_service_description, temp_sd->dependent_host_name); + errors++; + } + + /* save pointer for later */ + temp_sd->master_service_ptr = temp_service2; + + /* make sure they're not the same service */ + if(temp_service == temp_service2) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service dependency definition for service '%s' on host '%s' is circular (it depends on itself)!", temp_sd->dependent_service_description, temp_sd->dependent_host_name); + errors++; + } + + /* find the timeperiod */ + if(temp_sd->dependency_period != NULL) { + temp_timeperiod = find_timeperiod(temp_sd->dependency_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependency period '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!", temp_sd->dependency_period, temp_sd->dependent_service_description, temp_sd->dependent_host_name); + errors++; + } + + /* save the timeperiod pointer for later */ + temp_sd->dependency_period_ptr = temp_timeperiod; + } + } + + if(verify_config == TRUE) + printf("\tChecked %d service dependencies.\n", total_objects); + + + + /*****************************************/ + /* check all host escalations... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking host escalations...\n"); + + for(temp_he = hostescalation_list, total_objects = 0; temp_he != NULL; temp_he = temp_he->next, total_objects++) { + + /* find the host */ + temp_host = find_host(temp_he->host_name); + if(temp_host == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host '%s' specified in host escalation is not defined anywhere!", temp_he->host_name); + errors++; + } + + /* save the host pointer for later */ + temp_he->host_ptr = temp_host; + + /* find the timeperiod */ + if(temp_he->escalation_period != NULL) { + temp_timeperiod = find_timeperiod(temp_he->escalation_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Escalation period '%s' specified in host escalation for host '%s' is not defined anywhere!", temp_he->escalation_period, temp_he->host_name); + errors++; + } + + /* save the timeperiod pointer for later */ + temp_he->escalation_period_ptr = temp_timeperiod; + } + + /* find the contacts */ + for(temp_contactsmember = temp_he->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + + /* find the contact*/ + temp_contact = find_contact(temp_contactsmember->contact_name); + if(temp_contact == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in host escalation for host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_he->host_name); + errors++; + } + + /* save the contact pointer for later */ + temp_contactsmember->contact_ptr = temp_contact; + } + + /* check all contact groups */ + for(temp_contactgroupsmember = temp_he->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); + + if(temp_contactgroup == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in host escalation for host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_he->host_name); + errors++; + } + + /* save the contact group pointer for later */ + temp_contactgroupsmember->group_ptr = temp_contactgroup; + } + } + + if(verify_config == TRUE) + printf("\tChecked %d host escalations.\n", total_objects); + + + + /*****************************************/ + /* check all host dependencies... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking host dependencies...\n"); + + for(temp_hd = hostdependency_list, total_objects = 0; temp_hd != NULL; temp_hd = temp_hd->next, total_objects++) { + + /* find the dependent host */ + temp_host = find_host(temp_hd->dependent_host_name); + if(temp_host == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependent host specified in host dependency for host '%s' is not defined anywhere!", temp_hd->dependent_host_name); + errors++; + } + + /* save pointer for later */ + temp_hd->dependent_host_ptr = temp_host; + + /* find the host we're depending on */ + temp_host2 = find_host(temp_hd->host_name); + if(temp_host2 == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host specified in host dependency for host '%s' is not defined anywhere!", temp_hd->dependent_host_name); + errors++; + } + + /* save pointer for later */ + temp_hd->master_host_ptr = temp_host2; + + /* make sure they're not the same host */ + if(temp_host == temp_host2) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host dependency definition for host '%s' is circular (it depends on itself)!", temp_hd->dependent_host_name); + errors++; + } + + /* find the timeperiod */ + if(temp_hd->dependency_period != NULL) { + temp_timeperiod = find_timeperiod(temp_hd->dependency_period); + if(temp_timeperiod == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependency period '%s' specified in host dependency for host '%s' is not defined anywhere!", temp_hd->dependency_period, temp_hd->dependent_host_name); + errors++; + } + + /* save the timeperiod pointer for later */ + temp_hd->dependency_period_ptr = temp_timeperiod; + } + } + + if(verify_config == TRUE) + printf("\tChecked %d host dependencies.\n", total_objects); + + + + /*****************************************/ + /* check all commands... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking commands...\n"); + + for(temp_command = command_list, total_objects = 0; temp_command != NULL; temp_command = temp_command->next, total_objects++) { + + /* check for illegal characters in command name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_command->name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of command '%s' contains one or more illegal characters.", temp_command->name); + errors++; + } + } + } + + if(verify_config == TRUE) + printf("\tChecked %d commands.\n", total_objects); + + + + /*****************************************/ + /* check all timeperiods... */ + /*****************************************/ + if(verify_config == TRUE) + printf("Checking time periods...\n"); + + for(temp_timeperiod = timeperiod_list, total_objects = 0; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next, total_objects++) { + + /* check for illegal characters in timeperiod name */ + if(use_precached_objects == FALSE) { + if(contains_illegal_object_chars(temp_timeperiod->name) == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of time period '%s' contains one or more illegal characters.", temp_timeperiod->name); + errors++; + } + } + + /* check for valid timeperiod names in exclusion list */ + for(temp_timeperiodexclusion = temp_timeperiod->exclusions; temp_timeperiodexclusion != NULL; temp_timeperiodexclusion = temp_timeperiodexclusion->next) { + + temp_timeperiod2 = find_timeperiod(temp_timeperiodexclusion->timeperiod_name); + if(temp_timeperiod2 == NULL) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Excluded time period '%s' specified in timeperiod '%s' is not defined anywhere!", temp_timeperiodexclusion->timeperiod_name, temp_timeperiod->name); + errors++; + } + + /* save the timeperiod pointer for later */ + temp_timeperiodexclusion->timeperiod_ptr = temp_timeperiod2; + } + } + + if(verify_config == TRUE) + printf("\tChecked %d time periods.\n", total_objects); + + + + /* update warning and error count */ + *w += warnings; + *e += errors; + + return (errors > 0) ? ERROR : OK; + } + + +/* dfs status values */ +#define DFS_UNCHECKED 0 /* default value */ +#define DFS_TEMP_CHECKED 1 /* check just one time */ +#define DFS_OK 2 /* no problem */ +#define DFS_NEAR_LOOP 3 /* has trouble sons */ +#define DFS_LOOPY 4 /* is a part of a loop */ + +#define dfs_get_status(h) h->circular_path_checked +#define dfs_unset_status(h) h->circular_path_checked = 0 +#define dfs_set_status(h, flag) h->circular_path_checked = (flag) +#define dfs_host_status(h) (h ? dfs_get_status(h) : DFS_OK) + +/** + * Modified version of Depth-first Search + * http://en.wikipedia.org/wiki/Depth-first_search + */ +static int dfs_host_path(host *root) { + hostsmember *child = NULL; + + if(!root) + return DFS_NEAR_LOOP; + + if(dfs_get_status(root) != DFS_UNCHECKED) + return dfs_get_status(root); + + /* Mark the root temporary checked */ + dfs_set_status(root, DFS_TEMP_CHECKED); + + /* We are scanning the children */ + for(child = root->child_hosts; child != NULL; child = child->next) { + int child_status = dfs_get_status(child->host_ptr); + + /* If a child is not checked, check it */ + if(child_status == DFS_UNCHECKED) + child_status = dfs_host_path(child->host_ptr); + + /* If a child already temporary checked, its a problem, + * loop inside, and its a acked status */ + if(child_status == DFS_TEMP_CHECKED) { + dfs_set_status(child->host_ptr, DFS_LOOPY); + dfs_set_status(root, DFS_LOOPY); + } + + /* If a child already temporary checked, its a problem, loop inside */ + if(child_status == DFS_NEAR_LOOP || child_status == DFS_LOOPY) { + /* if a node is know to be part of a loop, do not let it be less */ + if(dfs_get_status(root) != DFS_LOOPY) + dfs_set_status(root, DFS_NEAR_LOOP); + + /* we already saw this child, it's a problem */ + dfs_set_status(child->host_ptr, DFS_LOOPY); + } + } + + /* + * If root have been modified, do not set it OK + * A node is OK if and only if all of his children are OK + * If it does not have child, goes ok + */ + if(dfs_get_status(root) == DFS_TEMP_CHECKED) + dfs_set_status(root, DFS_OK); + return dfs_get_status(root); + } + + +/* check for circular paths and dependencies */ +int pre_flight_circular_check(int *w, int *e) { + host *temp_host = NULL; + servicedependency *temp_sd = NULL; + servicedependency *temp_sd2 = NULL; + hostdependency *temp_hd = NULL; + hostdependency *temp_hd2 = NULL; + int found = FALSE; + int result = OK; + int warnings = 0; + int errors = 0; + + + /* bail out if we aren't supposed to verify circular paths */ + if(verify_circular_paths == FALSE) + return OK; + + + /********************************************/ + /* check for circular paths between hosts */ + /********************************************/ + if(verify_config == TRUE) + printf("Checking for circular paths between hosts...\n"); + + /* check routes between all hosts */ + found = FALSE; + result = OK; + + + /* We clean the dsf status from previous check */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + dfs_set_status(temp_host, DFS_UNCHECKED); + } + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(dfs_host_path(temp_host) == DFS_LOOPY) + errors = 1; + } + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(dfs_get_status(temp_host) == DFS_LOOPY) + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The host '%s' is part of a circular parent/child chain!", temp_host->name); + /* clean DFS status */ + dfs_set_status(temp_host, DFS_UNCHECKED); + } + + + /********************************************/ + /* check for circular dependencies */ + /********************************************/ + if(verify_config == TRUE) + printf("Checking for circular host and service dependencies...\n"); + + /* check execution dependencies between all services */ + for(temp_sd = servicedependency_list; temp_sd != NULL; temp_sd = temp_sd->next) { + + /* clear checked flag for all dependencies */ + for(temp_sd2 = servicedependency_list; temp_sd2 != NULL; temp_sd2 = temp_sd2->next) + temp_sd2->circular_path_checked = FALSE; + + found = check_for_circular_servicedependency_path(temp_sd, temp_sd, EXECUTION_DEPENDENCY); + if(found == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular execution dependency (which could result in a deadlock) exists for service '%s' on host '%s'!", temp_sd->service_description, temp_sd->host_name); + errors++; + } + } + + /* check notification dependencies between all services */ + for(temp_sd = servicedependency_list; temp_sd != NULL; temp_sd = temp_sd->next) { + + /* clear checked flag for all dependencies */ + for(temp_sd2 = servicedependency_list; temp_sd2 != NULL; temp_sd2 = temp_sd2->next) + temp_sd2->circular_path_checked = FALSE; + + found = check_for_circular_servicedependency_path(temp_sd, temp_sd, NOTIFICATION_DEPENDENCY); + if(found == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular notification dependency (which could result in a deadlock) exists for service '%s' on host '%s'!", temp_sd->service_description, temp_sd->host_name); + errors++; + } + } + + /* check execution dependencies between all hosts */ + for(temp_hd = hostdependency_list; temp_hd != NULL; temp_hd = temp_hd->next) { + + /* clear checked flag for all dependencies */ + for(temp_hd2 = hostdependency_list; temp_hd2 != NULL; temp_hd2 = temp_hd2->next) + temp_hd2->circular_path_checked = FALSE; + + found = check_for_circular_hostdependency_path(temp_hd, temp_hd, EXECUTION_DEPENDENCY); + if(found == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular execution dependency (which could result in a deadlock) exists for host '%s'!", temp_hd->host_name); + errors++; + } + } + + /* check notification dependencies between all hosts */ + for(temp_hd = hostdependency_list; temp_hd != NULL; temp_hd = temp_hd->next) { + + /* clear checked flag for all dependencies */ + for(temp_hd2 = hostdependency_list; temp_hd2 != NULL; temp_hd2 = temp_hd2->next) + temp_hd2->circular_path_checked = FALSE; + + found = check_for_circular_hostdependency_path(temp_hd, temp_hd, NOTIFICATION_DEPENDENCY); + if(found == TRUE) { + logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular notification dependency (which could result in a deadlock) exists for host '%s'!", temp_hd->host_name); + errors++; + } + } + + + /* update warning and error count */ + *w += warnings; + *e += errors; + + return (errors > 0) ? ERROR : OK; + } + diff --git a/base/events.c b/base/events.c new file mode 100644 index 0000000..9062621 --- /dev/null +++ b/base/events.c @@ -0,0 +1,1847 @@ +/***************************************************************************** + * + * EVENTS.C - Timed event 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/downtime.h" +#include "../include/comments.h" +#include "../include/statusdata.h" +#include "../include/nagios.h" +#include "../include/broker.h" +#include "../include/sretention.h" + + +extern char *config_file; + +extern int test_scheduling; + +extern time_t program_start; +extern time_t event_start; +extern time_t last_command_check; + +extern int sigshutdown; +extern int sigrestart; + +extern double sleep_time; +extern int interval_length; +extern int service_inter_check_delay_method; +extern int host_inter_check_delay_method; +extern int service_interleave_factor_method; +extern int max_host_check_spread; +extern int max_service_check_spread; + +extern int command_check_interval; +extern int check_reaper_interval; +extern int service_freshness_check_interval; +extern int host_freshness_check_interval; +extern int auto_rescheduling_interval; +extern int auto_rescheduling_window; + +extern int check_external_commands; +extern int check_orphaned_services; +extern int check_orphaned_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int auto_reschedule_checks; + +extern int retain_state_information; +extern int retention_update_interval; + +extern int max_parallel_service_checks; +extern int currently_running_service_checks; + +extern int aggregate_status_updates; +extern int status_update_interval; + +extern int log_rotation_method; + +extern int service_check_timeout; + +extern int execute_service_checks; +extern int execute_host_checks; + +extern int child_processes_fork_twice; + +extern int time_change_threshold; + +timed_event *event_list_low = NULL; +timed_event *event_list_low_tail = NULL; +timed_event *event_list_high = NULL; +timed_event *event_list_high_tail = NULL; + +extern host *host_list; +extern service *service_list; + +sched_info scheduling_info; + + + +/******************************************************************/ +/************ EVENT SCHEDULING/HANDLING FUNCTIONS *****************/ +/******************************************************************/ + + +/* initialize the event timing loop before we start monitoring */ +void init_timing_loop(void) { + host *temp_host = NULL; + service *temp_service = NULL; + time_t current_time = 0L; + unsigned long interval_to_use = 0L; + int total_interleave_blocks = 0; + int current_interleave_block = 1; + int interleave_block_index = 0; + int mult_factor = 0; + int is_valid_time = 0; + time_t next_valid_time = 0L; + int schedule_check = 0; + double max_inter_check_delay = 0.0; + struct timeval tv[9]; + double runtime[9]; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() start\n"); + + /* get the time right now */ + time(¤t_time); + + + /******** GET BASIC HOST/SERVICE INFO ********/ + + scheduling_info.total_services = 0; + scheduling_info.total_scheduled_services = 0; + scheduling_info.total_hosts = 0; + scheduling_info.total_scheduled_hosts = 0; + scheduling_info.average_services_per_host = 0.0; + scheduling_info.average_scheduled_services_per_host = 0.0; + scheduling_info.average_service_execution_time = 0.0; + scheduling_info.service_check_interval_total = 0; + scheduling_info.average_service_inter_check_delay = 0.0; + scheduling_info.host_check_interval_total = 0; + scheduling_info.average_host_inter_check_delay = 0.0; + + if(test_scheduling == TRUE) + gettimeofday(&tv[0], NULL); + + /* get info on service checks to be scheduled */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + schedule_check = TRUE; + + /* service has no check interval */ + if(temp_service->check_interval == 0) + schedule_check = FALSE; + + /* active checks are disabled */ + if(temp_service->checks_enabled == FALSE) + schedule_check = FALSE; + + /* are there any valid times this service can be checked? */ + is_valid_time = check_time_against_period(current_time, temp_service->check_period_ptr); + if(is_valid_time == ERROR) { + get_next_valid_time(current_time, &next_valid_time, temp_service->check_period_ptr); + if(current_time == next_valid_time) + schedule_check = FALSE; + } + + if(schedule_check == TRUE) { + + scheduling_info.total_scheduled_services++; + + /* used later in inter-check delay calculations */ + scheduling_info.service_check_interval_total += temp_service->check_interval; + + /* calculate rolling average execution time (available from retained state information) */ + scheduling_info.average_service_execution_time = (double)(((scheduling_info.average_service_execution_time * (scheduling_info.total_scheduled_services - 1)) + temp_service->execution_time) / (double)scheduling_info.total_scheduled_services); + } + else { + temp_service->should_be_scheduled = FALSE; + + log_debug_info(DEBUGL_EVENTS, 1, "Service '%s' on host '%s' should not be scheduled.\n", temp_service->description, temp_service->host_name); + } + + scheduling_info.total_services++; + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[1], NULL); + + /* get info on host checks to be scheduled */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + schedule_check = TRUE; + + /* host has no check interval */ + if(temp_host->check_interval == 0) + schedule_check = FALSE; + + /* active checks are disabled */ + if(temp_host->checks_enabled == FALSE) + schedule_check = FALSE; + + /* are there any valid times this host can be checked? */ + is_valid_time = check_time_against_period(current_time, temp_host->check_period_ptr); + if(is_valid_time == ERROR) { + get_next_valid_time(current_time, &next_valid_time, temp_host->check_period_ptr); + if(current_time == next_valid_time) + schedule_check = FALSE; + } + + if(schedule_check == TRUE) { + + scheduling_info.total_scheduled_hosts++; + + /* this is used later in inter-check delay calculations */ + scheduling_info.host_check_interval_total += temp_host->check_interval; + } + else { + temp_host->should_be_scheduled = FALSE; + + log_debug_info(DEBUGL_EVENTS, 1, "Host '%s' should not be scheduled.\n", temp_host->name); + } + + scheduling_info.total_hosts++; + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[2], NULL); + + scheduling_info.average_services_per_host = (double)((double)scheduling_info.total_services / (double)scheduling_info.total_hosts); + scheduling_info.average_scheduled_services_per_host = (double)((double)scheduling_info.total_scheduled_services / (double)scheduling_info.total_hosts); + + /* adjust the check interval total to correspond to the interval length */ + scheduling_info.service_check_interval_total = (scheduling_info.service_check_interval_total * interval_length); + + /* calculate the average check interval for services */ + scheduling_info.average_service_check_interval = (double)((double)scheduling_info.service_check_interval_total / (double)scheduling_info.total_scheduled_services); + + + /******** DETERMINE SERVICE SCHEDULING PARAMS ********/ + + log_debug_info(DEBUGL_EVENTS, 2, "Determining service scheduling parameters..."); + + /* default max service check spread (in minutes) */ + scheduling_info.max_service_check_spread = max_service_check_spread; + + /* how should we determine the service inter-check delay to use? */ + switch(service_inter_check_delay_method) { + + case ICD_NONE: + + /* don't spread checks out - useful for testing parallelization code */ + scheduling_info.service_inter_check_delay = 0.0; + break; + + case ICD_DUMB: + + /* be dumb and just schedule checks 1 second apart */ + scheduling_info.service_inter_check_delay = 1.0; + break; + + case ICD_USER: + + /* the user specified a delay, so don't try to calculate one */ + break; + + case ICD_SMART: + default: + + /* be smart and calculate the best delay to use to minimize local load... */ + if(scheduling_info.total_scheduled_services > 0 && scheduling_info.service_check_interval_total > 0) { + + /* calculate the average inter check delay (in seconds) needed to evenly space the service checks out */ + scheduling_info.average_service_inter_check_delay = (double)(scheduling_info.average_service_check_interval / (double)scheduling_info.total_scheduled_services); + + /* set the global inter check delay value */ + scheduling_info.service_inter_check_delay = scheduling_info.average_service_inter_check_delay; + + /* calculate max inter check delay and see if we should use that instead */ + max_inter_check_delay = (double)((scheduling_info.max_service_check_spread * 60.0) / (double)scheduling_info.total_scheduled_services); + if(scheduling_info.service_inter_check_delay > max_inter_check_delay) + scheduling_info.service_inter_check_delay = max_inter_check_delay; + } + else + scheduling_info.service_inter_check_delay = 0.0; + + log_debug_info(DEBUGL_EVENTS, 1, "Total scheduled service checks: %d\n", scheduling_info.total_scheduled_services); + log_debug_info(DEBUGL_EVENTS, 1, "Average service check interval: %0.2f sec\n", scheduling_info.average_service_check_interval); + log_debug_info(DEBUGL_EVENTS, 1, "Service inter-check delay: %0.2f sec\n", scheduling_info.service_inter_check_delay); + } + + /* how should we determine the service interleave factor? */ + switch(service_interleave_factor_method) { + + case ILF_USER: + + /* the user supplied a value, so don't do any calculation */ + break; + + case ILF_SMART: + default: + + /* protect against a divide by zero problem - shouldn't happen, but just in case... */ + if(scheduling_info.total_hosts == 0) + scheduling_info.total_hosts = 1; + + scheduling_info.service_interleave_factor = (int)(ceil(scheduling_info.average_scheduled_services_per_host)); + + log_debug_info(DEBUGL_EVENTS, 1, "Total scheduled service checks: %d\n", scheduling_info.total_scheduled_services); + log_debug_info(DEBUGL_EVENTS, 1, "Total hosts: %d\n", scheduling_info.total_hosts); + log_debug_info(DEBUGL_EVENTS, 1, "Service Interleave factor: %d\n", scheduling_info.service_interleave_factor); + } + + /* calculate number of service interleave blocks */ + if(scheduling_info.service_interleave_factor == 0) + total_interleave_blocks = scheduling_info.total_scheduled_services; + else + total_interleave_blocks = (int)ceil((double)scheduling_info.total_scheduled_services / (double)scheduling_info.service_interleave_factor); + + scheduling_info.first_service_check = (time_t)0L; + scheduling_info.last_service_check = (time_t)0L; + + log_debug_info(DEBUGL_EVENTS, 1, "Total scheduled services: %d\n", scheduling_info.total_scheduled_services); + log_debug_info(DEBUGL_EVENTS, 1, "Service Interleave factor: %d\n", scheduling_info.service_interleave_factor); + log_debug_info(DEBUGL_EVENTS, 1, "Total service interleave blocks: %d\n", total_interleave_blocks); + log_debug_info(DEBUGL_EVENTS, 1, "Service inter-check delay: %2.1f\n", scheduling_info.service_inter_check_delay); + + + if(test_scheduling == TRUE) + gettimeofday(&tv[3], NULL); + + /******** SCHEDULE SERVICE CHECKS ********/ + + log_debug_info(DEBUGL_EVENTS, 2, "Scheduling service checks..."); + + /* determine check times for service checks (with interleaving to minimize remote load) */ + current_interleave_block = 0; + for(temp_service = service_list; temp_service != NULL && scheduling_info.service_interleave_factor > 0;) { + + log_debug_info(DEBUGL_EVENTS, 2, "Current Interleave Block: %d\n", current_interleave_block); + + for(interleave_block_index = 0; interleave_block_index < scheduling_info.service_interleave_factor && temp_service != NULL; temp_service = temp_service->next) { + int check_delay = 0; + + log_debug_info(DEBUGL_EVENTS, 2, "Service '%s' on host '%s'\n", temp_service->description, temp_service->host_name); + /* skip this service if it shouldn't be scheduled */ + if(temp_service->should_be_scheduled == FALSE) { + log_debug_info(DEBUGL_EVENTS, 2, "Service check should not be scheduled.\n"); + continue; + } + + /* skip services whose checks are currently executing */ + if(temp_service->is_executing) { + log_debug_info(DEBUGL_EVENTS, 2, + "Service check '%s' on host '%s' is already executing.\n", + temp_service->description, temp_service->host_name); + continue; + } + + /* + * skip services that are already scheduled for the (near) + * future from retention data, but reschedule ones that + * were supposed to happen while we weren't running... + * We check to make sure the check isn't scheduled to run + * far in the future to make sure checks who've hade their + * timeperiods changed during the restart aren't left + * hanging too long without being run. + */ + check_delay = temp_service->next_check - current_time; + if(check_delay > 0 && check_delay < (temp_service->check_interval * interval_length)) { + log_debug_info(DEBUGL_EVENTS, 2, "Service is already scheduled to be checked in the future: %s\n", ctime(&temp_service->next_check)); + continue; + } + + /* interleave block index should only be increased when we find a schedulable service */ + /* moved from for() loop 11/05/05 EG */ + interleave_block_index++; + + mult_factor = current_interleave_block + (interleave_block_index * total_interleave_blocks); + + log_debug_info(DEBUGL_EVENTS, 2, "CIB: %d, IBI: %d, TIB: %d, SIF: %d\n", current_interleave_block, interleave_block_index, total_interleave_blocks, scheduling_info.service_interleave_factor); + log_debug_info(DEBUGL_EVENTS, 2, "Mult factor: %d\n", mult_factor); + + /* set the preferred next check time for the service */ + temp_service->next_check = (time_t)(current_time + (mult_factor * scheduling_info.service_inter_check_delay)); + + log_debug_info(DEBUGL_EVENTS, 2, "Preferred Check Time: %lu --> %s", (unsigned long)temp_service->next_check, ctime(&temp_service->next_check)); + + + /* make sure the service can actually be scheduled when we want */ + is_valid_time = check_time_against_period(temp_service->next_check, temp_service->check_period_ptr); + if(is_valid_time == ERROR) { + log_debug_info(DEBUGL_EVENTS, 2, "Preferred Time is Invalid In Timeperiod '%s': %lu --> %s", temp_service->check_period_ptr->name, (unsigned long)temp_service->next_check, ctime(&temp_service->next_check)); + get_next_valid_time(temp_service->next_check, &next_valid_time, temp_service->check_period_ptr); + temp_service->next_check = next_valid_time; + } + + log_debug_info(DEBUGL_EVENTS, 2, "Actual Check Time: %lu --> %s", (unsigned long)temp_service->next_check, ctime(&temp_service->next_check)); + + if(scheduling_info.first_service_check == (time_t)0 || (temp_service->next_check < scheduling_info.first_service_check)) + scheduling_info.first_service_check = temp_service->next_check; + if(temp_service->next_check > scheduling_info.last_service_check) + scheduling_info.last_service_check = temp_service->next_check; + } + + current_interleave_block++; + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[4], NULL); + + /* add scheduled service checks to event queue */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* Nagios XI/NDOUtils MOD */ + /* update status of all services (scheduled or not) */ + update_service_status(temp_service, FALSE); + + /* skip services whose checks are currently executing */ + if(temp_service->is_executing) + continue; + + /* skip most services that shouldn't be scheduled */ + if(temp_service->should_be_scheduled == FALSE) { + + /* passive checks are an exception if a forced check was scheduled before Nagios was restarted */ + if(!(temp_service->checks_enabled == FALSE && temp_service->next_check != (time_t)0L && (temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION))) + continue; + } + + /* create a new service check event */ + log_debug_info(DEBUGL_EVENTS, 2, + "Scheduling check for service '%s' on host '%s'.\n", + temp_service->description, temp_service->host_name); + schedule_new_event(EVENT_SERVICE_CHECK, FALSE, temp_service->next_check, FALSE, 0, NULL, TRUE, (void *)temp_service, NULL, temp_service->check_options); + } + + + if(test_scheduling == TRUE) + gettimeofday(&tv[5], NULL); + + /******** DETERMINE HOST SCHEDULING PARAMS ********/ + + log_debug_info(DEBUGL_EVENTS, 2, "Determining host scheduling parameters..."); + + scheduling_info.first_host_check = (time_t)0L; + scheduling_info.last_host_check = (time_t)0L; + + /* default max host check spread (in minutes) */ + scheduling_info.max_host_check_spread = max_host_check_spread; + + /* how should we determine the host inter-check delay to use? */ + switch(host_inter_check_delay_method) { + + case ICD_NONE: + + /* don't spread checks out */ + scheduling_info.host_inter_check_delay = 0.0; + break; + + case ICD_DUMB: + + /* be dumb and just schedule checks 1 second apart */ + scheduling_info.host_inter_check_delay = 1.0; + break; + + case ICD_USER: + + /* the user specified a delay, so don't try to calculate one */ + break; + + case ICD_SMART: + default: + + /* be smart and calculate the best delay to use to minimize local load... */ + if(scheduling_info.total_scheduled_hosts > 0 && scheduling_info.host_check_interval_total > 0) { + + /* adjust the check interval total to correspond to the interval length */ + scheduling_info.host_check_interval_total = (scheduling_info.host_check_interval_total * interval_length); + + /* calculate the average check interval for hosts */ + scheduling_info.average_host_check_interval = (double)((double)scheduling_info.host_check_interval_total / (double)scheduling_info.total_scheduled_hosts); + + /* calculate the average inter check delay (in seconds) needed to evenly space the host checks out */ + scheduling_info.average_host_inter_check_delay = (double)(scheduling_info.average_host_check_interval / (double)scheduling_info.total_scheduled_hosts); + + /* set the global inter check delay value */ + scheduling_info.host_inter_check_delay = scheduling_info.average_host_inter_check_delay; + + /* calculate max inter check delay and see if we should use that instead */ + max_inter_check_delay = (double)((scheduling_info.max_host_check_spread * 60.0) / (double)scheduling_info.total_scheduled_hosts); + if(scheduling_info.host_inter_check_delay > max_inter_check_delay) + scheduling_info.host_inter_check_delay = max_inter_check_delay; + } + else + scheduling_info.host_inter_check_delay = 0.0; + + log_debug_info(DEBUGL_EVENTS, 2, "Total scheduled host checks: %d\n", scheduling_info.total_scheduled_hosts); + log_debug_info(DEBUGL_EVENTS, 2, "Host check interval total: %lu\n", scheduling_info.host_check_interval_total); + log_debug_info(DEBUGL_EVENTS, 2, "Average host check interval: %0.2f sec\n", scheduling_info.average_host_check_interval); + log_debug_info(DEBUGL_EVENTS, 2, "Host inter-check delay: %0.2f sec\n", scheduling_info.host_inter_check_delay); + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[6], NULL); + + + /******** SCHEDULE HOST CHECKS ********/ + + log_debug_info(DEBUGL_EVENTS, 2, "Scheduling host checks..."); + + /* determine check times for host checks */ + mult_factor = 0; + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + log_debug_info(DEBUGL_EVENTS, 2, "Host '%s'\n", temp_host->name); + + /* skip hosts that shouldn't be scheduled */ + if(temp_host->should_be_scheduled == FALSE) { + log_debug_info(DEBUGL_EVENTS, 2, "Host check should not be scheduled.\n"); + continue; + } + + /* skip hosts whose checks are currently executing */ + if(temp_host->is_executing) { + log_debug_info(DEBUGL_EVENTS, 2, + "Host check %s is already executing.\n", temp_host->name); + continue; + } + + /* skip hosts that are already scheduled for the future (from retention data), but reschedule ones that were supposed to be checked before we started */ + if(temp_host->next_check > current_time) { + log_debug_info(DEBUGL_EVENTS, 2, "Host is already scheduled to be checked in the future: %s\n", ctime(&temp_host->next_check)); + continue; + } + + /* calculate preferred host check time */ + temp_host->next_check = (time_t)(current_time + (mult_factor * scheduling_info.host_inter_check_delay)); + + log_debug_info(DEBUGL_EVENTS, 2, "Preferred Check Time: %lu --> %s", (unsigned long)temp_host->next_check, ctime(&temp_host->next_check)); + + /* make sure the host can actually be scheduled at this time */ + is_valid_time = check_time_against_period(temp_host->next_check, temp_host->check_period_ptr); + if(is_valid_time == ERROR) { + get_next_valid_time(temp_host->next_check, &next_valid_time, temp_host->check_period_ptr); + temp_host->next_check = next_valid_time; + } + + log_debug_info(DEBUGL_EVENTS, 2, "Actual Check Time: %lu --> %s", (unsigned long)temp_host->next_check, ctime(&temp_host->next_check)); + + if(scheduling_info.first_host_check == (time_t)0 || (temp_host->next_check < scheduling_info.first_host_check)) + scheduling_info.first_host_check = temp_host->next_check; + if(temp_host->next_check > scheduling_info.last_host_check) + scheduling_info.last_host_check = temp_host->next_check; + + mult_factor++; + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[7], NULL); + + /* add scheduled host checks to event queue */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* Nagios XI/NDOUtils Mod */ + /* update status of all hosts (scheduled or not) */ + update_host_status(temp_host, FALSE); + + /* skip hosts whose checks are currently executing */ + if(temp_host->is_executing) + continue; + + /* skip most hosts that shouldn't be scheduled */ + if(temp_host->should_be_scheduled == FALSE) { + + /* passive checks are an exception if a forced check was scheduled before Nagios was restarted */ + if(!(temp_host->checks_enabled == FALSE && temp_host->next_check != (time_t)0L && (temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION))) + continue; + } + + /* schedule a new host check event */ + log_debug_info(DEBUGL_EVENTS, 2, "Scheduling check for host '%s'.\n", + temp_host->name); + schedule_new_event(EVENT_HOST_CHECK, FALSE, temp_host->next_check, FALSE, 0, NULL, TRUE, (void *)temp_host, NULL, temp_host->check_options); + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[8], NULL); + + + /******** SCHEDULE MISC EVENTS ********/ + + /* add a host and service check rescheduling event */ + if(auto_reschedule_checks == TRUE) + schedule_new_event(EVENT_RESCHEDULE_CHECKS, TRUE, current_time + auto_rescheduling_interval, TRUE, auto_rescheduling_interval, NULL, TRUE, NULL, NULL, 0); + + /* add a check result reaper event */ + schedule_new_event(EVENT_CHECK_REAPER, TRUE, current_time + check_reaper_interval, TRUE, check_reaper_interval, NULL, TRUE, NULL, NULL, 0); + + /* add an orphaned check event */ + if(check_orphaned_services == TRUE || check_orphaned_hosts == TRUE) + schedule_new_event(EVENT_ORPHAN_CHECK, TRUE, current_time + DEFAULT_ORPHAN_CHECK_INTERVAL, TRUE, DEFAULT_ORPHAN_CHECK_INTERVAL, NULL, TRUE, NULL, NULL, 0); + + /* add a service result "freshness" check event */ + if(check_service_freshness == TRUE) + schedule_new_event(EVENT_SFRESHNESS_CHECK, TRUE, current_time + service_freshness_check_interval, TRUE, service_freshness_check_interval, NULL, TRUE, NULL, NULL, 0); + + /* add a host result "freshness" check event */ + if(check_host_freshness == TRUE) + schedule_new_event(EVENT_HFRESHNESS_CHECK, TRUE, current_time + host_freshness_check_interval, TRUE, host_freshness_check_interval, NULL, TRUE, NULL, NULL, 0); + + /* add a status save event */ + if(aggregate_status_updates == TRUE) + schedule_new_event(EVENT_STATUS_SAVE, TRUE, current_time + status_update_interval, TRUE, status_update_interval, NULL, TRUE, NULL, NULL, 0); + + /* add an external command check event if needed */ + if(check_external_commands == TRUE) { + if(command_check_interval == -1) + interval_to_use = (unsigned long)5; + else + interval_to_use = (unsigned long)command_check_interval; + schedule_new_event(EVENT_COMMAND_CHECK, TRUE, current_time + interval_to_use, TRUE, interval_to_use, NULL, TRUE, NULL, NULL, 0); + } + + /* add a log rotation event if necessary */ + if(log_rotation_method != LOG_ROTATION_NONE) + schedule_new_event(EVENT_LOG_ROTATION, TRUE, get_next_log_rotation_time(), TRUE, 0, (void *)get_next_log_rotation_time, TRUE, NULL, NULL, 0); + + /* add a retention data save event if needed */ + if(retain_state_information == TRUE && retention_update_interval > 0) + schedule_new_event(EVENT_RETENTION_SAVE, TRUE, current_time + (retention_update_interval * 60), TRUE, (retention_update_interval * 60), NULL, TRUE, NULL, NULL, 0); + + if(test_scheduling == TRUE) { + + runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0); + runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0); + runtime[3] = (double)((double)(tv[4].tv_sec - tv[3].tv_sec) + (double)((tv[4].tv_usec - tv[3].tv_usec) / 1000.0) / 1000.0); + runtime[4] = (double)((double)(tv[5].tv_sec - tv[4].tv_sec) + (double)((tv[5].tv_usec - tv[4].tv_usec) / 1000.0) / 1000.0); + runtime[5] = (double)((double)(tv[6].tv_sec - tv[5].tv_sec) + (double)((tv[6].tv_usec - tv[5].tv_usec) / 1000.0) / 1000.0); + runtime[6] = (double)((double)(tv[7].tv_sec - tv[6].tv_sec) + (double)((tv[7].tv_usec - tv[6].tv_usec) / 1000.0) / 1000.0); + runtime[7] = (double)((double)(tv[8].tv_sec - tv[7].tv_sec) + (double)((tv[8].tv_usec - tv[7].tv_usec) / 1000.0) / 1000.0); + + runtime[8] = (double)((double)(tv[8].tv_sec - tv[0].tv_sec) + (double)((tv[8].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + + printf("EVENT SCHEDULING TIMES\n"); + printf("-------------------------------------\n"); + printf("Get service info: %.6lf sec\n", runtime[0]); + printf("Get host info info: %.6lf sec\n", runtime[1]); + printf("Get service params: %.6lf sec\n", runtime[2]); + printf("Schedule service times: %.6lf sec\n", runtime[3]); + printf("Schedule service events: %.6lf sec\n", runtime[4]); + printf("Get host params: %.6lf sec\n", runtime[5]); + printf("Schedule host times: %.6lf sec\n", runtime[6]); + printf("Schedule host events: %.6lf sec\n", runtime[7]); + printf(" ============\n"); + printf("TOTAL: %.6lf sec\n", runtime[8]); + printf("\n\n"); + } + + log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() end\n"); + + return; + } + + + +/* displays service check scheduling information */ +void display_scheduling_info(void) { + float minimum_concurrent_checks1 = 0.0; + float minimum_concurrent_checks2 = 0.0; + float minimum_concurrent_checks = 0.0; + float max_reaper_interval = 0.0; + int suggestions = 0; + + printf("Projected scheduling information for host and service checks\n"); + printf("is listed below. This information assumes that you are going\n"); + printf("to start running Nagios with your current config files.\n\n"); + + printf("HOST SCHEDULING INFORMATION\n"); + printf("---------------------------\n"); + printf("Total hosts: %d\n", scheduling_info.total_hosts); + printf("Total scheduled hosts: %d\n", scheduling_info.total_scheduled_hosts); + + printf("Host inter-check delay method: "); + if(host_inter_check_delay_method == ICD_NONE) + printf("NONE\n"); + else if(host_inter_check_delay_method == ICD_DUMB) + printf("DUMB\n"); + else if(host_inter_check_delay_method == ICD_SMART) { + printf("SMART\n"); + printf("Average host check interval: %.2f sec\n", scheduling_info.average_host_check_interval); + } + else + printf("USER-SUPPLIED VALUE\n"); + printf("Host inter-check delay: %.2f sec\n", scheduling_info.host_inter_check_delay); + printf("Max host check spread: %d min\n", scheduling_info.max_host_check_spread); + printf("First scheduled check: %s", (scheduling_info.total_scheduled_hosts == 0) ? "N/A\n" : ctime(&scheduling_info.first_host_check)); + printf("Last scheduled check: %s", (scheduling_info.total_scheduled_hosts == 0) ? "N/A\n" : ctime(&scheduling_info.last_host_check)); + printf("\n\n"); + + printf("SERVICE SCHEDULING INFORMATION\n"); + printf("-------------------------------\n"); + printf("Total services: %d\n", scheduling_info.total_services); + printf("Total scheduled services: %d\n", scheduling_info.total_scheduled_services); + + printf("Service inter-check delay method: "); + if(service_inter_check_delay_method == ICD_NONE) + printf("NONE\n"); + else if(service_inter_check_delay_method == ICD_DUMB) + printf("DUMB\n"); + else if(service_inter_check_delay_method == ICD_SMART) { + printf("SMART\n"); + printf("Average service check interval: %.2f sec\n", scheduling_info.average_service_check_interval); + } + else + printf("USER-SUPPLIED VALUE\n"); + printf("Inter-check delay: %.2f sec\n", scheduling_info.service_inter_check_delay); + + printf("Interleave factor method: %s\n", (service_interleave_factor_method == ILF_USER) ? "USER-SUPPLIED VALUE" : "SMART"); + if(service_interleave_factor_method == ILF_SMART) + printf("Average services per host: %.2f\n", scheduling_info.average_services_per_host); + printf("Service interleave factor: %d\n", scheduling_info.service_interleave_factor); + + printf("Max service check spread: %d min\n", scheduling_info.max_service_check_spread); + printf("First scheduled check: %s", ctime(&scheduling_info.first_service_check)); + printf("Last scheduled check: %s", ctime(&scheduling_info.last_service_check)); + printf("\n\n"); + + printf("CHECK PROCESSING INFORMATION\n"); + printf("----------------------------\n"); + printf("Check result reaper interval: %d sec\n", check_reaper_interval); + printf("Max concurrent service checks: "); + if(max_parallel_service_checks == 0) + printf("Unlimited\n"); + else + printf("%d\n", max_parallel_service_checks); + printf("\n\n"); + + printf("PERFORMANCE SUGGESTIONS\n"); + printf("-----------------------\n"); + + + /***** MAX REAPER INTERVAL RECOMMENDATION *****/ + + /* assume a 100% (2x) check burst for check reaper */ + /* assume we want a max of 2k files in the result queue at any given time */ + max_reaper_interval = floor(2000 * scheduling_info.service_inter_check_delay); + if(max_reaper_interval < 2.0) + max_reaper_interval = 2.0; + if(max_reaper_interval > 30.0) + max_reaper_interval = 30.0; + if((int)max_reaper_interval < check_reaper_interval) { + printf("* Value for 'check_result_reaper_frequency' should be <= %d seconds\n", (int)max_reaper_interval); + suggestions++; + } + if(check_reaper_interval < 2) { + printf("* Value for 'check_result_reaper_frequency' should be >= 2 seconds\n"); + suggestions++; + } + + /***** MINIMUM CONCURRENT CHECKS RECOMMENDATION *****/ + + /* first method (old) - assume a 100% (2x) service check burst for max concurrent checks */ + if(scheduling_info.service_inter_check_delay == 0.0) + minimum_concurrent_checks1 = ceil(check_reaper_interval * 2.0); + else + minimum_concurrent_checks1 = ceil((check_reaper_interval * 2.0) / scheduling_info.service_inter_check_delay); + + /* second method (new) - assume a 25% (1.25x) service check burst for max concurrent checks */ + minimum_concurrent_checks2 = ceil((((double)scheduling_info.total_scheduled_services) / scheduling_info.average_service_check_interval) * 1.25 * check_reaper_interval * scheduling_info.average_service_execution_time); + + /* use max of computed values */ + if(minimum_concurrent_checks1 > minimum_concurrent_checks2) + minimum_concurrent_checks = minimum_concurrent_checks1; + else + minimum_concurrent_checks = minimum_concurrent_checks2; + + /* compare with configured value */ + if(((int)minimum_concurrent_checks > max_parallel_service_checks) && max_parallel_service_checks != 0) { + printf("* Value for 'max_concurrent_checks' option should be >= %d\n", (int)minimum_concurrent_checks); + suggestions++; + } + + if(suggestions == 0) + printf("I have no suggestions - things look okay.\n"); + + printf("\n"); + + return; + } + + +/* schedule a new timed event */ +int schedule_new_event(int event_type, int high_priority, time_t run_time, int recurring, unsigned long event_interval, void *timing_func, int compensate_for_time_change, void *event_data, void *event_args, int event_options) { + timed_event **event_list = NULL; + timed_event **event_list_tail = NULL; + timed_event *new_event = NULL; + + char run_time_string[MAX_DATETIME_LENGTH] = ""; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "schedule_new_event()\n"); + + get_datetime_string(&run_time, run_time_string, MAX_DATETIME_LENGTH, + SHORT_DATE_TIME); + log_debug_info(DEBUGL_EVENTS, 0, "New Event Details:\n"); + log_debug_info(DEBUGL_EVENTS, 0, " Type: %s\n", + EVENT_TYPE_STR(event_type)); + log_debug_info(DEBUGL_EVENTS, 0, " High Priority: %s\n", + (high_priority ? "Yes" : "No")); + log_debug_info(DEBUGL_EVENTS, 0, " Run Time: %s\n", + run_time_string); + log_debug_info(DEBUGL_EVENTS, 0, " Recurring: %s\n", + (recurring ? "Yes" : "No")); + log_debug_info(DEBUGL_EVENTS, 0, " Event Interval: %lu\n", + event_interval); + log_debug_info(DEBUGL_EVENTS, 0, " Compensate for Time Change: %s\n", + (compensate_for_time_change ? "Yes" : "No")); + log_debug_info(DEBUGL_EVENTS, 0, " Event Options: %d\n", + event_options); + + if(high_priority == TRUE) { + event_list = &event_list_high; + event_list_tail = &event_list_high_tail; + } + else { + event_list = &event_list_low; + event_list_tail = &event_list_low_tail; + } + + new_event = (timed_event *)malloc(sizeof(timed_event)); + if(new_event != NULL) { + new_event->event_type = event_type; + new_event->event_data = event_data; + new_event->event_args = event_args; + new_event->event_options = event_options; + new_event->run_time = run_time; + new_event->recurring = recurring; + new_event->event_interval = event_interval; + new_event->timing_func = timing_func; + new_event->compensate_for_time_change = compensate_for_time_change; + } + else + return ERROR; + + /* add the event to the event list */ + add_event(new_event, event_list, event_list_tail); + + return OK; + } + + +/* reschedule an event in order of execution time */ +void reschedule_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) { + time_t current_time = 0L; + time_t (*timingfunc)(void); + + log_debug_info(DEBUGL_FUNCTIONS, 0, "reschedule_event()\n"); + + /* reschedule recurring events... */ + if(event->recurring == TRUE) { + + /* use custom timing function */ + if(event->timing_func != NULL) { + timingfunc = event->timing_func; + event->run_time = (*timingfunc)(); + } + + /* normal recurring events */ + else { + event->run_time = event->run_time + event->event_interval; + time(¤t_time); + if(event->run_time < current_time) + event->run_time = current_time; + } + } + + /* add the event to the event list */ + add_event(event, event_list, event_list_tail); + + return; + } + + +/* add an event to list ordered by execution time */ +void add_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) { + timed_event *temp_event = NULL; + timed_event *first_event = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "add_event()\n"); + + event->next = NULL; + event->prev = NULL; + + first_event = *event_list; + + /* add the event to the head of the list if there are no other events */ + if(*event_list == NULL) { + *event_list = event; + *event_list_tail = event; + } + + /* add event to head of the list if it should be executed first */ + else if(event->run_time < first_event->run_time) { + event->prev = NULL; + (*event_list)->prev = event; + event->next = *event_list; + *event_list = event; + } + + /* else place the event according to next execution time */ + else { + + /* start from the end of the list, as new events are likely to be executed in the future, rather than now... */ + for(temp_event = *event_list_tail; temp_event != NULL; temp_event = temp_event->prev) { + if(event->run_time >= temp_event->run_time) { + event->next = temp_event->next; + event->prev = temp_event; + temp_event->next = event; + if(event->next == NULL) + *event_list_tail = event; + else + event->next->prev = event; + break; + } + else if(temp_event->prev == NULL) { + temp_event->prev = event; + event->next = temp_event; + *event_list = event; + break; + } + } + } + +#ifdef USE_EVENT_BROKER + /* send event data to broker */ + broker_timed_event(NEBTYPE_TIMEDEVENT_ADD, NEBFLAG_NONE, NEBATTR_NONE, event, NULL); +#endif + + return; + } + + + +/* remove an event from the queue */ +void remove_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) { + timed_event *prev_event, *next_event; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "remove_event()\n"); + + if(!event) + return; + +#ifdef USE_EVENT_BROKER + /* send event data to broker */ + broker_timed_event(NEBTYPE_TIMEDEVENT_REMOVE, NEBFLAG_NONE, NEBATTR_NONE, event, NULL); +#endif + + if(*event_list == NULL) + return; + + prev_event = event->prev; + next_event = event->next; + if(prev_event) { + prev_event->next = next_event; + } + if(next_event) { + next_event->prev = prev_event; + } + + if(!prev_event) { + /* no previous event, so "next" is now first in list */ + *event_list = next_event; + } + if(!next_event) { + /* no following event, so "prev" is now last in list */ + *event_list_tail = prev_event; + } + + /* + * If there was only one event in the list, we're already + * done, just as if there were events before and efter the + * deleted event + */ + } + + + +/* this is the main event handler loop */ +int event_execution_loop(void) { + timed_event *temp_event = NULL; + timed_event sleep_event; + time_t last_time = 0L; + time_t current_time = 0L; + time_t last_status_update = 0L; + int run_event = TRUE; + int nudge_seconds; + host *temp_host = NULL; + service *temp_service = NULL; + struct timespec delay; + pid_t wait_result; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "event_execution_loop() start\n"); + + time(&last_time); + + /* initialize fake "sleep" event */ + sleep_event.event_type = EVENT_SLEEP; + sleep_event.run_time = last_time; + sleep_event.recurring = FALSE; + sleep_event.event_interval = 0L; + sleep_event.compensate_for_time_change = FALSE; + sleep_event.timing_func = NULL; + sleep_event.event_data = NULL; + sleep_event.event_args = NULL; + sleep_event.event_options = 0; + sleep_event.next = NULL; + sleep_event.prev = NULL; + + while(1) { + + /* see if we should exit or restart (a signal was encountered) */ + if(sigshutdown == TRUE || sigrestart == TRUE) + break; + + /* if we don't have any events to handle, exit */ + if(event_list_high == NULL && event_list_low == NULL) { + log_debug_info(DEBUGL_EVENTS, 0, "There aren't any events that need to be handled! Exiting...\n"); + break; + } + + /* get the current time */ + time(¤t_time); + + /* hey, wait a second... we traveled back in time! */ + if(current_time < last_time) + compensate_for_system_time_change((unsigned long)last_time, (unsigned long)current_time); + + /* else if the time advanced over the specified threshold, try and compensate... */ + else if((current_time - last_time) >= time_change_threshold) + compensate_for_system_time_change((unsigned long)last_time, (unsigned long)current_time); + + /* keep track of the last time */ + last_time = current_time; + + log_debug_info(DEBUGL_EVENTS, 1, "** Event Check Loop\n"); + if(event_list_high != NULL) + log_debug_info(DEBUGL_EVENTS, 1, "Next High Priority Event Time: %s", ctime(&event_list_high->run_time)); + else + log_debug_info(DEBUGL_EVENTS, 1, "No high priority events are scheduled...\n"); + if(event_list_low != NULL) + log_debug_info(DEBUGL_EVENTS, 1, "Next Low Priority Event Time: %s", ctime(&event_list_low->run_time)); + else + log_debug_info(DEBUGL_EVENTS, 1, "No low priority events are scheduled...\n"); + log_debug_info(DEBUGL_EVENTS, 1, "Current/Max Service Checks: %d/%d\n", currently_running_service_checks, max_parallel_service_checks); + + /* get rid of terminated child processes (zombies) */ + if(child_processes_fork_twice == FALSE) { + while((wait_result = waitpid(-1, NULL, WNOHANG)) > 0); + } + + /* handle high priority events */ + if(event_list_high != NULL && (current_time >= event_list_high->run_time)) { + + /* remove the first event from the timing loop */ + temp_event = event_list_high; + event_list_high = event_list_high->next; + event_list_high->prev = NULL; + + /* handle the event */ + handle_timed_event(temp_event); + + /* reschedule the event if necessary */ + if(temp_event->recurring == TRUE) + reschedule_event(temp_event, &event_list_high, &event_list_high_tail); + + /* else free memory associated with the event */ + else + my_free(temp_event); + } + + /* handle low priority events */ + else if(event_list_low != NULL && (current_time >= event_list_low->run_time)) { + + /* default action is to execute the event */ + run_event = TRUE; + nudge_seconds = 0; + + /* run a few checks before executing a service check... */ + if(event_list_low->event_type == EVENT_SERVICE_CHECK) { + + temp_service = (service *)event_list_low->event_data; + + /* don't run a service check if we're already maxed out on the number of parallel service checks... */ + if(max_parallel_service_checks != 0 && (currently_running_service_checks >= max_parallel_service_checks)) { + + /* Move it at least 5 seconds (to overcome the current peak), with a random 10 seconds (to spread the load) */ + nudge_seconds = 5 + (rand() % 10); + log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 0, "**WARNING** Max concurrent service checks (%d) has been reached! Nudging %s:%s by %d seconds...\n", max_parallel_service_checks, temp_service->host_name, temp_service->description, nudge_seconds); + + logit(NSLOG_RUNTIME_WARNING, TRUE, "\tMax concurrent service checks (%d) has been reached. Nudging %s:%s by %d seconds...\n", max_parallel_service_checks, temp_service->host_name, temp_service->description, nudge_seconds); + run_event = FALSE; + } + + /* don't run a service check if active checks are disabled */ + if(execute_service_checks == FALSE) { + + log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 1, "We're not executing service checks right now, so we'll skip this event.\n"); + + run_event = FALSE; + } + + /* forced checks override normal check logic */ + if((temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION)) + run_event = TRUE; + + /* reschedule the check if we can't run it now */ + if(run_event == FALSE) { + + /* remove the service check from the event queue and reschedule it for a later time */ + /* 12/20/05 since event was not executed, it needs to be remove()'ed to maintain sync with event broker modules */ + temp_event = event_list_low; + remove_event(temp_event, &event_list_low, &event_list_low_tail); + /* + event_list_low=event_list_low->next; + */ + if(nudge_seconds) { + /* We nudge the next check time when it is due to too many concurrent service checks */ + temp_service->next_check = (time_t)(temp_service->next_check + nudge_seconds); + } + else { + /* Otherwise reschedule (TODO: This should be smarter as it doesn't consider its timeperiod) */ + if(temp_service->state_type == SOFT_STATE && temp_service->current_state != STATE_OK) + temp_service->next_check = (time_t)(temp_service->next_check + (temp_service->retry_interval * interval_length)); + else + temp_service->next_check = (time_t)(temp_service->next_check + (temp_service->check_interval * interval_length)); + } + + temp_event->run_time = temp_service->next_check; + reschedule_event(temp_event, &event_list_low, &event_list_low_tail); + update_service_status(temp_service, FALSE); + + run_event = FALSE; + } + } + + /* run a few checks before executing a host check... */ + else if(event_list_low->event_type == EVENT_HOST_CHECK) { + + /* default action is to execute the event */ + run_event = TRUE; + + temp_host = (host *)event_list_low->event_data; + + /* don't run a host check if active checks are disabled */ + if(execute_host_checks == FALSE) { + + log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 1, "We're not executing host checks right now, so we'll skip this event.\n"); + + run_event = FALSE; + } + + /* forced checks override normal check logic */ + if((temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION)) + run_event = TRUE; + + /* reschedule the host check if we can't run it right now */ + if(run_event == FALSE) { + + /* remove the host check from the event queue and reschedule it for a later time */ + /* 12/20/05 since event was not executed, it needs to be remove()'ed to maintain sync with event broker modules */ + temp_event = event_list_low; + remove_event(temp_event, &event_list_low, &event_list_low_tail); + /* + event_list_low=event_list_low->next; + */ + if(temp_host->state_type == SOFT_STATE && temp_host->current_state != STATE_OK) + temp_host->next_check = (time_t)(temp_host->next_check + (temp_host->retry_interval * interval_length)); + else + temp_host->next_check = (time_t)(temp_host->next_check + (temp_host->check_interval * interval_length)); + + temp_event->run_time = temp_host->next_check; + reschedule_event(temp_event, &event_list_low, &event_list_low_tail); + update_host_status(temp_host, FALSE); + + run_event = FALSE; + } + } + + /* run the event */ + if(run_event == TRUE) { + + /* remove the first event from the timing loop */ + temp_event = event_list_low; + event_list_low = event_list_low->next; + /* we may have just removed the only item from the list */ + if(event_list_low != NULL) + event_list_low->prev = NULL; + + log_debug_info(DEBUGL_EVENTS, 1, "Running event...\n"); + +# /* handle the event */ + handle_timed_event(temp_event); + + /* reschedule the event if necessary */ + if(temp_event->recurring == TRUE) + reschedule_event(temp_event, &event_list_low, &event_list_low_tail); + + /* else free memory associated with the event */ + else + my_free(temp_event); + } + + } + + /* we don't have anything to do at this moment in time... */ + else if((event_list_high == NULL || (current_time < event_list_high->run_time)) && (event_list_low == NULL || (current_time < event_list_low->run_time))) { + + log_debug_info(DEBUGL_EVENTS, 2, "No events to execute at the moment. Idling for a bit...\n"); + + /* check for external commands if we're supposed to check as often as possible */ + if(command_check_interval == -1) + check_for_external_commands(); + + /* set time to sleep so we don't hog the CPU... */ +#ifdef USE_NANOSLEEP + delay.tv_sec = (time_t)sleep_time; + delay.tv_nsec = (long)((sleep_time - (double)delay.tv_sec) * 1000000000); +#else + delay.tv_sec = (time_t)sleep_time; + if(delay.tv_sec == 0L) + delay.tv_sec = 1; + delay.tv_nsec = 0L; +#endif + +#ifdef USE_EVENT_BROKER + /* populate fake "sleep" event */ + sleep_event.run_time = current_time; + sleep_event.event_data = (void *)&delay; + + /* send event data to broker */ + broker_timed_event(NEBTYPE_TIMEDEVENT_SLEEP, NEBFLAG_NONE, NEBATTR_NONE, &sleep_event, NULL); +#endif + + /* wait a while so we don't hog the CPU... */ +#ifdef USE_NANOSLEEP + nanosleep(&delay, NULL); +#else + sleep((unsigned int)delay.tv_sec); +#endif + } + + /* update status information occassionally - NagVis watches the NDOUtils DB to see if Nagios is alive */ + if((unsigned long)(current_time - last_status_update) > 5) { + last_status_update = current_time; + update_program_status(FALSE); + } + } + + log_debug_info(DEBUGL_FUNCTIONS, 0, "event_execution_loop() end\n"); + + return OK; + } + + + +/* handles a timed event */ +int handle_timed_event(timed_event *event) { + host *temp_host = NULL; + service *temp_service = NULL; + void (*userfunc)(void *); + struct timeval tv; + double latency = 0.0; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_timed_event() start\n"); + +#ifdef USE_EVENT_BROKER + /* send event data to broker */ + broker_timed_event(NEBTYPE_TIMEDEVENT_EXECUTE, NEBFLAG_NONE, NEBATTR_NONE, event, NULL); +#endif + + log_debug_info(DEBUGL_EVENTS, 0, "** Timed Event ** Type: %s, Run Time: %s", EVENT_TYPE_STR(event->event_type), ctime(&event->run_time)); + + /* how should we handle the event? */ + switch(event->event_type) { + + case EVENT_SERVICE_CHECK: + + temp_service = (service *)event->event_data; + + /* get check latency */ + gettimeofday(&tv, NULL); + latency = (double)((double)(tv.tv_sec - event->run_time) + (double)(tv.tv_usec / 1000) / 1000.0); + + log_debug_info(DEBUGL_EVENTS, 0, "** Service Check Event ==> Host: '%s', Service: '%s', Options: %d, Latency: %f sec\n", temp_service->host_name, temp_service->description, event->event_options, latency); + + /* run the service check */ + temp_service = (service *)event->event_data; + run_scheduled_service_check(temp_service, event->event_options, latency); + break; + + case EVENT_HOST_CHECK: + + temp_host = (host *)event->event_data; + + /* get check latency */ + gettimeofday(&tv, NULL); + latency = (double)((double)(tv.tv_sec - event->run_time) + (double)(tv.tv_usec / 1000) / 1000.0); + + log_debug_info(DEBUGL_EVENTS, 0, "** Host Check Event ==> Host: '%s', Options: %d, Latency: %f sec\n", temp_host->name, event->event_options, latency); + + /* run the host check */ + temp_host = (host *)event->event_data; + perform_scheduled_host_check(temp_host, event->event_options, latency); + break; + + case EVENT_COMMAND_CHECK: + + log_debug_info(DEBUGL_EVENTS, 0, "** External Command Check Event\n"); + + /* check for external commands */ + check_for_external_commands(); + break; + + case EVENT_LOG_ROTATION: + + log_debug_info(DEBUGL_EVENTS, 0, "** Log File Rotation Event\n"); + + /* rotate the log file */ + rotate_log_file(event->run_time); + break; + + case EVENT_PROGRAM_SHUTDOWN: + + log_debug_info(DEBUGL_EVENTS, 0, "** Program Shutdown Event\n"); + + /* set the shutdown flag */ + sigshutdown = TRUE; + + /* log the shutdown */ + logit(NSLOG_PROCESS_INFO, TRUE, "PROGRAM_SHUTDOWN event encountered, shutting down...\n"); + break; + + case EVENT_PROGRAM_RESTART: + + log_debug_info(DEBUGL_EVENTS, 0, "** Program Restart Event\n"); + + /* set the restart flag */ + sigrestart = TRUE; + + /* log the restart */ + logit(NSLOG_PROCESS_INFO, TRUE, "PROGRAM_RESTART event encountered, restarting...\n"); + break; + + case EVENT_CHECK_REAPER: + + log_debug_info(DEBUGL_EVENTS, 0, "** Check Result Reaper\n"); + + /* reap host and service check results */ + reap_check_results(); + break; + + case EVENT_ORPHAN_CHECK: + + log_debug_info(DEBUGL_EVENTS, 0, "** Orphaned Host and Service Check Event\n"); + + /* check for orphaned hosts and services */ + if(check_orphaned_hosts == TRUE) + check_for_orphaned_hosts(); + if(check_orphaned_services == TRUE) + check_for_orphaned_services(); + break; + + case EVENT_RETENTION_SAVE: + + log_debug_info(DEBUGL_EVENTS, 0, "** Retention Data Save Event\n"); + + /* save state retention data */ + save_state_information(TRUE); + break; + + case EVENT_STATUS_SAVE: + + log_debug_info(DEBUGL_EVENTS, 0, "** Status Data Save Event\n"); + + /* save all status data (program, host, and service) */ + update_all_status_data(); + break; + + case EVENT_SCHEDULED_DOWNTIME: + + log_debug_info(DEBUGL_EVENTS, 0, "** Scheduled Downtime Event\n"); + + /* process scheduled downtime info */ + if(event->event_data) { + handle_scheduled_downtime_by_id(*(unsigned long *)event->event_data); + free(event->event_data); + event->event_data = NULL; + } + break; + + case EVENT_SFRESHNESS_CHECK: + + log_debug_info(DEBUGL_EVENTS, 0, "** Service Result Freshness Check Event\n"); + + /* check service result freshness */ + check_service_result_freshness(); + break; + + case EVENT_HFRESHNESS_CHECK: + + log_debug_info(DEBUGL_EVENTS, 0, "** Host Result Freshness Check Event\n"); + + /* check host result freshness */ + check_host_result_freshness(); + break; + + case EVENT_EXPIRE_DOWNTIME: + + log_debug_info(DEBUGL_EVENTS, 0, "** Expire Downtime Event\n"); + + /* check for expired scheduled downtime entries */ + check_for_expired_downtime(); + break; + + case EVENT_RESCHEDULE_CHECKS: + + /* adjust scheduling of host and service checks */ + log_debug_info(DEBUGL_EVENTS, 0, "** Reschedule Checks Event\n"); + + adjust_check_scheduling(); + break; + + case EVENT_EXPIRE_COMMENT: + + log_debug_info(DEBUGL_EVENTS, 0, "** Expire Comment Event\n"); + + /* check for expired comment */ + check_for_expired_comment((unsigned long)event->event_data); + break; + + case EVENT_CHECK_PROGRAM_UPDATE: + + log_debug_info(DEBUGL_EVENTS, 0, "** Check For Program Update\n"); + + /* check for new versions of Nagios */ + check_for_nagios_updates(FALSE, TRUE); + break; + + case EVENT_USER_FUNCTION: + + log_debug_info(DEBUGL_EVENTS, 0, "** User Function Event\n"); + + /* run a user-defined function */ + if(event->event_data != NULL) { + userfunc = event->event_data; + (*userfunc)(event->event_args); + } + break; + + default: + + break; + } + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_timed_event() end\n"); + + return OK; + } + + + +/* adjusts scheduling of host and service checks */ +void adjust_check_scheduling(void) { + timed_event *temp_event = NULL; + service *temp_service = NULL; + host *temp_host = NULL; + double projected_host_check_overhead = 0.1; + double projected_service_check_overhead = 0.1; + time_t current_time = 0L; + time_t first_window_time = 0L; + time_t last_window_time = 0L; + time_t last_check_time = 0L; + time_t new_run_time = 0L; + int total_checks = 0; + int current_check = 0; + double inter_check_delay = 0.0; + double current_icd_offset = 0.0; + double total_check_exec_time = 0.0; + double last_check_exec_time = 0.0; + int adjust_scheduling = FALSE; + double exec_time_factor = 0.0; + double current_exec_time = 0.0; + double current_exec_time_offset = 0.0; + double new_run_time_offset = 0.0; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "adjust_check_scheduling() start\n"); + + /* TODO: + - Track host check overhead on a per-host basis + - Figure out how to calculate service check overhead + */ + + /* determine our adjustment window */ + time(¤t_time); + first_window_time = current_time; + last_window_time = first_window_time + auto_rescheduling_window; + + /* get current scheduling data */ + for(temp_event = event_list_low; temp_event != NULL; temp_event = temp_event->next) { + + /* skip events outside of our current window */ + if(temp_event->run_time <= first_window_time) + continue; + if(temp_event->run_time > last_window_time) + break; + + if(temp_event->event_type == EVENT_HOST_CHECK) { + + if((temp_host = (host *)temp_event->event_data) == NULL) + continue; + + /* ignore forced checks */ + if(temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION) + continue; + + /* does the last check "bump" into this one? */ + if((unsigned long)(last_check_time + last_check_exec_time) > temp_event->run_time) + adjust_scheduling = TRUE; + + last_check_time = temp_event->run_time; + + /* calculate time needed to perform check */ + /* NOTE: host check execution time is not taken into account, as scheduled host checks are run in parallel */ + last_check_exec_time = projected_host_check_overhead; + total_check_exec_time += last_check_exec_time; + } + + else if(temp_event->event_type == EVENT_SERVICE_CHECK) { + + if((temp_service = (service *)temp_event->event_data) == NULL) + continue; + + /* ignore forced checks */ + if(temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION) + continue; + + /* does the last check "bump" into this one? */ + if((unsigned long)(last_check_time + last_check_exec_time) > temp_event->run_time) + adjust_scheduling = TRUE; + + last_check_time = temp_event->run_time; + + /* calculate time needed to perform check */ + /* NOTE: service check execution time is not taken into account, as service checks are run in parallel */ + last_check_exec_time = projected_service_check_overhead; + total_check_exec_time += last_check_exec_time; + } + + else + continue; + + total_checks++; + } + + + /* nothing to do... */ + if(total_checks == 0 || adjust_scheduling == FALSE) { + + /* + printf("\n\n"); + printf("NOTHING TO DO!\n"); + printf("# CHECKS: %d\n",total_checks); + printf("WINDOW TIME: %d\n",auto_rescheduling_window); + printf("EXEC TIME: %.3f\n",total_check_exec_time); + */ + + return; + } + + if((unsigned long)total_check_exec_time > auto_rescheduling_window) { + inter_check_delay = 0.0; + exec_time_factor = (double)((double)auto_rescheduling_window / total_check_exec_time); + } + else { + inter_check_delay = (double)((((double)auto_rescheduling_window) - total_check_exec_time) / (double)(total_checks * 1.0)); + exec_time_factor = 1.0; + } + + /* + printf("\n\n"); + printf("TOTAL CHECKS: %d\n",total_checks); + printf("WINDOW TIME: %d\n",auto_rescheduling_window); + printf("EXEC TIME: %.3f\n",total_check_exec_time); + printf("ICD: %.3f\n",inter_check_delay); + printf("EXEC FACTOR: %.3f\n",exec_time_factor); + */ + + /* adjust check scheduling */ + current_icd_offset = (inter_check_delay / 2.0); + for(temp_event = event_list_low; temp_event != NULL; temp_event = temp_event->next) { + + /* skip events outside of our current window */ + if(temp_event->run_time <= first_window_time) + continue; + if(temp_event->run_time > last_window_time) + break; + + if(temp_event->event_type == EVENT_HOST_CHECK) { + + if((temp_host = (host *)temp_event->event_data) == NULL) + continue; + + /* ignore forced checks */ + if(temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION) + continue; + + current_exec_time = ((temp_host->execution_time + projected_host_check_overhead) * exec_time_factor); + } + + else if(temp_event->event_type == EVENT_SERVICE_CHECK) { + + if((temp_service = (service *)temp_event->event_data) == NULL) + continue; + + /* ignore forced checks */ + if(temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION) + continue; + + /* NOTE: service check execution time is not taken into account, as service checks are run in parallel */ + current_exec_time = (projected_service_check_overhead * exec_time_factor); + } + + else + continue; + + current_check++; + new_run_time_offset = current_exec_time_offset + current_icd_offset; + new_run_time = (time_t)(first_window_time + (unsigned long)new_run_time_offset); + + /* + printf(" CURRENT CHECK #: %d\n",current_check); + printf(" CURRENT ICD OFFSET: %.3f\n",current_icd_offset); + printf(" CURRENT EXEC TIME: %.3f\n",current_exec_time); + printf(" CURRENT EXEC OFFSET: %.3f\n",current_exec_time_offset); + printf(" NEW RUN TIME: %lu\n",new_run_time); + */ + + if(temp_event->event_type == EVENT_HOST_CHECK) { + temp_event->run_time = new_run_time; + temp_host->next_check = new_run_time; + update_host_status(temp_host, FALSE); + } + else { + temp_event->run_time = new_run_time; + temp_service->next_check = new_run_time; + update_service_status(temp_service, FALSE); + } + + current_icd_offset += inter_check_delay; + current_exec_time_offset += current_exec_time; + } + + /* resort event list (some events may be out of order at this point) */ + resort_event_list(&event_list_low, &event_list_low_tail); + + log_debug_info(DEBUGL_FUNCTIONS, 0, "adjust_check_scheduling() end\n"); + + return; + } + + + +/* attempts to compensate for a change in the system time */ +void compensate_for_system_time_change(unsigned long last_time, unsigned long current_time) { + unsigned long time_difference = 0L; + timed_event *temp_event = NULL; + service *temp_service = NULL; + host *temp_host = NULL; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + time_t (*timingfunc)(void); + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "compensate_for_system_time_change() start\n"); + + /* we moved back in time... */ + if(last_time > current_time) { + time_difference = last_time - current_time; + get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); + log_debug_info(DEBUGL_EVENTS, 0, "Detected a backwards time change of %dd %dh %dm %ds.\n", days, hours, minutes, seconds); + } + + /* we moved into the future... */ + else { + time_difference = current_time - last_time; + get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); + log_debug_info(DEBUGL_EVENTS, 0, "Detected a forwards time change of %dd %dh %dm %ds.\n", days, hours, minutes, seconds); + } + + /* log the time change */ + logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_WARNING, TRUE, "Warning: A system time change of %dd %dh %dm %ds (%s in time) has been detected. Compensating...\n", days, hours, minutes, seconds, (last_time > current_time) ? "backwards" : "forwards"); + + /* adjust the next run time for all high priority timed events */ + for(temp_event = event_list_high; temp_event != NULL; temp_event = temp_event->next) { + + /* skip special events that occur at specific times... */ + if(temp_event->compensate_for_time_change == FALSE) + continue; + + /* use custom timing function */ + if(temp_event->timing_func != NULL) { + timingfunc = temp_event->timing_func; + temp_event->run_time = (*timingfunc)(); + } + + /* else use standard adjustment */ + else + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_event->run_time); + } + + /* resort event list (some events may be out of order at this point) */ + resort_event_list(&event_list_high, &event_list_high_tail); + + /* adjust the next run time for all low priority timed events */ + for(temp_event = event_list_low; temp_event != NULL; temp_event = temp_event->next) { + + /* skip special events that occur at specific times... */ + if(temp_event->compensate_for_time_change == FALSE) + continue; + + /* use custom timing function */ + if(temp_event->timing_func != NULL) { + timingfunc = temp_event->timing_func; + temp_event->run_time = (*timingfunc)(); + } + + /* else use standard adjustment */ + else + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_event->run_time); + } + + /* resort event list (some events may be out of order at this point) */ + resort_event_list(&event_list_low, &event_list_low_tail); + + /* adjust service timestamps */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_notification); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_check); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->next_check); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_state_change); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_hard_state_change); + + /* recalculate next re-notification time */ + temp_service->next_notification = get_next_service_notification_time(temp_service, temp_service->last_notification); + + /* update the status data */ + update_service_status(temp_service, FALSE); + } + + /* adjust host timestamps */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_host_notification); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_check); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->next_check); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_state_change); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_hard_state_change); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_state_history_update); + + /* recalculate next re-notification time */ + temp_host->next_host_notification = get_next_host_notification_time(temp_host, temp_host->last_host_notification); + + /* update the status data */ + update_host_status(temp_host, FALSE); + } + + /* adjust program timestamps */ + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &program_start); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &event_start); + adjust_timestamp_for_time_change(last_time, current_time, time_difference, &last_command_check); + + /* update the status data */ + update_program_status(FALSE); + + return; + } + + + +/* resorts an event list by event execution time - needed when compensating for system time changes */ +void resort_event_list(timed_event **event_list, timed_event **event_list_tail) { + timed_event *temp_event_list = NULL; + timed_event *temp_event = NULL; + timed_event *next_event = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "resort_event_list()\n"); + + /* move current event list to temp list */ + temp_event_list = *event_list; + *event_list = NULL; + + /* move all events to the new event list */ + for(temp_event = temp_event_list; temp_event != NULL; temp_event = next_event) { + next_event = temp_event->next; + + /* add the event to the newly created event list so it will be resorted */ + temp_event->next = NULL; + temp_event->prev = NULL; + add_event(temp_event, event_list, event_list_tail); + } + + return; + } + + + +/* adjusts a timestamp variable in accordance with a system time change */ +void adjust_timestamp_for_time_change(time_t last_time, time_t current_time, unsigned long time_difference, time_t *ts) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "adjust_timestamp_for_time_change()\n"); + + /* we shouldn't do anything with epoch values */ + if(*ts == (time_t)0) + return; + + /* we moved back in time... */ + if(last_time > current_time) { + + /* we can't precede the UNIX epoch */ + if(time_difference > (unsigned long)*ts) + *ts = (time_t)0; + else + *ts = (time_t)(*ts - time_difference); + } + + /* we moved into the future... */ + else + *ts = (time_t)(*ts + time_difference); + + return; + } diff --git a/base/flapping.c b/base/flapping.c new file mode 100644 index 0000000..21be777 --- /dev/null +++ b/base/flapping.c @@ -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; + } + + + + + diff --git a/base/logging.c b/base/logging.c new file mode 100644 index 0000000..ef732ad --- /dev/null +++ b/base/logging.c @@ -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; + } + diff --git a/base/nagios.c b/base/nagios.c new file mode 100644 index 0000000..3f42684 --- /dev/null +++ b/base/nagios.c @@ -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 +#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] \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; + } + + diff --git a/base/nagiostats.c b/base/nagiostats.c new file mode 100644 index 0000000..e235ef7 --- /dev/null +++ b/base/nagiostats.c @@ -0,0 +1,1778 @@ +/***************************************************************************** + * + * NAGIOSTATS.C - Displays Nagios Statistics + * + * Program: Nagiostats + * Version: 3.5.1 + * License: GPL + * Copyright (c) 2003-2008 Ethan Galstad (egalstad@nagios.org) + * + * Last Modified: 12-20-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/nagios.h" +#include "../include/locations.h" + +#define STATUS_NO_DATA 0 +#define STATUS_INFO_DATA 1 +#define STATUS_PROGRAM_DATA 2 +#define STATUS_HOST_DATA 3 +#define STATUS_SERVICE_DATA 4 + + +char *main_config_file = NULL; +char *status_file = NULL; +char *nagiostats_file = NULL; +char *mrtg_variables = NULL; +char *mrtg_delimiter = "\n"; + +int mrtg_mode = FALSE; + +time_t status_creation_date = 0L; +char *status_version = NULL; +time_t program_start = 0L; +int status_service_entries = 0; +int status_host_entries = 0; +unsigned long nagios_pid = 0L; + +double min_service_state_change = 0.0; +int have_min_service_state_change = FALSE; +double max_service_state_change = 0.0; +int have_max_service_state_change = FALSE; +double average_service_state_change = 0.0; +double min_active_service_state_change = 0.0; +int have_min_active_service_state_change = FALSE; +double max_active_service_state_change = 0.0; +int have_max_active_service_state_change = FALSE; +double average_active_service_state_change = 0.0; +double min_active_service_latency = 0.0; +int have_min_active_service_latency = FALSE; +double max_active_service_latency = 0.0; +int have_max_active_service_latency = FALSE; +double average_active_service_latency = 0.0; +double min_active_service_execution_time = 0.0; +int have_min_active_service_execution_time = FALSE; +double max_active_service_execution_time = 0.0; +int have_max_active_service_execution_time = FALSE; +double average_active_service_execution_time = 0.0; +double min_passive_service_state_change = 0.0; +int have_min_passive_service_state_change = FALSE; +double max_passive_service_state_change = 0.0; +int have_max_passive_service_state_change = FALSE; +double average_passive_service_state_change = 0.0; +double min_passive_service_latency = 0.0; +int have_min_passive_service_latency = FALSE; +double max_passive_service_latency = 0.0; +int have_max_passive_service_latency = FALSE; +double average_passive_service_latency = 0.0; + +int have_min_host_state_change = FALSE; +double min_host_state_change = 0.0; +int have_max_host_state_change = FALSE; +double max_host_state_change = 0.0; +double average_host_state_change = 0.0; +int have_min_active_host_state_change = FALSE; +double min_active_host_state_change = 0.0; +int have_max_active_host_state_change = FALSE; +double max_active_host_state_change = 0.0; +double average_active_host_state_change = 0.0; +int have_min_active_host_latency = FALSE; +double min_active_host_latency = 0.0; +int have_max_active_host_latency = FALSE; +double max_active_host_latency = 0.0; +double average_active_host_latency = 0.0; +int have_min_active_host_execution_time = FALSE; +double min_active_host_execution_time = 0.0; +int have_max_active_host_execution_time = FALSE; +double max_active_host_execution_time = 0.0; +double average_active_host_execution_time = 0.0; +int have_min_passive_host_latency = FALSE; +double min_passive_host_latency = 0.0; +int have_max_passive_host_latency = FALSE; +double max_passive_host_latency = 0.0; +double average_passive_host_latency = 0.0; +double min_passive_host_state_change = 0.0; +int have_min_passive_host_state_change = FALSE; +double max_passive_host_state_change = 0.0; +int have_max_passive_host_state_change = FALSE; +double average_passive_host_state_change = 0.0; + +int passive_service_checks = 0; +int active_service_checks = 0; +int services_ok = 0; +int services_warning = 0; +int services_unknown = 0; +int services_critical = 0; +int services_flapping = 0; +int services_in_downtime = 0; +int services_checked = 0; +int services_scheduled = 0; +int passive_host_checks = 0; +int active_host_checks = 0; +int hosts_up = 0; +int hosts_down = 0; +int hosts_unreachable = 0; +int hosts_flapping = 0; +int hosts_in_downtime = 0; +int hosts_checked = 0; +int hosts_scheduled = 0; + +int passive_services_checked_last_1min = 0; +int passive_services_checked_last_5min = 0; +int passive_services_checked_last_15min = 0; +int passive_services_checked_last_1hour = 0; +int active_services_checked_last_1min = 0; +int active_services_checked_last_5min = 0; +int active_services_checked_last_15min = 0; +int active_services_checked_last_1hour = 0; +int passive_hosts_checked_last_1min = 0; +int passive_hosts_checked_last_5min = 0; +int passive_hosts_checked_last_15min = 0; +int passive_hosts_checked_last_1hour = 0; +int active_hosts_checked_last_1min = 0; +int active_hosts_checked_last_5min = 0; +int active_hosts_checked_last_15min = 0; +int active_hosts_checked_last_1hour = 0; + +int active_host_checks_last_1min = 0; +int active_host_checks_last_5min = 0; +int active_host_checks_last_15min = 0; +int active_ondemand_host_checks_last_1min = 0; +int active_ondemand_host_checks_last_5min = 0; +int active_ondemand_host_checks_last_15min = 0; +int active_scheduled_host_checks_last_1min = 0; +int active_scheduled_host_checks_last_5min = 0; +int active_scheduled_host_checks_last_15min = 0; +int passive_host_checks_last_1min = 0; +int passive_host_checks_last_5min = 0; +int passive_host_checks_last_15min = 0; +int active_cached_host_checks_last_1min = 0; +int active_cached_host_checks_last_5min = 0; +int active_cached_host_checks_last_15min = 0; +int parallel_host_checks_last_1min = 0; +int parallel_host_checks_last_5min = 0; +int parallel_host_checks_last_15min = 0; +int serial_host_checks_last_1min = 0; +int serial_host_checks_last_5min = 0; +int serial_host_checks_last_15min = 0; + +int active_service_checks_last_1min = 0; +int active_service_checks_last_5min = 0; +int active_service_checks_last_15min = 0; +int active_ondemand_service_checks_last_1min = 0; +int active_ondemand_service_checks_last_5min = 0; +int active_ondemand_service_checks_last_15min = 0; +int active_scheduled_service_checks_last_1min = 0; +int active_scheduled_service_checks_last_5min = 0; +int active_scheduled_service_checks_last_15min = 0; +int passive_service_checks_last_1min = 0; +int passive_service_checks_last_5min = 0; +int passive_service_checks_last_15min = 0; +int active_cached_service_checks_last_1min = 0; +int active_cached_service_checks_last_5min = 0; +int active_cached_service_checks_last_15min = 0; + +int external_commands_last_1min = 0; +int external_commands_last_5min = 0; +int external_commands_last_15min = 0; + +int total_external_command_buffer_slots = 0; +int used_external_command_buffer_slots = 0; +int high_external_command_buffer_slots = 0; + + + +int display_mrtg_values(void); +int display_stats(void); +int read_config_file(void); +int read_status_file(void); +void strip(char *); +void get_time_breakdown(unsigned long, int *, int *, int *, int *); +int read_nagiostats_file(void); + + +int main(int argc, char **argv) { + int result; + int error = FALSE; + int display_license = FALSE; + int display_help = FALSE; + int c; + +#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, 'L'}, + {"config", required_argument, 0, 'c'}, + {"statsfile", required_argument, 0, 's'}, + {"mrtg", no_argument, 0, 'm'}, + {"data", required_argument, 0, 'd'}, + {"delimiter", required_argument, 0, 'D'}, + {0, 0, 0, 0} + }; +#endif + + /* defaults */ + main_config_file = strdup(DEFAULT_CONFIG_FILE); + status_file = strdup(DEFAULT_STATUS_FILE); + + /* get all command line arguments */ + while(1) { + +#ifdef HAVE_GETOPT_H + c = getopt_long(argc, argv, "+hVLc:ms:d:D:", long_options, &option_index); +#else + c = getopt(argc, argv, "+hVLc:ms:d:D:"); +#endif + + if(c == -1 || c == EOF) + break; + + switch(c) { + + case '?': + case 'h': + display_help = TRUE; + break; + case 'V': + display_license = TRUE; + break; + case 'L': + display_license = TRUE; + break; + case 'c': + if(main_config_file) + free(main_config_file); + main_config_file = strdup(optarg); + break; + case 's': + nagiostats_file = strdup(optarg); + break; + case 'm': + mrtg_mode = TRUE; + break; + case 'd': + mrtg_variables = strdup(optarg); + break; + case 'D': + mrtg_delimiter = strdup(optarg); + break; + + default: + break; + } + + } + + if(mrtg_mode == FALSE) { + printf("\nNagios Stats %s\n", PROGRAM_VERSION); + printf("Copyright (c) 2003-2008 Ethan Galstad (www.nagios.org)\n"); + printf("Last Modified: %s\n", PROGRAM_MODIFICATION_DATE); + printf("License: GPL\n\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); + } + + /* 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]\n", argv[0]); + printf("\n"); + printf("Startup:\n"); + printf(" -V, --version display program version information and exit.\n"); + printf(" -L, --license display license information and exit.\n"); + printf(" -h, --help display usage information and exit.\n"); + printf("\n"); + printf("Input file:\n"); + printf(" -c, --config=FILE specifies location of main Nagios config file.\n"); + printf(" -s, --statsfile=FILE specifies alternate location of file to read Nagios\n"); + printf(" performance data from.\n"); + printf("\n"); + printf("Output:\n"); + printf(" -m, --mrtg display output in MRTG compatible format.\n"); + printf(" -d, --data=VARS comma-seperated list of variables to output in MRTG\n"); + printf(" (or compatible) format. See possible values below.\n"); + printf(" Percentages are rounded, times are in milliseconds.\n"); + printf(" -D, --delimiter=C character to use as delimiter in MRTG output mode.\n"); + printf(" Defaults to a newline.\n"); + printf("\n"); + printf("MRTG DATA VARIABLES (-d option):\n"); + printf(" PROGRUNTIME string with time Nagios process has been running.\n"); + printf(" PROGRUNTIMETT time Nagios process has been running (time_t format).\n"); + printf(" STATUSFILEAGE string with age of status data file.\n"); + printf(" STATUSFILEAGETT string with age of status data file (time_t format).\n"); + printf(" NAGIOSVERSION string with Nagios version.\n"); + printf(" NAGIOSPID pid number of Nagios deamon.\n"); + printf(" NAGIOSVERPID string with Nagios version and PID.\n"); + printf(" TOTCMDBUF total number of external command buffer slots available.\n"); + printf(" USEDCMDBUF number of external command buffer slots currently in use.\n"); + printf(" HIGHCMDBUF highest number of external command buffer slots ever in use.\n"); + printf(" NUMSERVICES total number of services.\n"); + printf(" NUMHOSTS total number of hosts.\n"); + printf(" NUMSVCOK number of services OK.\n"); + printf(" NUMSVCWARN number of services WARNING.\n"); + printf(" NUMSVCUNKN number of services UNKNOWN.\n"); + printf(" NUMSVCCRIT number of services CRITICAL.\n"); + printf(" NUMSVCPROB number of service problems (WARNING, UNKNOWN or CRITIAL).\n"); + printf(" NUMSVCCHECKED number of services that have been checked since start.\n"); + printf(" NUMSVCSCHEDULED number of services that are currently scheduled to be checked.\n"); + printf(" NUMSVCFLAPPING number of services that are currently flapping.\n"); + printf(" NUMSVCDOWNTIME number of services that are currently in downtime.\n"); + printf(" NUMHSTUP number of hosts UP.\n"); + printf(" NUMHSTDOWN number of hosts DOWN.\n"); + printf(" NUMHSTUNR number of hosts UNREACHABLE.\n"); + printf(" NUMHSTPROB number of host problems (DOWN or UNREACHABLE).\n"); + printf(" NUMHSTCHECKED number of hosts that have been checked since start.\n"); + printf(" NUMHSTSCHEDULED number of hosts that are currently scheduled to be checked.\n"); + printf(" NUMHSTFLAPPING number of hosts that are currently flapping.\n"); + printf(" NUMHSTDOWNTIME number of hosts that are currently in downtime.\n"); + printf(" NUMHSTACTCHKxM number of hosts actively checked in last 1/5/15/60 minutes.\n"); + printf(" NUMHSTPSVCHKxM number of hosts passively checked in last 1/5/15/60 minutes.\n"); + printf(" NUMSVCACTCHKxM number of services actively checked in last 1/5/15/60 minutes.\n"); + printf(" NUMSVCPSVCHKxM number of services passively checked in last 1/5/15/60 minutes.\n"); + printf(" xxxACTSVCLAT MIN/MAX/AVG active service check latency (ms).\n"); + printf(" xxxACTSVCEXT MIN/MAX/AVG active service check execution time (ms).\n"); + printf(" xxxACTSVCPSC MIN/MAX/AVG active service check %% state change.\n"); + printf(" xxxPSVSVCLAT MIN/MAX/AVG passive service check latency (ms).\n"); + printf(" xxxPSVSVCPSC MIN/MAX/AVG passive service check %% state change.\n"); + printf(" xxxSVCPSC MIN/MAX/AVG service check %% state change.\n"); + printf(" xxxACTHSTLAT MIN/MAX/AVG active host check latency (ms).\n"); + printf(" xxxACTHSTEXT MIN/MAX/AVG active host check execution time (ms).\n"); + printf(" xxxACTHSTPSC MIN/MAX/AVG active host check %% state change.\n"); + printf(" xxxPSVHSTLAT MIN/MAX/AVG passive host check latency (ms).\n"); + printf(" xxxPSVHSTPSC MIN/MAX/AVG passive host check %% state change.\n"); + printf(" xxxHSTPSC MIN/MAX/AVG host check %% state change.\n"); + printf(" NUMACTHSTCHECKSxM number of total active host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMOACTHSTCHECKSxM number of on-demand active host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMCACHEDHSTCHECKSxM number of cached host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMSACTHSTCHECKSxM number of scheduled active host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMPARHSTCHECKSxM number of parallel host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMSERHSTCHECKSxM number of serial host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMPSVHSTCHECKSxM number of passive host checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMACTSVCCHECKSxM number of total active service checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMOACTSVCCHECKSxM number of on-demand active service checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMCACHEDSVCCHECKSxM number of cached service checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMSACTSVCCHECKSxM number of scheduled active service checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMPSVSVCCHECKSxM number of passive service checks occuring in last 1/5/15 minutes.\n"); + printf(" NUMEXTCMDSxM number of external commands processed in last 1/5/15 minutes.\n"); + + printf("\n"); + printf(" Note: Replace x's in MRTG variable names with 'MIN', 'MAX', 'AVG', or the\n"); + printf(" the appropriate number (i.e. '1', '5', '15', or '60').\n"); + printf("\n"); + + exit(ERROR); + } + + /* read pre-processed stats file */ + if(nagiostats_file) { + result = read_nagiostats_file(); + if(result == ERROR && mrtg_mode == FALSE) { + printf("Error reading stats file '%s': %s\n", nagiostats_file, strerror(errno)); + return ERROR; + } + } + + /* else read the normal status file */ + else { + /* read main config file */ + result = read_config_file(); + if(result == ERROR && mrtg_mode == FALSE) { + printf("Error processing config file '%s'\n", main_config_file); + return ERROR; + } + + /* read status file */ + result = read_status_file(); + if(result == ERROR && mrtg_mode == FALSE) { + printf("Error reading status file '%s': %s\n", status_file, strerror(errno)); + return ERROR; + } + } + + /* display stats */ + if(mrtg_mode == FALSE) + display_stats(); + else + display_mrtg_values(); + + if(nagiostats_file); + free(nagiostats_file); + + /* Opsera patch - return based on error, because mrtg_mode was always returning OK */ + if(result == ERROR) + return ERROR; + else + return OK; + } + + + +int display_mrtg_values(void) { + char *temp_ptr; + time_t current_time; + unsigned long time_difference; + int days; + int hours; + int minutes; + int seconds; + + time(¤t_time); + + if(mrtg_variables == NULL) + return OK; + + /* process all variables */ + for(temp_ptr = strtok(mrtg_variables, ","); temp_ptr != NULL; temp_ptr = strtok(NULL, ",")) { + + if(!strcmp(temp_ptr, "PROGRUNTIME")) { + time_difference = (current_time - program_start); + get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); + printf("%dd %dh %dm %ds%s", days, hours, minutes, seconds, mrtg_delimiter); + } + else if(!strcmp(temp_ptr, "PROGRUNTIMETT")) { + time_difference = (current_time - program_start); + printf("%lu%s", time_difference, mrtg_delimiter); + } + else if(!strcmp(temp_ptr, "STATUSFILEAGE")) { + time_difference = (current_time - status_creation_date); + get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); + printf("%dd %dh %dm %ds%s", days, hours, minutes, seconds, mrtg_delimiter); + } + else if(!strcmp(temp_ptr, "STATUSFILEAGETT")) { + time_difference = (current_time - status_creation_date); + printf("%lu%s", time_difference, mrtg_delimiter); + } + else if(!strcmp(temp_ptr, "NAGIOSVERSION")) + printf("%s%s", status_version, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NAGIOSPID")) + printf("%lu%s", nagios_pid, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NAGIOSVERPID")) + printf("Nagios %s (pid=%lu)%s", status_version, nagios_pid, mrtg_delimiter); + + + else if(!strcmp(temp_ptr, "TOTCMDBUF")) + printf("%d%s", total_external_command_buffer_slots, mrtg_delimiter); + else if(!strcmp(temp_ptr, "USEDCMDBUF")) + printf("%d%s", used_external_command_buffer_slots, mrtg_delimiter); + else if(!strcmp(temp_ptr, "HIGHCMDBUF")) + printf("%d%s", high_external_command_buffer_slots, mrtg_delimiter); + + else if(!strcmp(temp_ptr, "NUMSERVICES")) + printf("%d%s", status_service_entries, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHOSTS")) + printf("%d%s", status_host_entries, mrtg_delimiter); + + /* active service check latency */ + else if(!strcmp(temp_ptr, "MINACTSVCLAT")) + printf("%d%s", (int)(min_active_service_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXACTSVCLAT")) + printf("%d%s", (int)(max_active_service_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGACTSVCLAT")) + printf("%d%s", (int)(average_active_service_latency * 1000), mrtg_delimiter); + + /* active service check execution time */ + else if(!strcmp(temp_ptr, "MINACTSVCEXT")) + printf("%d%s", (int)(min_active_service_execution_time * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXACTSVCEXT")) + printf("%d%s", (int)(max_active_service_execution_time * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGACTSVCEXT")) + printf("%d%s", (int)(average_active_service_execution_time * 1000), mrtg_delimiter); + + /* active service check percent state change */ + else if(!strcmp(temp_ptr, "MINACTSVCPSC")) + printf("%d%s", (int)min_active_service_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXACTSVCPSC")) + printf("%d%s", (int)max_active_service_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGACTSVCPSC")) + printf("%d%s", (int)average_active_service_state_change, mrtg_delimiter); + + /* passive service check latency */ + else if(!strcmp(temp_ptr, "MINPSVSVCLAT")) + printf("%d%s", (int)(min_passive_service_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXPSVSVCLAT")) + printf("%d%s", (int)(max_passive_service_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGPSVSVCLAT")) + printf("%d%s", (int)(average_passive_service_latency * 1000), mrtg_delimiter); + + /* passive service check percent state change */ + else if(!strcmp(temp_ptr, "MINPSVSVCPSC")) + printf("%d%s", (int)min_passive_service_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXPSVSVCPSC")) + printf("%d%s", (int)max_passive_service_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGPSVSVCPSC")) + printf("%d%s", (int)average_passive_service_state_change, mrtg_delimiter); + + /* service check percent state change */ + else if(!strcmp(temp_ptr, "MINSVCPSC")) + printf("%d%s", (int)min_service_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXSVCPSC")) + printf("%d%s", (int)max_service_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGSVCPSC")) + printf("%d%s", (int)average_service_state_change, mrtg_delimiter); + + /* active host check latency */ + else if(!strcmp(temp_ptr, "MINACTHSTLAT")) + printf("%d%s", (int)(min_active_host_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXACTHSTLAT")) + printf("%d%s", (int)(max_active_host_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGACTHSTLAT")) + printf("%d%s", (int)(average_active_host_latency * 1000), mrtg_delimiter); + + /* active host check execution time */ + else if(!strcmp(temp_ptr, "MINACTHSTEXT")) + printf("%d%s", (int)(min_active_host_execution_time * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXACTHSTEXT")) + printf("%d%s", (int)(max_active_host_execution_time * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGACTHSTEXT")) + printf("%d%s", (int)(average_active_host_execution_time * 1000), mrtg_delimiter); + + /* active host check percent state change */ + else if(!strcmp(temp_ptr, "MINACTHSTPSC")) + printf("%d%s", (int)min_active_host_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXACTHSTPSC")) + printf("%d%s", (int)max_active_host_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGACTHSTPSC")) + printf("%d%s", (int)average_active_host_state_change, mrtg_delimiter); + + /* passive host check latency */ + else if(!strcmp(temp_ptr, "MINPSVHSTLAT")) + printf("%d%s", (int)(min_passive_host_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXPSVHSTLAT")) + printf("%d%s", (int)(max_passive_host_latency * 1000), mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGPSVHSTLAT")) + printf("%d%s", (int)(average_passive_host_latency * 1000), mrtg_delimiter); + + /* passive host check percent state change */ + else if(!strcmp(temp_ptr, "MINPSVHSTPSC")) + printf("%d%s", (int)min_passive_host_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXPSVHSTPSC")) + printf("%d%s", (int)max_passive_host_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGPSVHSTPSC")) + printf("%d%s", (int)average_passive_host_state_change, mrtg_delimiter); + + /* host check percent state change */ + else if(!strcmp(temp_ptr, "MINHSTPSC")) + printf("%d%s", (int)min_host_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "MAXHSTPSC")) + printf("%d%s", (int)max_host_state_change, mrtg_delimiter); + else if(!strcmp(temp_ptr, "AVGHSTPSC")) + printf("%d%s", (int)average_host_state_change, mrtg_delimiter); + + /* active host checks over time */ + else if(!strcmp(temp_ptr, "NUMHSTACTCHK1M")) + printf("%d%s", active_hosts_checked_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTACTCHK5M")) + printf("%d%s", active_hosts_checked_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTACTCHK15M")) + printf("%d%s", active_hosts_checked_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTACTCHK60M")) + printf("%d%s", active_hosts_checked_last_1hour, mrtg_delimiter); + + /* passive host checks over time */ + else if(!strcmp(temp_ptr, "NUMHSTPSVCHK1M")) + printf("%d%s", passive_hosts_checked_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTPSVCHK5M")) + printf("%d%s", passive_hosts_checked_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTPSVCHK15M")) + printf("%d%s", passive_hosts_checked_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTPSVCHK60M")) + printf("%d%s", passive_hosts_checked_last_1hour, mrtg_delimiter); + + /* active service checks over time */ + else if(!strcmp(temp_ptr, "NUMSVCACTCHK1M")) + printf("%d%s", active_services_checked_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCACTCHK5M")) + printf("%d%s", active_services_checked_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCACTCHK15M")) + printf("%d%s", active_services_checked_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCACTCHK60M")) + printf("%d%s", active_services_checked_last_1hour, mrtg_delimiter); + + /* passive service checks over time */ + else if(!strcmp(temp_ptr, "NUMSVCPSVCHK1M")) + printf("%d%s", passive_services_checked_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCPSVCHK5M")) + printf("%d%s", passive_services_checked_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCPSVCHK15M")) + printf("%d%s", passive_services_checked_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCPSVCHK60M")) + printf("%d%s", passive_services_checked_last_1hour, mrtg_delimiter); + + /* host check statistics */ + else if(!strcmp(temp_ptr, "NUMACTHSTCHECKS1M")) + printf("%d%s", active_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMACTHSTCHECKS5M")) + printf("%d%s", active_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMACTHSTCHECKS15M")) + printf("%d%s", active_host_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMOACTHSTCHECKS1M")) + printf("%d%s", active_ondemand_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMOACTHSTCHECKS5M")) + printf("%d%s", active_ondemand_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMOACTHSTCHECKS15M")) + printf("%d%s", active_ondemand_host_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSACTHSTCHECKS1M")) + printf("%d%s", active_scheduled_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSACTHSTCHECKS5M")) + printf("%d%s", active_scheduled_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSACTHSTCHECKS15M")) + printf("%d%s", active_scheduled_host_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPARHSTCHECKS1M")) + printf("%d%s", parallel_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPARHSTCHECKS5M")) + printf("%d%s", parallel_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPARHSTCHECKS15M")) + printf("%d%s", parallel_host_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSERHSTCHECKS1M")) + printf("%d%s", serial_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSERHSTCHECKS5M")) + printf("%d%s", serial_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSERHSTCHECKS15M")) + printf("%d%s", serial_host_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPSVHSTCHECKS1M")) + printf("%d%s", passive_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPSVHSTCHECKS5M")) + printf("%d%s", passive_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPSVHSTCHECKS15M")) + printf("%d%s", passive_host_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMCACHEDHSTCHECKS1M")) + printf("%d%s", active_cached_host_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMCACHEDHSTCHECKS5M")) + printf("%d%s", active_cached_host_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMCACHEDHSTCHECKS15M")) + printf("%d%s", active_cached_host_checks_last_15min, mrtg_delimiter); + + /* service check statistics */ + else if(!strcmp(temp_ptr, "NUMACTSVCCHECKS1M")) + printf("%d%s", active_service_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMACTSVCCHECKS5M")) + printf("%d%s", active_service_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMACTSVCCHECKS15M")) + printf("%d%s", active_service_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMOACTSVCCHECKS1M")) + printf("%d%s", active_ondemand_service_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMOACTSVCCHECKS5M")) + printf("%d%s", active_ondemand_service_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMOACTSVCCHECKS15M")) + printf("%d%s", active_ondemand_service_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSACTSVCCHECKS1M")) + printf("%d%s", active_scheduled_service_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSACTSVCCHECKS5M")) + printf("%d%s", active_scheduled_service_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSACTSVCCHECKS15M")) + printf("%d%s", active_scheduled_service_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPSVSVCCHECKS1M")) + printf("%d%s", passive_service_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPSVSVCCHECKS5M")) + printf("%d%s", passive_service_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMPSVSVCCHECKS15M")) + printf("%d%s", passive_service_checks_last_15min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMCACHEDSVCCHECKS1M")) + printf("%d%s", active_cached_service_checks_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMCACHEDSVCCHECKS5M")) + printf("%d%s", active_cached_service_checks_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMCACHEDSVCCHECKS15M")) + printf("%d%s", active_cached_service_checks_last_15min, mrtg_delimiter); + + /* external command stats */ + else if(!strcmp(temp_ptr, "NUMEXTCMDS1M")) + printf("%d%s", external_commands_last_1min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMEXTCMDS5M")) + printf("%d%s", external_commands_last_5min, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMEXTCMDS15M")) + printf("%d%s", external_commands_last_15min, mrtg_delimiter); + + /* service states */ + else if(!strcmp(temp_ptr, "NUMSVCOK")) + printf("%d%s", services_ok, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCWARN")) + printf("%d%s", services_warning, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCUNKN")) + printf("%d%s", services_unknown, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCCRIT")) + printf("%d%s", services_critical, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCPROB")) + printf("%d%s", services_warning + services_unknown + services_critical, mrtg_delimiter); + + /* misc service info */ + else if(!strcmp(temp_ptr, "NUMSVCCHECKED")) + printf("%d%s", services_checked, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCSCHEDULED")) + printf("%d%s", services_scheduled, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCFLAPPING")) + printf("%d%s", services_flapping, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMSVCDOWNTIME")) + printf("%d%s", services_in_downtime, mrtg_delimiter); + + /* host states */ + else if(!strcmp(temp_ptr, "NUMHSTUP")) + printf("%d%s", hosts_up, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTDOWN")) + printf("%d%s", hosts_down, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTUNR")) + printf("%d%s", hosts_unreachable, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTPROB")) + printf("%d%s", hosts_down + hosts_unreachable, mrtg_delimiter); + + /* misc host info */ + else if(!strcmp(temp_ptr, "NUMHSTCHECKED")) + printf("%d%s", hosts_checked, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTSCHEDULED")) + printf("%d%s", hosts_scheduled, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTFLAPPING")) + printf("%d%s", hosts_flapping, mrtg_delimiter); + else if(!strcmp(temp_ptr, "NUMHSTDOWNTIME")) + printf("%d%s", hosts_in_downtime, mrtg_delimiter); + + else + printf("%s%s", temp_ptr, mrtg_delimiter); + } + + /* add a newline if necessary */ + if(strcmp(mrtg_delimiter, "\n")) + printf("\n"); + + return OK; + } + + +int display_stats(void) { + time_t current_time; + unsigned long time_difference; + int days; + int hours; + int minutes; + int seconds; + + time(¤t_time); + + printf("CURRENT STATUS DATA\n"); + printf("------------------------------------------------------\n"); + printf("Status File: %s\n", (nagiostats_file != NULL) ? nagiostats_file : status_file); + time_difference = (current_time - status_creation_date); + get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); + printf("Status File Age: %dd %dh %dm %ds\n", days, hours, minutes, seconds); + printf("Status File Version: %s\n", status_version); + printf("\n"); + time_difference = (current_time - program_start); + get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); + printf("Program Running Time: %dd %dh %dm %ds\n", days, hours, minutes, seconds); + printf("Nagios PID: %lu\n", nagios_pid); + printf("Used/High/Total Command Buffers: %d / %d / %d\n", used_external_command_buffer_slots, high_external_command_buffer_slots, total_external_command_buffer_slots); + printf("\n"); + printf("Total Services: %d\n", status_service_entries); + printf("Services Checked: %d\n", services_checked); + printf("Services Scheduled: %d\n", services_scheduled); + printf("Services Actively Checked: %d\n", active_service_checks); + printf("Services Passively Checked: %d\n", passive_service_checks); + printf("Total Service State Change: %.3f / %.3f / %.3f %%\n", min_service_state_change, max_service_state_change, average_service_state_change); + printf("Active Service Latency: %.3f / %.3f / %.3f sec\n", min_active_service_latency, max_active_service_latency, average_active_service_latency); + printf("Active Service Execution Time: %.3f / %.3f / %.3f sec\n", min_active_service_execution_time, max_active_service_execution_time, average_active_service_execution_time); + printf("Active Service State Change: %.3f / %.3f / %.3f %%\n", min_active_service_state_change, max_active_service_state_change, average_active_service_state_change); + printf("Active Services Last 1/5/15/60 min: %d / %d / %d / %d\n", active_services_checked_last_1min, active_services_checked_last_5min, active_services_checked_last_15min, active_services_checked_last_1hour); + printf("Passive Service Latency: %.3f / %.3f / %.3f sec\n", min_passive_service_latency, max_passive_service_latency, average_passive_service_latency); + printf("Passive Service State Change: %.3f / %.3f / %.3f %%\n", min_passive_service_state_change, max_passive_service_state_change, average_passive_service_state_change); + printf("Passive Services Last 1/5/15/60 min: %d / %d / %d / %d\n", passive_services_checked_last_1min, passive_services_checked_last_5min, passive_services_checked_last_15min, passive_services_checked_last_1hour); + printf("Services Ok/Warn/Unk/Crit: %d / %d / %d / %d\n", services_ok, services_warning, services_unknown, services_critical); + printf("Services Flapping: %d\n", services_flapping); + printf("Services In Downtime: %d\n", services_in_downtime); + printf("\n"); + printf("Total Hosts: %d\n", status_host_entries); + printf("Hosts Checked: %d\n", hosts_checked); + printf("Hosts Scheduled: %d\n", hosts_scheduled); + printf("Hosts Actively Checked: %d\n", active_host_checks); + printf("Host Passively Checked: %d\n", passive_host_checks); + printf("Total Host State Change: %.3f / %.3f / %.3f %%\n", min_host_state_change, max_host_state_change, average_host_state_change); + printf("Active Host Latency: %.3f / %.3f / %.3f sec\n", min_active_host_latency, max_active_host_latency, average_active_host_latency); + printf("Active Host Execution Time: %.3f / %.3f / %.3f sec\n", min_active_host_execution_time, max_active_host_execution_time, average_active_host_execution_time); + printf("Active Host State Change: %.3f / %.3f / %.3f %%\n", min_active_host_state_change, max_active_host_state_change, average_active_host_state_change); + printf("Active Hosts Last 1/5/15/60 min: %d / %d / %d / %d\n", active_hosts_checked_last_1min, active_hosts_checked_last_5min, active_hosts_checked_last_15min, active_hosts_checked_last_1hour); + printf("Passive Host Latency: %.3f / %.3f / %.3f sec\n", min_passive_host_latency, max_passive_host_latency, average_passive_host_latency); + printf("Passive Host State Change: %.3f / %.3f / %.3f %%\n", min_passive_host_state_change, max_passive_host_state_change, average_passive_host_state_change); + printf("Passive Hosts Last 1/5/15/60 min: %d / %d / %d / %d\n", passive_hosts_checked_last_1min, passive_hosts_checked_last_5min, passive_hosts_checked_last_15min, passive_hosts_checked_last_1hour); + printf("Hosts Up/Down/Unreach: %d / %d / %d\n", hosts_up, hosts_down, hosts_unreachable); + printf("Hosts Flapping: %d\n", hosts_flapping); + printf("Hosts In Downtime: %d\n", hosts_in_downtime); + printf("\n"); + printf("Active Host Checks Last 1/5/15 min: %d / %d / %d\n", active_host_checks_last_1min, active_host_checks_last_5min, active_host_checks_last_15min); + printf(" Scheduled: %d / %d / %d\n", active_scheduled_host_checks_last_1min, active_scheduled_host_checks_last_5min, active_scheduled_host_checks_last_15min); + printf(" On-demand: %d / %d / %d\n", active_ondemand_host_checks_last_1min, active_ondemand_host_checks_last_5min, active_ondemand_host_checks_last_15min); + printf(" Parallel: %d / %d / %d\n", parallel_host_checks_last_1min, parallel_host_checks_last_5min, parallel_host_checks_last_15min); + printf(" Serial: %d / %d / %d\n", serial_host_checks_last_1min, serial_host_checks_last_5min, serial_host_checks_last_15min); + printf(" Cached: %d / %d / %d\n", active_cached_host_checks_last_1min, active_cached_host_checks_last_5min, active_cached_host_checks_last_15min); + printf("Passive Host Checks Last 1/5/15 min: %d / %d / %d\n", passive_host_checks_last_1min, passive_host_checks_last_5min, passive_host_checks_last_15min); + + printf("Active Service Checks Last 1/5/15 min: %d / %d / %d\n", active_service_checks_last_1min, active_service_checks_last_5min, active_service_checks_last_15min); + printf(" Scheduled: %d / %d / %d\n", active_scheduled_service_checks_last_1min, active_scheduled_service_checks_last_5min, active_scheduled_service_checks_last_15min); + printf(" On-demand: %d / %d / %d\n", active_ondemand_service_checks_last_1min, active_ondemand_service_checks_last_5min, active_ondemand_service_checks_last_15min); + printf(" Cached: %d / %d / %d\n", active_cached_service_checks_last_1min, active_cached_service_checks_last_5min, active_cached_service_checks_last_15min); + printf("Passive Service Checks Last 1/5/15 min: %d / %d / %d\n", passive_service_checks_last_1min, passive_service_checks_last_5min, passive_service_checks_last_15min); + printf("\n"); + printf("External Commands Last 1/5/15 min: %d / %d / %d\n", external_commands_last_1min, external_commands_last_5min, external_commands_last_15min); + printf("\n"); + printf("\n"); + + + /* + printf("CURRENT COMMENT DATA\n"); + printf("----------------------------------------------------\n"); + printf("\n"); + printf("\n"); + + printf("CURRENT DOWNTIME DATA\n"); + printf("----------------------------------------------------\n"); + printf("\n"); + */ + + return OK; + } + + +int read_config_file(void) { + char temp_buffer[MAX_INPUT_BUFFER]; + FILE *fp; + char *var; + char *val; + + + fp = fopen(main_config_file, "r"); + if(fp == NULL) + return ERROR; + + /* read all lines from the main nagios config file */ + while(fgets(temp_buffer, sizeof(temp_buffer) - 1, fp)) { + + strip(temp_buffer); + + /* skip blank lines and comments */ + if(temp_buffer[0] == '#' || temp_buffer[0] == '\x0') + continue; + + var = strtok(temp_buffer, "="); + val = strtok(NULL, "\n"); + if(val == NULL) + continue; + + if(!strcmp(var, "status_file") || !strcmp(var, "status_log") || !strcmp(var, "xsddefault_status_log")) { + if(status_file) + free(status_file); + status_file = strdup(val); + } + + } + + fclose(fp); + + return OK; + } + + +int read_status_file(void) { + char temp_buffer[MAX_INPUT_BUFFER]; + FILE *fp = NULL; + int data_type = STATUS_NO_DATA; + char *var = NULL; + char *val = NULL; + char *temp_ptr = NULL; + time_t current_time; + unsigned long time_difference = 0L; + + double execution_time = 0.0; + double latency = 0.0; + int check_type = SERVICE_CHECK_ACTIVE; + int current_state = STATE_OK; + double state_change = 0.0; + int is_flapping = FALSE; + int downtime_depth = 0; + time_t last_check = 0L; + int should_be_scheduled = TRUE; + int has_been_checked = TRUE; + + + time(¤t_time); + + fp = fopen(status_file, "r"); + if(fp == NULL) + return ERROR; + + /* read all lines in the status file */ + while(fgets(temp_buffer, sizeof(temp_buffer) - 1, fp)) { + + /* skip blank lines and comments */ + if(temp_buffer[0] == '#' || temp_buffer[0] == '\x0') + continue; + + strip(temp_buffer); + + /* start of definition */ + if(!strcmp(temp_buffer, "servicestatus {")) { + data_type = STATUS_SERVICE_DATA; + status_service_entries++; + } + else if(!strcmp(temp_buffer, "hoststatus {")) { + data_type = STATUS_HOST_DATA; + status_host_entries++; + } + else if(!strcmp(temp_buffer, "info {")) + data_type = STATUS_INFO_DATA; + else if(!strcmp(temp_buffer, "programstatus {")) + data_type = STATUS_PROGRAM_DATA; + + + /* end of definition */ + else if(!strcmp(temp_buffer, "}")) { + + switch(data_type) { + + case STATUS_INFO_DATA: + break; + + case STATUS_PROGRAM_DATA: + /* 02-15-2008 exclude cached host checks from total (they were ondemand checks that never actually executed) */ + active_host_checks_last_1min = active_scheduled_host_checks_last_1min + active_ondemand_host_checks_last_1min; + active_host_checks_last_5min = active_scheduled_host_checks_last_5min + active_ondemand_host_checks_last_5min; + active_host_checks_last_15min = active_scheduled_host_checks_last_15min + active_ondemand_host_checks_last_15min; + + /* 02-15-2008 exclude cached service checks from total (they were ondemand checks that never actually executed) */ + active_service_checks_last_1min = active_scheduled_service_checks_last_1min + active_ondemand_service_checks_last_1min; + active_service_checks_last_5min = active_scheduled_service_checks_last_5min + active_ondemand_service_checks_last_5min; + active_service_checks_last_15min = active_scheduled_service_checks_last_15min + active_ondemand_service_checks_last_15min; + break; + + case STATUS_HOST_DATA: + average_host_state_change = (((average_host_state_change * ((double)status_host_entries - 1.0)) + state_change) / (double)status_host_entries); + if(have_min_host_state_change == FALSE || min_host_state_change > state_change) { + have_min_host_state_change = TRUE; + min_host_state_change = state_change; + } + if(have_max_host_state_change == FALSE || max_host_state_change < state_change) { + have_max_host_state_change = TRUE; + max_host_state_change = state_change; + } + if(check_type == HOST_CHECK_ACTIVE) { + active_host_checks++; + average_active_host_latency = (((average_active_host_latency * ((double)active_host_checks - 1.0)) + latency) / (double)active_host_checks); + if(have_min_active_host_latency == FALSE || min_active_host_latency > latency) { + have_min_active_host_latency = TRUE; + min_active_host_latency = latency; + } + if(have_max_active_host_latency == FALSE || max_active_host_latency < latency) { + have_max_active_host_latency = TRUE; + max_active_host_latency = latency; + } + average_active_host_execution_time = (((average_active_host_execution_time * ((double)active_host_checks - 1.0)) + execution_time) / (double)active_host_checks); + if(have_min_active_host_execution_time == FALSE || min_active_host_execution_time > execution_time) { + have_min_active_host_execution_time = TRUE; + min_active_host_execution_time = execution_time; + } + if(have_max_active_host_execution_time == FALSE || max_active_host_execution_time < execution_time) { + have_max_active_host_execution_time = TRUE; + max_active_host_execution_time = execution_time; + } + average_active_host_state_change = (((average_active_host_state_change * ((double)active_host_checks - 1.0)) + state_change) / (double)active_host_checks); + if(have_min_active_host_state_change == FALSE || min_active_host_state_change > state_change) { + have_min_active_host_state_change = TRUE; + min_active_host_state_change = state_change; + } + if(have_max_active_host_state_change == FALSE || max_active_host_state_change < state_change) { + have_max_active_host_state_change = TRUE; + max_active_host_state_change = state_change; + } + time_difference = current_time - last_check; + if(time_difference <= 3600) + active_hosts_checked_last_1hour++; + if(time_difference <= 900) + active_hosts_checked_last_15min++; + if(time_difference <= 300) + active_hosts_checked_last_5min++; + if(time_difference <= 60) + active_hosts_checked_last_1min++; + } + else { + passive_host_checks++; + average_passive_host_latency = (((average_passive_host_latency * ((double)passive_host_checks - 1.0)) + latency) / (double)passive_host_checks); + if(have_min_passive_host_latency == FALSE || min_passive_host_latency > latency) { + have_min_passive_host_latency = TRUE; + min_passive_host_latency = latency; + } + if(have_max_passive_host_latency == FALSE || max_passive_host_latency < latency) { + have_max_passive_host_latency = TRUE; + max_passive_host_latency = latency; + } + average_passive_host_state_change = (((average_passive_host_state_change * ((double)passive_host_checks - 1.0)) + state_change) / (double)passive_host_checks); + if(have_min_passive_host_state_change == FALSE || min_passive_host_state_change > state_change) { + have_min_passive_host_state_change = TRUE; + min_passive_host_state_change = state_change; + } + if(have_max_passive_host_state_change == FALSE || max_passive_host_state_change < state_change) { + have_max_passive_host_state_change = TRUE; + max_passive_host_state_change = state_change; + } + time_difference = current_time - last_check; + if(time_difference <= 3600) + passive_hosts_checked_last_1hour++; + if(time_difference <= 900) + passive_hosts_checked_last_15min++; + if(time_difference <= 300) + passive_hosts_checked_last_5min++; + if(time_difference <= 60) + passive_hosts_checked_last_1min++; + } + switch(current_state) { + case HOST_UP: + hosts_up++; + break; + case HOST_DOWN: + hosts_down++; + break; + case HOST_UNREACHABLE: + hosts_unreachable++; + break; + default: + break; + } + if(is_flapping == TRUE) + hosts_flapping++; + if(downtime_depth > 0) + hosts_in_downtime++; + if(has_been_checked == TRUE) + hosts_checked++; + if(should_be_scheduled == TRUE) + hosts_scheduled++; + break; + + case STATUS_SERVICE_DATA: + average_service_state_change = (((average_service_state_change * ((double)status_service_entries - 1.0)) + state_change) / (double)status_service_entries); + if(have_min_service_state_change == FALSE || min_service_state_change > state_change) { + have_min_service_state_change = TRUE; + min_service_state_change = state_change; + } + if(have_max_service_state_change == FALSE || max_service_state_change < state_change) { + have_max_service_state_change = TRUE; + max_service_state_change = state_change; + } + if(check_type == SERVICE_CHECK_ACTIVE) { + active_service_checks++; + average_active_service_latency = (((average_active_service_latency * ((double)active_service_checks - 1.0)) + latency) / (double)active_service_checks); + if(have_min_active_service_latency == FALSE || min_active_service_latency > latency) { + have_min_active_service_latency = TRUE; + min_active_service_latency = latency; + } + if(have_max_active_service_latency == FALSE || max_active_service_latency < latency) { + have_max_active_service_latency = TRUE; + max_active_service_latency = latency; + } + average_active_service_execution_time = (((average_active_service_execution_time * ((double)active_service_checks - 1.0)) + execution_time) / (double)active_service_checks); + if(have_min_active_service_execution_time == FALSE || min_active_service_execution_time > execution_time) { + have_min_active_service_execution_time = TRUE; + min_active_service_execution_time = execution_time; + } + if(have_max_active_service_execution_time == FALSE || max_active_service_execution_time < execution_time) { + have_max_active_service_execution_time = TRUE; + max_active_service_execution_time = execution_time; + } + average_active_service_state_change = (((average_active_service_state_change * ((double)active_service_checks - 1.0)) + state_change) / (double)active_service_checks); + if(have_min_active_service_state_change == FALSE || min_active_service_state_change > state_change) { + have_min_active_service_state_change = TRUE; + min_active_service_state_change = state_change; + } + if(have_max_active_service_state_change == FALSE || max_active_service_state_change < state_change) { + have_max_active_service_state_change = TRUE; + max_active_service_state_change = state_change; + } + time_difference = current_time - last_check; + if(time_difference <= 3600) + active_services_checked_last_1hour++; + if(time_difference <= 900) + active_services_checked_last_15min++; + if(time_difference <= 300) + active_services_checked_last_5min++; + if(time_difference <= 60) + active_services_checked_last_1min++; + } + else { + passive_service_checks++; + average_passive_service_latency = (((average_passive_service_latency * ((double)passive_service_checks - 1.0)) + latency) / (double)passive_service_checks); + if(have_min_passive_service_latency == FALSE || min_passive_service_latency > latency) { + have_min_passive_service_latency = TRUE; + min_passive_service_latency = latency; + } + if(have_max_passive_service_latency == FALSE || max_passive_service_latency < latency) { + have_max_passive_service_latency = TRUE; + max_passive_service_latency = latency; + } + average_passive_service_state_change = (((average_passive_service_state_change * ((double)passive_service_checks - 1.0)) + state_change) / (double)passive_service_checks); + if(have_min_passive_service_state_change == FALSE || min_passive_service_state_change > state_change) { + have_min_passive_service_state_change = TRUE; + min_passive_service_state_change = state_change; + } + if(have_max_passive_service_state_change == FALSE || max_passive_service_state_change < state_change) { + have_max_passive_service_state_change = TRUE; + max_passive_service_state_change = state_change; + } + time_difference = current_time - last_check; + if(time_difference <= 3600) + passive_services_checked_last_1hour++; + if(time_difference <= 900) + passive_services_checked_last_15min++; + if(time_difference <= 300) + passive_services_checked_last_5min++; + if(time_difference <= 60) + passive_services_checked_last_1min++; + } + switch(current_state) { + case STATE_OK: + services_ok++; + break; + case STATE_WARNING: + services_warning++; + break; + case STATE_UNKNOWN: + services_unknown++; + break; + case STATE_CRITICAL: + services_critical++; + break; + default: + break; + } + if(is_flapping == TRUE) + services_flapping++; + if(downtime_depth > 0) + services_in_downtime++; + if(has_been_checked == TRUE) + services_checked++; + if(should_be_scheduled == TRUE) + services_scheduled++; + break; + + default: + break; + } + + data_type = STATUS_NO_DATA; + + execution_time = 0.0; + latency = 0.0; + check_type = 0; + current_state = 0; + state_change = 0.0; + is_flapping = FALSE; + downtime_depth = 0; + last_check = (time_t)0; + has_been_checked = FALSE; + should_be_scheduled = FALSE; + } + + + /* inside definition */ + else if(data_type != STATUS_NO_DATA) { + + var = strtok(temp_buffer, "="); + val = strtok(NULL, "\n"); + if(val == NULL) + continue; + + switch(data_type) { + + case STATUS_INFO_DATA: + if(!strcmp(var, "created")) + status_creation_date = strtoul(val, NULL, 10); + else if(!strcmp(var, "version")) + status_version = strdup(val); + break; + + case STATUS_PROGRAM_DATA: + if(!strcmp(var, "program_start")) + program_start = strtoul(val, NULL, 10); + else if(!strcmp(var, "total_external_command_buffer_slots")) + total_external_command_buffer_slots = atoi(val); + else if(!strcmp(var, "used_external_command_buffer_slots")) + used_external_command_buffer_slots = atoi(val); + else if(!strcmp(var, "high_external_command_buffer_slots")) + high_external_command_buffer_slots = atoi(val); + else if(!strcmp(var, "nagios_pid")) + nagios_pid = strtoul(val, NULL, 10); + else if(!strcmp(var, "active_scheduled_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_scheduled_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "active_ondemand_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_ondemand_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "cached_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_cached_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "passive_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + passive_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "active_scheduled_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_scheduled_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "active_ondemand_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_ondemand_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "cached_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_cached_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "passive_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + passive_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "external_command_stats")) { + if((temp_ptr = strtok(val, ","))) + external_commands_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + external_commands_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + external_commands_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "parallel_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + parallel_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + parallel_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + parallel_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "serial_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + serial_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + serial_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + serial_host_checks_last_15min = atoi(temp_ptr); + } + break; + + case STATUS_HOST_DATA: + if(!strcmp(var, "check_execution_time")) + execution_time = strtod(val, NULL); + else if(!strcmp(var, "check_latency")) + latency = strtod(val, NULL); + else if(!strcmp(var, "percent_state_change")) + state_change = strtod(val, NULL); + else if(!strcmp(var, "check_type")) + check_type = atoi(val); + else if(!strcmp(var, "current_state")) + current_state = atoi(val); + else if(!strcmp(var, "is_flapping")) + is_flapping = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "scheduled_downtime_depth")) + downtime_depth = atoi(val); + else if(!strcmp(var, "last_check")) + last_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "has_been_checked")) + has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "should_be_scheduled")) + should_be_scheduled = (atoi(val) > 0) ? TRUE : FALSE; + break; + + case STATUS_SERVICE_DATA: + if(!strcmp(var, "check_execution_time")) + execution_time = strtod(val, NULL); + else if(!strcmp(var, "check_latency")) + latency = strtod(val, NULL); + else if(!strcmp(var, "percent_state_change")) + state_change = strtod(val, NULL); + else if(!strcmp(var, "check_type")) + check_type = atoi(val); + else if(!strcmp(var, "current_state")) + current_state = atoi(val); + else if(!strcmp(var, "is_flapping")) + is_flapping = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "scheduled_downtime_depth")) + downtime_depth = atoi(val); + else if(!strcmp(var, "last_check")) + last_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "has_been_checked")) + has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "should_be_scheduled")) + should_be_scheduled = (atoi(val) > 0) ? TRUE : FALSE; + break; + + default: + break; + } + + } + } + + fclose(fp); + + return OK; + } + + +int read_nagiostats_file(void) { + char temp_buffer[MAX_INPUT_BUFFER]; + FILE *fp = NULL; + char *var = NULL; + char *val = NULL; + char *temp_ptr = NULL; + time_t current_time; + + time(¤t_time); + + fp = fopen(nagiostats_file, "r"); + if(fp == NULL) + return ERROR; + + /* read all lines in the status file */ + while(fgets(temp_buffer, sizeof(temp_buffer) - 1, fp)) { + + /* skip comments */ + if(temp_buffer[0] == '#') + continue; + + strip(temp_buffer); + + var = strtok(temp_buffer, "="); + val = strtok(NULL, "\n"); + if(val == NULL) + continue; + + /**** INFO ****/ + if(!strcmp(var, "created")) + status_creation_date = strtoul(val, NULL, 10); + else if(!strcmp(var, "nagios_version")) + status_version = strdup(val); + + /**** PROGRAM INFO ****/ + else if(!strcmp(var, "program_start")) + program_start = strtoul(val, NULL, 10); + else if(!strcmp(var, "total_external_command_buffer_slots")) + total_external_command_buffer_slots = atoi(val); + else if(!strcmp(var, "used_external_command_buffer_slots")) + used_external_command_buffer_slots = atoi(val); + else if(!strcmp(var, "high_external_command_buffer_slots")) + high_external_command_buffer_slots = atoi(val); + else if(!strcmp(var, "nagios_pid")) + nagios_pid = strtoul(val, NULL, 10); + else if(!strcmp(var, "active_scheduled_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_scheduled_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "active_ondemand_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_ondemand_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "cached_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_cached_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "passive_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + passive_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "active_scheduled_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_scheduled_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_scheduled_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "active_ondemand_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_ondemand_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_ondemand_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "cached_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + active_cached_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_cached_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "passive_service_check_stats")) { + if((temp_ptr = strtok(val, ","))) + passive_service_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_service_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_service_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "external_command_stats")) { + if((temp_ptr = strtok(val, ","))) + external_commands_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + external_commands_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + external_commands_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "parallel_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + parallel_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + parallel_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + parallel_host_checks_last_15min = atoi(temp_ptr); + } + else if(!strcmp(var, "serial_host_check_stats")) { + if((temp_ptr = strtok(val, ","))) + serial_host_checks_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + serial_host_checks_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + serial_host_checks_last_15min = atoi(temp_ptr); + } + + /***** HOST INFO *****/ + + else if(!strcmp(var, "total_hosts")) + status_host_entries = atoi(val); + else if(!strcmp(var, "hosts_checked")) + hosts_checked = atoi(val); + else if(!strcmp(var, "hosts_scheduled")) + hosts_scheduled = atoi(val); + else if(!strcmp(var, "hosts_flapping")) + hosts_flapping = atoi(val); + else if(!strcmp(var, "hosts_in_downtime")) + hosts_in_downtime = atoi(val); + else if(!strcmp(var, "hosts_up")) + hosts_up = atoi(val); + else if(!strcmp(var, "hosts_down")) + hosts_down = atoi(val); + else if(!strcmp(var, "hosts_unreachable")) + hosts_unreachable = atoi(val); + else if(!strcmp(var, "hosts_actively_checked")) + active_host_checks = atoi(val); + else if(!strcmp(var, "hosts_passively_checked")) + passive_host_checks = atoi(val); + else if(!strcmp(var, "total_host_state_change")) { + if((temp_ptr = strtok(val, ","))) + min_host_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_host_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_host_state_change = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_host_latency")) { + if((temp_ptr = strtok(val, ","))) + min_active_host_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_active_host_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_active_host_latency = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_host_execution_time")) { + if((temp_ptr = strtok(val, ","))) + min_active_host_execution_time = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_active_host_execution_time = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_active_host_execution_time = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_host_state_change")) { + if((temp_ptr = strtok(val, ","))) + min_active_host_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_active_host_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_active_host_state_change = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_hosts_last_x")) { + if((temp_ptr = strtok(val, ","))) + active_hosts_checked_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_hosts_checked_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_hosts_checked_last_15min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_hosts_checked_last_1hour = atoi(temp_ptr); + } + else if(!strcmp(var, "passive_host_latency")) { + if((temp_ptr = strtok(val, ","))) + min_passive_host_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_passive_host_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_passive_host_latency = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "passive_host_state_change")) { + if((temp_ptr = strtok(val, ","))) + min_passive_host_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_passive_host_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_passive_host_state_change = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "passive_hosts_last_x")) { + if((temp_ptr = strtok(val, ","))) + passive_hosts_checked_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_hosts_checked_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_hosts_checked_last_15min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_hosts_checked_last_1hour = atoi(temp_ptr); + } + + + /***** SERVICE INFO *****/ + + else if(!strcmp(var, "total_services")) + status_service_entries = atoi(val); + else if(!strcmp(var, "services_checked")) + services_checked = atoi(val); + else if(!strcmp(var, "services_scheduled")) + services_scheduled = atoi(val); + else if(!strcmp(var, "services_flapping")) + services_flapping = atoi(val); + else if(!strcmp(var, "services_in_downtime")) + services_in_downtime = atoi(val); + else if(!strcmp(var, "services_ok")) + services_ok = atoi(val); + else if(!strcmp(var, "services_warning")) + services_warning = atoi(val); + else if(!strcmp(var, "services_critical")) + services_critical = atoi(val); + else if(!strcmp(var, "services_unknown")) + services_unknown = atoi(val); + else if(!strcmp(var, "services_actively_checked")) + active_service_checks = atoi(val); + else if(!strcmp(var, "services_passively_checked")) + passive_service_checks = atoi(val); + else if(!strcmp(var, "total_service_state_change")) { + if((temp_ptr = strtok(val, ","))) + min_service_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_service_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_service_state_change = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_service_latency")) { + if((temp_ptr = strtok(val, ","))) + min_active_service_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_active_service_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_active_service_latency = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_service_execution_time")) { + if((temp_ptr = strtok(val, ","))) + min_active_service_execution_time = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_active_service_execution_time = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_active_service_execution_time = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_service_state_change")) { + if((temp_ptr = strtok(val, ","))) + min_active_service_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_active_service_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_active_service_state_change = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "active_services_last_x")) { + if((temp_ptr = strtok(val, ","))) + active_services_checked_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_services_checked_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_services_checked_last_15min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + active_services_checked_last_1hour = atoi(temp_ptr); + } + else if(!strcmp(var, "passive_service_latency")) { + if((temp_ptr = strtok(val, ","))) + min_passive_service_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_passive_service_latency = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_passive_service_latency = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "passive_service_state_change")) { + if((temp_ptr = strtok(val, ","))) + min_passive_service_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + max_passive_service_state_change = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ","))) + average_passive_service_state_change = strtod(temp_ptr, NULL); + } + else if(!strcmp(var, "passive_services_last_x")) { + if((temp_ptr = strtok(val, ","))) + passive_services_checked_last_1min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_services_checked_last_5min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_services_checked_last_15min = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ","))) + passive_services_checked_last_1hour = atoi(temp_ptr); + } + } + + fclose(fp); + + /* 02-15-2008 exclude cached host checks from total (they were ondemand checks that never actually executed) */ + active_host_checks_last_1min = active_scheduled_host_checks_last_1min + active_ondemand_host_checks_last_1min; + active_host_checks_last_5min = active_scheduled_host_checks_last_5min + active_ondemand_host_checks_last_5min; + active_host_checks_last_15min = active_scheduled_host_checks_last_15min + active_ondemand_host_checks_last_15min; + + /* 02-15-2008 exclude cached service checks from total (they were ondemand checks that never actually executed) */ + active_service_checks_last_1min = active_scheduled_service_checks_last_1min + active_ondemand_service_checks_last_1min; + active_service_checks_last_5min = active_scheduled_service_checks_last_5min + active_ondemand_service_checks_last_5min; + active_service_checks_last_15min = active_scheduled_service_checks_last_15min + active_ondemand_service_checks_last_15min; + + return OK; + } + + +/* strip newline, carriage return, and tab characters from beginning and end of a string */ +void strip(char *buffer) { + register int x; + register int y; + register int z; + + if(buffer == NULL || buffer[0] == '\x0') + return; + + /* strip end of string */ + y = (int)strlen(buffer); + for(x = y - 1; x >= 0; x--) { + if(buffer[x] == ' ' || buffer[x] == '\n' || buffer[x] == '\r' || buffer[x] == '\t' || buffer[x] == 13) + buffer[x] = '\x0'; + else + break; + } + + /* strip beginning of string (by shifting) */ + y = (int)strlen(buffer); + for(x = 0; x < y; x++) { + if(buffer[x] == ' ' || buffer[x] == '\n' || buffer[x] == '\r' || buffer[x] == '\t' || buffer[x] == 13) + continue; + else + break; + } + if(x > 0) { + for(z = x; z < y; z++) + buffer[z - x] = buffer[z]; + buffer[y - x] = '\x0'; + } + + return; + } + + + +/* 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; + + return; + } + diff --git a/base/nebmods.c b/base/nebmods.c new file mode 100644 index 0000000..5b7dca7 --- /dev/null +++ b/base/nebmods.c @@ -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 diff --git a/base/netutils.c b/base/netutils.c new file mode 100644 index 0000000..2b7f6c2 --- /dev/null +++ b/base/netutils.c @@ -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; + } diff --git a/base/notifications.c b/base/notifications.c new file mode 100644 index 0000000..ffe3b68 --- /dev/null +++ b/base/notifications.c @@ -0,0 +1,2170 @@ +/***************************************************************************** + * + * NOTIFICATIONS.C - Service and host notification functions for Nagios + * + * Copyright (c) 2009-2010 Nagios Core Development Team and Community Contributors + * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 08-04-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/objects.h" +#include "../include/statusdata.h" +#include "../include/macros.h" +#include "../include/nagios.h" +#include "../include/broker.h" +#include "../include/neberrors.h" + +extern notification *notification_list; +extern contact *contact_list; +extern serviceescalation *serviceescalation_list; +extern hostescalation *hostescalation_list; + +extern time_t program_start; + +extern int interval_length; +extern int log_notifications; + +extern int enable_notifications; + +extern int notification_timeout; + +extern unsigned long next_notification_id; + +extern char *generic_summary; + + + +/******************************************************************/ +/***************** SERVICE NOTIFICATION FUNCTIONS *****************/ +/******************************************************************/ + + +/* notify contacts about a service problem or recovery */ +int service_notification(service *svc, int type, char *not_author, char *not_data, int options) { + host *temp_host = NULL; + notification *temp_notification = NULL; + contact *temp_contact = NULL; + time_t current_time; + struct timeval start_time; + struct timeval end_time; + int escalated = FALSE; + int result = OK; + int contacts_notified = 0; + int increment_notification_number = FALSE; + nagios_macros mac; + int neb_result; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "service_notification()\n"); + + /* get the current time */ + time(¤t_time); + gettimeofday(&start_time, NULL); + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "** Service Notification Attempt ** Host: '%s', Service: '%s', Type: %d, Options: %d, Current State: %d, Last Notification: %s", svc->host_name, svc->description, type, options, svc->current_state, ctime(&svc->last_notification)); + + /* if we couldn't find the host, return an error */ + if((temp_host = svc->host_ptr) == NULL) { + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "Couldn't find the host associated with this service, so we won't send a notification!\n"); + return ERROR; + } + + /* check the viability of sending out a service notification */ + if(check_service_notification_viability(svc, type, options) == ERROR) { + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "Notification viability test failed. No notification will be sent out.\n"); + return OK; + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "Notification viability test passed.\n"); + + /* should the notification number be increased? */ + if(type == NOTIFICATION_NORMAL || (options & NOTIFICATION_OPTION_INCREMENT)) { + svc->current_notification_number++; + increment_notification_number = TRUE; + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Current notification number: %d (%s)\n", svc->current_notification_number, (increment_notification_number == TRUE) ? "incremented" : "unchanged"); + + /* save and increase the current notification id */ + svc->current_notification_id = next_notification_id; + next_notification_id++; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Creating list of contacts to be notified.\n"); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + neb_result = broker_notification_data(NEBTYPE_NOTIFICATION_START, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_NOTIFICATION, type, start_time, end_time, (void *)svc, not_author, not_data, escalated, 0, NULL); + if(NEBERROR_CALLBACKCANCEL == neb_result) { + free_notification_list(); + return ERROR; + } + else if(NEBERROR_CALLBACKOVERRIDE == neb_result) { + free_notification_list(); + return OK; + } +#endif + + /* allocate memory for macros */ + memset(&mac, 0, sizeof(mac)); + + /* create the contact notification list for this service */ + + /* 2011-11-01 MF: + check viability before adding a contact + to the notification list, requires type + this prevents us from running through all + the steps until notify_contact_of_host|service + is reached. furthermore the $NOTIFICATIONRECIPIENTS$ + macro only gets populated with actual recipients, + not all contacts assigned to that host|service. + + note: checks against timeperiod will happen now(), + and not when the notification is actually being sent. + + original patch by Opsview Team + */ + create_notification_list_from_service(&mac, svc, options, &escalated, type); + + /* XXX: crazy indent */ + /* we have contacts to notify... */ + if(notification_list != NULL) { + + /* grab the macro variables */ + grab_host_macros_r(&mac, temp_host); + grab_service_macros_r(&mac, svc); + + /* if this notification has an author, attempt to lookup the associated contact */ + if(not_author != NULL) { + + /* see if we can find the contact - first by name, then by alias */ + if((temp_contact = find_contact(not_author)) == NULL) { + for(temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + if(!strcmp(temp_contact->alias, not_author)) + break; + } + } + } + + /* get author and comment macros */ + if(not_author) + mac.x[MACRO_NOTIFICATIONAUTHOR] = strdup(not_author); + if(temp_contact != NULL) { + mac.x[MACRO_NOTIFICATIONAUTHORNAME] = strdup(temp_contact->name); + mac.x[MACRO_NOTIFICATIONAUTHORALIAS] = strdup(temp_contact->alias); + } + if(not_data) + mac.x[MACRO_NOTIFICATIONCOMMENT] = strdup(not_data); + + /* NOTE: these macros are deprecated and will likely disappear in Nagios 4.x */ + /* if this is an acknowledgement, get author and comment macros */ + if(type == NOTIFICATION_ACKNOWLEDGEMENT) { + if(not_author) + mac.x[MACRO_SERVICEACKAUTHOR] = strdup(not_author); + + if(not_data) + mac.x[MACRO_SERVICEACKCOMMENT] = strdup(not_data); + + if(temp_contact != NULL) { + mac.x[MACRO_SERVICEACKAUTHORNAME] = strdup(temp_contact->name); + mac.x[MACRO_SERVICEACKAUTHORALIAS] = strdup(temp_contact->alias); + } + } + + /* set the notification type macro */ + if(type == NOTIFICATION_ACKNOWLEDGEMENT) + mac.x[MACRO_NOTIFICATIONTYPE] = "ACKNOWLEDGEMENT"; + else if(type == NOTIFICATION_FLAPPINGSTART) + mac.x[MACRO_NOTIFICATIONTYPE] = "FLAPPINGSTART"; + else if(type == NOTIFICATION_FLAPPINGSTOP) + mac.x[MACRO_NOTIFICATIONTYPE] = "FLAPPINGSTOP"; + else if(type == NOTIFICATION_FLAPPINGDISABLED) + mac.x[MACRO_NOTIFICATIONTYPE] = "FLAPPINGDISABLED"; + else if(type == NOTIFICATION_DOWNTIMESTART) + mac.x[MACRO_NOTIFICATIONTYPE] = "DOWNTIMESTART"; + else if(type == NOTIFICATION_DOWNTIMEEND) + mac.x[MACRO_NOTIFICATIONTYPE] = "DOWNTIMEEND"; + else if(type == NOTIFICATION_DOWNTIMECANCELLED) + mac.x[MACRO_NOTIFICATIONTYPE] = "DOWNTIMECANCELLED"; + else if(type == NOTIFICATION_CUSTOM) + mac.x[MACRO_NOTIFICATIONTYPE] = "CUSTOM"; + else if(svc->current_state == STATE_OK) + mac.x[MACRO_NOTIFICATIONTYPE] = "RECOVERY"; + else + mac.x[MACRO_NOTIFICATIONTYPE] = "PROBLEM"; + + mac.x[MACRO_NOTIFICATIONTYPE] = strdup(mac.x[MACRO_NOTIFICATIONTYPE]); + + /* set the notification number macro */ + asprintf(&mac.x[MACRO_SERVICENOTIFICATIONNUMBER], "%d", svc->current_notification_number); + + /* the $NOTIFICATIONNUMBER$ macro is maintained for backward compatability */ + mac.x[MACRO_NOTIFICATIONNUMBER] = strdup(mac.x[MACRO_SERVICENOTIFICATIONNUMBER]); + + /* set the notification id macro */ + asprintf(&mac.x[MACRO_SERVICENOTIFICATIONID], "%lu", svc->current_notification_id); + + /* notify each contact (duplicates have been removed) */ + for(temp_notification = notification_list; temp_notification != NULL; temp_notification = temp_notification->next) { + + /* grab the macro variables for this contact */ + grab_contact_macros_r(&mac, temp_notification->contact); + + /* notify this contact */ + result = notify_contact_of_service(&mac, temp_notification->contact, svc, type, not_author, not_data, options, escalated); + + /* keep track of how many contacts were notified */ + if(result == OK) + contacts_notified++; + } + + /* free memory allocated to the notification list */ + free_notification_list(); + + /* clear out all macros we created */ + my_free(mac.x[MACRO_NOTIFICATIONNUMBER]); + my_free(mac.x[MACRO_SERVICENOTIFICATIONNUMBER]); + my_free(mac.x[MACRO_SERVICENOTIFICATIONID]); + my_free(mac.x[MACRO_NOTIFICATIONCOMMENT]); + my_free(mac.x[MACRO_NOTIFICATIONTYPE]); + my_free(mac.x[MACRO_NOTIFICATIONAUTHOR]); + my_free(mac.x[MACRO_NOTIFICATIONAUTHORNAME]); + my_free(mac.x[MACRO_NOTIFICATIONAUTHORALIAS]); + my_free(mac.x[MACRO_SERVICEACKAUTHORNAME]); + my_free(mac.x[MACRO_SERVICEACKAUTHORALIAS]); + my_free(mac.x[MACRO_SERVICEACKAUTHOR]); + my_free(mac.x[MACRO_SERVICEACKCOMMENT]); + + /* this gets set in add_notification() */ + my_free(mac.x[MACRO_NOTIFICATIONRECIPIENTS]); + + /* + * Clear all macros, or they will linger in memory + * now that we're done with the notifications. + */ + clear_summary_macros_r(&mac); + clear_contact_macros_r(&mac); + clear_argv_macros_r(&mac); + clear_host_macros_r(&mac); + clear_service_macros_r(&mac); + + if(type == NOTIFICATION_NORMAL) { + + /* adjust last/next notification time and notification flags if we notified someone */ + if(contacts_notified > 0) { + + /* calculate the next acceptable re-notification time */ + svc->next_notification = get_next_service_notification_time(svc, current_time); + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "%d contacts were notified. Next possible notification time: %s", contacts_notified, ctime(&svc->next_notification)); + + /* update the last notification time for this service (this is needed for rescheduling later notifications) */ + svc->last_notification = current_time; + + /* update notifications flags */ + if(svc->current_state == STATE_UNKNOWN) + svc->notified_on_unknown = TRUE; + else if(svc->current_state == STATE_WARNING) + svc->notified_on_warning = TRUE; + else if(svc->current_state == STATE_CRITICAL) + svc->notified_on_critical = TRUE; + } + + /* we didn't end up notifying anyone */ + else if(increment_notification_number == TRUE) { + + /* adjust current notification number */ + svc->current_notification_number--; + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "No contacts were notified. Next possible notification time: %s", ctime(&svc->next_notification)); + } + + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "%d contacts were notified.\n", contacts_notified); + } + + /* there were no contacts, so no notification really occurred... */ + else { + + /* readjust current notification number, since one didn't go out */ + if(increment_notification_number == TRUE) + svc->current_notification_number--; + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "No contacts were found for notification purposes. No notification was sent out.\n"); + } + + /* this gets set in create_notification_list_from_service() */ + my_free(mac.x[MACRO_NOTIFICATIONISESCALATED]); + + /* get the time we finished */ + gettimeofday(&end_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_notification_data(NEBTYPE_NOTIFICATION_END, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_NOTIFICATION, type, start_time, end_time, (void *)svc, not_author, not_data, escalated, contacts_notified, NULL); +#endif + + /* update the status log with the service information */ + update_service_status(svc, FALSE); + + return OK; + } + + + +/* checks the viability of sending out a service alert (top level filters) */ +int check_service_notification_viability(service *svc, int type, int options) { + host *temp_host; + timeperiod *temp_period; + time_t current_time; + time_t timeperiod_start; + time_t first_problem_time; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_service_notification_viability()\n"); + + /* forced notifications bust through everything */ + if(options & NOTIFICATION_OPTION_FORCED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This is a forced service notification, so we'll send it out.\n"); + return OK; + } + + /* get current time */ + time(¤t_time); + + /* are notifications enabled? */ + if(enable_notifications == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Notifications are disabled, so service notifications will not be sent out.\n"); + return ERROR; + } + + /* find the host this service is associated with */ + if((temp_host = (host *)svc->host_ptr) == NULL) + return ERROR; + + /* if we couldn't find the host, return an error */ + if(temp_host == NULL) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Couldn't find the host associated with this service, so we won't send a notification.\n"); + return ERROR; + } + + /* if the service has no notification period, inherit one from the host */ + temp_period = svc->notification_period_ptr; + if(temp_period == NULL) { + temp_period = svc->host_ptr->notification_period_ptr; + } + + /* see if the service can have notifications sent out at this time */ + if(check_time_against_period(current_time, temp_period) == ERROR) { + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This service shouldn't have notifications sent out at this time.\n"); + + /* calculate the next acceptable notification time, once the next valid time range arrives... */ + if(type == NOTIFICATION_NORMAL) { + + get_next_valid_time(current_time, &timeperiod_start, svc->notification_period_ptr); + + /* looks like there are no valid notification times defined, so schedule the next one far into the future (one year)... */ + if(timeperiod_start == (time_t)0) + svc->next_notification = (time_t)(current_time + (60 * 60 * 24 * 365)); + + /* else use the next valid notification time */ + else + svc->next_notification = timeperiod_start; + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Next possible notification time: %s\n", ctime(&svc->next_notification)); + } + + return ERROR; + } + + /* are notifications temporarily disabled for this service? */ + if(svc->notifications_enabled == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Notifications are temporarily disabled for this service, so we won't send one out.\n"); + return ERROR; + } + + + /*********************************************/ + /*** SPECIAL CASE FOR CUSTOM NOTIFICATIONS ***/ + /*********************************************/ + + /* custom notifications are good to go at this point... */ + if(type == NOTIFICATION_CUSTOM) { + if(svc->scheduled_downtime_depth > 0 || temp_host->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't send custom notification during scheduled downtime.\n"); + return ERROR; + } + return OK; + } + + + + /****************************************/ + /*** SPECIAL CASE FOR ACKNOWLEGEMENTS ***/ + /****************************************/ + + /* acknowledgements only have to pass three general filters, although they have another test of their own... */ + if(type == NOTIFICATION_ACKNOWLEDGEMENT) { + + /* don't send an acknowledgement if there isn't a problem... */ + if(svc->current_state == STATE_OK) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "The service is currently OK, so we won't send an acknowledgement.\n"); + return ERROR; + } + + /* acknowledgement viability test passed, so the notification can be sent out */ + return OK; + } + + + /****************************************/ + /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ + /****************************************/ + + /* flapping notifications only have to pass three general filters */ + if(type == NOTIFICATION_FLAPPINGSTART || type == NOTIFICATION_FLAPPINGSTOP || type == NOTIFICATION_FLAPPINGDISABLED) { + + /* don't send a notification if we're not supposed to... */ + if(svc->notify_on_flapping == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about FLAPPING events for this service.\n"); + return ERROR; + } + + /* don't send notifications during scheduled downtime */ + if(svc->scheduled_downtime_depth > 0 || temp_host->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about FLAPPING events during scheduled downtime.\n"); + return ERROR; + } + + /* flapping viability test passed, so the notification can be sent out */ + return OK; + } + + + /****************************************/ + /*** SPECIAL CASE FOR DOWNTIME ALERTS ***/ + /****************************************/ + + /* downtime notifications only have to pass three general filters */ + if(type == NOTIFICATION_DOWNTIMESTART || type == NOTIFICATION_DOWNTIMEEND || type == NOTIFICATION_DOWNTIMECANCELLED) { + + /* don't send a notification if we're not supposed to... */ + if(svc->notify_on_downtime == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about DOWNTIME events for this service.\n"); + return ERROR; + } + + /* don't send notifications during scheduled downtime (for service only, not host) */ + if(svc->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about DOWNTIME events during scheduled downtime.\n"); + return ERROR; + } + + /* downtime viability test passed, so the notification can be sent out */ + return OK; + } + + + /****************************************/ + /*** NORMAL NOTIFICATIONS ***************/ + /****************************************/ + + /* is this a hard problem/recovery? */ + if(svc->state_type == SOFT_STATE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This service is in a soft state, so we won't send a notification out.\n"); + return ERROR; + } + + /* has this problem already been acknowledged? */ + if(svc->problem_has_been_acknowledged == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This service problem has already been acknowledged, so we won't send a notification out.\n"); + return ERROR; + } + + /* check service notification dependencies */ + if(check_service_dependencies(svc, NOTIFICATION_DEPENDENCY) == DEPENDENCIES_FAILED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Service notification dependencies for this service have failed, so we won't sent a notification out.\n"); + return ERROR; + } + + /* check host notification dependencies */ + if(check_host_dependencies(temp_host, NOTIFICATION_DEPENDENCY) == DEPENDENCIES_FAILED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Host notification dependencies for this service have failed, so we won't sent a notification out.\n"); + return ERROR; + } + + /* see if we should notify about problems with this service */ + if(svc->current_state == STATE_UNKNOWN && svc->notify_on_unknown == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about UNKNOWN states for this service.\n"); + return ERROR; + } + if(svc->current_state == STATE_WARNING && svc->notify_on_warning == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about WARNING states for this service.\n"); + return ERROR; + } + if(svc->current_state == STATE_CRITICAL && svc->notify_on_critical == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about CRITICAL states for this service.\n"); + return ERROR; + } + if(svc->current_state == STATE_OK) { + if(svc->notify_on_recovery == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about RECOVERY states for this service.\n"); + return ERROR; + } + if(!(svc->notified_on_unknown == TRUE || svc->notified_on_warning == TRUE || svc->notified_on_critical == TRUE)) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about this recovery.\n"); + return ERROR; + } + } + + /* see if enough time has elapsed for first notification (Mathias Sundman) */ + /* 10/02/07 don't place restrictions on recoveries or non-normal notifications, must use last time ok (or program start) in calculation */ + /* it is reasonable to assume that if the host was never up, the program start time should be used in this calculation */ + if(type == NOTIFICATION_NORMAL && svc->current_notification_number == 0 && svc->current_state != STATE_OK) { + + /* determine the time to use of the first problem point */ + first_problem_time = svc->last_time_ok; /* not accurate, but its the earliest time we could use in the comparison */ + if((svc->last_time_warning < first_problem_time) && (svc->last_time_warning > svc->last_time_ok)) + first_problem_time = svc->last_time_warning; + if((svc->last_time_unknown < first_problem_time) && (svc->last_time_unknown > svc->last_time_ok)) + first_problem_time = svc->last_time_unknown; + if((svc->last_time_critical < first_problem_time) && (svc->last_time_critical > svc->last_time_ok)) + first_problem_time = svc->last_time_critical; + + if(current_time < (time_t)((first_problem_time == (time_t)0L) ? program_start : first_problem_time) + (time_t)(svc->first_notification_delay * interval_length)) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Not enough time has elapsed since the service changed to a non-OK state, so we should not notify about this problem yet\n"); + return ERROR; + } + } + + /* if this service is currently flapping, don't send the notification */ + if(svc->is_flapping == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This service is currently flapping, so we won't send notifications.\n"); + return ERROR; + } + + /***** RECOVERY NOTIFICATIONS ARE GOOD TO GO AT THIS POINT *****/ + if(svc->current_state == STATE_OK) + return OK; + + /* don't notify contacts about this service problem again if the notification interval is set to 0 */ + if(svc->no_more_notifications == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't re-notify contacts about this service problem.\n"); + return ERROR; + } + + /* if the host is down or unreachable, don't notify contacts about service failures */ + if(temp_host->current_state != HOST_UP) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "The host is either down or unreachable, so we won't notify contacts about this service.\n"); + return ERROR; + } + + /* don't notify if we haven't waited long enough since the last time (and the service is not marked as being volatile) */ + if((current_time < svc->next_notification) && svc->is_volatile == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We haven't waited long enough to re-notify contacts about this service.\n"); + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Next valid notification time: %s", ctime(&svc->next_notification)); + return ERROR; + } + + /* if this service is currently in a scheduled downtime period, don't send the notification */ + if(svc->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This service is currently in a scheduled downtime, so we won't send notifications.\n"); + return ERROR; + } + + /* if this host is currently in a scheduled downtime period, don't send the notification */ + if(temp_host->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "The host this service is associated with is currently in a scheduled downtime, so we won't send notifications.\n"); + return ERROR; + } + + return OK; + } + + + +/* check viability of sending out a service notification to a specific contact (contact-specific filters) */ +int check_contact_service_notification_viability(contact *cntct, service *svc, int type, int options) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_contact_service_notification_viability()\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Checking service notification viability for contact '%s'...\n", cntct->name); + + /* forced notifications bust through everything */ + if(options & NOTIFICATION_OPTION_FORCED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This is a forced service notification, so we'll send it out to this contact.\n"); + return OK; + } + + /* are notifications enabled? */ + if(cntct->service_notifications_enabled == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Service notifications are disabled for this contact.\n"); + return ERROR; + } + + /* see if the contact can be notified at this time */ + if(check_time_against_period(time(NULL), cntct->service_notification_period_ptr) == ERROR) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "This contact shouldn't be notified at this time.\n"); + return ERROR; + } + + /*********************************************/ + /*** SPECIAL CASE FOR CUSTOM NOTIFICATIONS ***/ + /*********************************************/ + + /* custom notifications are good to go at this point... */ + if(type == NOTIFICATION_CUSTOM) + return OK; + + + /****************************************/ + /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ + /****************************************/ + + if(type == NOTIFICATION_FLAPPINGSTART || type == NOTIFICATION_FLAPPINGSTOP || type == NOTIFICATION_FLAPPINGDISABLED) { + + if(cntct->notify_on_service_flapping == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about FLAPPING service events.\n"); + return ERROR; + } + + return OK; + } + + /****************************************/ + /*** SPECIAL CASE FOR DOWNTIME ALERTS ***/ + /****************************************/ + + if(type == NOTIFICATION_DOWNTIMESTART || type == NOTIFICATION_DOWNTIMEEND || type == NOTIFICATION_DOWNTIMECANCELLED) { + + if(cntct->notify_on_service_downtime == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about DOWNTIME service events.\n"); + return ERROR; + } + + return OK; + } + + /*************************************/ + /*** ACKS AND NORMAL NOTIFICATIONS ***/ + /*************************************/ + + /* see if we should notify about problems with this service */ + if(svc->current_state == STATE_UNKNOWN && cntct->notify_on_service_unknown == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about UNKNOWN service states.\n"); + return ERROR; + } + + if(svc->current_state == STATE_WARNING && cntct->notify_on_service_warning == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about WARNING service states.\n"); + return ERROR; + } + + if(svc->current_state == STATE_CRITICAL && cntct->notify_on_service_critical == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about CRITICAL service states.\n"); + return ERROR; + } + + if(svc->current_state == STATE_OK) { + + if(cntct->notify_on_service_recovery == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about RECOVERY service states.\n"); + return ERROR; + } + + if(!((svc->notified_on_unknown == TRUE && cntct->notify_on_service_unknown == TRUE) || (svc->notified_on_warning == TRUE && cntct->notify_on_service_warning == TRUE) || (svc->notified_on_critical == TRUE && cntct->notify_on_service_critical == TRUE))) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify about this recovery.\n"); + return ERROR; + } + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Service notification viability for contact '%s' PASSED.\n", cntct->name); + + return OK; + } + + + +/* notify a specific contact about a service problem or recovery */ +int notify_contact_of_service(nagios_macros *mac, contact *cntct, service *svc, int type, char *not_author, char *not_data, int options, int escalated) { + commandsmember *temp_commandsmember = NULL; + char *command_name = NULL; + char *command_name_ptr = NULL; + char *raw_command = NULL; + char *processed_command = NULL; + char *temp_buffer = NULL; + char *processed_buffer = NULL; + int early_timeout = FALSE; + double exectime; + struct timeval start_time, end_time; + struct timeval method_start_time, method_end_time; + int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; + int neb_result; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "notify_contact_of_service()\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Notifying contact '%s'\n", cntct->name); + + /* get start time */ + gettimeofday(&start_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + neb_result = broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_START, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_NOTIFICATION, type, start_time, end_time, (void *)svc, cntct, not_author, not_data, escalated, NULL); + if(NEBERROR_CALLBACKCANCEL == neb_result) + return ERROR; + else if(NEBERROR_CALLBACKOVERRIDE == neb_result) + return OK; +#endif + + /* process all the notification commands this user has */ + for(temp_commandsmember = cntct->service_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) { + + /* get start time */ + gettimeofday(&method_start_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + method_end_time.tv_sec = 0L; + method_end_time.tv_usec = 0L; + neb_result = broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_START, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_NOTIFICATION, type, method_start_time, method_end_time, (void *)svc, cntct, temp_commandsmember->command, not_author, not_data, escalated, NULL); + if(NEBERROR_CALLBACKCANCEL == neb_result) + break ; + else if(NEBERROR_CALLBACKOVERRIDE == neb_result) + continue ; +#endif + + /* get the raw command line */ + get_raw_command_line_r(mac, temp_commandsmember->command_ptr, temp_commandsmember->command, &raw_command, macro_options); + if(raw_command == NULL) + continue; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Raw notification command: %s\n", raw_command); + + /* process any macros contained in the argument */ + process_macros_r(mac, raw_command, &processed_command, macro_options); + my_free(raw_command); + if(processed_command == NULL) + continue; + + /* get the command name */ + command_name = (char *)strdup(temp_commandsmember->command); + command_name_ptr = strtok(command_name, "!"); + + /* run the notification command... */ + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Processed notification command: %s\n", processed_command); + + /* log the notification to program log file */ + if(log_notifications == TRUE) { + switch(type) { + case NOTIFICATION_CUSTOM: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;CUSTOM ($SERVICESTATE$);%s;$SERVICEOUTPUT$;$NOTIFICATIONAUTHOR$;$NOTIFICATIONCOMMENT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_ACKNOWLEDGEMENT: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;ACKNOWLEDGEMENT ($SERVICESTATE$);%s;$SERVICEOUTPUT$;$NOTIFICATIONAUTHOR$;$NOTIFICATIONCOMMENT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_FLAPPINGSTART: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;FLAPPINGSTART ($SERVICESTATE$);%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_FLAPPINGSTOP: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;FLAPPINGSTOP ($SERVICESTATE$);%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_FLAPPINGDISABLED: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;FLAPPINGDISABLED ($SERVICESTATE$);%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_DOWNTIMESTART: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;DOWNTIMESTART ($SERVICESTATE$);%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_DOWNTIMEEND: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;DOWNTIMEEND ($SERVICESTATE$);%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + case NOTIFICATION_DOWNTIMECANCELLED: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;DOWNTIMECANCELLED ($SERVICESTATE$);%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + default: + asprintf(&temp_buffer, "SERVICE NOTIFICATION: %s;%s;%s;$SERVICESTATE$;%s;$SERVICEOUTPUT$\n", cntct->name, svc->host_name, svc->description, command_name_ptr); + break; + } + + process_macros_r(mac, temp_buffer, &processed_buffer, 0); + write_to_all_logs(processed_buffer, NSLOG_SERVICE_NOTIFICATION); + + my_free(temp_buffer); + my_free(processed_buffer); + } + + /* run the notification command */ + my_system_r(mac, processed_command, notification_timeout, &early_timeout, &exectime, NULL, 0); + + /* check to see if the notification command timed out */ + if(early_timeout == TRUE) { + logit(NSLOG_SERVICE_NOTIFICATION | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Contact '%s' service notification command '%s' timed out after %d seconds\n", cntct->name, processed_command, notification_timeout); + } + + /* free memory */ + my_free(command_name); + my_free(processed_command); + + /* get end time */ + gettimeofday(&method_end_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_END, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_NOTIFICATION, type, method_start_time, method_end_time, (void *)svc, cntct, temp_commandsmember->command, not_author, not_data, escalated, NULL); +#endif + } + + /* get end time */ + gettimeofday(&end_time, NULL); + + /* update the contact's last service notification time */ + cntct->last_service_notification = start_time.tv_sec; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_END, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_NOTIFICATION, type, start_time, end_time, (void *)svc, cntct, not_author, not_data, escalated, NULL); +#endif + + return OK; + } + + +/* checks to see if a service escalation entry is a match for the current service notification */ +int is_valid_escalation_for_service_notification(service *svc, serviceescalation *se, int options) { + int notification_number = 0; + time_t current_time = 0L; + service *temp_service = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "is_valid_escalation_for_service_notification()\n"); + + /* get the current time */ + time(¤t_time); + + /* if this is a recovery, really we check for who got notified about a previous problem */ + if(svc->current_state == STATE_OK) + notification_number = svc->current_notification_number - 1; + else + notification_number = svc->current_notification_number; + + /* this entry if it is not for this service */ + temp_service = se->service_ptr; + if(temp_service == NULL || temp_service != svc) + return FALSE; + + /*** EXCEPTION ***/ + /* broadcast options go to everyone, so this escalation is valid */ + if(options & NOTIFICATION_OPTION_BROADCAST) + return TRUE; + + /* skip this escalation if it happens later */ + if(se->first_notification > notification_number) + return FALSE; + + /* skip this escalation if it has already passed */ + if(se->last_notification != 0 && se->last_notification < notification_number) + return FALSE; + + /* skip this escalation if it has a timeperiod and the current time isn't valid */ + if(se->escalation_period != NULL && check_time_against_period(current_time, se->escalation_period_ptr) == ERROR) + return FALSE; + + /* skip this escalation if the state options don't match */ + if(svc->current_state == STATE_OK && se->escalate_on_recovery == FALSE) + return FALSE; + else if(svc->current_state == STATE_WARNING && se->escalate_on_warning == FALSE) + return FALSE; + else if(svc->current_state == STATE_UNKNOWN && se->escalate_on_unknown == FALSE) + return FALSE; + else if(svc->current_state == STATE_CRITICAL && se->escalate_on_critical == FALSE) + return FALSE; + + return TRUE; + } + + +/* checks to see whether a service notification should be escalation */ +int should_service_notification_be_escalated(service *svc) { + serviceescalation *temp_se = NULL; + void *ptr = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "should_service_notification_be_escalated()\n"); + + /* search the service escalation list */ + for(temp_se = get_first_serviceescalation_by_service(svc->host_name, svc->description, &ptr); temp_se != NULL; temp_se = get_next_serviceescalation_by_service(svc->host_name, svc->description, &ptr)) { + + /* we found a matching entry, so escalate this notification! */ + if(is_valid_escalation_for_service_notification(svc, temp_se, NOTIFICATION_OPTION_NONE) == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Service notification WILL be escalated.\n"); + return TRUE; + } + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Service notification will NOT be escalated.\n"); + + return FALSE; + } + + +/* given a service, create a list of contacts to be notified, removing duplicates, checking contact notification viability */ +int create_notification_list_from_service(nagios_macros *mac, service *svc, int options, int *escalated, int type) { + serviceescalation *temp_se = NULL; + contactsmember *temp_contactsmember = NULL; + contact *temp_contact = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + contactgroup *temp_contactgroup = NULL; + int escalate_notification = FALSE; + void *ptr = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "create_notification_list_from_service()\n"); + + /* see if this notification should be escalated */ + escalate_notification = should_service_notification_be_escalated(svc); + + /* set the escalation flag */ + *escalated = escalate_notification; + + /* make sure there aren't any leftover contacts */ + free_notification_list(); + + /* set the escalation macro */ + mac->x[MACRO_NOTIFICATIONISESCALATED] = strdup(escalate_notification ? "1" : "0"); + + if(options & NOTIFICATION_OPTION_BROADCAST) + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This notification will be BROADCAST to all (escalated and normal) contacts...\n"); + + /* use escalated contacts for this notification */ + if(escalate_notification == TRUE || (options & NOTIFICATION_OPTION_BROADCAST)) { + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Adding contacts from service escalation(s) to notification list.\n"); + + /* search all the escalation entries for valid matches */ + for(temp_se = get_first_serviceescalation_by_service(svc->host_name, svc->description, &ptr); temp_se != NULL; temp_se = get_next_serviceescalation_by_service(svc->host_name, svc->description, &ptr)) { + + /* skip this entry if it isn't appropriate */ + if(is_valid_escalation_for_service_notification(svc, temp_se, options) == FALSE) + continue; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding individual contacts from service escalation(s) to notification list.\n"); + + /* add all individual contacts for this escalation entry */ + for(temp_contactsmember = temp_se->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_service_notification_viability(temp_contact, svc, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact groups from service escalation(s) to notification list.\n"); + + /* add all contacts that belong to contactgroups for this escalation */ + for(temp_contactgroupsmember = temp_se->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact group '%s' for service escalation to notification list.\n", temp_contactgroupsmember->group_name); + if((temp_contactgroup = temp_contactgroupsmember->group_ptr) == NULL) + continue; + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_service_notification_viability(temp_contact, svc, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + } + } + } + + /* else use normal, non-escalated contacts */ + if(escalate_notification == FALSE || (options & NOTIFICATION_OPTION_BROADCAST)) { + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Adding normal contacts for service to notification list.\n"); + + /* add all individual contacts for this service */ + for(temp_contactsmember = svc->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_service_notification_viability(temp_contact, svc, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + + /* add all contacts that belong to contactgroups for this service */ + for(temp_contactgroupsmember = svc->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact group '%s' for service to notification list.\n", temp_contactgroupsmember->group_name); + if((temp_contactgroup = temp_contactgroupsmember->group_ptr) == NULL) + continue; + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_service_notification_viability(temp_contact, svc, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + } + } + + return OK; + } + + + + +/******************************************************************/ +/******************* HOST NOTIFICATION FUNCTIONS ******************/ +/******************************************************************/ + + + +/* notify all contacts for a host that the entire host is down or up */ +int host_notification(host *hst, int type, char *not_author, char *not_data, int options) { + notification *temp_notification = NULL; + contact *temp_contact = NULL; + time_t current_time; + struct timeval start_time; + struct timeval end_time; + int escalated = FALSE; + int result = OK; + int contacts_notified = 0; + int increment_notification_number = FALSE; + nagios_macros mac; + int neb_result; + + /* get the current time */ + time(¤t_time); + gettimeofday(&start_time, NULL); + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "** Host Notification Attempt ** Host: '%s', Type: %d, Options: %d, Current State: %d, Last Notification: %s", hst->name, type, options, hst->current_state, ctime(&hst->last_host_notification)); + + + /* check viability of sending out a host notification */ + if(check_host_notification_viability(hst, type, options) == ERROR) { + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "Notification viability test failed. No notification will be sent out.\n"); + return OK; + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "Notification viability test passed.\n"); + + /* should the notification number be increased? */ + if(type == NOTIFICATION_NORMAL || (options & NOTIFICATION_OPTION_INCREMENT)) { + hst->current_notification_number++; + increment_notification_number = TRUE; + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Current notification number: %d (%s)\n", hst->current_notification_number, (increment_notification_number == TRUE) ? "incremented" : "unchanged"); + + /* save and increase the current notification id */ + hst->current_notification_id = next_notification_id; + next_notification_id++; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Creating list of contacts to be notified.\n"); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + neb_result = broker_notification_data(NEBTYPE_NOTIFICATION_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_NOTIFICATION, type, start_time, end_time, (void *)hst, not_author, not_data, escalated, 0, NULL); + if(NEBERROR_CALLBACKCANCEL == neb_result) { + free_notification_list(); + return ERROR; + } + else if(NEBERROR_CALLBACKOVERRIDE == neb_result) { + free_notification_list(); + return OK; + } +#endif + + /* reset memory for local macro data */ + memset(&mac, 0, sizeof(mac)); + + /* 2011-11-01 MF: + check viability before adding a contact + to the notification list, requires type + this prevents us from running through all + the steps until notify_contact_of_host|service + is reached. furthermore the $NOTIFICATIONRECIPIENTS$ + macro only gets populated with actual recipients, + not all contacts assigned to that host|service. + + note: checks against timeperiod will happen now(), + and not when the notification is actually being sent. + + original patch by Opsview Team + */ + create_notification_list_from_host(&mac, hst, options, &escalated, type); + + /* XXX: crazy indent */ + /* there are contacts to be notified... */ + if(notification_list != NULL) { + + /* grab the macro variables */ + grab_host_macros_r(&mac, hst); + + /* if this notification has an author, attempt to lookup the associated contact */ + if(not_author != NULL) { + + /* see if we can find the contact - first by name, then by alias */ + if((temp_contact = find_contact(not_author)) == NULL) { + for(temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + if(!strcmp(temp_contact->alias, not_author)) + break; + } + } + } + + /* get author and comment macros */ + if(not_author) + mac.x[MACRO_NOTIFICATIONAUTHOR] = strdup(not_author); + if(temp_contact != NULL) { + mac.x[MACRO_NOTIFICATIONAUTHORNAME] = strdup(temp_contact->name); + mac.x[MACRO_NOTIFICATIONAUTHORALIAS] = strdup(temp_contact->alias); + } + if(not_data) + mac.x[MACRO_NOTIFICATIONCOMMENT] = strdup(not_data); + + /* NOTE: these macros are deprecated and will likely disappear in Nagios 4.x */ + /* if this is an acknowledgement, get author and comment macros */ + if(type == NOTIFICATION_ACKNOWLEDGEMENT) { + + if(not_author) + mac.x[MACRO_HOSTACKAUTHOR] = strdup(not_author); + + if(not_data) + mac.x[MACRO_HOSTACKCOMMENT] = strdup(not_data); + + if(temp_contact != NULL) { + mac.x[MACRO_HOSTACKAUTHORNAME] = strdup(temp_contact->name); + mac.x[MACRO_HOSTACKAUTHORALIAS] = strdup(temp_contact->alias); + } + } + + /* set the notification type macro */ + if(type == NOTIFICATION_ACKNOWLEDGEMENT) + mac.x[MACRO_NOTIFICATIONTYPE] = "ACKNOWLEDGEMENT"; + else if(type == NOTIFICATION_FLAPPINGSTART) + mac.x[MACRO_NOTIFICATIONTYPE] = "FLAPPINGSTART"; + else if(type == NOTIFICATION_FLAPPINGSTOP) + mac.x[MACRO_NOTIFICATIONTYPE] = "FLAPPINGSTOP"; + else if(type == NOTIFICATION_FLAPPINGDISABLED) + mac.x[MACRO_NOTIFICATIONTYPE] = "FLAPPINGDISABLED"; + else if(type == NOTIFICATION_DOWNTIMESTART) + mac.x[MACRO_NOTIFICATIONTYPE] = "DOWNTIMESTART"; + else if(type == NOTIFICATION_DOWNTIMEEND) + mac.x[MACRO_NOTIFICATIONTYPE] = "DOWNTIMEEND"; + else if(type == NOTIFICATION_DOWNTIMECANCELLED) + mac.x[MACRO_NOTIFICATIONTYPE] = "DOWNTIMECANCELLED"; + else if(type == NOTIFICATION_CUSTOM) + mac.x[MACRO_NOTIFICATIONTYPE] = "CUSTOM"; + else if(hst->current_state == HOST_UP) + mac.x[MACRO_NOTIFICATIONTYPE] = "RECOVERY"; + else + mac.x[MACRO_NOTIFICATIONTYPE] = "PROBLEM"; + + mac.x[MACRO_NOTIFICATIONTYPE] = strdup(mac.x[MACRO_NOTIFICATIONTYPE]); + + /* set the notification number macro */ + asprintf(&mac.x[MACRO_HOSTNOTIFICATIONNUMBER], "%d", hst->current_notification_number); + + /* the $NOTIFICATIONNUMBER$ macro is maintained for backward compatability */ + mac.x[MACRO_NOTIFICATIONNUMBER] = strdup(mac.x[MACRO_HOSTNOTIFICATIONNUMBER]); + + /* set the notification id macro */ + asprintf(&mac.x[MACRO_HOSTNOTIFICATIONID], "%lu", hst->current_notification_id); + + /* notify each contact (duplicates have been removed) */ + for(temp_notification = notification_list; temp_notification != NULL; temp_notification = temp_notification->next) { + + /* grab the macro variables for this contact */ + grab_contact_macros_r(&mac, temp_notification->contact); + + /* clear summary macros (they are customized for each contact) */ + clear_summary_macros_r(&mac); + + /* notify this contact */ + result = notify_contact_of_host(&mac, temp_notification->contact, hst, type, not_author, not_data, options, escalated); + + /* keep track of how many contacts were notified */ + if(result == OK) + contacts_notified++; + } + + /* free memory allocated to the notification list */ + free_notification_list(); + + /* clear out all macros we created */ + my_free(mac.x[MACRO_HOSTNOTIFICATIONID]); + my_free(mac.x[MACRO_NOTIFICATIONNUMBER]); + my_free(mac.x[MACRO_NOTIFICATIONCOMMENT]); + my_free(mac.x[MACRO_HOSTNOTIFICATIONNUMBER]); + my_free(mac.x[MACRO_NOTIFICATIONTYPE]); + my_free(mac.x[MACRO_NOTIFICATIONAUTHOR]); + my_free(mac.x[MACRO_NOTIFICATIONAUTHORNAME]); + my_free(mac.x[MACRO_NOTIFICATIONAUTHORALIAS]); + my_free(mac.x[MACRO_HOSTACKAUTHORNAME]); + my_free(mac.x[MACRO_HOSTACKAUTHORALIAS]); + my_free(mac.x[MACRO_HOSTACKAUTHOR]); + my_free(mac.x[MACRO_HOSTACKCOMMENT]); + /* this gets set in add_notification() */ + my_free(mac.x[MACRO_NOTIFICATIONRECIPIENTS]); + + /* + * Clear all macros, or they will linger in memory + * now that we're done with the notifications. + */ + clear_summary_macros_r(&mac); + clear_contact_macros_r(&mac); + clear_argv_macros_r(&mac); + clear_host_macros_r(&mac); + + if(type == NOTIFICATION_NORMAL) { + + /* adjust last/next notification time and notification flags if we notified someone */ + if(contacts_notified > 0) { + + /* calculate the next acceptable re-notification time */ + hst->next_host_notification = get_next_host_notification_time(hst, current_time); + + /* update the last notification time for this host (this is needed for scheduling the next problem notification) */ + hst->last_host_notification = current_time; + + /* update notifications flags */ + if(hst->current_state == HOST_DOWN) + hst->notified_on_down = TRUE; + else if(hst->current_state == HOST_UNREACHABLE) + hst->notified_on_unreachable = TRUE; + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "%d contacts were notified. Next possible notification time: %s", contacts_notified, ctime(&hst->next_host_notification)); + } + + /* we didn't end up notifying anyone */ + else if(increment_notification_number == TRUE) { + + /* adjust current notification number */ + hst->current_notification_number--; + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "No contacts were notified. Next possible notification time: %s", ctime(&hst->next_host_notification)); + } + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "%d contacts were notified.\n", contacts_notified); + } + + /* there were no contacts, so no notification really occurred... */ + else { + + /* adjust notification number, since no notification actually went out */ + if(increment_notification_number == TRUE) + hst->current_notification_number--; + + log_debug_info(DEBUGL_NOTIFICATIONS, 0, "No contacts were found for notification purposes. No notification was sent out.\n"); + } + + /* this gets set in create_notification_list_from_host() */ + my_free(mac.x[MACRO_NOTIFICATIONISESCALATED]); + + /* get the time we finished */ + gettimeofday(&end_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_notification_data(NEBTYPE_NOTIFICATION_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_NOTIFICATION, type, start_time, end_time, (void *)hst, not_author, not_data, escalated, contacts_notified, NULL); +#endif + + /* update the status log with the host info */ + update_host_status(hst, FALSE); + + return OK; + } + + + +/* checks viability of sending a host notification */ +int check_host_notification_viability(host *hst, int type, int options) { + time_t current_time; + time_t timeperiod_start; + time_t first_problem_time; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_host_notification_viability()\n"); + + /* forced notifications bust through everything */ + if(options & NOTIFICATION_OPTION_FORCED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This is a forced host notification, so we'll send it out.\n"); + return OK; + } + + /* get current time */ + time(¤t_time); + + /* are notifications enabled? */ + if(enable_notifications == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Notifications are disabled, so host notifications will not be sent out.\n"); + return ERROR; + } + + /* see if the host can have notifications sent out at this time */ + if(check_time_against_period(current_time, hst->notification_period_ptr) == ERROR) { + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This host shouldn't have notifications sent out at this time.\n"); + + /* if this is a normal notification, calculate the next acceptable notification time, once the next valid time range arrives... */ + if(type == NOTIFICATION_NORMAL) { + + get_next_valid_time(current_time, &timeperiod_start, hst->notification_period_ptr); + + /* it looks like there is no notification time defined, so schedule next one far into the future (one year)... */ + if(timeperiod_start == (time_t)0) + hst->next_host_notification = (time_t)(current_time + (60 * 60 * 24 * 365)); + + /* else use the next valid notification time */ + else + hst->next_host_notification = timeperiod_start; + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Next possible notification time: %s\n", ctime(&hst->next_host_notification)); + } + + return ERROR; + } + + /* are notifications temporarily disabled for this host? */ + if(hst->notifications_enabled == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Notifications are temporarily disabled for this host, so we won't send one out.\n"); + return ERROR; + } + + + /*********************************************/ + /*** SPECIAL CASE FOR CUSTOM NOTIFICATIONS ***/ + /*********************************************/ + + /* custom notifications are good to go at this point... */ + if(type == NOTIFICATION_CUSTOM) { + if(hst->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't send custom notification during scheduled downtime.\n"); + return ERROR; + } + return OK; + } + + + + /****************************************/ + /*** SPECIAL CASE FOR ACKNOWLEGEMENTS ***/ + /****************************************/ + + /* acknowledgements only have to pass three general filters, although they have another test of their own... */ + if(type == NOTIFICATION_ACKNOWLEDGEMENT) { + + /* don't send an acknowledgement if there isn't a problem... */ + if(hst->current_state == HOST_UP) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "The host is currently UP, so we won't send an acknowledgement.\n"); + return ERROR; + } + + /* acknowledgement viability test passed, so the notification can be sent out */ + return OK; + } + + + /*****************************************/ + /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ + /*****************************************/ + + /* flapping notifications only have to pass three general filters */ + if(type == NOTIFICATION_FLAPPINGSTART || type == NOTIFICATION_FLAPPINGSTOP || type == NOTIFICATION_FLAPPINGDISABLED) { + + /* don't send a notification if we're not supposed to... */ + if(hst->notify_on_flapping == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about FLAPPING events for this host.\n"); + return ERROR; + } + + /* don't send notifications during scheduled downtime */ + if(hst->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about FLAPPING events during scheduled downtime.\n"); + return ERROR; + } + + /* flapping viability test passed, so the notification can be sent out */ + return OK; + } + + + /*****************************************/ + /*** SPECIAL CASE FOR DOWNTIME ALERTS ***/ + /*****************************************/ + + /* flapping notifications only have to pass three general filters */ + if(type == NOTIFICATION_DOWNTIMESTART || type == NOTIFICATION_DOWNTIMEEND || type == NOTIFICATION_DOWNTIMECANCELLED) { + + /* don't send a notification if we're not supposed to... */ + if(hst->notify_on_downtime == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about DOWNTIME events for this host.\n"); + return ERROR; + } + + /* don't send notifications during scheduled downtime */ + if(hst->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about DOWNTIME events during scheduled downtime!\n"); + return ERROR; + } + + /* downtime viability test passed, so the notification can be sent out */ + return OK; + } + + + /****************************************/ + /*** NORMAL NOTIFICATIONS ***************/ + /****************************************/ + + /* is this a hard problem/recovery? */ + if(hst->state_type == SOFT_STATE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This host is in a soft state, so we won't send a notification out.\n"); + return ERROR; + } + + /* has this problem already been acknowledged? */ + if(hst->problem_has_been_acknowledged == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This host problem has already been acknowledged, so we won't send a notification out!\n"); + return ERROR; + } + + /* check notification dependencies */ + if(check_host_dependencies(hst, NOTIFICATION_DEPENDENCY) == DEPENDENCIES_FAILED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Notification dependencies for this host have failed, so we won't sent a notification out!\n"); + return ERROR; + } + + /* see if we should notify about problems with this host */ + if(hst->current_state == HOST_UNREACHABLE && hst->notify_on_unreachable == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about UNREACHABLE status for this host.\n"); + return ERROR; + } + if(hst->current_state == HOST_DOWN && hst->notify_on_down == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about DOWN states for this host.\n"); + return ERROR; + } + if(hst->current_state == HOST_UP) { + + if(hst->notify_on_recovery == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about RECOVERY states for this host.\n"); + return ERROR; + } + if(!(hst->notified_on_down == TRUE || hst->notified_on_unreachable == TRUE)) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't notify about this recovery.\n"); + return ERROR; + } + + } + + /* see if enough time has elapsed for first notification (Mathias Sundman) */ + /* 10/02/07 don't place restrictions on recoveries or non-normal notifications, must use last time up (or program start) in calculation */ + /* it is reasonable to assume that if the host was never up, the program start time should be used in this calculation */ + if(type == NOTIFICATION_NORMAL && hst->current_notification_number == 0 && hst->current_state != HOST_UP) { + + /* determine the time to use of the first problem point */ + first_problem_time = hst->last_time_up; /* not accurate, but its the earliest time we could use in the comparison */ + if((hst->last_time_down < first_problem_time) && (hst->last_time_down > hst->last_time_up)) + first_problem_time = hst->last_time_down; + if((hst->last_time_unreachable < first_problem_time) && (hst->last_time_unreachable > hst->last_time_unreachable)) + first_problem_time = hst->last_time_unreachable; + + if(current_time < (time_t)((first_problem_time == (time_t)0L) ? program_start : first_problem_time) + (time_t)(hst->first_notification_delay * interval_length)) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Not enough time has elapsed since the host changed to a non-UP state (or since program start), so we shouldn't notify about this problem yet.\n"); + return ERROR; + } + } + + /* if this host is currently flapping, don't send the notification */ + if(hst->is_flapping == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This host is currently flapping, so we won't send notifications.\n"); + return ERROR; + } + + /***** RECOVERY NOTIFICATIONS ARE GOOD TO GO AT THIS POINT *****/ + if(hst->current_state == HOST_UP) + return OK; + + /* if this host is currently in a scheduled downtime period, don't send the notification */ + if(hst->scheduled_downtime_depth > 0) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This host is currently in a scheduled downtime, so we won't send notifications.\n"); + return ERROR; + } + + /* check if we shouldn't renotify contacts about the host problem */ + if(hst->no_more_notifications == TRUE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "We shouldn't re-notify contacts about this host problem.\n"); + return ERROR; + } + + /* check if its time to re-notify the contacts about the host... */ + if(current_time < hst->next_host_notification) { + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Its not yet time to re-notify the contacts about this host problem...\n"); + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Next acceptable notification time: %s", ctime(&hst->next_host_notification)); + return ERROR; + } + + return OK; + } + + + +/* checks the viability of notifying a specific contact about a host */ +int check_contact_host_notification_viability(contact *cntct, host *hst, int type, int options) { + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_contact_host_notification_viability()\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Checking host notification viability for contact '%s'...\n", cntct->name); + + /* forced notifications bust through everything */ + if(options & NOTIFICATION_OPTION_FORCED) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "This is a forced host notification, so we'll send it out for this contact.\n"); + return OK; + } + + /* are notifications enabled? */ + if(cntct->host_notifications_enabled == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Host notifications are disabled for this contact.\n"); + return ERROR; + } + + /* see if the contact can be notified at this time */ + if(check_time_against_period(time(NULL), cntct->host_notification_period_ptr) == ERROR) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "This contact shouldn't be notified at this time.\n"); + return ERROR; + } + + + /*********************************************/ + /*** SPECIAL CASE FOR CUSTOM NOTIFICATIONS ***/ + /*********************************************/ + + /* custom notifications are good to go at this point... */ + if(type == NOTIFICATION_CUSTOM) + return OK; + + + /****************************************/ + /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ + /****************************************/ + + if(type == NOTIFICATION_FLAPPINGSTART || type == NOTIFICATION_FLAPPINGSTOP || type == NOTIFICATION_FLAPPINGDISABLED) { + + if(cntct->notify_on_host_flapping == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about FLAPPING host events.\n"); + return ERROR; + } + + return OK; + } + + + /****************************************/ + /*** SPECIAL CASE FOR DOWNTIME ALERTS ***/ + /****************************************/ + + if(type == NOTIFICATION_DOWNTIMESTART || type == NOTIFICATION_DOWNTIMEEND || type == NOTIFICATION_DOWNTIMECANCELLED) { + + if(cntct->notify_on_host_downtime == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about DOWNTIME host events.\n"); + return ERROR; + } + + return OK; + } + + + /*************************************/ + /*** ACKS AND NORMAL NOTIFICATIONS ***/ + /*************************************/ + + /* see if we should notify about problems with this host */ + if(hst->current_state == HOST_DOWN && cntct->notify_on_host_down == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about DOWN states.\n"); + return ERROR; + } + + if(hst->current_state == HOST_UNREACHABLE && cntct->notify_on_host_unreachable == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about UNREACHABLE states,\n"); + return ERROR; + } + + if(hst->current_state == HOST_UP) { + + if(cntct->notify_on_host_recovery == FALSE) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify this contact about RECOVERY states.\n"); + return ERROR; + } + + if(!((hst->notified_on_down == TRUE && cntct->notify_on_host_down == TRUE) || (hst->notified_on_unreachable == TRUE && cntct->notify_on_host_unreachable == TRUE))) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "We shouldn't notify about this recovery.\n"); + return ERROR; + } + + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Host notification viability for contact '%s' PASSED.\n", cntct->name); + + return OK; + } + + + +/* notify a specific contact that an entire host is down or up */ +int notify_contact_of_host(nagios_macros *mac, contact *cntct, host *hst, int type, char *not_author, char *not_data, int options, int escalated) { + commandsmember *temp_commandsmember = NULL; + char *command_name = NULL; + char *command_name_ptr = NULL; + char *temp_buffer = NULL; + char *processed_buffer = NULL; + char *raw_command = NULL; + char *processed_command = NULL; + int early_timeout = FALSE; + double exectime; + struct timeval start_time; + struct timeval end_time; + struct timeval method_start_time; + struct timeval method_end_time; + int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; + int neb_result; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "notify_contact_of_host()\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "** Notifying contact '%s'\n", cntct->name); + + /* get start time */ + gettimeofday(&start_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + neb_result = broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_NOTIFICATION, type, start_time, end_time, (void *)hst, cntct, not_author, not_data, escalated, NULL); + if(NEBERROR_CALLBACKCANCEL == neb_result) + return ERROR; + else if(NEBERROR_CALLBACKOVERRIDE == neb_result) + return OK; +#endif + + /* process all the notification commands this user has */ + for(temp_commandsmember = cntct->host_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) { + + /* get start time */ + gettimeofday(&method_start_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + method_end_time.tv_sec = 0L; + method_end_time.tv_usec = 0L; + neb_result = broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_NOTIFICATION, type, method_start_time, method_end_time, (void *)hst, cntct, temp_commandsmember->command, not_author, not_data, escalated, NULL); + if(NEBERROR_CALLBACKCANCEL == neb_result) + break ; + else if(NEBERROR_CALLBACKOVERRIDE == neb_result) + continue ; +#endif + + /* get the raw command line */ + get_raw_command_line_r(mac, temp_commandsmember->command_ptr, temp_commandsmember->command, &raw_command, macro_options); + if(raw_command == NULL) + continue; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Raw notification command: %s\n", raw_command); + + /* process any macros contained in the argument */ + process_macros_r(mac, raw_command, &processed_command, macro_options); + my_free(raw_command); + if(processed_command == NULL) + continue; + + /* get the command name */ + command_name = (char *)strdup(temp_commandsmember->command); + command_name_ptr = strtok(command_name, "!"); + + /* run the notification command... */ + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Processed notification command: %s\n", processed_command); + + /* log the notification to program log file */ + if(log_notifications == TRUE) { + switch(type) { + case NOTIFICATION_CUSTOM: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;CUSTOM ($HOSTSTATE$);%s;$HOSTOUTPUT$;$NOTIFICATIONAUTHOR$;$NOTIFICATIONCOMMENT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_ACKNOWLEDGEMENT: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;ACKNOWLEDGEMENT ($HOSTSTATE$);%s;$HOSTOUTPUT$;$NOTIFICATIONAUTHOR$;$NOTIFICATIONCOMMENT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_FLAPPINGSTART: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;FLAPPINGSTART ($HOSTSTATE$);%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_FLAPPINGSTOP: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;FLAPPINGSTOP ($HOSTSTATE$);%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_FLAPPINGDISABLED: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;FLAPPINGDISABLED ($HOSTSTATE$);%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_DOWNTIMESTART: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;DOWNTIMESTART ($HOSTSTATE$);%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_DOWNTIMEEND: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;DOWNTIMEEND ($HOSTSTATE$);%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + case NOTIFICATION_DOWNTIMECANCELLED: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;DOWNTIMECANCELLED ($HOSTSTATE$);%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + default: + asprintf(&temp_buffer, "HOST NOTIFICATION: %s;%s;$HOSTSTATE$;%s;$HOSTOUTPUT$\n", cntct->name, hst->name, command_name_ptr); + break; + } + + process_macros_r(mac, temp_buffer, &processed_buffer, 0); + write_to_all_logs(processed_buffer, NSLOG_HOST_NOTIFICATION); + + my_free(temp_buffer); + my_free(processed_buffer); + } + + /* run the notification command */ + my_system_r(mac, processed_command, notification_timeout, &early_timeout, &exectime, NULL, 0); + + /* check to see if the notification timed out */ + if(early_timeout == TRUE) { + logit(NSLOG_HOST_NOTIFICATION | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Contact '%s' host notification command '%s' timed out after %d seconds\n", cntct->name, processed_command, notification_timeout); + } + + /* free memory */ + my_free(command_name); + my_free(processed_command); + + /* get end time */ + gettimeofday(&method_end_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_NOTIFICATION, type, method_start_time, method_end_time, (void *)hst, cntct, temp_commandsmember->command, not_author, not_data, escalated, NULL); +#endif + } + + /* get end time */ + gettimeofday(&end_time, NULL); + + /* update the contact's last host notification time */ + cntct->last_host_notification = start_time.tv_sec; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_NOTIFICATION, type, start_time, end_time, (void *)hst, cntct, not_author, not_data, escalated, NULL); +#endif + + return OK; + } + + +/* checks to see if a host escalation entry is a match for the current host notification */ +int is_valid_escalation_for_host_notification(host *hst, hostescalation *he, int options) { + int notification_number = 0; + time_t current_time = 0L; + host *temp_host = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "is_valid_escalation_for_host_notification()\n"); + + /* get the current time */ + time(¤t_time); + + /* if this is a recovery, really we check for who got notified about a previous problem */ + if(hst->current_state == HOST_UP) + notification_number = hst->current_notification_number - 1; + else + notification_number = hst->current_notification_number; + + /* find the host this escalation entry is associated with */ + temp_host = he->host_ptr; + if(temp_host == NULL || temp_host != hst) + return FALSE; + + /*** EXCEPTION ***/ + /* broadcast options go to everyone, so this escalation is valid */ + if(options & NOTIFICATION_OPTION_BROADCAST) + return TRUE; + + /* skip this escalation if it happens later */ + if(he->first_notification > notification_number) + return FALSE; + + /* skip this escalation if it has already passed */ + if(he->last_notification != 0 && he->last_notification < notification_number) + return FALSE; + + /* skip this escalation if it has a timeperiod and the current time isn't valid */ + if(he->escalation_period != NULL && check_time_against_period(current_time, he->escalation_period_ptr) == ERROR) + return FALSE; + + /* skip this escalation if the state options don't match */ + if(hst->current_state == HOST_UP && he->escalate_on_recovery == FALSE) + return FALSE; + else if(hst->current_state == HOST_DOWN && he->escalate_on_down == FALSE) + return FALSE; + else if(hst->current_state == HOST_UNREACHABLE && he->escalate_on_unreachable == FALSE) + return FALSE; + + return TRUE; + } + + + +/* checks to see whether a host notification should be escalation */ +int should_host_notification_be_escalated(host *hst) { + hostescalation *temp_he = NULL; + void *ptr = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "should_host_notification_be_escalated()\n"); + + if(hst == NULL) + return FALSE; + + /* search the host escalation list */ + for(temp_he = get_first_hostescalation_by_host(hst->name, &ptr); temp_he != NULL; temp_he = get_next_hostescalation_by_host(hst->name, &ptr)) { + + /* we found a matching entry, so escalate this notification! */ + if(is_valid_escalation_for_host_notification(hst, temp_he, NOTIFICATION_OPTION_NONE) == TRUE) + return TRUE; + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Host notification will NOT be escalated.\n"); + + return FALSE; + } + + +/* given a host, create a list of contacts to be notified, removing duplicates, checking contact notification viability */ +int create_notification_list_from_host(nagios_macros *mac, host *hst, int options, int *escalated, int type) { + hostescalation *temp_he = NULL; + contactsmember *temp_contactsmember = NULL; + contact *temp_contact = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + contactgroup *temp_contactgroup = NULL; + int escalate_notification = FALSE; + void *ptr = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "create_notification_list_from_host()\n"); + + /* see if this notification should be escalated */ + escalate_notification = should_host_notification_be_escalated(hst); + + /* set the escalation flag */ + *escalated = escalate_notification; + + /* make sure there aren't any leftover contacts */ + free_notification_list(); + + /* set the escalation macro */ + mac->x[MACRO_NOTIFICATIONISESCALATED] = strdup(escalate_notification ? "1" : "0"); + + if(options & NOTIFICATION_OPTION_BROADCAST) + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "This notification will be BROADCAST to all (escalated and normal) contacts...\n"); + + /* use escalated contacts for this notification */ + if(escalate_notification == TRUE || (options & NOTIFICATION_OPTION_BROADCAST)) { + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Adding contacts from host escalation(s) to notification list.\n"); + + /* check all the host escalation entries */ + for(temp_he = get_first_hostescalation_by_host(hst->name, &ptr); temp_he != NULL; temp_he = get_next_hostescalation_by_host(hst->name, &ptr)) { + + /* see if this escalation if valid for this notification */ + if(is_valid_escalation_for_host_notification(hst, temp_he, options) == FALSE) + continue; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding individual contacts from host escalation(s) to notification list.\n"); + + /* add all individual contacts for this escalation */ + for(temp_contactsmember = temp_he->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_host_notification_viability(temp_contact, hst, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact groups from host escalation(s) to notification list.\n"); + + /* add all contacts that belong to contactgroups for this escalation */ + for(temp_contactgroupsmember = temp_he->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact group '%s' for host escalation to notification list.\n", temp_contactgroupsmember->group_name); + if((temp_contactgroup = temp_contactgroupsmember->group_ptr) == NULL) + continue; + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_host_notification_viability(temp_contact, hst, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + } + } + } + + /* use normal, non-escalated contacts for this notification */ + if(escalate_notification == FALSE || (options & NOTIFICATION_OPTION_BROADCAST)) { + + log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Adding normal contacts for host to notification list.\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding individual contacts for host to notification list.\n"); + + /* add all individual contacts for this host */ + for(temp_contactsmember = hst->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_host_notification_viability(temp_contact, hst, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact groups for host to notification list.\n"); + + /* add all contacts that belong to contactgroups for this host */ + for(temp_contactgroupsmember = hst->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding members of contact group '%s' for host to notification list.\n", temp_contactgroupsmember->group_name); + + if((temp_contactgroup = temp_contactgroupsmember->group_ptr) == NULL) + continue; + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + /* check now if the contact can be notified */ + if(check_contact_host_notification_viability(temp_contact, hst, type, options) == OK) + add_notification(mac, temp_contact); + else + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Not adding contact '%s'\n", temp_contact->name); + } + } + } + + return OK; + } + + + + +/******************************************************************/ +/***************** NOTIFICATION TIMING FUNCTIONS ******************/ +/******************************************************************/ + + +/* calculates next acceptable re-notification time for a service */ +time_t get_next_service_notification_time(service *svc, time_t offset) { + time_t next_notification = 0L; + double interval_to_use = 0.0; + serviceescalation *temp_se = NULL; + int have_escalated_interval = FALSE; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "get_next_service_notification_time()\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Calculating next valid notification time...\n"); + + /* default notification interval */ + interval_to_use = svc->notification_interval; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Default interval: %f\n", interval_to_use); + + /* search all the escalation entries for valid matches for this service (at its current notification number) */ + for(temp_se = serviceescalation_list; temp_se != NULL; temp_se = temp_se->next) { + + /* interval < 0 means to use non-escalated interval */ + if(temp_se->notification_interval < 0.0) + continue; + + /* skip this entry if it isn't appropriate */ + if(is_valid_escalation_for_service_notification(svc, temp_se, NOTIFICATION_OPTION_NONE) == FALSE) + continue; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Found a valid escalation w/ interval of %f\n", temp_se->notification_interval); + + /* if we haven't used a notification interval from an escalation yet, use this one */ + if(have_escalated_interval == FALSE) { + have_escalated_interval = TRUE; + interval_to_use = temp_se->notification_interval; + } + + /* else use the shortest of all valid escalation intervals */ + else if(temp_se->notification_interval < interval_to_use) + interval_to_use = temp_se->notification_interval; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "New interval: %f\n", interval_to_use); + } + + /* if notification interval is 0, we shouldn't send any more problem notifications (unless service is volatile) */ + if(interval_to_use == 0.0 && svc->is_volatile == FALSE) + svc->no_more_notifications = TRUE; + else + svc->no_more_notifications = FALSE; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Interval used for calculating next valid notification time: %f\n", interval_to_use); + + /* calculate next notification time */ + next_notification = offset + (interval_to_use * interval_length); + + return next_notification; + } + + + +/* calculates next acceptable re-notification time for a host */ +time_t get_next_host_notification_time(host *hst, time_t offset) { + time_t next_notification = 0L; + double interval_to_use = 0.0; + hostescalation *temp_he = NULL; + int have_escalated_interval = FALSE; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "get_next_host_notification_time()\n"); + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Calculating next valid notification time...\n"); + + /* default notification interval */ + interval_to_use = hst->notification_interval; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Default interval: %f\n", interval_to_use); + + /* check all the host escalation entries for valid matches for this host (at its current notification number) */ + for(temp_he = hostescalation_list; temp_he != NULL; temp_he = temp_he->next) { + + /* interval < 0 means to use non-escalated interval */ + if(temp_he->notification_interval < 0.0) + continue; + + /* skip this entry if it isn't appropriate */ + if(is_valid_escalation_for_host_notification(hst, temp_he, NOTIFICATION_OPTION_NONE) == FALSE) + continue; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Found a valid escalation w/ interval of %f\n", temp_he->notification_interval); + + /* if we haven't used a notification interval from an escalation yet, use this one */ + if(have_escalated_interval == FALSE) { + have_escalated_interval = TRUE; + interval_to_use = temp_he->notification_interval; + } + + /* else use the shortest of all valid escalation intervals */ + else if(temp_he->notification_interval < interval_to_use) + interval_to_use = temp_he->notification_interval; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "New interval: %f\n", interval_to_use); + } + + /* if interval is 0, no more notifications should be sent */ + if(interval_to_use == 0.0) + hst->no_more_notifications = TRUE; + else + hst->no_more_notifications = FALSE; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Interval used for calculating next valid notification time: %f\n", interval_to_use); + + /* calculate next notification time */ + next_notification = offset + (interval_to_use * interval_length); + + return next_notification; + } + + + +/******************************************************************/ +/***************** NOTIFICATION OBJECT FUNCTIONS ******************/ +/******************************************************************/ + + +/* given a contact name, find the notification entry for them for the list in memory */ +notification * find_notification(contact *cntct) { + notification *temp_notification = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "find_notification() start\n"); + + if(cntct == NULL) + return NULL; + + for(temp_notification = notification_list; temp_notification != NULL; temp_notification = temp_notification->next) { + if(temp_notification->contact == cntct) + return temp_notification; + } + + /* we couldn't find the contact in the notification list */ + return NULL; + } + + + +/* add a new notification to the list in memory */ +int add_notification(nagios_macros *mac, contact *cntct) { + notification *new_notification = NULL; + notification *temp_notification = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "add_notification() start\n"); + + if(cntct == NULL) + return ERROR; + + log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Adding contact '%s' to notification list.\n", cntct->name); + + /* don't add anything if this contact is already on the notification list */ + if((temp_notification = find_notification(cntct)) != NULL) + return OK; + + /* allocate memory for a new contact in the notification list */ + if((new_notification = malloc(sizeof(notification))) == NULL) + return ERROR; + + /* fill in the contact info */ + new_notification->contact = cntct; + + /* add new notification to head of list */ + new_notification->next = notification_list; + notification_list = new_notification; + + /* add contact to notification recipients macro */ + if(mac->x[MACRO_NOTIFICATIONRECIPIENTS] == NULL) + mac->x[MACRO_NOTIFICATIONRECIPIENTS] = (char *)strdup(cntct->name); + else { + if((mac->x[MACRO_NOTIFICATIONRECIPIENTS] = (char *)realloc(mac->x[MACRO_NOTIFICATIONRECIPIENTS], strlen(mac->x[MACRO_NOTIFICATIONRECIPIENTS]) + strlen(cntct->name) + 2))) { + strcat(mac->x[MACRO_NOTIFICATIONRECIPIENTS], ","); + strcat(mac->x[MACRO_NOTIFICATIONRECIPIENTS], cntct->name); + } + } + + return OK; + } diff --git a/base/perfdata.c b/base/perfdata.c new file mode 100644 index 0000000..111082d --- /dev/null +++ b/base/perfdata.c @@ -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; + } diff --git a/base/sehandlers.c b/base/sehandlers.c new file mode 100644 index 0000000..fbecc07 --- /dev/null +++ b/base/sehandlers.c @@ -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; + } + + + diff --git a/base/sretention.c b/base/sretention.c new file mode 100644 index 0000000..b0ede5b --- /dev/null +++ b/base/sretention.c @@ -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; + } + + + diff --git a/base/utils.c b/base/utils.c new file mode 100644 index 0000000..da3de8b --- /dev/null +++ b/base/utils.c @@ -0,0 +1,4526 @@ +/***************************************************************************** + * + * UTILS.C - Miscellaneous utility functions for Nagios + * + * Copyright (c) 1999-2009 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 06-16-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. + * + *****************************************************************************/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/statusdata.h" +#include "../include/comments.h" +#include "../include/macros.h" +#include "../include/nagios.h" +#include "../include/netutils.h" +#include "../include/broker.h" +#include "../include/nebmods.h" +#include "../include/nebmodules.h" + + +#ifdef EMBEDDEDPERL +#include "../include/epn_nagios.h" +static PerlInterpreter *my_perl = NULL; +int use_embedded_perl = TRUE; +#endif + +extern char *config_file; +extern char *log_file; +extern char *command_file; +extern char *temp_file; +extern char *temp_path; +extern char *check_result_path; +extern char *check_result_path; +extern char *lock_file; +extern char *log_archive_path; +extern char *auth_file; +extern char *p1_file; + +extern char *xodtemplate_cache_file; +extern char *xodtemplate_precache_file; +extern char *xsddefault_status_log; +extern char *xrddefault_retention_file; +extern char *xpddefault_host_perfdata_file; +extern char *xpddefault_service_perfdata_file; + +extern char *nagios_user; +extern char *nagios_group; + +extern char *macro_x_names[MACRO_X_COUNT]; +extern char *macro_user[MAX_USER_MACROS]; +extern customvariablesmember *macro_custom_host_vars; +extern customvariablesmember *macro_custom_service_vars; +extern customvariablesmember *macro_custom_contact_vars; + +extern host *macro_host_ptr; +extern hostgroup *macro_hostgroup_ptr; +extern service *macro_service_ptr; +extern servicegroup *macro_servicegroup_ptr; +extern contact *macro_contact_ptr; +extern contactgroup *macro_contactgroup_ptr; + +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 char *illegal_object_chars; +extern char *illegal_output_chars; + +extern int use_regexp_matches; +extern int use_true_regexp_matching; + +extern int sigshutdown; +extern int sigrestart; +extern char *sigs[35]; +extern int caught_signal; +extern int sig_id; + +extern int daemon_mode; +extern int daemon_dumps_core; + +extern int nagios_pid; + +extern int use_syslog; +extern int log_notifications; +extern int log_service_retries; +extern int log_host_retries; +extern int log_event_handlers; +extern int log_external_commands; +extern int log_passive_checks; + +extern unsigned long logging_options; +extern unsigned long syslog_options; + +extern int service_check_timeout; +extern int service_check_timeout_state; +extern int host_check_timeout; +extern int event_handler_timeout; +extern int notification_timeout; +extern int ocsp_timeout; +extern int ochp_timeout; + +extern int log_initial_states; + +extern double sleep_time; +extern int interval_length; +extern int service_inter_check_delay_method; +extern int host_inter_check_delay_method; +extern int service_interleave_factor_method; +extern int max_host_check_spread; +extern int max_service_check_spread; + +extern int command_check_interval; +extern int check_reaper_interval; +extern int max_check_reaper_time; +extern int service_freshness_check_interval; +extern int host_freshness_check_interval; +extern int auto_rescheduling_interval; +extern int auto_rescheduling_window; + +extern int check_external_commands; +extern int check_orphaned_services; +extern int check_orphaned_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int auto_reschedule_checks; + +extern int additional_freshness_latency; + +extern int check_for_updates; +extern int bare_update_check; +extern time_t last_update_check; +extern unsigned long update_uid; +extern char *last_program_version; +extern int update_available; +extern char *last_program_version; +extern char *new_program_version; + +extern int use_aggressive_host_checking; +extern unsigned long cached_host_check_horizon; +extern unsigned long cached_service_check_horizon; +extern int enable_predictive_host_dependency_checks; +extern int enable_predictive_service_dependency_checks; + +extern int soft_state_dependencies; + +extern int retain_state_information; +extern int retention_update_interval; +extern int use_retained_program_state; +extern int use_retained_scheduling_info; +extern int retention_scheduling_horizon; +extern unsigned long modified_host_process_attributes; +extern unsigned long modified_service_process_attributes; +extern unsigned long retained_host_attribute_mask; +extern unsigned long retained_service_attribute_mask; +extern unsigned long retained_contact_host_attribute_mask; +extern unsigned long retained_contact_service_attribute_mask; +extern unsigned long retained_process_host_attribute_mask; +extern unsigned long retained_process_service_attribute_mask; + +extern unsigned long next_comment_id; +extern unsigned long next_downtime_id; +extern unsigned long next_event_id; +extern unsigned long next_notification_id; + +extern int log_rotation_method; + +extern time_t program_start; + +extern time_t last_command_check; +extern time_t last_command_status_update; +extern time_t last_log_rotation; + +extern int verify_config; +extern int test_scheduling; + +extern check_result check_result_info; + +extern int max_parallel_service_checks; +extern int currently_running_service_checks; + +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int enable_failure_prediction; +extern int process_performance_data; + +extern int translate_passive_host_checks; +extern int passive_host_checks_are_soft; + +extern int aggregate_status_updates; +extern int status_update_interval; + +extern int time_change_threshold; + +extern unsigned long event_broker_options; + +extern int process_performance_data; + +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 int use_large_installation_tweaks; +extern int enable_environment_macros; +extern int free_child_process_memory; +extern int child_processes_fork_twice; + +extern int enable_embedded_perl; +extern int use_embedded_perl_implicitly; + +extern int date_format; + +extern contact *contact_list; +extern contactgroup *contactgroup_list; +extern host *host_list; +extern hostgroup *hostgroup_list; +extern service *service_list; +extern servicegroup *servicegroup_list; +extern timed_event *event_list_high; +extern timed_event *event_list_low; +extern notification *notification_list; +extern command *command_list; +extern timeperiod *timeperiod_list; + +extern int command_file_fd; +extern FILE *command_file_fp; +extern int command_file_created; + +#ifdef HAVE_TZNAME +#ifdef CYGWIN +extern char *_tzname[2] __declspec(dllimport); +#else +extern char *tzname[2]; +#endif +#endif + +extern check_result *check_result_list; +extern unsigned long max_check_result_file_age; + +extern dbuf check_result_dbuf; + +extern pthread_t worker_threads[TOTAL_WORKER_THREADS]; +extern circular_buffer external_command_buffer; +extern circular_buffer check_result_buffer; +extern circular_buffer event_broker_buffer; +extern int external_command_buffer_slots; + +extern check_stats check_statistics[MAX_CHECK_STATS_TYPES]; + +extern char *debug_file; +extern int debug_level; +extern int debug_verbosity; +extern unsigned long max_debug_file_size; + +/* from GNU defines errno as a macro, since it's a per-thread variable */ +#ifndef errno +extern int errno; +#endif + + +static long long check_file_size(char *, unsigned long, struct rlimit); + +/******************************************************************/ +/******************** SYSTEM COMMAND FUNCTIONS ********************/ +/******************************************************************/ + + +/* executes a system command - used for notifications, event handlers, etc. */ +int my_system_r(nagios_macros *mac, char *cmd, int timeout, int *early_timeout, double *exectime, char **output, int max_output_length) { + pid_t pid = 0; + int status = 0; + int result = 0; + char buffer[MAX_INPUT_BUFFER] = ""; + char *temp_buffer = NULL; + int fd[2]; + FILE *fp = NULL; + int bytes_read = 0; + struct timeval start_time, end_time; + dbuf output_dbuf; + int dbuf_chunk = 1024; + int flags; +#ifdef EMBEDDEDPERL + char fname[512] = ""; + char *args[5] = {"", DO_CLEAN, "", "", NULL }; + SV *plugin_hndlr_cr = NULL; + char *perl_output = NULL; + int count; + int use_epn = FALSE; +#ifdef aTHX + dTHX; +#endif + dSP; +#endif + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "my_system_r()\n"); + + /* initialize return variables */ + if(output != NULL) + *output = NULL; + *early_timeout = FALSE; + *exectime = 0.0; + + /* if no command was passed, return with no error */ + if(cmd == NULL) + return STATE_OK; + + log_debug_info(DEBUGL_COMMANDS, 1, "Running command '%s'...\n", cmd); + +#ifdef EMBEDDEDPERL + + /* get"filename" component of command */ + strncpy(fname, cmd, strcspn(cmd, " ")); + fname[strcspn(cmd, " ")] = '\x0'; + + /* should we use the embedded Perl interpreter to run this script? */ + use_epn = file_uses_embedded_perl(fname); + + /* if yes, do some initialization */ + if(use_epn == TRUE) { + + args[0] = fname; + args[2] = ""; + + if(strchr(cmd, ' ') == NULL) + args[3] = ""; + else + args[3] = cmd + strlen(fname) + 1; + + /* call our perl interpreter to compile and optionally cache the compiled script. */ + + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(sv_2mortal(newSVpv(args[2], 0))); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + call_pv("Embed::Persistent::eval_file", G_EVAL); + + SPAGAIN; + + if(SvTRUE(ERRSV)) { + /* + * XXXX need pipe open to send the compilation failure message back to Nagios ? + */ + (void) POPs ; + + asprintf(&temp_buffer, "%s", SvPVX(ERRSV)); + + log_debug_info(DEBUGL_COMMANDS, 0, "Embedded perl failed to compile %s, compile error %s\n", fname, temp_buffer); + + logit(NSLOG_RUNTIME_WARNING, TRUE, "%s\n", temp_buffer); + + my_free(temp_buffer); + + return STATE_UNKNOWN; + } + else { + plugin_hndlr_cr = newSVsv(POPs); + + log_debug_info(DEBUGL_COMMANDS, 0, "Embedded perl successfully compiled %s and returned plugin handler (Perl subroutine code ref)\n", fname); + + PUTBACK ; + FREETMPS ; + LEAVE ; + } + } +#endif + + /* create a pipe */ + pipe(fd); + + /* make the pipe non-blocking */ + fcntl(fd[0], F_SETFL, O_NONBLOCK); + fcntl(fd[1], F_SETFL, O_NONBLOCK); + + /* get the command start time */ + gettimeofday(&start_time, NULL); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + end_time.tv_sec = 0L; + end_time.tv_usec = 0L; + broker_system_command(NEBTYPE_SYSTEM_COMMAND_START, NEBFLAG_NONE, NEBATTR_NONE, start_time, end_time, *exectime, timeout, *early_timeout, result, cmd, NULL, NULL); +#endif + + /* fork */ + pid = fork(); + + /* return an error if we couldn't fork */ + if(pid == -1) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: fork() in my_system_r() failed for command \"%s\"\n", cmd); + + /* close both ends of the pipe */ + close(fd[0]); + close(fd[1]); + + return STATE_UNKNOWN; + } + + /* execute the command in the child process */ + if(pid == 0) { + + /* become process group leader */ + setpgid(0, 0); + + /* set environment variables */ + set_all_macro_environment_vars_r(mac, TRUE); + + /* ADDED 11/12/07 EG */ + /* close external command file and shut down worker thread */ + close_command_file(); + + /* reset signal handling */ + reset_sighandler(); + + /* close pipe for reading */ + close(fd[0]); + + /* prevent fd from being inherited by child processed */ + flags = fcntl(fd[1], F_GETFD, 0); + flags |= FD_CLOEXEC; + fcntl(fd[1], F_SETFD, flags); + + /* trap commands that timeout */ + signal(SIGALRM, my_system_sighandler); + alarm(timeout); + + + /******** BEGIN EMBEDDED PERL CODE EXECUTION ********/ + +#ifdef EMBEDDEDPERL + if(use_epn == TRUE) { + + /* execute our previously compiled script - by call_pv("Embed::Persistent::eval_file",..) */ + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(plugin_hndlr_cr); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + count = call_pv("Embed::Persistent::run_package", G_ARRAY); + /* count is a debug hook. It should always be two (2), because the persistence framework tries to return two (2) args */ + + SPAGAIN; + + perl_output = POPpx ; + strip(perl_output); + strncpy(buffer, (perl_output == NULL) ? "" : perl_output, sizeof(buffer)); + buffer[sizeof(buffer) - 1] = '\x0'; + status = POPi ; + + PUTBACK; + FREETMPS; + LEAVE; + + log_debug_info(DEBUGL_COMMANDS, 0, "Embedded perl ran command %s with output %d, %s\n", fname, status, buffer); + + /* write the output back to the parent process */ + write(fd[1], buffer, strlen(buffer) + 1); + + /* close pipe for writing */ + close(fd[1]); + + /* reset the alarm */ + alarm(0); + + _exit(status); + } +#endif + /******** END EMBEDDED PERL CODE EXECUTION ********/ + + + /* run the command */ + fp = (FILE *)popen(cmd, "r"); + + /* report an error if we couldn't run the command */ + if(fp == NULL) { + + strncpy(buffer, "(Error: Could not execute command)\n", sizeof(buffer) - 1); + buffer[sizeof(buffer) - 1] = '\x0'; + + /* write the error back to the parent process */ + write(fd[1], buffer, strlen(buffer) + 1); + + result = STATE_CRITICAL; + } + else { + + /* write all the lines of output back to the parent process */ + while(fgets(buffer, sizeof(buffer) - 1, fp)) + write(fd[1], buffer, strlen(buffer)); + + /* close the command and get termination status */ + status = pclose(fp); + + /* report an error if we couldn't close the command */ + if(status == -1) + result = STATE_CRITICAL; + else { + if(WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) + result = 128 + WTERMSIG(status); + result = WEXITSTATUS(status); + } + } + + /* close pipe for writing */ + close(fd[1]); + + /* reset the alarm */ + alarm(0); + + /* clear environment variables */ + set_all_macro_environment_vars_r(mac, FALSE); + +#ifndef DONT_USE_MEMORY_PERFORMANCE_TWEAKS + /* free allocated memory */ + /* this needs to be done last, so we don't free memory for variables before they're used above */ + if(free_child_process_memory == TRUE) + free_memory(mac); +#endif + + _exit(result); + } + + /* parent waits for child to finish executing command */ + else { + + /* close pipe for writing */ + close(fd[1]); + + /* wait for child to exit */ + waitpid(pid, &status, 0); + + /* get the end time for running the command */ + gettimeofday(&end_time, NULL); + + /* return execution time in milliseconds */ + *exectime = (double)((double)(end_time.tv_sec - start_time.tv_sec) + (double)((end_time.tv_usec - start_time.tv_usec) / 1000) / 1000.0); + if(*exectime < 0.0) + *exectime = 0.0; + + /* get the exit code returned from the program */ + result = WEXITSTATUS(status); + + /* check for possibly missing scripts/binaries/etc */ + if(result == 126 || result == 127) { + temp_buffer = "\163\157\151\147\141\156\040\145\144\151\163\156\151"; + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Attempting to execute the command \"%s\" resulted in a return code of %d. Make sure the script or binary you are trying to execute actually exists...\n", cmd, result); + } + + /* check bounds on the return value */ + if(result < -1 || result > 3) + result = STATE_UNKNOWN; + + /* initialize dynamic buffer */ + dbuf_init(&output_dbuf, dbuf_chunk); + + /* Opsera patch to check timeout before attempting to read output via pipe. Originally by Sven Nierlein */ + /* if there was a critical return code AND the command time exceeded the timeout thresholds, assume a timeout */ + if(result == STATE_CRITICAL && (end_time.tv_sec - start_time.tv_sec) >= timeout) { + + /* set the early timeout flag */ + *early_timeout = TRUE; + + /* try to kill the command that timed out by sending termination signal to child process group */ + kill((pid_t)(-pid), SIGTERM); + sleep(1); + kill((pid_t)(-pid), SIGKILL); + } + + /* read output if timeout has not occurred */ + else { + + /* initialize output */ + strcpy(buffer, ""); + + /* try and read the results from the command output (retry if we encountered a signal) */ + do { + bytes_read = read(fd[0], buffer, sizeof(buffer) - 1); + + /* append data we just read to dynamic buffer */ + if(bytes_read > 0) { + buffer[bytes_read] = '\x0'; + dbuf_strcat(&output_dbuf, buffer); + } + + /* handle errors */ + if(bytes_read == -1) { + /* we encountered a recoverable error, so try again */ + if(errno == EINTR) + continue; + /* patch by Henning Brauer to prevent CPU hogging */ + else if(errno == EAGAIN) { + struct pollfd pfd; + + pfd.fd = fd[0]; + pfd.events = POLLIN; + poll(&pfd, 1, -1); + continue; + } + else + break; + } + + /* we're done */ + if(bytes_read == 0) + break; + + } + while(1); + + /* cap output length - this isn't necessary, but it keeps runaway plugin output from causing problems */ + if(max_output_length > 0 && output_dbuf.used_size > max_output_length) + output_dbuf.buf[max_output_length] = '\x0'; + + if(output != NULL && output_dbuf.buf) + *output = (char *)strdup(output_dbuf.buf); + + } + + log_debug_info(DEBUGL_COMMANDS, 1, "Execution time=%.3f sec, early timeout=%d, result=%d, output=%s\n", *exectime, *early_timeout, result, (output_dbuf.buf == NULL) ? "(null)" : output_dbuf.buf); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_system_command(NEBTYPE_SYSTEM_COMMAND_END, NEBFLAG_NONE, NEBATTR_NONE, start_time, end_time, *exectime, timeout, *early_timeout, result, cmd, (output_dbuf.buf == NULL) ? NULL : output_dbuf.buf, NULL); +#endif + + /* free memory */ + dbuf_free(&output_dbuf); + + /* close the pipe for reading */ + close(fd[0]); + } + + return result; + } + +/* + * For API compatibility, we must include a my_system() whose + * signature doesn't include the nagios_macros variable. + * NDOUtils uses this. Possibly other modules as well. + */ +int my_system(char *cmd, int timeout, int *early_timeout, double *exectime, char **output, int max_output_length) { + return my_system_r(get_global_macros(), cmd, timeout, early_timeout, exectime, output, max_output_length); + } + + +/* given a "raw" command, return the "expanded" or "whole" command line */ +int get_raw_command_line_r(nagios_macros *mac, command *cmd_ptr, char *cmd, char **full_command, int macro_options) { + char temp_arg[MAX_COMMAND_BUFFER] = ""; + char *arg_buffer = NULL; + register int x = 0; + register int y = 0; + register int arg_index = 0; + register int escaped = FALSE; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "get_raw_command_line_r()\n"); + + /* clear the argv macros */ + clear_argv_macros_r(mac); + + /* make sure we've got all the requirements */ + if(cmd_ptr == NULL || full_command == NULL) + return ERROR; + + log_debug_info(DEBUGL_COMMANDS | DEBUGL_CHECKS | DEBUGL_MACROS, 2, "Raw Command Input: %s\n", cmd_ptr->command_line); + + /* get the full command line */ + *full_command = (char *)strdup((cmd_ptr->command_line == NULL) ? "" : cmd_ptr->command_line); + + /* XXX: Crazy indent */ + /* get the command arguments */ + if(cmd != NULL) { + + /* skip the command name (we're about to get the arguments)... */ + for(arg_index = 0;; arg_index++) { + if(cmd[arg_index] == '!' || cmd[arg_index] == '\x0') + break; + } + + /* get each command argument */ + for(x = 0; x < MAX_COMMAND_ARGUMENTS; x++) { + + /* we reached the end of the arguments... */ + if(cmd[arg_index] == '\x0') + break; + + /* get the next argument */ + /* can't use strtok(), as that's used in process_macros... */ + for(arg_index++, y = 0; y < sizeof(temp_arg) - 1; arg_index++) { + + /* backslashes escape */ + if(cmd[arg_index] == '\\' && escaped == FALSE) { + escaped = TRUE; + continue; + } + + /* end of argument */ + if((cmd[arg_index] == '!' && escaped == FALSE) || cmd[arg_index] == '\x0') + break; + + /* normal of escaped char */ + temp_arg[y] = cmd[arg_index]; + y++; + + /* clear escaped flag */ + escaped = FALSE; + } + temp_arg[y] = '\x0'; + + /* ADDED 01/29/04 EG */ + /* process any macros we find in the argument */ + process_macros_r(mac, temp_arg, &arg_buffer, macro_options); + + mac->argv[x] = arg_buffer; + } + } + + log_debug_info(DEBUGL_COMMANDS | DEBUGL_CHECKS | DEBUGL_MACROS, 2, "Expanded Command Output: %s\n", *full_command); + + return OK; + } + +/* + * This function modifies the global macro struct and is thus not + * threadsafe + */ +int get_raw_command_line(command *cmd_ptr, char *cmd, char **full_command, int macro_options) { + nagios_macros *mac; + + mac = get_global_macros(); + return get_raw_command_line_r(mac, cmd_ptr, cmd, full_command, macro_options); + } + + + +/******************************************************************/ +/******************** ENVIRONMENT FUNCTIONS ***********************/ +/******************************************************************/ + +/* sets or unsets an environment variable */ +int set_environment_var(char *name, char *value, int set) { +#ifndef HAVE_SETENV + char *env_string = NULL; +#endif + + /* we won't mess with null variable names */ + if(name == NULL) + return ERROR; + + /* set the environment variable */ + if(set == TRUE) { + +#ifdef HAVE_SETENV + setenv(name, (value == NULL) ? "" : value, 1); +#else + /* needed for Solaris and systems that don't have setenv() */ + /* this will leak memory, but in a "controlled" way, since lost memory should be freed when the child process exits */ + asprintf(&env_string, "%s=%s", name, (value == NULL) ? "" : value); + if(env_string) + putenv(env_string); +#endif + } + /* clear the variable */ + else { +#ifdef HAVE_UNSETENV + unsetenv(name); +#endif + } + + return OK; + } + + + + +/******************************************************************/ +/************************* TIME FUNCTIONS *************************/ +/******************************************************************/ + + +/* Checks if the given time is in daylight time saving period */ +int is_dst_time(time_t *time) { + struct tm *bt = localtime(time); + return bt->tm_isdst; + } + +/* Returns the shift in seconds if the given times are across the daylight time saving period change */ +int get_dst_shift(time_t *start, time_t *end) { + int shift = 0, dst_end, dst_start; + dst_start = is_dst_time(start); + dst_end = is_dst_time(end); + if(dst_start < dst_end) { + shift = 3600; + } + else if(dst_start > dst_end) { + shift = -3600; + } + return shift; + } + +/*#define TEST_TIMEPERIODS_A 1*/ + +/* see if the specified time falls into a valid time range in the given time period */ +int check_time_against_period(time_t test_time, timeperiod *tperiod) { + timeperiodexclusion *temp_timeperiodexclusion = NULL; + timeperiodexclusion *first_timeperiodexclusion = NULL; + daterange *temp_daterange = NULL; + timerange *temp_timerange = NULL; + time_t midnight = (time_t)0L; + time_t start_time = (time_t)0L; + time_t end_time = (time_t)0L; + int found_match = FALSE; + struct tm *t, tm_s; + int daterange_type = 0; + unsigned long days = 0L; + time_t day_range_start = (time_t)0L; + time_t day_range_end = (time_t)0L; + int test_time_year = 0; + int test_time_mon = 0; + int test_time_mday = 0; + int test_time_wday = 0; + int year = 0; + int shift; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_time_against_period()\n"); + + /* if no period was specified, assume the time is good */ + if(tperiod == NULL) + return OK; + + /* test exclusions first - if exclusions match current time, bail out with an error */ + /* clear exclusions list before recursing (and restore afterwards) to prevent endless loops... */ + first_timeperiodexclusion = tperiod->exclusions; + tperiod->exclusions = NULL; + for(temp_timeperiodexclusion = first_timeperiodexclusion; temp_timeperiodexclusion != NULL; temp_timeperiodexclusion = temp_timeperiodexclusion->next) { + if(check_time_against_period(test_time, temp_timeperiodexclusion->timeperiod_ptr) == OK) { + tperiod->exclusions = first_timeperiodexclusion; + return ERROR; + } + } + tperiod->exclusions = first_timeperiodexclusion; + + /* save values for later */ + t = localtime_r((time_t *)&test_time, &tm_s); + test_time_year = t->tm_year; + test_time_mon = t->tm_mon; + test_time_mday = t->tm_mday; + test_time_wday = t->tm_wday; + + /* calculate the start of the day (midnight, 00:00 hours) when the specified test time occurs */ + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + midnight = mktime(t); + + /**** check exceptions first ****/ + for(daterange_type = 0; daterange_type < DATERANGE_TYPES; daterange_type++) { + + for(temp_daterange = tperiod->exceptions[daterange_type]; temp_daterange != NULL; temp_daterange = temp_daterange->next) { + +#ifdef TEST_TIMEPERIODS_A + printf("TYPE: %d\n", daterange_type); + printf("TEST: %lu = %s", (unsigned long)test_time, ctime(&test_time)); + printf("MIDNIGHT: %lu = %s", (unsigned long)midnight, ctime(&midnight)); +#endif + + /* get the start time */ + switch(daterange_type) { + case DATERANGE_CALENDAR_DATE: + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_wday = 0; + t->tm_mday = temp_daterange->smday; + t->tm_mon = temp_daterange->smon; + t->tm_year = (temp_daterange->syear - 1900); + t->tm_isdst = -1; + start_time = mktime(t); + break; + case DATERANGE_MONTH_DATE: + start_time = calculate_time_from_day_of_month(test_time_year, temp_daterange->smon, temp_daterange->smday); + break; + case DATERANGE_MONTH_DAY: + start_time = calculate_time_from_day_of_month(test_time_year, test_time_mon, temp_daterange->smday); + break; + case DATERANGE_MONTH_WEEK_DAY: + start_time = calculate_time_from_weekday_of_month(test_time_year, temp_daterange->smon, temp_daterange->swday, temp_daterange->swday_offset); + break; + case DATERANGE_WEEK_DAY: + start_time = calculate_time_from_weekday_of_month(test_time_year, test_time_mon, temp_daterange->swday, temp_daterange->swday_offset); + break; + default: + continue; + break; + } + + /* get the end time */ + switch(daterange_type) { + case DATERANGE_CALENDAR_DATE: + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_wday = 0; + t->tm_mday = temp_daterange->emday; + t->tm_mon = temp_daterange->emon; + t->tm_year = (temp_daterange->eyear - 1900); + t->tm_isdst = -1; + end_time = mktime(t); + break; + case DATERANGE_MONTH_DATE: + year = test_time_year; + end_time = calculate_time_from_day_of_month(year, temp_daterange->emon, temp_daterange->emday); + /* advance a year if necessary: august 2 - february 5 */ + if(end_time < start_time) { + year++; + end_time = calculate_time_from_day_of_month(year, temp_daterange->emon, temp_daterange->emday); + } + break; + case DATERANGE_MONTH_DAY: + end_time = calculate_time_from_day_of_month(test_time_year, test_time_mon, temp_daterange->emday); + break; + case DATERANGE_MONTH_WEEK_DAY: + year = test_time_year; + end_time = calculate_time_from_weekday_of_month(year, temp_daterange->emon, temp_daterange->ewday, temp_daterange->ewday_offset); + /* advance a year if necessary: thursday 2 august - monday 3 february */ + if(end_time < start_time) { + year++; + end_time = calculate_time_from_weekday_of_month(year, temp_daterange->emon, temp_daterange->ewday, temp_daterange->ewday_offset); + } + break; + case DATERANGE_WEEK_DAY: + end_time = calculate_time_from_weekday_of_month(test_time_year, test_time_mon, temp_daterange->ewday, temp_daterange->ewday_offset); + break; + default: + continue; + break; + } + +#ifdef TEST_TIMEPERIODS_A + printf("START: %lu = %s", (unsigned long)start_time, ctime(&start_time)); + printf("END: %lu = %s", (unsigned long)end_time, ctime(&end_time)); +#endif + + /* start date was bad, so skip this date range */ + if((unsigned long)start_time == 0L) + continue; + + /* end date was bad - see if we can handle the error */ + if((unsigned long)end_time == 0L) { + switch(daterange_type) { + case DATERANGE_CALENDAR_DATE: + continue; + break; + case DATERANGE_MONTH_DATE: + /* end date can't be helped, so skip it */ + if(temp_daterange->emday < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + /* use same year calculated above */ + end_time = calculate_time_from_day_of_month(year, temp_daterange->emon, -1); + break; + case DATERANGE_MONTH_DAY: + /* end date can't be helped, so skip it */ + if(temp_daterange->emday < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + end_time = calculate_time_from_day_of_month(test_time_year, test_time_mon, -1); + break; + case DATERANGE_MONTH_WEEK_DAY: + /* end date can't be helped, so skip it */ + if(temp_daterange->ewday_offset < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + /* use same year calculated above */ + end_time = calculate_time_from_day_of_month(year, test_time_mon, -1); + break; + case DATERANGE_WEEK_DAY: + /* end date can't be helped, so skip it */ + if(temp_daterange->ewday_offset < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + end_time = calculate_time_from_day_of_month(test_time_year, test_time_mon, -1); + break; + default: + continue; + break; + } + } + + /* calculate skip date start (and end) */ + if(temp_daterange->skip_interval > 1) { + + /* skip start date must be before test time */ + if(start_time > test_time) + continue; + + /* check if interval is across dlst change and gets the compensation */ + shift = get_dst_shift(&start_time, &midnight); + + /* how many days have passed between skip start date and test time? */ + days = (shift + (unsigned long)midnight - (unsigned long)start_time) / (3600 * 24); + + /* if test date doesn't fall on a skip interval day, bail out early */ + if((days % temp_daterange->skip_interval) != 0) + continue; + + /* use midnight of test date as start time */ + else + start_time = midnight; + + /* if skipping range has no end, use test date as end */ + if((daterange_type == DATERANGE_CALENDAR_DATE) && (is_daterange_single_day(temp_daterange) == TRUE)) + end_time = midnight; + } + +#ifdef TEST_TIMEPERIODS_A + printf("NEW START: %lu = %s", (unsigned long)start_time, ctime(&start_time)); + printf("NEW END: %lu = %s", (unsigned long)end_time, ctime(&end_time)); + printf("%d DAYS PASSED\n", days); + printf("DLST SHIFT: %d", shift); +#endif + + /* time falls into the range of days */ + if(midnight >= start_time && midnight <= end_time) + found_match = TRUE; + + /* found a day match, so see if time ranges are good */ + if(found_match == TRUE) { + + for(temp_timerange = temp_daterange->times; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + + /* ranges with start/end of zero mean exlude this day */ + if(temp_timerange->range_start == 0 && temp_timerange->range_end == 0) { +#ifdef TEST_TIMEPERIODS_A + printf("0 MINUTE RANGE EXCLUSION\n"); +#endif + continue; + } + + day_range_start = (time_t)(midnight + temp_timerange->range_start); + day_range_end = (time_t)(midnight + temp_timerange->range_end); + +#ifdef TEST_TIMEPERIODS_A + printf(" RANGE START: %lu (%lu) = %s", temp_timerange->range_start, (unsigned long)day_range_start, ctime(&day_range_start)); + printf(" RANGE END: %lu (%lu) = %s", temp_timerange->range_end, (unsigned long)day_range_end, ctime(&day_range_end)); +#endif + + /* if the user-specified time falls in this range, return with a positive result */ + if(test_time >= day_range_start && test_time <= day_range_end) + return OK; + } + + /* no match, so bail with error */ + return ERROR; + } + } + } + + + /**** check normal, weekly rotating schedule last ****/ + + /* check weekday time ranges */ + for(temp_timerange = tperiod->days[test_time_wday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + + day_range_start = (time_t)(midnight + temp_timerange->range_start); + day_range_end = (time_t)(midnight + temp_timerange->range_end); + + /* if the user-specified time falls in this range, return with a positive result */ + if(test_time >= day_range_start && test_time <= day_range_end) + return OK; + } + + return ERROR; + } + + + +/*#define TEST_TIMEPERIODS_B 1*/ + +/* Separate this out from public get_next_valid_time for testing, so we can mock current_time */ +void _get_next_valid_time(time_t pref_time, time_t current_time, time_t *valid_time, timeperiod *tperiod) { + time_t preferred_time = (time_t)0L; + timerange *temp_timerange; + daterange *temp_daterange; + time_t midnight = (time_t)0L; + struct tm *t, tm_s; + time_t day_start = (time_t)0L; + time_t day_range_start = (time_t)0L; + time_t day_range_end = (time_t)0L; + time_t start_time = (time_t)0L; + time_t end_time = (time_t)0L; + int have_earliest_time = FALSE; + time_t earliest_time = (time_t)0L; + time_t earliest_day = (time_t)0L; + time_t potential_time = (time_t)0L; + int weekday = 0; + int has_looped = FALSE; + int days_into_the_future = 0; + int daterange_type = 0; + unsigned long days = 0L; + unsigned long advance_interval = 0L; + int year = 0; /* new */ + int month = 0; /* new */ + + int pref_time_year = 0; + int pref_time_mon = 0; + int pref_time_mday = 0; + int pref_time_wday = 0; + int current_time_year = 0; + int current_time_mon = 0; + int current_time_mday = 0; + int current_time_wday = 0; + int shift; + + /* preferred time must be now or in the future */ + preferred_time = (pref_time < current_time) ? current_time : pref_time; + + /* if no timeperiod, go with preferred time */ + if(tperiod == NULL) { + *valid_time = preferred_time; + return; + } + + /* if the preferred time is valid in timeperiod, go with it */ + /* this is necessary because the code below won't catch exceptions where preferred day is last (or only) date in timeperiod (date range) and last valid time has already passed */ + /* performing this check and bailing out early allows us to skip having to check the next instance of a date range exception or weekday to determine the next valid time */ + if(check_time_against_period(preferred_time, tperiod) == OK) { +#ifdef TEST_TIMEPERIODS_B + printf("PREF TIME IS VALID\n"); +#endif + *valid_time = preferred_time; + return; + } + + /* calculate the start of the day (midnight, 00:00 hours) of preferred time */ + t = localtime_r(&preferred_time, &tm_s); + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + midnight = mktime(t); + + /* save pref time values for later */ + pref_time_year = t->tm_year; + pref_time_mon = t->tm_mon; + pref_time_mday = t->tm_mday; + pref_time_wday = t->tm_wday; + + /* save current time values for later */ + t = localtime_r(¤t_time, &tm_s); + current_time_year = t->tm_year; + current_time_mon = t->tm_mon; + current_time_mday = t->tm_mday; + current_time_wday = t->tm_wday; + +#ifdef TEST_TIMEPERIODS_B + printf("PREF TIME: %lu = %s", (unsigned long)preferred_time, ctime(&preferred_time)); + printf("CURRENT TIME: %lu = %s", (unsigned long)current_time, ctime(¤t_time)); + printf("PREF YEAR: %d, MON: %d, MDAY: %d, WDAY: %d\n", pref_time_year, pref_time_mon, pref_time_mday, pref_time_wday); + printf("CURRENT YEAR: %d, MON: %d, MDAY: %d, WDAY: %d\n", current_time_year, current_time_mon, current_time_mday, current_time_wday); +#endif + + /**** check exceptions (in this timeperiod definition) first ****/ + for(daterange_type = 0; daterange_type < DATERANGE_TYPES; daterange_type++) { + +#ifdef TEST_TIMEPERIODS_B + printf("TYPE: %d\n", daterange_type); +#endif + + for(temp_daterange = tperiod->exceptions[daterange_type]; temp_daterange != NULL; temp_daterange = temp_daterange->next) { + + /* get the start time */ + switch(daterange_type) { + case DATERANGE_CALENDAR_DATE: /* 2009-08-11 */ + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_mday = temp_daterange->smday; + t->tm_mon = temp_daterange->smon; + t->tm_year = (temp_daterange->syear - 1900); + t->tm_isdst = -1; + start_time = mktime(t); + break; + case DATERANGE_MONTH_DATE: /* january 1 */ + /* what year should we use? */ + year = (pref_time_year < current_time_year) ? current_time_year : pref_time_year; + /* advance an additional year if we already passed the end month date */ + if((temp_daterange->emon < current_time_mon) || ((temp_daterange->emon == current_time_mon) && temp_daterange->emday < current_time_mday)) + year++; + start_time = calculate_time_from_day_of_month(year, temp_daterange->smon, temp_daterange->smday); + break; + case DATERANGE_MONTH_DAY: /* day 3 */ + /* what year should we use? */ + year = (pref_time_year < current_time_year) ? current_time_year : pref_time_year; + /* use current month */ + month = current_time_mon; + /* advance an additional month (and possibly the year) if we already passed the end day of month */ + if(temp_daterange->emday < current_time_mday) { + /*if(month==1){*/ + if(month == 11) { + month = 0; + year++; + } + else + month++; + } + start_time = calculate_time_from_day_of_month(year, month, temp_daterange->smday); + break; + case DATERANGE_MONTH_WEEK_DAY: /* thursday 2 april */ + /* what year should we use? */ + year = (pref_time_year < current_time_year) ? current_time_year : pref_time_year; + /* calculate time of specified weekday of specific month */ + start_time = calculate_time_from_weekday_of_month(year, temp_daterange->smon, temp_daterange->swday, temp_daterange->swday_offset); + /* advance to next year if we've passed this month weekday already this year */ + if(start_time < preferred_time) { + year++; + start_time = calculate_time_from_weekday_of_month(year, temp_daterange->smon, temp_daterange->swday, temp_daterange->swday_offset); + } + break; + case DATERANGE_WEEK_DAY: /* wednesday 1 */ + /* what year should we use? */ + year = (pref_time_year < current_time_year) ? current_time_year : pref_time_year; + /* calculate time of specified weekday of month */ + start_time = calculate_time_from_weekday_of_month(year, pref_time_mon, temp_daterange->swday, temp_daterange->swday_offset); + /* advance to next month (or year) if we've passed this weekday of this month already */ + if(start_time < preferred_time) { + month = pref_time_mon; + if(month == 11) { + month = 0; + year++; + } + else + month++; + start_time = calculate_time_from_weekday_of_month(year, month, temp_daterange->swday, temp_daterange->swday_offset); + } + break; + default: + continue; + break; + } + +#ifdef TEST_TIMEPERIODS_B + printf("START TIME: %lu = %s", start_time, ctime(&start_time)); +#endif + + /* get the end time */ + switch(daterange_type) { + case DATERANGE_CALENDAR_DATE: + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_mday = temp_daterange->emday; + t->tm_mon = temp_daterange->emon; + t->tm_year = (temp_daterange->eyear - 1900); + t->tm_isdst = -1; + end_time = mktime(t); + break; + case DATERANGE_MONTH_DATE: + /* use same year as was calculated for start time above */ + end_time = calculate_time_from_day_of_month(year, temp_daterange->emon, temp_daterange->emday); + /* advance a year if necessary: august 5 - feburary 2 */ + if(end_time < start_time) { + year++; + end_time = calculate_time_from_day_of_month(year, temp_daterange->emon, temp_daterange->emday); + } + break; + case DATERANGE_MONTH_DAY: + /* use same year and month as was calculated for start time above */ + end_time = calculate_time_from_day_of_month(year, month, temp_daterange->emday); + break; + case DATERANGE_MONTH_WEEK_DAY: + /* use same year as was calculated for start time above */ + end_time = calculate_time_from_weekday_of_month(year, temp_daterange->emon, temp_daterange->ewday, temp_daterange->ewday_offset); + /* advance a year if necessary: thursday 2 august - monday 3 february */ + if(end_time < start_time) { + year++; + end_time = calculate_time_from_weekday_of_month(year, temp_daterange->emon, temp_daterange->ewday, temp_daterange->ewday_offset); + } + break; + case DATERANGE_WEEK_DAY: + /* use same year and month as was calculated for start time above */ + end_time = calculate_time_from_weekday_of_month(year, month, temp_daterange->ewday, temp_daterange->ewday_offset); + break; + default: + continue; + break; + } + +#ifdef TEST_TIMEPERIODS_B + printf("STARTTIME: %lu = %s", (unsigned long)start_time, ctime(&start_time)); + printf("ENDTIME1: %lu = %s", (unsigned long)end_time, ctime(&end_time)); +#endif + + /* start date was bad, so skip this date range */ + if((unsigned long)start_time == 0L) + continue; + + /* end date was bad - see if we can handle the error */ + if((unsigned long)end_time == 0L) { + switch(daterange_type) { + case DATERANGE_CALENDAR_DATE: + continue; + break; + case DATERANGE_MONTH_DATE: + /* end date can't be helped, so skip it */ + if(temp_daterange->emday < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + end_time = calculate_time_from_day_of_month(year, temp_daterange->emon, -1); + break; + case DATERANGE_MONTH_DAY: + /* end date can't be helped, so skip it */ + if(temp_daterange->emday < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + end_time = calculate_time_from_day_of_month(year, month, -1); + break; + case DATERANGE_MONTH_WEEK_DAY: + /* end date can't be helped, so skip it */ + if(temp_daterange->ewday_offset < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + end_time = calculate_time_from_day_of_month(year, pref_time_mon, -1); + break; + case DATERANGE_WEEK_DAY: + /* end date can't be helped, so skip it */ + if(temp_daterange->ewday_offset < 0) + continue; + + /* else end date slipped past end of month, so use last day of month as end date */ + end_time = calculate_time_from_day_of_month(year, month, -1); + break; + default: + continue; + break; + } + } + +#ifdef TEST_TIMEPERIODS_B + printf("ENDTIME2: %lu = %s", (unsigned long)end_time, ctime(&end_time)); +#endif + + /* if skipping days... */ + if(temp_daterange->skip_interval > 1) { + + /* advance to the next possible skip date */ + if(start_time < preferred_time) { + /* check if interval is across dlst change and gets the compensation */ + shift = get_dst_shift(&start_time, &midnight); + + /* how many days have passed between skip start date and preferred time? */ + days = (shift + (unsigned long)midnight - (unsigned long)start_time) / (3600 * 24); + +#ifdef TEST_TIMEPERIODS_B + printf("MIDNIGHT: %lu = %s", midnight, ctime(&midnight)); + printf("%lu SECONDS PASSED\n", (midnight - (unsigned long)start_time)); + printf("%d DAYS PASSED\n", days); + printf("REMAINDER: %d\n", (days % temp_daterange->skip_interval)); + printf("SKIP INTERVAL: %d\n", temp_daterange->skip_interval); + printf("DLST SHIFT: %d", shift); +#endif + + /* advance start date to next skip day */ + if((days % temp_daterange->skip_interval) == 0) + start_time += (days * 3600 * 24); + else + start_time += ((days - (days % temp_daterange->skip_interval) + temp_daterange->skip_interval) * 3600 * 24); + } + + /* if skipping has no end, use start date as end */ + if((daterange_type == DATERANGE_CALENDAR_DATE) && is_daterange_single_day(temp_daterange) == TRUE) + end_time = start_time; + } + +#ifdef TEST_TIMEPERIODS_B + printf("\nSTART: %lu = %s", (unsigned long)start_time, ctime(&start_time)); + printf("END: %lu = %s", (unsigned long)end_time, ctime(&end_time)); + printf("PREFERRED: %lu = %s", (unsigned long)preferred_time, ctime(&preferred_time)); + printf("CURRENT: %lu = %s", (unsigned long)current_time, ctime(¤t_time)); +#endif + + /* skip this date range its out of bounds with what we want */ + if(preferred_time > end_time) + continue; + + /* how many days at a time should we advance? */ + if(temp_daterange->skip_interval > 1) + advance_interval = temp_daterange->skip_interval; + else + advance_interval = 1; + + /* advance through the date range */ + for(day_start = start_time; day_start <= end_time; day_start += (advance_interval * 3600 * 24)) { + + /* we already found a time from a higher-precendence date range exception */ + if(day_start >= earliest_day && have_earliest_time == TRUE) + continue; + + for(temp_timerange = temp_daterange->times; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + + /* ranges with start/end of zero mean exlude this day */ + if(temp_timerange->range_start == 0 && temp_timerange->range_end == 0) + continue; + + day_range_start = (time_t)(day_start + temp_timerange->range_start); + day_range_end = (time_t)(day_start + temp_timerange->range_end); + +#ifdef TEST_TIMEPERIODS_B + printf(" RANGE START: %lu (%lu) = %s", temp_timerange->range_start, (unsigned long)day_range_start, ctime(&day_range_start)); + printf(" RANGE END: %lu (%lu) = %s", temp_timerange->range_end, (unsigned long)day_range_end, ctime(&day_range_end)); +#endif + + /* range is out of bounds */ + if(day_range_end < preferred_time) + continue; + + /* preferred time occurs before range start, so use range start time as earliest potential time */ + if(day_range_start >= preferred_time) + potential_time = day_range_start; + /* preferred time occurs between range start/end, so use preferred time as earliest potential time */ + else if(day_range_end >= preferred_time) + potential_time = preferred_time; + + /* is this the earliest time found thus far? */ + if(have_earliest_time == FALSE || potential_time < earliest_time) { + have_earliest_time = TRUE; + earliest_time = potential_time; + earliest_day = day_start; +#ifdef TEST_TIMEPERIODS_B + printf(" EARLIEST TIME: %lu = %s", (unsigned long)earliest_time, ctime(&earliest_time)); +#endif + } + } + } + } + + } + + + /**** find next available time from normal, weekly rotating schedule (in this timeperiod definition) ****/ + + /* check a one week rotation of time */ + has_looped = FALSE; + for(weekday = pref_time_wday, days_into_the_future = 0;; weekday++, days_into_the_future++) { + + /* break out of the loop if we have checked an entire week already */ + if(has_looped == TRUE && weekday >= pref_time_wday) + break; + + if(weekday >= 7) { + weekday -= 7; + has_looped = TRUE; + } + + /* calculate start of this future weekday */ + day_start = (time_t)(midnight + (days_into_the_future * 3600 * 24)); + + /* we already found a time from a higher-precendence date range exception */ + if(day_start == earliest_day) + continue; + + /* check all time ranges for this day of the week */ + for(temp_timerange = tperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + + /* calculate the time for the start of this time range */ + day_range_start = (time_t)(day_start + temp_timerange->range_start); + + if((have_earliest_time == FALSE || day_range_start < earliest_time) && day_range_start >= preferred_time) { + have_earliest_time = TRUE; + earliest_time = day_range_start; + earliest_day = day_start; + } + } + } + + + /* if we couldn't find a time period there must be none defined */ + if(have_earliest_time == FALSE || earliest_time == (time_t)0) + *valid_time = (time_t)preferred_time; + + /* else use the calculated time */ + else + *valid_time = earliest_time; + + return; + } + + +/* given a preferred time, get the next valid time within a time period */ +void get_next_valid_time(time_t pref_time, time_t *valid_time, timeperiod *tperiod) { + time_t current_time = (time_t)0L; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "get_next_valid_time()\n"); + + /* get time right now, preferred time must be now or in the future */ + time(¤t_time); + + _get_next_valid_time(pref_time, current_time, valid_time, tperiod); + } + + +/* tests if a date range covers just a single day */ +int is_daterange_single_day(daterange *dr) { + + if(dr == NULL) + return FALSE; + + if(dr->syear != dr->eyear) + return FALSE; + if(dr->smon != dr->emon) + return FALSE; + if(dr->smday != dr->emday) + return FALSE; + if(dr->swday != dr->ewday) + return FALSE; + if(dr->swday_offset != dr->ewday_offset) + return FALSE; + + return TRUE; + } + + + +/* returns a time (midnight) of particular (3rd, last) day in a given month */ +time_t calculate_time_from_day_of_month(int year, int month, int monthday) { + time_t midnight; + int day = 0; + struct tm t; + +#ifdef TEST_TIMEPERIODS + printf("YEAR: %d, MON: %d, MDAY: %d\n", year, month, monthday); +#endif + + /* positive day (3rd day) */ + if(monthday > 0) { + + t.tm_sec = 0; + t.tm_min = 0; + t.tm_hour = 0; + t.tm_year = year; + t.tm_mon = month; + t.tm_mday = monthday; + t.tm_isdst = -1; + + midnight = mktime(&t); + +#ifdef TEST_TIMEPERIODS + printf("MIDNIGHT CALC: %s", ctime(&midnight)); +#endif + + /* if we rolled over to the next month, time is invalid */ + /* assume the user's intention is to keep it in the current month */ + if(t.tm_mon != month) + midnight = (time_t)0L; + } + + /* negative offset (last day, 3rd to last day) */ + else { + /* find last day in the month */ + day = 32; + do { + /* back up a day */ + day--; + + /* make the new time */ + t.tm_mon = month; + t.tm_year = year; + t.tm_mday = day; + t.tm_isdst = -1; + midnight = mktime(&t); + + } + while(t.tm_mon != month); + + /* now that we know the last day, back up more */ + /* make the new time */ + t.tm_mon = month; + t.tm_year = year; + /* -1 means last day of month, so add one to to make this correct - Mike Bird */ + t.tm_mday += (monthday < -30) ? -30 : monthday + 1; + t.tm_isdst = -1; + midnight = mktime(&t); + + /* if we rolled over to the previous month, time is invalid */ + /* assume the user's intention is to keep it in the current month */ + if(t.tm_mon != month) + midnight = (time_t)0L; + } + + return midnight; + } + + + +/* returns a time (midnight) of particular (3rd, last) weekday in a given month */ +time_t calculate_time_from_weekday_of_month(int year, int month, int weekday, int weekday_offset) { + time_t midnight; + int days = 0; + int weeks = 0; + struct tm t; + + t.tm_sec = 0; + t.tm_min = 0; + t.tm_hour = 0; + t.tm_year = year; + t.tm_mon = month; + t.tm_mday = 1; + t.tm_isdst = -1; + + midnight = mktime(&t); + + /* how many days must we advance to reach the first instance of the weekday this month? */ + days = weekday - (t.tm_wday); + if(days < 0) + days += 7; + + /* positive offset (3rd thursday) */ + if(weekday_offset > 0) { + + /* how many weeks must we advance (no more than 5 possible) */ + weeks = (weekday_offset > 5) ? 5 : weekday_offset; + days += ((weeks - 1) * 7); + + /* make the new time */ + t.tm_mon = month; + t.tm_year = year; + t.tm_mday = days + 1; + t.tm_isdst = -1; + midnight = mktime(&t); + + /* if we rolled over to the next month, time is invalid */ + /* assume the user's intention is to keep it in the current month */ + if(t.tm_mon != month) + midnight = (time_t)0L; + } + + /* negative offset (last thursday, 3rd to last tuesday) */ + else { + /* find last instance of weekday in the month */ + days += (5 * 7); + do { + /* back up a week */ + days -= 7; + + /* make the new time */ + t.tm_mon = month; + t.tm_year = year; + t.tm_mday = days + 1; + t.tm_isdst = -1; + midnight = mktime(&t); + + } + while(t.tm_mon != month); + + /* now that we know the last instance of the weekday, back up more */ + weeks = (weekday_offset < -5) ? -5 : weekday_offset; + days = ((weeks + 1) * 7); + + /* make the new time */ + t.tm_mon = month; + t.tm_year = year; + t.tm_mday += days; + t.tm_isdst = -1; + midnight = mktime(&t); + + /* if we rolled over to the previous month, time is invalid */ + /* assume the user's intention is to keep it in the current month */ + if(t.tm_mon != month) + midnight = (time_t)0L; + } + + return midnight; + } + + +/* get the next time to schedule a log rotation */ +time_t get_next_log_rotation_time(void) { + time_t current_time; + struct tm *t, tm_s; + int is_dst_now = FALSE; + time_t run_time; + + time(¤t_time); + t = localtime_r(¤t_time, &tm_s); + t->tm_min = 0; + t->tm_sec = 0; + is_dst_now = (t->tm_isdst > 0) ? TRUE : FALSE; + + switch(log_rotation_method) { + case LOG_ROTATION_HOURLY: + t->tm_hour++; + run_time = mktime(t); + break; + case LOG_ROTATION_DAILY: + t->tm_mday++; + t->tm_hour = 0; + run_time = mktime(t); + break; + case LOG_ROTATION_WEEKLY: + t->tm_mday += (7 - t->tm_wday); + t->tm_hour = 0; + run_time = mktime(t); + break; + case LOG_ROTATION_MONTHLY: + default: + t->tm_mon++; + t->tm_mday = 1; + t->tm_hour = 0; + run_time = mktime(t); + break; + } + + if(is_dst_now == TRUE && t->tm_isdst == 0) + run_time += 3600; + else if(is_dst_now == FALSE && t->tm_isdst > 0) + run_time -= 3600; + + return run_time; + } + + + +/******************************************************************/ +/******************** SIGNAL HANDLER FUNCTIONS ********************/ +/******************************************************************/ + + +/* trap signals so we can exit gracefully */ +void setup_sighandler(void) { + + /* reset the shutdown flag */ + sigshutdown = FALSE; + + /* remove buffering from stderr, stdin, and stdout */ + setbuf(stdin, (char *)NULL); + setbuf(stdout, (char *)NULL); + setbuf(stderr, (char *)NULL); + + /* initialize signal handling */ + signal(SIGPIPE, SIG_IGN); + signal(SIGQUIT, sighandler); + signal(SIGTERM, sighandler); + signal(SIGHUP, sighandler); + if(daemon_dumps_core == FALSE && daemon_mode == TRUE) + signal(SIGSEGV, sighandler); + + return; + } + + +/* reset signal handling... */ +void reset_sighandler(void) { + + /* set signal handling to default actions */ + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGSEGV, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGXFSZ, SIG_DFL); + + return; + } + + +/* handle signals */ +void sighandler(int sig) { + int x = 0; + + /* if shutdown is already true, we're in a signal trap loop! */ + /* changed 09/07/06 to only exit on segfaults */ + if(sigshutdown == TRUE && sig == SIGSEGV) + exit(ERROR); + + caught_signal = TRUE; + + if(sig < 0) + sig = -sig; + + for(x = 0; sigs[x] != (char *)NULL; x++); + sig %= x; + + sig_id = sig; + + /* log errors about segfaults now, as we might not get a chance to later */ + /* all other signals are logged at a later point in main() to prevent problems with NPTL */ + if(sig == SIGSEGV) + logit(NSLOG_PROCESS_INFO, TRUE, "Caught SIG%s, shutting down...\n", sigs[sig]); + + /* we received a SIGHUP, so restart... */ + if(sig == SIGHUP) + sigrestart = TRUE; + + /* else begin shutting down... */ + else if(sig < 16) + sigshutdown = TRUE; + + return; + } + +/* Handle the SIGXFSZ signal. A SIGXFSZ signal is received when a file exceeds + the maximum allowable size either as dictated by the fzise paramater in + /etc/security/limits.conf (ulimit -f) or by the maximum size allowed by + the filesystem */ +void handle_sigxfsz(int sig) { + + static time_t lastlog_time = (time_t)0; /* Save the last log time so we + don't log too often. */ + unsigned long log_interval = 300; /* How frequently to log messages + about receiving the signal */ + struct rlimit rlim; + time_t now; + char *files[] = { + log_file, + debug_file, + xpddefault_host_perfdata_file, + xpddefault_service_perfdata_file, + xodtemplate_cache_file, + xodtemplate_precache_file, + xsddefault_status_log, + xrddefault_retention_file, + }; + int x; + char **filep; + long long size; + long long max_size = 0LL; + char *max_name = NULL; + + if(SIGXFSZ == sig) { /* Make sure we're handling the correct signal */ + /* Check the current time and if less time has passed since the last + time the signal was received, ignore it */ + time(&now); + if((unsigned long)(now - lastlog_time) < log_interval) return; + + /* Get the current file size limit */ + if(getrlimit(RLIMIT_FSIZE, &rlim) != 0) { + /* Attempt to log the error, realizing that the logging may fail + if it is the log file that is over the size limit. */ + logit(NSLOG_RUNTIME_ERROR, TRUE, + "Unable to determine current resoure limits: %s\n", + strerror(errno)); + } + + /* Try to figure out which file caused the signal and react + appropriately */ + for(x = 0, filep = files; x < (sizeof(files) / sizeof(files[0])); + x++, filep++) { + if((*filep != NULL) && strcmp(*filep, "/dev/null")) { + if((size = check_file_size(*filep, 1024, rlim)) == -1) { + lastlog_time = now; + return; + } + else if(size > max_size) { + max_size = size; + max_name = log_file; + } + } + } + /* TODO: Perhaps add check of the check results files in + check_results_path. This is likely not needed because these + files aren't very big */ + if((max_size > 0) && (max_name != NULL)) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "SIGXFSZ received because a " + "file's size may have exceeded the file size limits of " + "the filesystem. The largest file checked, '%s', has a " + "size of %lld bytes", max_name, max_size); + + } + else { + logit(NSLOG_RUNTIME_ERROR, TRUE, "SIGXFSZ received but unable to " + "determine which file may have caused it."); + } + } + return; + } + +/* Checks a file to determine whether it exceeds resource limit imposed + limits. Returns the file size if file is OK, 0 if it's status could not + be determined, or -1 if not OK. fudge is the fudge factor (in bytes) for + checking the file size */ +static long long check_file_size(char *path, unsigned long fudge, + struct rlimit rlim) { + + struct stat status; + + /* Make sure we were passed a legitimate file path */ + if(NULL == path) { + return 0; + } + + /* Get the status of the file */ + if(stat(path, &status) == 0) { + /* Make sure it is a file */ + if(S_ISREG(status.st_mode)) { + /* If the file size plus the fudge factor exceeds the + current resource limit imposed size limit, log an error */ + if(status.st_size + fudge > rlim.rlim_cur) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Size of file '%s' (%llu) " + "exceeds (or nearly exceeds) size imposed by resource " + "limits (%llu). Consider increasing limits with " + "ulimit(1).\n", path, + (unsigned long long)status.st_size, + (unsigned long long)rlim.rlim_cur); + return -1; + } + else { + return status.st_size; + } + } + else { + return 0; + } + } + else { + /* If we could not determine the file status, log an error message */ + logit(NSLOG_RUNTIME_ERROR, TRUE, + "Unable to determine status of file %s: %s\n", + log_file, strerror(errno)); + return 0; + } + } + +/* handle timeouts when executing service checks */ +/* 07/16/08 EG also called when parent process gets a TERM signal */ +void service_check_sighandler(int sig) { + struct timeval end_time; + + /* get the current time */ + gettimeofday(&end_time, NULL); + + check_result_info.return_code = service_check_timeout_state; + check_result_info.finish_time = end_time; + check_result_info.early_timeout = TRUE; + + /* write check result to file */ + if(check_result_info.output_file_fp) { + + fprintf(check_result_info.output_file_fp, "finish_time=%lu.%lu\n", check_result_info.finish_time.tv_sec, check_result_info.finish_time.tv_usec); + fprintf(check_result_info.output_file_fp, "early_timeout=%d\n", check_result_info.early_timeout); + fprintf(check_result_info.output_file_fp, "exited_ok=%d\n", check_result_info.exited_ok); + fprintf(check_result_info.output_file_fp, "return_code=%d\n", check_result_info.return_code); + fprintf(check_result_info.output_file_fp, "output=%s\n", "(Service Check Timed Out)"); + + /* close the temp file */ + fclose(check_result_info.output_file_fp); + + /* move check result to queue directory */ + move_check_result_to_queue(check_result_info.output_file); + } + + /* free check result memory */ + free_check_result(&check_result_info); + + /* try to kill the command that timed out by sending termination signal to our process group */ + /* we also kill ourselves while doing this... */ + kill((pid_t)0, SIGKILL); + + /* force the child process (service check) to exit... */ + _exit(STATE_CRITICAL); + } + + +/* handle timeouts when executing host checks */ +/* 07/16/08 EG also called when parent process gets a TERM signal */ +void host_check_sighandler(int sig) { + struct timeval end_time; + + /* get the current time */ + gettimeofday(&end_time, NULL); + + check_result_info.return_code = STATE_CRITICAL; + check_result_info.finish_time = end_time; + check_result_info.early_timeout = TRUE; + + /* write check result to file */ + if(check_result_info.output_file_fp) { + + fprintf(check_result_info.output_file_fp, "finish_time=%lu.%lu\n", check_result_info.finish_time.tv_sec, check_result_info.finish_time.tv_usec); + fprintf(check_result_info.output_file_fp, "early_timeout=%d\n", check_result_info.early_timeout); + fprintf(check_result_info.output_file_fp, "exited_ok=%d\n", check_result_info.exited_ok); + fprintf(check_result_info.output_file_fp, "return_code=%d\n", check_result_info.return_code); + fprintf(check_result_info.output_file_fp, "output=%s\n", "(Host Check Timed Out)"); + + /* close the temp file */ + fclose(check_result_info.output_file_fp); + + /* move check result to queue directory */ + move_check_result_to_queue(check_result_info.output_file); + } + + /* free check result memory */ + free_check_result(&check_result_info); + + /* try to kill the command that timed out by sending termination signal to our process group */ + /* we also kill ourselves while doing this... */ + kill((pid_t)0, SIGKILL); + + /* force the child process (service check) to exit... */ + _exit(STATE_CRITICAL); + } + + +/* handle timeouts when executing commands via my_system_r() */ +void my_system_sighandler(int sig) { + + /* force the child process to exit... */ + _exit(STATE_CRITICAL); + } + + + + +/******************************************************************/ +/************************ DAEMON FUNCTIONS ************************/ +/******************************************************************/ + +int daemon_init(void) { + pid_t pid = -1; + int pidno = 0; + int lockfile = 0; + int val = 0; + char buf[256]; + struct flock lock; + char *homedir = NULL; + +#ifdef RLIMIT_CORE + struct rlimit limit; +#endif + + /* change working directory. scuttle home if we're dumping core */ + homedir = getenv("HOME"); + if(daemon_dumps_core == TRUE && homedir != NULL) + chdir(homedir); + else + chdir("/"); + + umask(S_IWGRP | S_IWOTH); + + lockfile = open(lock_file, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); + + if(lockfile < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Failed to obtain lock on file %s: %s\n", lock_file, strerror(errno)); + logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to errors encountered while attempting to daemonize... (PID=%d)", (int)getpid()); + + cleanup(); + exit(ERROR); + } + + /* see if we can read the contents of the lockfile */ + if((val = read(lockfile, buf, (size_t)10)) < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Lockfile exists but cannot be read"); + cleanup(); + exit(ERROR); + } + + /* we read something - check the PID */ + if(val > 0) { + if((val = sscanf(buf, "%d", &pidno)) < 1) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Lockfile '%s' does not contain a valid PID (%s)", lock_file, buf); + cleanup(); + exit(ERROR); + } + } + + /* check for SIGHUP */ + if(val == 1 && (pid = (pid_t)pidno) == getpid()) { + close(lockfile); + return OK; + } + + /* exit on errors... */ + if((pid = fork()) < 0) + return(ERROR); + + /* parent process goes away.. */ + else if((int)pid != 0) + exit(OK); + + /* child continues... */ + + /* child becomes session leader... */ + setsid(); + + /* place a file lock on the lock file */ + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + if(fcntl(lockfile, F_SETLK, &lock) < 0) { + if(errno == EACCES || errno == EAGAIN) { + fcntl(lockfile, F_GETLK, &lock); + logit(NSLOG_RUNTIME_ERROR, TRUE, "Lockfile '%s' looks like its already held by another instance of Nagios (PID %d). Bailing out...", lock_file, (int)lock.l_pid); + } + else + logit(NSLOG_RUNTIME_ERROR, TRUE, "Cannot lock lockfile '%s': %s. Bailing out...", lock_file, strerror(errno)); + + cleanup(); + exit(ERROR); + } + + /* prevent daemon from dumping a core file... */ +#ifdef RLIMIT_CORE + if(daemon_dumps_core == FALSE) { + getrlimit(RLIMIT_CORE, &limit); + limit.rlim_cur = 0; + setrlimit(RLIMIT_CORE, &limit); + } +#endif + + /* write PID to lockfile... */ + lseek(lockfile, 0, SEEK_SET); + ftruncate(lockfile, 0); + sprintf(buf, "%d\n", (int)getpid()); + write(lockfile, buf, strlen(buf)); + + /* make sure lock file stays open while program is executing... */ + val = fcntl(lockfile, F_GETFD, 0); + val |= FD_CLOEXEC; + fcntl(lockfile, F_SETFD, val); + + /* close existing stdin, stdout, stderr */ + close(0); + close(1); + close(2); + + /* THIS HAS TO BE DONE TO AVOID PROBLEMS WITH STDERR BEING REDIRECTED TO SERVICE MESSAGE PIPE! */ + /* re-open stdin, stdout, stderr with known values */ + open("/dev/null", O_RDONLY); + open("/dev/null", O_WRONLY); + open("/dev/null", O_WRONLY); + +#ifdef USE_EVENT_BROKER + /* send program data to broker */ + broker_program_state(NEBTYPE_PROCESS_DAEMONIZE, NEBFLAG_NONE, NEBATTR_NONE, NULL); +#endif + + return OK; + } + + + +/******************************************************************/ +/*********************** SECURITY FUNCTIONS ***********************/ +/******************************************************************/ + +/* drops privileges */ +int drop_privileges(char *user, char *group) { + uid_t uid = -1; + gid_t gid = -1; + struct group *grp = NULL; + struct passwd *pw = NULL; + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "drop_privileges() start\n"); + log_debug_info(DEBUGL_PROCESS, 0, "Original UID/GID: %d/%d\n", (int)getuid(), (int)getgid()); + + /* only drop privileges if we're running as root, so we don't interfere with being debugged while running as some random user */ + if(getuid() != 0) + return OK; + + /* set effective group ID */ + if(group != NULL) { + + /* see if this is a group name */ + if(strspn(group, "0123456789") < strlen(group)) { + grp = (struct group *)getgrnam(group); + if(grp != NULL) + gid = (gid_t)(grp->gr_gid); + else + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not get group entry for '%s'", group); + } + + /* else we were passed the GID */ + else + gid = (gid_t)atoi(group); + + /* set effective group ID if other than current EGID */ + if(gid != getegid()) { + + if(setgid(gid) == -1) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not set effective GID=%d", (int)gid); + result = ERROR; + } + } + } + + + /* set effective user ID */ + if(user != NULL) { + + /* see if this is a user name */ + if(strspn(user, "0123456789") < strlen(user)) { + pw = (struct passwd *)getpwnam(user); + if(pw != NULL) + uid = (uid_t)(pw->pw_uid); + else + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not get passwd entry for '%s'", user); + } + + /* else we were passed the UID */ + else + uid = (uid_t)atoi(user); + +#ifdef HAVE_INITGROUPS + + if(uid != geteuid()) { + + /* initialize supplementary groups */ + if(initgroups(user, gid) == -1) { + if(errno == EPERM) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Unable to change supplementary groups using initgroups() -- I hope you know what you're doing"); + else { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Possibly root user failed dropping privileges with initgroups()"); + return ERROR; + } + } + } +#endif + /* Change the ownership on the debug log file */ + chown_debug_log(uid, gid); + + if(setuid(uid) == -1) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not set effective UID=%d", (int)uid); + result = ERROR; + } + } + + log_debug_info(DEBUGL_PROCESS, 0, "New UID/GID: %d/%d\n", (int)getuid(), (int)getgid()); + + return result; + } + + + + +/******************************************************************/ +/************************* IPC FUNCTIONS **************************/ +/******************************************************************/ + +/* move check result to queue directory */ +int move_check_result_to_queue(char *checkresult_file) { + char *output_file = NULL; + char *temp_buffer = NULL; + int output_file_fd = -1; + mode_t new_umask = 077; + mode_t old_umask; + int result = 0; + + /* save the file creation mask */ + old_umask = umask(new_umask); + + /* create a safe temp file */ + asprintf(&output_file, "%s/cXXXXXX", check_result_path); + output_file_fd = mkstemp(output_file); + + /* file created okay */ + if(output_file_fd >= 0) { + + log_debug_info(DEBUGL_CHECKS, 2, "Moving temp check result file '%s' to queue file '%s'...\n", checkresult_file, output_file); + +#ifdef __CYGWIN__ + /* Cygwin cannot rename open files - gives Permission Denied */ + /* close the file */ + close(output_file_fd); +#endif + + /* move the original file */ + result = my_rename(checkresult_file, output_file); + +#ifndef __CYGWIN__ + /* close the file */ + close(output_file_fd); +#endif + + /* create an ok-to-go indicator file */ + asprintf(&temp_buffer, "%s.ok", output_file); + if((output_file_fd = open(temp_buffer, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) + close(output_file_fd); + my_free(temp_buffer); + + /* delete the original file if it couldn't be moved */ + if(result != 0) + unlink(checkresult_file); + } + else + result = -1; + + /* reset the file creation mask */ + umask(old_umask); + + /* log a warning on errors */ + if(result != 0) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Unable to move file '%s' to check results queue.\n", checkresult_file); + + /* free memory */ + my_free(output_file); + + return OK; + } + + + +/* processes files in the check result queue directory */ +int process_check_result_queue(char *dirname) { + char file[MAX_FILENAME_LENGTH]; + DIR *dirp = NULL; + struct dirent *dirfile = NULL; + register int x = 0; + struct stat stat_buf; + struct stat ok_stat_buf; + char *temp_buffer = NULL; + int result = OK; + + /* make sure we have what we need */ + if(dirname == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: No check result queue directory specified.\n"); + return ERROR; + } + + /* open the directory for reading */ + if((dirp = opendir(dirname)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not open check result queue directory '%s' for reading.\n", dirname); + return ERROR; + } + + log_debug_info(DEBUGL_CHECKS, 1, "Starting to read check result queue '%s'...\n", dirname); + + /* process all files in the directory... */ + while((dirfile = readdir(dirp)) != NULL) { + + /* create /path/to/file */ + snprintf(file, sizeof(file), "%s/%s", dirname, dirfile->d_name); + file[sizeof(file) - 1] = '\x0'; + + /* process this if it's a check result file... */ + x = strlen(dirfile->d_name); + if(x == 7 && dirfile->d_name[0] == 'c') { + + if(stat(file, &stat_buf) == -1) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not stat() check result file '%s'.\n", file); + continue; + } + + switch(stat_buf.st_mode & S_IFMT) { + + case S_IFREG: + /* don't process symlinked files */ + if(!S_ISREG(stat_buf.st_mode)) + continue; + break; + + default: + /* everything else we ignore */ + continue; + break; + } + + /* at this point we have a regular file... */ + + /* can we find the associated ok-to-go file ? */ + asprintf(&temp_buffer, "%s.ok", file); + result = stat(temp_buffer, &ok_stat_buf); + my_free(temp_buffer); + if(result == -1) + continue; + + /* process the file */ + result = process_check_result_file(file, &check_result_list, + TRUE, TRUE); + + /* break out if we encountered an error */ + if(result == ERROR) + break; + } + } + + closedir(dirp); + + return result; + + } + + + + +/* Find checks that are currently executing. This function is intended to + be used on a Nagios restart to prevent currently executing checks from + being rescheduled. */ +int find_executing_checks(char *dirname) { + char file[MAX_FILENAME_LENGTH]; + DIR *dirp = NULL; + struct dirent *dirfile = NULL; + int x = 0; + struct stat stat_buf; + int result = OK; + check_result *crl = NULL; + check_result *cr = NULL; + service *svc = NULL; + host *host = NULL; + time_t current_time; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "find_executing_checks() start\n"); + + /* make sure we have what we need */ + if(dirname == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: No check directory specified.\n"); + return ERROR; + } + + /* open the directory for reading */ + if((dirp = opendir(dirname)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not open check directory '%s' for reading.\n", dirname); + return ERROR; + } + + log_debug_info(DEBUGL_CHECKS, 1, "Starting to read check directory '%s'...\n", dirname); + + /* process all files in the directory... */ + while((dirfile = readdir(dirp)) != NULL) { + + /* create /path/to/file */ + snprintf(file, sizeof(file), "%s/%s", dirname, dirfile->d_name); + file[sizeof(file) - 1] = '\x0'; + + /* process this if it's a check result file... */ + x = strlen(dirfile->d_name); + if(x == 11 && !strncmp(dirfile->d_name, "check", 5)) { + + if(stat(file, &stat_buf) == -1) { + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Could not stat() check status '%s'.\n", file); + continue; + } + + switch(stat_buf.st_mode & S_IFMT) { + + case S_IFREG: + /* don't process symlinked files */ + if(!S_ISREG(stat_buf.st_mode)) + continue; + break; + + default: + /* everything else we ignore */ + continue; + break; + } + + /* at this point we have a regular file... */ + log_debug_info(DEBUGL_CHECKS, 2, + "Looking for still-executing checks in %s.\n", file); + + /* process the file */ + result = process_check_result_file(file, &crl, FALSE, FALSE); + + /* break out if we encountered an error */ + if(result == ERROR) + break; + + time(¤t_time); + + /* examine the check results */ + while((cr = read_check_result(&crl)) != NULL) { + if(HOST_CHECK == cr->object_check_type) { + log_debug_info(DEBUGL_CHECKS, 2, + "Determining whether check for host '%s' is still executing.\n", + cr->host_name); + if((host = find_host(cr->host_name)) == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, + "Warning: Check status contained host '%s', " + "but the host could not be found! Ignoring " + "check.\n", cr->host_name); + } + else if(current_time - cr->start_time.tv_sec < + host_check_timeout) { + log_debug_info(DEBUGL_CHECKS, 1, + "Check for host %s is still executing.\n", + cr->host_name); + host->is_executing = TRUE; + } + } + else if(SERVICE_CHECK == cr->object_check_type) { + log_debug_info(DEBUGL_CHECKS, 2, + "Determining whether check for service '%s' on host '%s' is still executing.\n", + cr->host_name, cr->service_description); + if((svc = find_service(cr->host_name, + cr->service_description)) == NULL) { + logit(NSLOG_RUNTIME_WARNING, TRUE, + "Warning: Check status contained service '%s' " + "on host '%s', but the service could not be " + "found! Ignoring check.\n", + cr->service_description, cr->host_name); + } + else if(current_time - cr->start_time.tv_sec < + service_check_timeout) { + log_debug_info(DEBUGL_CHECKS, 1, + "Check for service %s:%s is still executing.\n", + cr->host_name, cr->service_description); + svc->is_executing = TRUE; + } + } + free_check_result_list(&crl); + } + } + } + + closedir(dirp); + + return result; + + } + + + + +/* reads check result(s) from a file */ +int process_check_result_file(char *fname, check_result **listp, int delete_file, int need_output) { + mmapfile *thefile = NULL; + char *input = NULL; + char *var = NULL; + char *val = NULL; + char *v1 = NULL, *v2 = NULL; + time_t current_time; + check_result *new_cr = NULL; + + if(fname == NULL) + return ERROR; + + time(¤t_time); + + log_debug_info(DEBUGL_CHECKS, 1, "Processing check result file: '%s'\n", fname); + + /* open the file for reading */ + if((thefile = mmap_fopen(fname)) == NULL) { + + /* try removing the file - zero length files can't be mmap()'ed, so it might exist */ + unlink(fname); + + return ERROR; + } + + /* read in all lines from the file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + /* skip comments */ + if(input[0] == '#') + continue; + + /* empty line indicates end of record */ + else if(input[0] == '\n') { + + /* we have something... */ + if(new_cr) { + + /* do we have the minimum amount of data? */ + if(new_cr->host_name != NULL && + (!need_output || new_cr->output != NULL)) { + + /* add check result to list in memory */ + add_check_result_to_list(listp, new_cr); + + /* reset pointer */ + new_cr = NULL; + } + + /* discard partial input */ + else { + free_check_result(new_cr); + init_check_result(new_cr); + new_cr->output_file = (char *)strdup(fname); + } + } + } + + if((var = my_strtok(input, "=")) == NULL) + continue; + if((val = my_strtok(NULL, "\n")) == NULL) + continue; + + /* found the file time */ + if(!strcmp(var, "file_time")) { + + /* file is too old - ignore check results it contains and delete it */ + /* this will only work as intended if file_time comes before check results */ + if(max_check_result_file_age > 0 && (current_time - (strtoul(val, NULL, 0)) > max_check_result_file_age)) { + delete_file = TRUE; + break; + } + } + + /* else we have check result data */ + else { + + /* allocate new check result if necessary */ + if(new_cr == NULL) { + + if((new_cr = (check_result *)malloc(sizeof(check_result))) == NULL) + continue; + + /* init values */ + init_check_result(new_cr); + new_cr->output_file = (char *)strdup(fname); + } + + if(!strcmp(var, "host_name")) + new_cr->host_name = (char *)strdup(val); + else if(!strcmp(var, "service_description")) { + new_cr->service_description = (char *)strdup(val); + new_cr->object_check_type = SERVICE_CHECK; + } + else if(!strcmp(var, "check_type")) + new_cr->check_type = atoi(val); + else if(!strcmp(var, "check_options")) + new_cr->check_options = atoi(val); + else if(!strcmp(var, "scheduled_check")) + new_cr->scheduled_check = atoi(val); + else if(!strcmp(var, "reschedule_check")) + new_cr->reschedule_check = atoi(val); + else if(!strcmp(var, "latency")) + new_cr->latency = strtod(val, NULL); + else if(!strcmp(var, "start_time")) { + if((v1 = strtok(val, ".")) == NULL) + continue; + if((v2 = strtok(NULL, "\n")) == NULL) + continue; + new_cr->start_time.tv_sec = strtoul(v1, NULL, 0); + new_cr->start_time.tv_usec = strtoul(v2, NULL, 0); + } + else if(!strcmp(var, "finish_time")) { + if((v1 = strtok(val, ".")) == NULL) + continue; + if((v2 = strtok(NULL, "\n")) == NULL) + continue; + new_cr->finish_time.tv_sec = strtoul(v1, NULL, 0); + new_cr->finish_time.tv_usec = strtoul(v2, NULL, 0); + } + else if(!strcmp(var, "early_timeout")) + new_cr->early_timeout = atoi(val); + else if(!strcmp(var, "exited_ok")) + new_cr->exited_ok = atoi(val); + else if(!strcmp(var, "return_code")) + new_cr->return_code = atoi(val); + else if(!strcmp(var, "output")) + new_cr->output = (char *)strdup(val); + } + } + + /* we have something */ + if(new_cr) { + + /* do we have the minimum amount of data? */ + if(new_cr->host_name != NULL && + (!need_output || new_cr->output != NULL)) { + + /* add check result to list in memory */ + add_check_result_to_list(listp, new_cr); + + /* reset pointer */ + new_cr = NULL; + } + + /* discard partial input */ + /* free memory for current check result record */ + else { + free_check_result(new_cr); + my_free(new_cr); + } + } + + /* free memory and close file */ + my_free(input); + mmap_fclose(thefile); + + /* delete the file (as well its ok-to-go file) if they exist */ + if(TRUE == delete_file) + delete_check_result_file(fname); + + return OK; + } + + + + +/* deletes as check result file, as well as its ok-to-go file */ +int delete_check_result_file(char *fname) { + char *temp_buffer = NULL; + + /* delete the result file */ + unlink(fname); + + /* delete the ok-to-go file */ + asprintf(&temp_buffer, "%s.ok", fname); + unlink(temp_buffer); + my_free(temp_buffer); + + return OK; + } + + + + +/* reads the first host/service check result from the list in memory */ +check_result *read_check_result(check_result **listp) { + check_result *first_cr = NULL; + + if(*listp == NULL) + return NULL; + + first_cr = *listp; + *listp = (*listp)->next; + + return first_cr; + } + + + +/* initializes a host/service check result */ +int init_check_result(check_result *info) { + + if(info == NULL) + return ERROR; + + /* reset vars */ + info->object_check_type = HOST_CHECK; + info->host_name = NULL; + info->service_description = NULL; + info->check_type = HOST_CHECK_ACTIVE; + info->check_options = CHECK_OPTION_NONE; + info->scheduled_check = FALSE; + info->reschedule_check = FALSE; + info->output_file_fp = NULL; + info->output_file_fd = -1; + info->latency = 0.0; + info->start_time.tv_sec = 0; + info->start_time.tv_usec = 0; + info->finish_time.tv_sec = 0; + info->finish_time.tv_usec = 0; + info->early_timeout = FALSE; + info->exited_ok = TRUE; + info->return_code = 0; + info->output = NULL; + info->next = NULL; + + return OK; + } + + + + +/* adds a new host/service check result to the list in memory */ +int add_check_result_to_list(check_result **listp, check_result *new_cr) { + check_result *temp_cr = NULL; + check_result *last_cr = NULL; + + if(new_cr == NULL) + return ERROR; + + /* add to list, sorted by finish time (asc) */ + + /* find insertion point */ + last_cr = *listp; + for(temp_cr = *listp; temp_cr != NULL; temp_cr = temp_cr->next) { + if(temp_cr->finish_time.tv_sec >= new_cr->finish_time.tv_sec) { + if(temp_cr->finish_time.tv_sec > new_cr->finish_time.tv_sec) + break; + else if(temp_cr->finish_time.tv_usec > new_cr->finish_time.tv_usec) + break; + } + last_cr = temp_cr; + } + + /* item goes at head of list */ + if(*listp == NULL || temp_cr == *listp) { + new_cr->next = *listp; + *listp = new_cr; + } + + /* item goes in middle or at end of list */ + else { + new_cr->next = temp_cr; + last_cr->next = new_cr; + } + + return OK; + } + + + + +/* frees all memory associated with the check result list */ +int free_check_result_list(check_result **listp) { + check_result *this_cr = NULL; + check_result *next_cr = NULL; + + for(this_cr = *listp; this_cr != NULL; this_cr = next_cr) { + next_cr = this_cr->next; + free_check_result(this_cr); + my_free(this_cr); + } + + *listp = NULL; + + return OK; + } + + + + +/* frees memory associated with a host/service check result */ +int free_check_result(check_result *info) { + + if(info == NULL) + return OK; + + my_free(info->host_name); + my_free(info->service_description); + my_free(info->output_file); + my_free(info->output); + + return OK; + } + + +/* creates external command file as a named pipe (FIFO) and opens it for reading (non-blocked mode) */ +int open_command_file(void) { + struct stat st; + int result = 0; + + /* if we're not checking external commands, don't do anything */ + if(check_external_commands == FALSE) + return OK; + + /* the command file was already created */ + if(command_file_created == TRUE) + return OK; + + /* reset umask (group needs write permissions) */ + umask(S_IWOTH); + + /* use existing FIFO if possible */ + if(!(stat(command_file, &st) != -1 && (st.st_mode & S_IFIFO))) { + + /* create the external command file as a named pipe (FIFO) */ + if((result = mkfifo(command_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) != 0) { + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not create external command file '%s' as named pipe: (%d) -> %s. If this file already exists and you are sure that another copy of Nagios is not running, you should delete this file.\n", command_file, errno, strerror(errno)); + return ERROR; + } + } + + /* open the command file for reading (non-blocked) - O_TRUNC flag cannot be used due to errors on some systems */ + /* NOTE: file must be opened read-write for poll() to work */ + if((command_file_fd = open(command_file, O_RDWR | O_NONBLOCK)) < 0) { + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open external command file for reading via open(): (%d) -> %s\n", errno, strerror(errno)); + + return ERROR; + } + + /* re-open the FIFO for use with fgets() */ + if((command_file_fp = (FILE *)fdopen(command_file_fd, "r")) == NULL) { + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open external command file for reading via fdopen(): (%d) -> %s\n", errno, strerror(errno)); + + return ERROR; + } + + /* initialize worker thread */ + if(init_command_file_worker_thread() == ERROR) { + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not initialize command file worker thread.\n"); + + /* close the command file */ + fclose(command_file_fp); + + /* delete the named pipe */ + unlink(command_file); + + return ERROR; + } + + /* set a flag to remember we already created the file */ + command_file_created = TRUE; + + return OK; + } + + +/* closes the external command file FIFO and deletes it */ +int close_command_file(void) { + + /* if we're not checking external commands, don't do anything */ + if(check_external_commands == FALSE) + return OK; + + /* the command file wasn't created or was already cleaned up */ + if(command_file_created == FALSE) + return OK; + + /* reset our flag */ + command_file_created = FALSE; + + /* close the command file */ + fclose(command_file_fp); + + return OK; + } + + + + +/******************************************************************/ +/************************ STRING FUNCTIONS ************************/ +/******************************************************************/ + +/* gets the next string from a buffer in memory - strings are terminated by newlines, which are removed */ +char *get_next_string_from_buf(char *buf, int *start_index, int bufsize) { + char *sptr = NULL; + char *nl = "\n"; + int x; + + if(buf == NULL || start_index == NULL) + return NULL; + if(bufsize < 0) + return NULL; + if(*start_index >= (bufsize - 1)) + return NULL; + + sptr = buf + *start_index; + + /* end of buffer */ + if(sptr[0] == '\x0') + return NULL; + + x = strcspn(sptr, nl); + sptr[x] = '\x0'; + + *start_index += x + 1; + + return sptr; + } + + + +/* determines whether or not an object name (host, service, etc) contains illegal characters */ +int contains_illegal_object_chars(char *name) { + register int x = 0; + register int y = 0; + register int ch = 0; + + if(name == NULL) + return FALSE; + + x = (int)strlen(name) - 1; + + for(; x >= 0; x--) { + + ch = (int)name[x]; + + /* illegal user-specified characters */ + if(illegal_object_chars != NULL) + for(y = 0; illegal_object_chars[y]; y++) + if(name[x] == illegal_object_chars[y]) + return TRUE; + } + + return FALSE; + } + + +/* escapes newlines in a string */ +char *escape_newlines(char *rawbuf) { + char *newbuf = NULL; + register int x, y; + + if(rawbuf == NULL) + return NULL; + + /* allocate enough memory to escape all chars if necessary */ + if((newbuf = malloc((strlen(rawbuf) * 2) + 1)) == NULL) + return NULL; + + for(x = 0, y = 0; rawbuf[x] != (char)'\x0'; x++) { + + /* escape backslashes */ + if(rawbuf[x] == '\\') { + newbuf[y++] = '\\'; + newbuf[y++] = '\\'; + } + + /* escape newlines */ + else if(rawbuf[x] == '\n') { + newbuf[y++] = '\\'; + newbuf[y++] = 'n'; + } + + else + newbuf[y++] = rawbuf[x]; + } + newbuf[y] = '\x0'; + + return newbuf; + } + + +/* compares strings */ +int compare_strings(char *val1a, char *val2a) { + + /* use the compare_hashdata() function */ + return compare_hashdata(val1a, NULL, val2a, NULL); + } + + +/******************************************************************/ +/************************* FILE FUNCTIONS *************************/ +/******************************************************************/ + +/* renames a file - works across filesystems (Mike Wiacek) */ +int my_rename(char *source, char *dest) { + int rename_result = 0; + + + /* make sure we have something */ + if(source == NULL || dest == NULL) + return -1; + + /* first see if we can rename file with standard function */ + rename_result = rename(source, dest); + + /* handle any errors... */ + if(rename_result == -1) { + + /* an error occurred because the source and dest files are on different filesystems */ + if(errno == EXDEV) { + + /* try copying the file */ + if(my_fcopy(source, dest) == ERROR) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to rename file '%s' to '%s': %s\n", source, dest, strerror(errno)); + return -1; + } + + /* delete the original file */ + unlink(source); + + /* reset result since we successfully copied file */ + rename_result = 0; + } + + /* some other error occurred */ + else { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to rename file '%s' to '%s': %s\n", source, dest, strerror(errno)); + return rename_result; + } + } + + return rename_result; + } + +/* + * copy a file from the path at source to the already opened + * destination file dest. + * This is handy when creating tempfiles with mkstemp() + */ +int my_fdcopy(char *source, char *dest, int dest_fd) { + int source_fd, rd_result = 0, wr_result = 0; + unsigned long tot_written = 0, tot_read = 0, buf_size = 0; + struct stat st; + char *buf; + + /* open source file for reading */ + if((source_fd = open(source, O_RDONLY, 0644)) < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to open file '%s' for reading: %s\n", source, strerror(errno)); + return ERROR; + } + + /* + * find out how large the source-file is so we can be sure + * we've written all of it + */ + if(fstat(source_fd, &st) < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to stat source file '%s' for my_fcopy(): %s\n", source, strerror(errno)); + close(source_fd); + return ERROR; + } + + /* + * If the file is huge, read it and write it in chunks. + * This value (128K) is the result of "pick-one-at-random" + * with some minimal testing and may not be optimal for all + * hardware setups, but it should work ok for most. It's + * faster than 1K buffers and 1M buffers, so change at your + * own peril. Note that it's useful to make it fit in the L2 + * cache, so larger isn't necessarily better. + */ + buf_size = st.st_size > 128 << 10 ? 128 << 10 : st.st_size; + buf = malloc(buf_size); + if(!buf) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to malloc(%lu) bytes: %s\n", buf_size, strerror(errno)); + close(source_fd); + return ERROR; + } + /* most of the times, this loop will be gone through once */ + while(tot_written < st.st_size) { + int loop_wr = 0; + + rd_result = read(source_fd, buf, buf_size); + if(rd_result < 0) { + if(errno == EAGAIN || errno == EINTR) + continue; + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: my_fcopy() failed to read from '%s': %s\n", source, strerror(errno)); + break; + } + tot_read += rd_result; + + while(loop_wr < rd_result) { + wr_result = write(dest_fd, buf + loop_wr, rd_result - loop_wr); + + if(wr_result < 0) { + if(errno == EAGAIN || errno == EINTR) + continue; + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: my_fcopy() failed to write to '%s': %s\n", dest, strerror(errno)); + break; + } + loop_wr += wr_result; + } + if(wr_result < 0) + break; + tot_written += loop_wr; + } + + /* + * clean up irregardless of how things went. dest_fd comes from + * our caller, so we mustn't close it. + */ + close(source_fd); + free(buf); + + if(rd_result < 0 || wr_result < 0) { + /* don't leave half-written files around */ + unlink(dest); + return ERROR; + } + + return OK; + } + +/* copies a file */ +int my_fcopy(char *source, char *dest) { + int dest_fd, result; + + /* make sure we have something */ + if(source == NULL || dest == NULL) + return ERROR; + + /* unlink destination file first (not doing so can cause problems on network file systems like CIFS) */ + unlink(dest); + + /* open destination file for writing */ + if((dest_fd = open(dest, O_WRONLY | O_TRUNC | O_CREAT | O_APPEND, 0644)) < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to open file '%s' for writing: %s\n", dest, strerror(errno)); + return ERROR; + } + + result = my_fdcopy(source, dest, dest_fd); + close(dest_fd); + return result; + } + +/******************************************************************/ +/******************** DYNAMIC BUFFER FUNCTIONS ********************/ +/******************************************************************/ + +/* initializes a dynamic buffer */ +int dbuf_init(dbuf *db, int chunk_size) { + + if(db == NULL) + return ERROR; + + db->buf = NULL; + db->used_size = 0L; + db->allocated_size = 0L; + db->chunk_size = chunk_size; + + return OK; + } + + +/* frees a dynamic buffer */ +int dbuf_free(dbuf *db) { + + if(db == NULL) + return ERROR; + + if(db->buf != NULL) + my_free(db->buf); + db->buf = NULL; + db->used_size = 0L; + db->allocated_size = 0L; + + return OK; + } + + +/* dynamically expands a string */ +int dbuf_strcat(dbuf *db, char *buf) { + char *newbuf = NULL; + unsigned long buflen = 0L; + unsigned long new_size = 0L; + unsigned long memory_needed = 0L; + + if(db == NULL || buf == NULL) + return ERROR; + + /* how much memory should we allocate (if any)? */ + buflen = strlen(buf); + new_size = db->used_size + buflen + 1; + + /* we need more memory */ + if(db->allocated_size < new_size) { + + memory_needed = ((ceil(new_size / db->chunk_size) + 1) * db->chunk_size); + + /* allocate memory to store old and new string */ + if((newbuf = (char *)realloc((void *)db->buf, (size_t)memory_needed)) == NULL) + return ERROR; + + /* update buffer pointer */ + db->buf = newbuf; + + /* update allocated size */ + db->allocated_size = memory_needed; + + /* terminate buffer */ + db->buf[db->used_size] = '\x0'; + } + + /* append the new string */ + strcat(db->buf, buf); + + /* update size allocated */ + db->used_size += buflen; + + return OK; + } + + + +/******************************************************************/ +/******************** EMBEDDED PERL FUNCTIONS *********************/ +/******************************************************************/ + +/* initializes embedded perl interpreter */ +int init_embedded_perl(char **env) { +#ifdef EMBEDDEDPERL + char **embedding; + int exitstatus = 0; + int argc = 2; + struct stat stat_buf; + + /* make sure the P1 file exists... */ + if(p1_file == NULL || stat(p1_file, &stat_buf) != 0) { + + use_embedded_perl = FALSE; + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: p1.pl file required for embedded Perl interpreter is missing!\n"); + } + + else { + + embedding = malloc(2 * sizeof(char *)); + if(embedding == NULL) + return ERROR; + *embedding = strdup(""); + *(embedding + 1) = strdup(p1_file); + + use_embedded_perl = TRUE; + + PERL_SYS_INIT3(&argc, &embedding, &env); + + if((my_perl = perl_alloc()) == NULL) { + use_embedded_perl = FALSE; + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not allocate memory for embedded Perl interpreter!\n"); + } + } + + /* a fatal error occurred... */ + if(use_embedded_perl == FALSE) { + + logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to errors encountered while initializing the embedded Perl interpreter. (PID=%d)\n", (int)getpid()); + + cleanup(); + exit(ERROR); + } + + perl_construct(my_perl); + exitstatus = perl_parse(my_perl, xs_init, 2, (char **)embedding, env); + if(!exitstatus) + exitstatus = perl_run(my_perl); + +#endif + return OK; + } + + +/* closes embedded perl interpreter */ +int deinit_embedded_perl(void) { +#ifdef EMBEDDEDPERL + + PL_perl_destruct_level = 0; + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + +#endif + return OK; + } + + +/* checks to see if we should run a script using the embedded Perl interpreter */ +int file_uses_embedded_perl(char *fname) { +#ifndef EMBEDDEDPERL + return FALSE; +#else + int line, use_epn = FALSE; + FILE *fp = NULL; + char buf[256] = ""; + + if(enable_embedded_perl != TRUE) + return FALSE; + + /* open the file, check if its a Perl script and see if we can use epn */ + fp = fopen(fname, "r"); + if(fp == NULL) + return FALSE; + + /* grab the first line - we should see Perl. go home if not */ + if(fgets(buf, 80, fp) == NULL || strstr(buf, "/bin/perl") == NULL) { + fclose(fp); + return FALSE; + } + + /* epn directives must be found in first ten lines of plugin */ + for(line = 1; line < 10; line++) { + if(fgets(buf, sizeof(buf) - 1, fp) == NULL) + break; + + buf[sizeof(buf) - 1] = '\0'; + + /* skip lines not containing nagios 'epn' directives */ + if(strstr(buf, "# nagios:")) { + char *p; + p = strstr(buf + 8, "epn"); + if(!p) + continue; + + /* + * we found it, so close the file and return + * whatever it shows. '+epn' means yes. everything + * else means no + */ + fclose(fp); + return *(p - 1) == '+' ? TRUE : FALSE; + } + } + + fclose(fp); + + return use_embedded_perl_implicitly; +#endif + } + + + + + +/******************************************************************/ +/************************ THREAD FUNCTIONS ************************/ +/******************************************************************/ + +/* initializes command file worker thread */ +int init_command_file_worker_thread(void) { + int result = 0; + sigset_t newmask; + + /* initialize circular buffer */ + external_command_buffer.head = 0; + external_command_buffer.tail = 0; + external_command_buffer.items = 0; + external_command_buffer.high = 0; + external_command_buffer.overflow = 0L; + external_command_buffer.buffer = (void **)malloc(external_command_buffer_slots * sizeof(char **)); + if(external_command_buffer.buffer == NULL) + return ERROR; + + /* initialize mutex (only on cold startup) */ + if(sigrestart == FALSE) + pthread_mutex_init(&external_command_buffer.buffer_lock, NULL); + + /* new thread should block all signals */ + sigfillset(&newmask); + pthread_sigmask(SIG_BLOCK, &newmask, NULL); + + /* create worker thread */ + result = pthread_create(&worker_threads[COMMAND_WORKER_THREAD], NULL, command_file_worker_thread, NULL); + + /* main thread should unblock all signals */ + pthread_sigmask(SIG_UNBLOCK, &newmask, NULL); + + if(result) + return ERROR; + + return OK; + } + + +/* shutdown command file worker thread */ +int shutdown_command_file_worker_thread(void) { + int result = 0; + + /* + * calling pthread_cancel(0) will cause segfaults with some + * thread libraries. It's possible that will happen if the + * user has a number of config files larger than the max + * open file descriptor limit (ulimit -n) and some retarded + * eventbroker module leaks filedescriptors, since we'll then + * enter the cleanup() routine from main() before we've + * spawned any threads. + */ + if(worker_threads[COMMAND_WORKER_THREAD]) { + /* tell the worker thread to exit */ + result = pthread_cancel(worker_threads[COMMAND_WORKER_THREAD]); + + /* wait for the worker thread to exit */ + if(result == 0) { + result = pthread_join(worker_threads[COMMAND_WORKER_THREAD], NULL); + } + + /* we're being called from a fork()'ed child process - can't cancel thread, so just cleanup memory */ + else { + cleanup_command_file_worker_thread(NULL); + } + } + + return OK; + } + + +/* clean up resources used by command file worker thread */ +void cleanup_command_file_worker_thread(void *arg) { + register int x = 0; + + /* release memory allocated to circular buffer */ + for(x = external_command_buffer.tail; x != external_command_buffer.head; x = (x + 1) % external_command_buffer_slots) { + my_free(((char **)external_command_buffer.buffer)[x]); + } + my_free(external_command_buffer.buffer); + + return; + } + + + +/* worker thread - artificially increases buffer of named pipe */ +void * command_file_worker_thread(void *arg) { + char input_buffer[MAX_EXTERNAL_COMMAND_LENGTH]; + struct pollfd pfd; + int pollval; + struct timeval tv; + int buffer_items = 0; + int result = 0; + + /* specify cleanup routine */ + pthread_cleanup_push(cleanup_command_file_worker_thread, NULL); + + /* set cancellation info */ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); + + while(1) { + + /* should we shutdown? */ + pthread_testcancel(); + + /* wait for data to arrive */ + /* select seems to not work, so we have to use poll instead */ + /* 10-15-08 EG check into implementing William's patch @ http://blog.netways.de/2008/08/15/nagios-unter-mac-os-x-installieren/ */ + /* 10-15-08 EG poll() seems broken on OSX - see Jonathan's patch a few lines down */ + pfd.fd = command_file_fd; + pfd.events = POLLIN; + pollval = poll(&pfd, 1, 500); + + /* loop if no data */ + if(pollval == 0) + continue; + + /* check for errors */ + if(pollval == -1) { + + switch(errno) { + case EBADF: + write_to_log("command_file_worker_thread(): poll(): EBADF", logging_options, NULL); + break; + case ENOMEM: + write_to_log("command_file_worker_thread(): poll(): ENOMEM", logging_options, NULL); + break; + case EFAULT: + write_to_log("command_file_worker_thread(): poll(): EFAULT", logging_options, NULL); + break; + case EINTR: + /* this can happen when running under a debugger like gdb */ + /* + write_to_log("command_file_worker_thread(): poll(): EINTR (impossible)",logging_options,NULL); + */ + break; + default: + write_to_log("command_file_worker_thread(): poll(): Unknown errno value.", logging_options, NULL); + break; + } + + continue; + } + + /* should we shutdown? */ + pthread_testcancel(); + + /* get number of items in the buffer */ + pthread_mutex_lock(&external_command_buffer.buffer_lock); + buffer_items = external_command_buffer.items; + pthread_mutex_unlock(&external_command_buffer.buffer_lock); + +#ifdef DEBUG_CFWT + printf("(CFWT) BUFFER ITEMS: %d/%d\n", buffer_items, external_command_buffer_slots); +#endif + + /* 10-15-08 Fix for OS X by Jonathan Saggau - see http://www.jonathansaggau.com/blog/2008/09/using_shark_and_custom_dtrace.html */ + /* Not sure if this would have negative effects on other OSes... */ + if(buffer_items == 0) { + /* pause a bit so OS X doesn't go nuts with CPU overload */ + tv.tv_sec = 0; + tv.tv_usec = 500; + select(0, NULL, NULL, NULL, &tv); + } + + /* process all commands in the file (named pipe) if there's some space in the buffer */ + if(buffer_items < external_command_buffer_slots) { + + /* clear EOF condition from prior run (FreeBSD fix) */ + /* FIXME: use_poll_on_cmd_pipe: Still needed? */ + clearerr(command_file_fp); + + /* read and process the next command in the file */ + while(fgets(input_buffer, (int)(sizeof(input_buffer) - 1), command_file_fp) != NULL) { + +#ifdef DEBUG_CFWT + printf("(CFWT) READ: %s", input_buffer); +#endif + + /* submit the external command for processing (retry if buffer is full) */ + while((result = submit_external_command(input_buffer, &buffer_items)) == ERROR && buffer_items == external_command_buffer_slots) { + + /* wait a bit */ + tv.tv_sec = 0; + tv.tv_usec = 250000; + select(0, NULL, NULL, NULL, &tv); + + /* should we shutdown? */ + pthread_testcancel(); + } + +#ifdef DEBUG_CFWT + printf("(CFWT) RES: %d, BUFFER_ITEMS: %d/%d\n", result, buffer_items, external_comand_buffer_slots); +#endif + + /* bail if the circular buffer is full */ + if(buffer_items == external_command_buffer_slots) + break; + + /* should we shutdown? */ + pthread_testcancel(); + } + } + } + + /* removes cleanup handler - this should never be reached */ + pthread_cleanup_pop(0); + + return NULL; + } + + + +/* submits an external command for processing */ +int submit_external_command(char *cmd, int *buffer_items) { + int result = OK; + + if(cmd == NULL || external_command_buffer.buffer == NULL) { + if(buffer_items != NULL) + *buffer_items = -1; + return ERROR; + } + + /* obtain a lock for writing to the buffer */ + pthread_mutex_lock(&external_command_buffer.buffer_lock); + + if(external_command_buffer.items < external_command_buffer_slots) { + + /* save the line in the buffer */ + ((char **)external_command_buffer.buffer)[external_command_buffer.head] = (char *)strdup(cmd); + + /* increment the head counter and items */ + external_command_buffer.head = (external_command_buffer.head + 1) % external_command_buffer_slots; + external_command_buffer.items++; + if(external_command_buffer.items > external_command_buffer.high) + external_command_buffer.high = external_command_buffer.items; + } + + /* buffer was full */ + else + result = ERROR; + + /* return number of items now in buffer */ + if(buffer_items != NULL) + *buffer_items = external_command_buffer.items; + + /* release lock on buffer */ + pthread_mutex_unlock(&external_command_buffer.buffer_lock); + + return result; + } + + + +/* submits a raw external command (without timestamp) for processing */ +int submit_raw_external_command(char *cmd, time_t *ts, int *buffer_items) { + char *newcmd = NULL; + int result = OK; + time_t timestamp; + + if(cmd == NULL) + return ERROR; + + /* get the time */ + if(ts != NULL) + timestamp = *ts; + else + time(×tamp); + + /* create the command string */ + asprintf(&newcmd, "[%lu] %s", (unsigned long)timestamp, cmd); + + /* submit the command */ + result = submit_external_command(newcmd, buffer_items); + + /* free allocated memory */ + my_free(newcmd); + + return result; + } + + + +/******************************************************************/ +/********************** CHECK STATS FUNCTIONS *********************/ +/******************************************************************/ + +/* initialize check statistics data structures */ +int init_check_stats(void) { + int x = 0; + int y = 0; + + for(x = 0; x < MAX_CHECK_STATS_TYPES; x++) { + check_statistics[x].current_bucket = 0; + for(y = 0; y < CHECK_STATS_BUCKETS; y++) + check_statistics[x].bucket[y] = 0; + check_statistics[x].overflow_bucket = 0; + for(y = 0; y < 3; y++) + check_statistics[x].minute_stats[y] = 0; + check_statistics[x].last_update = (time_t)0L; + } + + return OK; + } + + +/* records stats for a given type of check */ +int update_check_stats(int check_type, time_t check_time) { + time_t current_time; + unsigned long minutes = 0L; + int new_current_bucket = 0; + int this_bucket = 0; + int x = 0; + + if(check_type < 0 || check_type >= MAX_CHECK_STATS_TYPES) + return ERROR; + + time(¤t_time); + + if((unsigned long)check_time == 0L) { +#ifdef DEBUG_CHECK_STATS + printf("TYPE[%d] CHECK TIME==0!\n", check_type); +#endif + check_time = current_time; + } + + /* do some sanity checks on the age of the stats data before we start... */ + /* get the new current bucket number */ + minutes = ((unsigned long)check_time - (unsigned long)program_start) / 60; + new_current_bucket = minutes % CHECK_STATS_BUCKETS; + + /* its been more than 15 minutes since stats were updated, so clear the stats */ + if((((unsigned long)current_time - (unsigned long)check_statistics[check_type].last_update) / 60) > CHECK_STATS_BUCKETS) { + for(x = 0; x < CHECK_STATS_BUCKETS; x++) + check_statistics[check_type].bucket[x] = 0; + check_statistics[check_type].overflow_bucket = 0; +#ifdef DEBUG_CHECK_STATS + printf("CLEARING ALL: TYPE[%d], CURRENT=%lu, LASTUPDATE=%lu\n", check_type, (unsigned long)current_time, (unsigned long)check_statistics[check_type].last_update); +#endif + } + + /* different current bucket number than last time */ + else if(new_current_bucket != check_statistics[check_type].current_bucket) { + + /* clear stats in buckets between last current bucket and new current bucket - stats haven't been updated in a while */ + for(x = check_statistics[check_type].current_bucket; x < (CHECK_STATS_BUCKETS * 2); x++) { + + this_bucket = (x + CHECK_STATS_BUCKETS + 1) % CHECK_STATS_BUCKETS; + + if(this_bucket == new_current_bucket) + break; + +#ifdef DEBUG_CHECK_STATS + printf("CLEARING BUCKET %d, (NEW=%d, OLD=%d)\n", this_bucket, new_current_bucket, check_statistics[check_type].current_bucket); +#endif + + /* clear old bucket value */ + check_statistics[check_type].bucket[this_bucket] = 0; + } + + /* update the current bucket number, push old value to overflow bucket */ + check_statistics[check_type].overflow_bucket = check_statistics[check_type].bucket[new_current_bucket]; + check_statistics[check_type].current_bucket = new_current_bucket; + check_statistics[check_type].bucket[new_current_bucket] = 0; + } +#ifdef DEBUG_CHECK_STATS + else + printf("NO CLEARING NEEDED\n"); +#endif + + + /* increment the value of the current bucket */ + check_statistics[check_type].bucket[new_current_bucket]++; + +#ifdef DEBUG_CHECK_STATS + printf("TYPE[%d].BUCKET[%d]=%d\n", check_type, new_current_bucket, check_statistics[check_type].bucket[new_current_bucket]); + printf(" "); + for(x = 0; x < CHECK_STATS_BUCKETS; x++) + printf("[%d] ", check_statistics[check_type].bucket[x]); + printf(" (%d)\n", check_statistics[check_type].overflow_bucket); +#endif + + /* record last update time */ + check_statistics[check_type].last_update = current_time; + + return OK; + } + + +/* generate 1/5/15 minute stats for a given type of check */ +int generate_check_stats(void) { + time_t current_time; + int x = 0; + int new_current_bucket = 0; + int this_bucket = 0; + int last_bucket = 0; + int this_bucket_value = 0; + int last_bucket_value = 0; + int bucket_value = 0; + int seconds = 0; + int minutes = 0; + int check_type = 0; + float this_bucket_weight = 0.0; + float last_bucket_weight = 0.0; + int left_value = 0; + int right_value = 0; + + + time(¤t_time); + + /* do some sanity checks on the age of the stats data before we start... */ + /* get the new current bucket number */ + minutes = ((unsigned long)current_time - (unsigned long)program_start) / 60; + new_current_bucket = minutes % CHECK_STATS_BUCKETS; + for(check_type = 0; check_type < MAX_CHECK_STATS_TYPES; check_type++) { + + /* its been more than 15 minutes since stats were updated, so clear the stats */ + if((((unsigned long)current_time - (unsigned long)check_statistics[check_type].last_update) / 60) > CHECK_STATS_BUCKETS) { + for(x = 0; x < CHECK_STATS_BUCKETS; x++) + check_statistics[check_type].bucket[x] = 0; + check_statistics[check_type].overflow_bucket = 0; +#ifdef DEBUG_CHECK_STATS + printf("GEN CLEARING ALL: TYPE[%d], CURRENT=%lu, LASTUPDATE=%lu\n", check_type, (unsigned long)current_time, (unsigned long)check_statistics[check_type].last_update); +#endif + } + + /* different current bucket number than last time */ + else if(new_current_bucket != check_statistics[check_type].current_bucket) { + + /* clear stats in buckets between last current bucket and new current bucket - stats haven't been updated in a while */ + for(x = check_statistics[check_type].current_bucket; x < (CHECK_STATS_BUCKETS * 2); x++) { + + this_bucket = (x + CHECK_STATS_BUCKETS + 1) % CHECK_STATS_BUCKETS; + + if(this_bucket == new_current_bucket) + break; + +#ifdef DEBUG_CHECK_STATS + printf("GEN CLEARING BUCKET %d, (NEW=%d, OLD=%d), CURRENT=%lu, LASTUPDATE=%lu\n", this_bucket, new_current_bucket, check_statistics[check_type].current_bucket, (unsigned long)current_time, (unsigned long)check_statistics[check_type].last_update); +#endif + + /* clear old bucket value */ + check_statistics[check_type].bucket[this_bucket] = 0; + } + + /* update the current bucket number, push old value to overflow bucket */ + check_statistics[check_type].overflow_bucket = check_statistics[check_type].bucket[new_current_bucket]; + check_statistics[check_type].current_bucket = new_current_bucket; + check_statistics[check_type].bucket[new_current_bucket] = 0; + } +#ifdef DEBUG_CHECK_STATS + else + printf("GEN NO CLEARING NEEDED: TYPE[%d], CURRENT=%lu, LASTUPDATE=%lu\n", check_type, (unsigned long)current_time, (unsigned long)check_statistics[check_type].last_update); +#endif + + /* update last check time */ + check_statistics[check_type].last_update = current_time; + } + + /* determine weights to use for this/last buckets */ + seconds = ((unsigned long)current_time - (unsigned long)program_start) % 60; + this_bucket_weight = (seconds / 60.0); + last_bucket_weight = ((60 - seconds) / 60.0); + + /* update statistics for all check types */ + for(check_type = 0; check_type < MAX_CHECK_STATS_TYPES; check_type++) { + + /* clear the old statistics */ + for(x = 0; x < 3; x++) + check_statistics[check_type].minute_stats[x] = 0; + + /* loop through each bucket */ + for(x = 0; x < CHECK_STATS_BUCKETS; x++) { + + /* which buckets should we use for this/last bucket? */ + this_bucket = (check_statistics[check_type].current_bucket + CHECK_STATS_BUCKETS - x) % CHECK_STATS_BUCKETS; + last_bucket = (this_bucket + CHECK_STATS_BUCKETS - 1) % CHECK_STATS_BUCKETS; + + /* raw/unweighted value for this bucket */ + this_bucket_value = check_statistics[check_type].bucket[this_bucket]; + + /* raw/unweighted value for last bucket - use overflow bucket if last bucket is current bucket */ + if(last_bucket == check_statistics[check_type].current_bucket) + last_bucket_value = check_statistics[check_type].overflow_bucket; + else + last_bucket_value = check_statistics[check_type].bucket[last_bucket]; + + /* determine value by weighting this/last buckets... */ + /* if this is the current bucket, use its full value + weighted % of last bucket */ + if(x == 0) { + right_value = this_bucket_value; + left_value = (int)floor(last_bucket_value * last_bucket_weight); + bucket_value = (int)(this_bucket_value + floor(last_bucket_value * last_bucket_weight)); + } + /* otherwise use weighted % of this and last bucket */ + else { + right_value = (int)ceil(this_bucket_value * this_bucket_weight); + left_value = (int)floor(last_bucket_value * last_bucket_weight); + bucket_value = (int)(ceil(this_bucket_value * this_bucket_weight) + floor(last_bucket_value * last_bucket_weight)); + } + + /* 1 minute stats */ + if(x == 0) + check_statistics[check_type].minute_stats[0] = bucket_value; + + /* 5 minute stats */ + if(x < 5) + check_statistics[check_type].minute_stats[1] += bucket_value; + + /* 15 minute stats */ + if(x < 15) + check_statistics[check_type].minute_stats[2] += bucket_value; + +#ifdef DEBUG_CHECK_STATS2 + printf("X=%d, THIS[%d]=%d, LAST[%d]=%d, 1/5/15=%d,%d,%d L=%d R=%d\n", x, this_bucket, this_bucket_value, last_bucket, last_bucket_value, check_statistics[check_type].minute_stats[0], check_statistics[check_type].minute_stats[1], check_statistics[check_type].minute_stats[2], left_value, right_value); +#endif + /* record last update time */ + check_statistics[check_type].last_update = current_time; + } + +#ifdef DEBUG_CHECK_STATS + printf("TYPE[%d] 1/5/15 = %d, %d, %d (seconds=%d, this_weight=%f, last_weight=%f)\n", check_type, check_statistics[check_type].minute_stats[0], check_statistics[check_type].minute_stats[1], check_statistics[check_type].minute_stats[2], seconds, this_bucket_weight, last_bucket_weight); +#endif + } + + return OK; + } + + + + +/******************************************************************/ +/************************ UPDATE FUNCTIONS ************************/ +/******************************************************************/ + +/* check for new releases of Nagios */ +int check_for_nagios_updates(int force, int reschedule) { + time_t current_time; + int result = OK; + int api_result = OK; + int do_check = TRUE; + time_t next_check = 0L; + unsigned int rand_seed = 0; + int randnum = 0; + + time(¤t_time); + + /* + printf("NOW: %s",ctime(¤t_time)); + printf("LAST CHECK: %s",ctime(&last_update_check)); + */ + + /* seed the random generator */ + rand_seed = (unsigned int)(current_time + nagios_pid); + srand(rand_seed); + + /* generate a (probably) unique ID for this nagios install */ + /* the server api currently sees thousands of nagios installs behind single ip addresses, so this help determine if there are really thousands of servers out there, or if some nagios installs are misbehaving */ + if(update_uid == 0L) + update_uid = current_time; + + /* update chekcs are disabled */ + if(check_for_updates == FALSE) + do_check = FALSE; + /* we checked for updates recently, so don't do it again */ + if((current_time - last_update_check) < MINIMUM_UPDATE_CHECK_INTERVAL) + do_check = FALSE; + /* the check is being forced */ + if(force == TRUE) + do_check = TRUE; + + /* do a check */ + if(do_check == TRUE) { + + /*printf("RUNNING QUERY...\n");*/ + + /* query api */ + api_result = query_update_api(); + } + + /* should we reschedule the update check? */ + if(reschedule == TRUE) { + + /*printf("RESCHEDULING...\n");*/ + + randnum = rand(); + /* + printf("RAND: %d\n",randnum); + printf("RANDMAX: %d\n",RAND_MAX); + printf("UCIW: %d\n",UPDATE_CHECK_INTERVAL_WOBBLE); + printf("MULT: %f\n",(float)randnum/RAND_MAX); + */ + + + + /* we didn't do an update, so calculate next possible update time */ + if(do_check == FALSE) { + next_check = last_update_check + BASE_UPDATE_CHECK_INTERVAL; + next_check = next_check + (unsigned long)(((float)randnum / RAND_MAX) * UPDATE_CHECK_INTERVAL_WOBBLE); + } + + /* we tried to check for an update */ + else { + + /* api query was okay */ + if(api_result == OK) { + next_check = current_time + BASE_UPDATE_CHECK_INTERVAL; + next_check += (unsigned long)(((float)randnum / RAND_MAX) * UPDATE_CHECK_INTERVAL_WOBBLE); + } + + /* query resulted in an error - retry at a shorter interval */ + else { + next_check = current_time + BASE_UPDATE_CHECK_RETRY_INTERVAL; + next_check += (unsigned long)(((float)randnum / RAND_MAX) * UPDATE_CHECK_RETRY_INTERVAL_WOBBLE); + } + } + + /* make sure next check isn't in the past - if it is, schedule a check in 1 minute */ + if(next_check < current_time) + next_check = current_time + 60; + + /*printf("NEXT CHECK: %s",ctime(&next_check));*/ + + /* schedule the next update event */ + schedule_new_event(EVENT_CHECK_PROGRAM_UPDATE, TRUE, next_check, FALSE, BASE_UPDATE_CHECK_INTERVAL, NULL, TRUE, NULL, NULL, 0); + } + + return result; + } + + + +/* checks for updates at api.nagios.org */ +int query_update_api(void) { + char *api_server = "api.nagios.org"; + char *api_path = "/versioncheck/"; + char *api_query = NULL; + char *api_query_opts = NULL; + char *buf = NULL; + char recv_buf[1024]; + int report_install = FALSE; + int result = OK; + char *ptr = NULL; + int current_line = 0; + int buf_index = 0; + int in_header = TRUE; + char *var = NULL; + char *val = NULL; + int sd = 0; + int send_len = 0; + int recv_len = 0; + int update_check_succeeded = FALSE; + + /* report a new install, upgrade, or rollback */ + /* Nagios monitors the world and we monitor Nagios taking over the world. :-) */ + if(last_update_check == (time_t)0L) + report_install = TRUE; + if(last_program_version == NULL || strcmp(PROGRAM_VERSION, last_program_version)) + report_install = TRUE; + if(report_install == TRUE) { + asprintf(&api_query_opts, "&firstcheck=1"); + if(last_program_version != NULL) { + char *qopts2 = NULL; + asprintf(&qopts2, "%s&last_version=%s", api_query_opts, last_program_version); + my_free(api_query_opts); + api_query_opts = qopts2; + } + } + + /* generate the query */ + asprintf(&api_query, "v=1&product=nagios&tinycheck=1&stableonly=1&uid=%lu", update_uid); + if(bare_update_check == FALSE) { + char *api_query2 = NULL; + asprintf(&api_query2, "%s&version=%s%s", api_query, PROGRAM_VERSION, (api_query_opts == NULL) ? "" : api_query_opts); + my_free(api_query); + api_query = api_query2; + } + + /* generate the HTTP request */ + asprintf(&buf, + "POST %s HTTP/1.0\r\nUser-Agent: Nagios/%s\r\n" + "Connection: close\r\nHost: %s\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: %zd\r\n\r\n%s", + api_path, PROGRAM_VERSION, api_server, + strlen(api_query), api_query); + + /* + printf("SENDING...\n"); + printf("==========\n"); + printf("%s",buf); + printf("\n"); + */ + + + result = my_tcp_connect(api_server, 80, &sd, 2); + /*printf("CONN RESULT: %d, SD: %d\n",result,sd);*/ + if(sd > 0) { + + /* send request */ + send_len = strlen(buf); + result = my_sendall(sd, buf, &send_len, 2); + /*printf("SEND RESULT: %d, SENT: %d\n",result,send_len);*/ + + /* get response */ + recv_len = sizeof(recv_buf); + result = my_recvall(sd, recv_buf, &recv_len, 2); + recv_buf[sizeof(recv_buf) - 1] = '\x0'; + /*printf("RECV RESULT: %d, RECEIVED: %d\n",result,recv_len);*/ + + /* + printf("\n"); + printf("RECEIVED...\n"); + printf("===========\n"); + printf("%s",recv_buf); + printf("\n"); + */ + + /* close connection */ + close(sd); + + /* parse the result */ + in_header = TRUE; + while((ptr = get_next_string_from_buf(recv_buf, &buf_index, sizeof(recv_buf)))) { + + strip(ptr); + current_line++; + + if(!strcmp(ptr, "")) { + in_header = FALSE; + continue; + } + if(in_header == TRUE) + continue; + + var = strtok(ptr, "="); + val = strtok(NULL, "\n"); + /*printf("VAR: %s, VAL: %s\n",var,val);*/ + + if(!strcmp(var, "UPDATE_AVAILABLE")) { + update_available = atoi(val); + /* we were successful */ + update_check_succeeded = TRUE; + } + else if(!strcmp(var, "UPDATE_VERSION")) { + if(new_program_version) + my_free(new_program_version); + new_program_version = strdup(val); + } + else if(!strcmp(var, "UPDATE_RELEASEDATE")) { + } + } + } + + /* cleanup */ + my_free(buf); + my_free(api_query); + my_free(api_query_opts); + + /* we were successful! */ + if(update_check_succeeded == TRUE) { + + time(&last_update_check); + if(last_program_version) + free(last_program_version); + last_program_version = (char *)strdup(PROGRAM_VERSION); + } + + return OK; + } + + + + +/******************************************************************/ +/************************* MISC FUNCTIONS *************************/ +/******************************************************************/ + +/* returns Nagios version */ +char *get_program_version(void) { + + return (char *)PROGRAM_VERSION; + } + + +/* returns Nagios modification date */ +char *get_program_modification_date(void) { + + return (char *)PROGRAM_MODIFICATION_DATE; + } + + + +/******************************************************************/ +/*********************** CLEANUP FUNCTIONS ************************/ +/******************************************************************/ + +/* do some cleanup before we exit */ +void cleanup(void) { + +#ifdef USE_EVENT_BROKER + /* unload modules */ + if(test_scheduling == FALSE && verify_config == FALSE) { + neb_free_callback_list(); + neb_unload_all_modules(NEBMODULE_FORCE_UNLOAD, (sigshutdown == TRUE) ? NEBMODULE_NEB_SHUTDOWN : NEBMODULE_NEB_RESTART); + neb_free_module_list(); + neb_deinit_modules(); + } +#endif + + /* free all allocated memory - including macros */ + free_memory(get_global_macros()); + + return; + } + + +/* free the memory allocated to the linked lists */ +void free_memory(nagios_macros *mac) { + timed_event *this_event = NULL; + timed_event *next_event = NULL; + + /* free all allocated memory for the object definitions */ + free_object_data(); + + /* free memory allocated to comments */ + free_comment_data(); + + /* free check result list */ + free_check_result_list(&check_result_list); + + /* free memory for the high priority event list */ + this_event = event_list_high; + while(this_event != NULL) { + if(this_event->event_type == EVENT_SCHEDULED_DOWNTIME) + my_free(this_event->event_data); + next_event = this_event->next; + my_free(this_event); + this_event = next_event; + } + + /* reset the event pointer */ + event_list_high = NULL; + + /* free memory for the low priority event list */ + this_event = event_list_low; + while(this_event != NULL) { + if(this_event->event_type == EVENT_SCHEDULED_DOWNTIME) + my_free(this_event->event_data); + next_event = this_event->next; + my_free(this_event); + this_event = next_event; + } + + /* reset the event pointer */ + event_list_low = NULL; + + /* free memory for global event handlers */ + my_free(global_host_event_handler); + my_free(global_service_event_handler); + + /* free any notification list that may have been overlooked */ + free_notification_list(); + + /* free obsessive compulsive commands */ + my_free(ocsp_command); + my_free(ochp_command); + + /* + * free memory associated with macros. + * It's ok to only free the volatile ones, as the non-volatile + * are always free()'d before assignment if they're set. + * Doing a full free of them here means we'll wipe the constant + * macros when we get a reload or restart request through the + * command pipe, or when we receive a SIGHUP. + */ + clear_volatile_macros_r(mac); + + free_macrox_names(); + + /* free illegal char strings */ + my_free(illegal_object_chars); + my_free(illegal_output_chars); + + /* free nagios user and group */ + my_free(nagios_user); + my_free(nagios_group); + + /* free version strings */ + my_free(last_program_version); + my_free(new_program_version); + + /* free file/path variables */ + my_free(log_file); + my_free(debug_file); + my_free(temp_file); + my_free(temp_path); + my_free(check_result_path); + my_free(command_file); + my_free(lock_file); + my_free(auth_file); + my_free(p1_file); + my_free(log_archive_path); + + return; + } + + +/* free a notification list that was created */ +void free_notification_list(void) { + notification *temp_notification = NULL; + notification *next_notification = NULL; + + temp_notification = notification_list; + while(temp_notification != NULL) { + next_notification = temp_notification->next; + my_free(temp_notification); + temp_notification = next_notification; + } + + /* reset notification list pointer */ + notification_list = NULL; + + return; + } + + +/* reset all system-wide variables, so when we've receive a SIGHUP we can restart cleanly */ +int reset_variables(void) { + + log_file = (char *)strdup(DEFAULT_LOG_FILE); + temp_file = (char *)strdup(DEFAULT_TEMP_FILE); + temp_path = (char *)strdup(DEFAULT_TEMP_PATH); + check_result_path = (char *)strdup(DEFAULT_CHECK_RESULT_PATH); + command_file = (char *)strdup(DEFAULT_COMMAND_FILE); + lock_file = (char *)strdup(DEFAULT_LOCK_FILE); + auth_file = (char *)strdup(DEFAULT_AUTH_FILE); + p1_file = (char *)strdup(DEFAULT_P1_FILE); + log_archive_path = (char *)strdup(DEFAULT_LOG_ARCHIVE_PATH); + debug_file = (char *)strdup(DEFAULT_DEBUG_FILE); + + nagios_user = (char *)strdup(DEFAULT_NAGIOS_USER); + nagios_group = (char *)strdup(DEFAULT_NAGIOS_GROUP); + + use_regexp_matches = FALSE; + use_true_regexp_matching = FALSE; + + use_syslog = DEFAULT_USE_SYSLOG; + log_service_retries = DEFAULT_LOG_SERVICE_RETRIES; + log_host_retries = DEFAULT_LOG_HOST_RETRIES; + log_initial_states = DEFAULT_LOG_INITIAL_STATES; + + log_notifications = DEFAULT_NOTIFICATION_LOGGING; + log_event_handlers = DEFAULT_LOG_EVENT_HANDLERS; + log_external_commands = DEFAULT_LOG_EXTERNAL_COMMANDS; + log_passive_checks = DEFAULT_LOG_PASSIVE_CHECKS; + + logging_options = NSLOG_RUNTIME_ERROR | NSLOG_RUNTIME_WARNING | NSLOG_VERIFICATION_ERROR | NSLOG_VERIFICATION_WARNING | NSLOG_CONFIG_ERROR | NSLOG_CONFIG_WARNING | NSLOG_PROCESS_INFO | NSLOG_HOST_NOTIFICATION | NSLOG_SERVICE_NOTIFICATION | NSLOG_EVENT_HANDLER | NSLOG_EXTERNAL_COMMAND | NSLOG_PASSIVE_CHECK | NSLOG_HOST_UP | NSLOG_HOST_DOWN | NSLOG_HOST_UNREACHABLE | NSLOG_SERVICE_OK | NSLOG_SERVICE_WARNING | NSLOG_SERVICE_UNKNOWN | NSLOG_SERVICE_CRITICAL | NSLOG_INFO_MESSAGE; + + syslog_options = NSLOG_RUNTIME_ERROR | NSLOG_RUNTIME_WARNING | NSLOG_VERIFICATION_ERROR | NSLOG_VERIFICATION_WARNING | NSLOG_CONFIG_ERROR | NSLOG_CONFIG_WARNING | NSLOG_PROCESS_INFO | NSLOG_HOST_NOTIFICATION | NSLOG_SERVICE_NOTIFICATION | NSLOG_EVENT_HANDLER | NSLOG_EXTERNAL_COMMAND | NSLOG_PASSIVE_CHECK | NSLOG_HOST_UP | NSLOG_HOST_DOWN | NSLOG_HOST_UNREACHABLE | NSLOG_SERVICE_OK | NSLOG_SERVICE_WARNING | NSLOG_SERVICE_UNKNOWN | NSLOG_SERVICE_CRITICAL | NSLOG_INFO_MESSAGE; + + service_check_timeout = DEFAULT_SERVICE_CHECK_TIMEOUT; + host_check_timeout = DEFAULT_HOST_CHECK_TIMEOUT; + event_handler_timeout = DEFAULT_EVENT_HANDLER_TIMEOUT; + notification_timeout = DEFAULT_NOTIFICATION_TIMEOUT; + ocsp_timeout = DEFAULT_OCSP_TIMEOUT; + ochp_timeout = DEFAULT_OCHP_TIMEOUT; + + sleep_time = DEFAULT_SLEEP_TIME; + interval_length = DEFAULT_INTERVAL_LENGTH; + service_inter_check_delay_method = ICD_SMART; + host_inter_check_delay_method = ICD_SMART; + service_interleave_factor_method = ILF_SMART; + max_service_check_spread = DEFAULT_SERVICE_CHECK_SPREAD; + max_host_check_spread = DEFAULT_HOST_CHECK_SPREAD; + + use_aggressive_host_checking = DEFAULT_AGGRESSIVE_HOST_CHECKING; + cached_host_check_horizon = DEFAULT_CACHED_HOST_CHECK_HORIZON; + cached_service_check_horizon = DEFAULT_CACHED_SERVICE_CHECK_HORIZON; + enable_predictive_host_dependency_checks = DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS; + enable_predictive_service_dependency_checks = DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS; + + soft_state_dependencies = FALSE; + + retain_state_information = FALSE; + retention_update_interval = DEFAULT_RETENTION_UPDATE_INTERVAL; + use_retained_program_state = TRUE; + use_retained_scheduling_info = FALSE; + retention_scheduling_horizon = DEFAULT_RETENTION_SCHEDULING_HORIZON; + modified_host_process_attributes = MODATTR_NONE; + modified_service_process_attributes = MODATTR_NONE; + retained_host_attribute_mask = 0L; + retained_service_attribute_mask = 0L; + retained_process_host_attribute_mask = 0L; + retained_process_service_attribute_mask = 0L; + retained_contact_host_attribute_mask = 0L; + retained_contact_service_attribute_mask = 0L; + + command_check_interval = DEFAULT_COMMAND_CHECK_INTERVAL; + check_reaper_interval = DEFAULT_CHECK_REAPER_INTERVAL; + max_check_reaper_time = DEFAULT_MAX_REAPER_TIME; + max_check_result_file_age = DEFAULT_MAX_CHECK_RESULT_AGE; + service_freshness_check_interval = DEFAULT_FRESHNESS_CHECK_INTERVAL; + host_freshness_check_interval = DEFAULT_FRESHNESS_CHECK_INTERVAL; + auto_rescheduling_interval = DEFAULT_AUTO_RESCHEDULING_INTERVAL; + auto_rescheduling_window = DEFAULT_AUTO_RESCHEDULING_WINDOW; + + check_external_commands = DEFAULT_CHECK_EXTERNAL_COMMANDS; + check_orphaned_services = DEFAULT_CHECK_ORPHANED_SERVICES; + check_orphaned_hosts = DEFAULT_CHECK_ORPHANED_HOSTS; + check_service_freshness = DEFAULT_CHECK_SERVICE_FRESHNESS; + check_host_freshness = DEFAULT_CHECK_HOST_FRESHNESS; + auto_reschedule_checks = DEFAULT_AUTO_RESCHEDULE_CHECKS; + + log_rotation_method = LOG_ROTATION_NONE; + + last_command_check = 0L; + last_command_status_update = 0L; + last_log_rotation = 0L; + + max_parallel_service_checks = DEFAULT_MAX_PARALLEL_SERVICE_CHECKS; + currently_running_service_checks = 0; + + enable_notifications = TRUE; + execute_service_checks = TRUE; + accept_passive_service_checks = TRUE; + execute_host_checks = TRUE; + accept_passive_service_checks = TRUE; + enable_event_handlers = TRUE; + obsess_over_services = FALSE; + obsess_over_hosts = FALSE; + enable_failure_prediction = TRUE; + + next_comment_id = 0L; /* comment and downtime id get initialized to nonzero elsewhere */ + next_downtime_id = 0L; + next_event_id = 1; + next_notification_id = 1; + + aggregate_status_updates = TRUE; + status_update_interval = DEFAULT_STATUS_UPDATE_INTERVAL; + + event_broker_options = BROKER_NOTHING; + + time_change_threshold = DEFAULT_TIME_CHANGE_THRESHOLD; + + enable_flap_detection = DEFAULT_ENABLE_FLAP_DETECTION; + low_service_flap_threshold = DEFAULT_LOW_SERVICE_FLAP_THRESHOLD; + high_service_flap_threshold = DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD; + low_host_flap_threshold = DEFAULT_LOW_HOST_FLAP_THRESHOLD; + high_host_flap_threshold = DEFAULT_HIGH_HOST_FLAP_THRESHOLD; + + process_performance_data = DEFAULT_PROCESS_PERFORMANCE_DATA; + + translate_passive_host_checks = DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS; + passive_host_checks_are_soft = DEFAULT_PASSIVE_HOST_CHECKS_SOFT; + + use_large_installation_tweaks = DEFAULT_USE_LARGE_INSTALLATION_TWEAKS; + enable_environment_macros = FALSE; + free_child_process_memory = FALSE; + child_processes_fork_twice = FALSE; + + additional_freshness_latency = DEFAULT_ADDITIONAL_FRESHNESS_LATENCY; + + enable_embedded_perl = DEFAULT_ENABLE_EMBEDDED_PERL; + use_embedded_perl_implicitly = DEFAULT_USE_EMBEDDED_PERL_IMPLICITLY; + + external_command_buffer_slots = DEFAULT_EXTERNAL_COMMAND_BUFFER_SLOTS; + + debug_level = DEFAULT_DEBUG_LEVEL; + debug_verbosity = DEFAULT_DEBUG_VERBOSITY; + max_debug_file_size = DEFAULT_MAX_DEBUG_FILE_SIZE; + + date_format = DATE_FORMAT_US; + + /* initialize macros */ + init_macros(); + + global_host_event_handler = NULL; + global_service_event_handler = NULL; + global_host_event_handler_ptr = NULL; + global_service_event_handler_ptr = NULL; + + ocsp_command = NULL; + ochp_command = NULL; + ocsp_command_ptr = NULL; + ochp_command_ptr = NULL; + + /* reset umask */ + umask(S_IWGRP | S_IWOTH); + + return OK; + } + diff --git a/cgi/.gitignore b/cgi/.gitignore new file mode 100644 index 0000000..46c15cc --- /dev/null +++ b/cgi/.gitignore @@ -0,0 +1,3 @@ +*.o +*.cgi +Makefile diff --git a/cgi/Makefile.in b/cgi/Makefile.in new file mode 100644 index 0000000..e45b126 --- /dev/null +++ b/cgi/Makefile.in @@ -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 + + diff --git a/cgi/avail.c b/cgi/avail.c new file mode 100644 index 0000000..db9f0b5 --- /dev/null +++ b/cgi/avail.c @@ -0,0 +1,4871 @@ +/************************************************************************** + * + * AVAIL.C - Nagios Availability CGI + * + * Copyright (c) 2000-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/common.h" +#include "../include/objects.h" +#include "../include/comments.h" +#include "../include/statusdata.h" + +#include "../include/cgiutils.h" +#include "../include/cgiauth.h" +#include "../include/getcgi.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 host *host_list; +extern hostgroup *hostgroup_list; +extern servicegroup *servicegroup_list; +extern service *service_list; +extern timeperiod *timeperiod_list; + +extern int log_rotation_method; + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + + + +/* output types */ +#define HTML_OUTPUT 0 +#define CSV_OUTPUT 1 + + +/* archived state types */ +#define AS_CURRENT_STATE -1 /* special case for initial assumed state */ +#define AS_NO_DATA 0 +#define AS_PROGRAM_END 1 +#define AS_PROGRAM_START 2 +#define AS_HOST_UP 3 +#define AS_HOST_DOWN 4 +#define AS_HOST_UNREACHABLE 5 +#define AS_SVC_OK 6 +#define AS_SVC_UNKNOWN 7 +#define AS_SVC_WARNING 8 +#define AS_SVC_CRITICAL 9 + +#define AS_SVC_DOWNTIME_START 10 +#define AS_SVC_DOWNTIME_END 11 +#define AS_HOST_DOWNTIME_START 12 +#define AS_HOST_DOWNTIME_END 13 + +#define AS_SOFT_STATE 1 +#define AS_HARD_STATE 2 + + +/* display types */ +#define DISPLAY_NO_AVAIL 0 +#define DISPLAY_HOSTGROUP_AVAIL 1 +#define DISPLAY_HOST_AVAIL 2 +#define DISPLAY_SERVICE_AVAIL 3 +#define DISPLAY_SERVICEGROUP_AVAIL 4 + +/* subject types */ +#define HOST_SUBJECT 0 +#define SERVICE_SUBJECT 1 + + +/* standard report times */ +#define TIMEPERIOD_CUSTOM 0 +#define TIMEPERIOD_TODAY 1 +#define TIMEPERIOD_YESTERDAY 2 +#define TIMEPERIOD_THISWEEK 3 +#define TIMEPERIOD_LASTWEEK 4 +#define TIMEPERIOD_THISMONTH 5 +#define TIMEPERIOD_LASTMONTH 6 +#define TIMEPERIOD_THISQUARTER 7 +#define TIMEPERIOD_LASTQUARTER 8 +#define TIMEPERIOD_THISYEAR 9 +#define TIMEPERIOD_LASTYEAR 10 +#define TIMEPERIOD_LAST24HOURS 11 +#define TIMEPERIOD_LAST7DAYS 12 +#define TIMEPERIOD_LAST31DAYS 13 + +#define MIN_TIMESTAMP_SPACING 10 + +#define MAX_ARCHIVE_SPREAD 65 +#define MAX_ARCHIVE 65 +#define MAX_ARCHIVE_BACKTRACKS 60 + +authdata current_authdata; + +typedef struct archived_state_struct { + time_t time_stamp; + int entry_type; + int state_type; + char *state_info; + int processed_state; + struct archived_state_struct *misc_ptr; + struct archived_state_struct *next; + } archived_state; + +typedef struct avail_subject_struct { + int type; + char *host_name; + char *service_description; + archived_state *as_list; /* archived state list */ + archived_state *as_list_tail; + archived_state *sd_list; /* scheduled downtime list */ + int last_known_state; + time_t earliest_time; + time_t latest_time; + int earliest_state; + int latest_state; + + unsigned long time_up; + unsigned long time_down; + unsigned long time_unreachable; + unsigned long time_ok; + unsigned long time_warning; + unsigned long time_unknown; + unsigned long time_critical; + + unsigned long scheduled_time_up; + unsigned long scheduled_time_down; + unsigned long scheduled_time_unreachable; + unsigned long scheduled_time_ok; + unsigned long scheduled_time_warning; + unsigned long scheduled_time_unknown; + unsigned long scheduled_time_critical; + unsigned long scheduled_time_indeterminate; + + unsigned long time_indeterminate_nodata; + unsigned long time_indeterminate_notrunning; + + struct avail_subject_struct *next; + } avail_subject; + +avail_subject *subject_list = NULL; + +time_t t1; +time_t t2; + +int display_type = DISPLAY_NO_AVAIL; +int timeperiod_type = TIMEPERIOD_LAST24HOURS; +int show_log_entries = FALSE; +int full_log_entries = FALSE; +int show_scheduled_downtime = TRUE; + +int start_second = 0; +int start_minute = 0; +int start_hour = 0; +int start_day = 1; +int start_month = 1; +int start_year = 2000; +int end_second = 0; +int end_minute = 0; +int end_hour = 24; +int end_day = 1; +int end_month = 1; +int end_year = 2000; + +int get_date_parts = FALSE; +int select_hostgroups = FALSE; +int select_hosts = FALSE; +int select_servicegroups = FALSE; +int select_services = FALSE; +int select_output_format = FALSE; + +int compute_time_from_parts = FALSE; + +int show_all_hostgroups = FALSE; +int show_all_hosts = FALSE; +int show_all_servicegroups = FALSE; +int show_all_services = FALSE; + +int assume_initial_states = TRUE; +int assume_state_retention = TRUE; +int assume_states_during_notrunning = TRUE; +int initial_assumed_host_state = AS_NO_DATA; +int initial_assumed_service_state = AS_NO_DATA; +int include_soft_states = FALSE; + +char *hostgroup_name = ""; +char *host_name = ""; +char *servicegroup_name = ""; +char *svc_description = ""; + +void create_subject_list(void); +void add_subject(int, char *, char *); +avail_subject *find_subject(int, char *, char *); +void compute_availability(void); +void compute_subject_availability(avail_subject *, time_t); +void compute_subject_availability_times(int, int, time_t, time_t, time_t, avail_subject *, archived_state *); +void compute_subject_downtime(avail_subject *, time_t); +void compute_subject_downtime_times(time_t, time_t, avail_subject *, archived_state *); +void compute_subject_downtime_part_times(time_t, time_t, int, avail_subject *); +void display_hostgroup_availability(void); +void display_specific_hostgroup_availability(hostgroup *); +void display_servicegroup_availability(void); +void display_specific_servicegroup_availability(servicegroup *); +void display_host_availability(void); +void display_service_availability(void); +void write_log_entries(avail_subject *); + +void get_running_average(double *, double, int); + +void host_report_url(char *, char *); +void service_report_url(char *, char *, char *); +void compute_report_times(void); + +int convert_host_state_to_archived_state(int); +int convert_service_state_to_archived_state(int); +void add_global_archived_state(int, int, time_t, char *); +void add_archived_state(int, int, time_t, char *, avail_subject *); +void add_scheduled_downtime(int, time_t, avail_subject *); +void free_availability_data(void); +void free_archived_state_list(archived_state *); +void read_archived_state_data(void); +void scan_log_file_for_archived_state_data(char *); +void convert_timeperiod_to_times(int); +unsigned long calculate_total_time(time_t, time_t); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + + + +int backtrack_archives = 2; +int earliest_archive = 0; + +int embedded = FALSE; +int display_header = TRUE; + +timeperiod *current_timeperiod = NULL; + +int output_format = HTML_OUTPUT; + + + +int main(int argc, char **argv) { + int result = OK; + char temp_buffer[MAX_INPUT_BUFFER]; + char start_timestring[MAX_DATETIME_LENGTH]; + char end_timestring[MAX_DATETIME_LENGTH]; + host *temp_host; + service *temp_service; + int is_authorized = TRUE; + time_t report_start_time; + time_t report_end_time; + int days, hours, minutes, seconds; + hostgroup *temp_hostgroup; + servicegroup *temp_servicegroup; + timeperiod *temp_timeperiod; + time_t t3; + time_t current_time; + struct tm *t; + char *firsthostpointer; + + /* 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; + } + + /* 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(); + return ERROR; + } + + /* initialize time period to last 24 hours */ + time(¤t_time); + t2 = current_time; + t1 = (time_t)(current_time - (60 * 60 * 24)); + + /* default number of backtracked archives */ + switch(log_rotation_method) { + case LOG_ROTATION_MONTHLY: + backtrack_archives = 1; + break; + case LOG_ROTATION_WEEKLY: + backtrack_archives = 2; + break; + case LOG_ROTATION_DAILY: + backtrack_archives = 4; + break; + case LOG_ROTATION_HOURLY: + backtrack_archives = 8; + break; + default: + backtrack_archives = 2; + break; + } + + /* get the arguments passed in the URL */ + process_cgivars(); + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + + if(compute_time_from_parts == TRUE) + compute_report_times(); + + /* make sure times are sane, otherwise swap them */ + if(t2 < t1) { + t3 = t2; + t2 = t1; + t1 = t3; + } + + /* don't let user create reports in the future */ + if(t2 > current_time) { + t2 = current_time; + if(t1 > t2) + t1 = t2 - (60 * 60 * 24); + } + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* center column of top row */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
\n"); + + switch(display_type) { + case DISPLAY_HOST_AVAIL: + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Availability Report"); + break; + case DISPLAY_SERVICE_AVAIL: + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Availability Report"); + break; + case DISPLAY_HOSTGROUP_AVAIL: + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Hostgroup Availability Report"); + break; + case DISPLAY_SERVICEGROUP_AVAIL: + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Servicegroup Availability Report"); + break; + default: + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Availability Report"); + break; + } + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + display_info_table(temp_buffer, FALSE, ¤t_authdata); + + if(((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) && get_date_parts == FALSE) { + + printf("\n"); + printf("\n"); + printf("\n"); + } + + printf("\n"); + + if(display_type != DISPLAY_NO_AVAIL && get_date_parts == FALSE) { + + printf("
\n"); + if(display_type == DISPLAY_HOST_AVAIL) { + if(show_all_hosts == TRUE) + printf("All Hosts"); + else + printf("Host '%s'", host_name); + } + else if(display_type == DISPLAY_SERVICE_AVAIL) { + if(show_all_services == TRUE) + printf("All Services"); + else + printf("Service '%s' On Host '%s'", svc_description, host_name); + } + else if(display_type == DISPLAY_HOSTGROUP_AVAIL) { + if(show_all_hostgroups == TRUE) + printf("All Hostgroups"); + else + printf("Hostgroup '%s'", hostgroup_name); + } + else if(display_type == DISPLAY_SERVICEGROUP_AVAIL) { + if(show_all_servicegroups == TRUE) + printf("All Servicegroups"); + else + printf("Servicegroup '%s'", servicegroup_name); + } + printf("
\n"); + + printf("
\n"); + + printf("Availability Report\n", url_images_path, TRENDS_ICON); + + printf("
\n"); + + get_time_string(&t1, start_timestring, sizeof(start_timestring) - 1, SHORT_DATE_TIME); + get_time_string(&t2, end_timestring, sizeof(end_timestring) - 1, SHORT_DATE_TIME); + printf("
%s to %s
\n", start_timestring, end_timestring); + + get_time_breakdown((time_t)(t2 - t1), &days, &hours, &minutes, &seconds); + printf("
Duration: %dd %dh %dm %ds
\n", days, hours, minutes, seconds); + } + + printf("
\n"); + + printf("
\n", AVAIL_CGI); + printf("\n"); + + if(display_type != DISPLAY_NO_AVAIL && get_date_parts == FALSE) { + + printf("\n", (display_type == DISPLAY_SERVICE_AVAIL) ? "service" : "host", (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) ? "First assumed service state" : ""); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + } + + /* display context-sensitive help */ + printf("\n"); + + printf("
First assumed %s state:%s
\n"); + + printf("\n", (unsigned long)t1); + printf("\n", (unsigned long)t2); + if(show_log_entries == TRUE) + printf("\n"); + if(full_log_entries == TRUE) + printf("\n"); + if(display_type == DISPLAY_HOSTGROUP_AVAIL) + printf("\n", escape_string(hostgroup_name)); + if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICE_AVAIL) + printf("\n", escape_string(host_name)); + if(display_type == DISPLAY_SERVICE_AVAIL) + printf("\n", escape_string(svc_description)); + if(display_type == DISPLAY_SERVICEGROUP_AVAIL) + printf("\n", escape_string(servicegroup_name)); + + printf("\n", (assume_initial_states == TRUE) ? "yes" : "no"); + printf("\n", (assume_state_retention == TRUE) ? "yes" : "no"); + printf("\n", (assume_states_during_notrunning == TRUE) ? "yes" : "no"); + printf("\n", (include_soft_states == TRUE) ? "yes" : "no"); + + if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { + printf("\n"); + } + else { + printf("", initial_assumed_host_state); + printf("\n"); + } + printf("\n"); + if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { + printf("\n"); + } + printf("
Report period:Backtracked archives:
\n"); + printf("\n"); + printf("\n"); + printf("\n", backtrack_archives); + printf("
\n"); + printf("\n"); + printf("
\n"); + if(get_date_parts == TRUE) + display_context_help(CONTEXTHELP_AVAIL_MENU5); + else if(select_hostgroups == TRUE) + display_context_help(CONTEXTHELP_AVAIL_MENU2); + else if(select_hosts == TRUE) + display_context_help(CONTEXTHELP_AVAIL_MENU3); + else if(select_services == TRUE) + display_context_help(CONTEXTHELP_AVAIL_MENU4); + else if(display_type == DISPLAY_HOSTGROUP_AVAIL) + display_context_help(CONTEXTHELP_AVAIL_HOSTGROUP); + else if(display_type == DISPLAY_HOST_AVAIL) + display_context_help(CONTEXTHELP_AVAIL_HOST); + else if(display_type == DISPLAY_SERVICE_AVAIL) + display_context_help(CONTEXTHELP_AVAIL_SERVICE); + else if(display_type == DISPLAY_SERVICEGROUP_AVAIL) + display_context_help(CONTEXTHELP_AVAIL_SERVICEGROUP); + else + display_context_help(CONTEXTHELP_AVAIL_MENU1); + printf("
\n"); + printf("
\n"); + + printf("
\n"); + } + + + + + /* step 3 - ask user for report date range */ + if(get_date_parts == TRUE) { + + time(¤t_time); + t = localtime(¤t_time); + + start_day = 1; + start_year = t->tm_year + 1900; + end_day = t->tm_mday; + end_year = t->tm_year + 1900; + + printf("

Step 3: Select Report Options

\n"); + + printf("

\n"); + + printf("
\n", AVAIL_CGI); + printf("\n"); + if(display_type == DISPLAY_HOSTGROUP_AVAIL) + printf("\n", escape_string(hostgroup_name)); + if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICE_AVAIL) + printf("\n", escape_string(host_name)); + if(display_type == DISPLAY_SERVICE_AVAIL) + printf("\n", escape_string(svc_description)); + if(display_type == DISPLAY_SERVICEGROUP_AVAIL) + printf("\n", escape_string(servicegroup_name)); + + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + if(display_type != DISPLAY_SERVICE_AVAIL) { + printf("\n"); + printf("\n"); + } + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + if((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == TRUE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == TRUE)) { + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + } + + printf("\n"); + + printf("
Report Period:\n"); + printf("\n"); + printf("
If Custom Report Period...
Start Date (Inclusive):"); + printf("\n "); + printf(" ", start_day); + printf("", start_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
End Date (Inclusive):"); + printf("\n "); + printf(" ", end_day); + printf("", end_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("

Report time Period:\n"); + printf("\n"); + printf("

Assume Initial States:\n"); + printf("\n"); + printf("
Assume State Retention:\n"); + printf("\n"); + printf("
Assume States During Program Downtime:\n"); + printf("\n"); + printf("
Include Soft States:\n"); + printf("\n"); + printf("
First Assumed Host State:\n"); + printf("\n"); + printf("
First Assumed Service State:\n"); + printf("\n"); + printf("
Backtracked Archives (To Scan For Initial States):\n"); + printf("\n", backtrack_archives); + printf("
Output in CSV Format:"); + printf("\n"); + printf("
\n"); + + printf("
\n"); + printf("

\n"); + } + + + /* step 2 - the user wants to select a hostgroup */ + else if(select_hostgroups == TRUE) { + printf("

Step 2: Select Hostgroup

\n"); + + printf("

\n"); + + printf("
\n", AVAIL_CGI); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("
Hostgroup(s):\n"); + printf("\n"); + printf("
\n"); + + printf("
\n"); + + printf("

\n"); + } + + /* step 2 - the user wants to select a host */ + else if(select_hosts == TRUE) { + printf("

Step 2: Select Host

\n"); + + printf("

\n"); + + printf("
\n", AVAIL_CGI); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("
Host(s):\n"); + printf("\n"); + printf("
\n"); + + printf("
\n"); + + printf("

\n"); + + printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL HOSTS **' from the pull-down menu.\n"); + } + + /* step 2 - the user wants to select a servicegroup */ + else if(select_servicegroups == TRUE) { + printf("

Step 2: Select Servicegroup

\n"); + + printf("

\n"); + + printf("
\n", AVAIL_CGI); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("
Servicegroup(s):\n"); + printf("\n"); + printf("
\n"); + + printf("
\n"); + + printf("

\n"); + } + + /* step 2 - the user wants to select a service */ + else if(select_services == TRUE) { + + printf("\n"); + + printf("

Step 2: Select Service

\n"); + + printf("

\n"); + + printf("
\n", AVAIL_CGI); + printf("\n"); + printf("\n", (firsthostpointer == NULL) ? "unknown" : (char *)escape_string(firsthostpointer)); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("
Service(s):\n"); + printf("\n"); + printf("
\n"); + + printf("
\n"); + + printf("

\n"); + + printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL SERVICES **' from the pull-down menu.\n"); + } + + + /* generate availability report */ + else if(display_type != DISPLAY_NO_AVAIL) { + + /* check authorization */ + is_authorized = TRUE; + if((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) { + + if(display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) + is_authorized = is_authorized_for_host(find_host(host_name), ¤t_authdata); + else + is_authorized = is_authorized_for_service(find_service(host_name, svc_description), ¤t_authdata); + } + + if(is_authorized == FALSE) + printf("

It appears as though you are not authorized to view information for the specified %s...

\n", (display_type == DISPLAY_HOST_AVAIL) ? "host" : "service"); + + else { + + time(&report_start_time); + + /* create list of subjects to collect availability data for */ + create_subject_list(); + + /* read in all necessary archived state data */ + read_archived_state_data(); + + /* compute availability data */ + compute_availability(); + + time(&report_end_time); + + if(output_format == HTML_OUTPUT) { + get_time_breakdown((time_t)(report_end_time - report_start_time), &days, &hours, &minutes, &seconds); + printf("
[ Availability report completed in %d min %d sec ]
\n", minutes, seconds); + printf("

\n"); + } + + /* display availability data */ + if(display_type == DISPLAY_HOST_AVAIL) + display_host_availability(); + else if(display_type == DISPLAY_SERVICE_AVAIL) + display_service_availability(); + else if(display_type == DISPLAY_HOSTGROUP_AVAIL) + display_hostgroup_availability(); + else if(display_type == DISPLAY_SERVICEGROUP_AVAIL) + display_servicegroup_availability(); + + /* free memory allocated to availability data */ + free_availability_data(); + } + } + + + /* step 1 - ask the user what kind of report they want */ + else { + + printf("

Step 1: Select Report Type

\n"); + + printf("

\n"); + + printf("
\n", AVAIL_CGI); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
Type:\n"); + printf("\n"); + printf("
\n"); + + printf("
\n"); + + printf("

\n"); + } + + + document_footer(); + + /* free all other 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)0; + get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME); + printf("Expires: %s\r\n", date_time); + + if(output_format == HTML_OUTPUT) + printf("Content-type: text/html\r\n\r\n"); + else { + printf("Content-type: text/csv\r\n\r\n"); + return; + } + + if(embedded == TRUE || output_format == CSV_OUTPUT) + return; + + printf("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios Availability\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, AVAIL_CSS); + } + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(AVAIL_CGI, SSI_HEADER); + + return; + } + + + +void document_footer(void) { + + if(output_format != HTML_OUTPUT) + return; + + if(embedded == TRUE) + return; + + /* include user SSI footer */ + include_ssi_files(AVAIL_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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 hostgroup argument */ + else if(!strcmp(variables[x], "hostgroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((hostgroup_name = (char *)strdup(variables[x])) == NULL) + hostgroup_name = ""; + strip_html_brackets(hostgroup_name); + + display_type = DISPLAY_HOSTGROUP_AVAIL; + show_all_hostgroups = (strcmp(hostgroup_name, "all")) ? FALSE : TRUE; + } + + /* we found the servicegroup argument */ + else if(!strcmp(variables[x], "servicegroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((servicegroup_name = (char *)strdup(variables[x])) == NULL) + servicegroup_name = ""; + strip_html_brackets(servicegroup_name); + + display_type = DISPLAY_SERVICEGROUP_AVAIL; + show_all_servicegroups = (strcmp(servicegroup_name, "all")) ? FALSE : TRUE; + } + + /* 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_HOST_AVAIL; + show_all_hosts = (strcmp(host_name, "all")) ? FALSE : TRUE; + } + + /* we found the service description 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_SERVICE_AVAIL; + show_all_services = (strcmp(svc_description, "all")) ? FALSE : TRUE; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t1")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t1 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = FALSE; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t2")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t2 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = FALSE; + } + + /* we found the assume initial states option */ + else if(!strcmp(variables[x], "assumeinitialstates")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_initial_states = TRUE; + else + assume_initial_states = FALSE; + } + + /* we found the assume state during program not running option */ + else if(!strcmp(variables[x], "assumestatesduringnotrunning")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_states_during_notrunning = TRUE; + else + assume_states_during_notrunning = FALSE; + } + + /* we found the initial assumed host state option */ + else if(!strcmp(variables[x], "initialassumedhoststate")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + initial_assumed_host_state = atoi(variables[x]); + } + + /* we found the initial assumed service state option */ + else if(!strcmp(variables[x], "initialassumedservicestate")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + initial_assumed_service_state = atoi(variables[x]); + } + + /* we found the assume state retention option */ + else if(!strcmp(variables[x], "assumestateretention")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_state_retention = TRUE; + else + assume_state_retention = FALSE; + } + + /* we found the include soft states option */ + else if(!strcmp(variables[x], "includesoftstates")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + include_soft_states = TRUE; + else + include_soft_states = FALSE; + } + + /* we found the backtrack archives argument */ + else if(!strcmp(variables[x], "backtrack")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + backtrack_archives = atoi(variables[x]); + if(backtrack_archives < 0) + backtrack_archives = 0; + if(backtrack_archives > MAX_ARCHIVE_BACKTRACKS) + backtrack_archives = MAX_ARCHIVE_BACKTRACKS; + +#ifdef DEBUG + printf("BACKTRACK ARCHIVES: %d\n", backtrack_archives); +#endif + } + + /* we found the standard timeperiod argument */ + else if(!strcmp(variables[x], "timeperiod")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "today")) + timeperiod_type = TIMEPERIOD_TODAY; + else if(!strcmp(variables[x], "yesterday")) + timeperiod_type = TIMEPERIOD_YESTERDAY; + else if(!strcmp(variables[x], "thisweek")) + timeperiod_type = TIMEPERIOD_THISWEEK; + else if(!strcmp(variables[x], "lastweek")) + timeperiod_type = TIMEPERIOD_LASTWEEK; + else if(!strcmp(variables[x], "thismonth")) + timeperiod_type = TIMEPERIOD_THISMONTH; + else if(!strcmp(variables[x], "lastmonth")) + timeperiod_type = TIMEPERIOD_LASTMONTH; + else if(!strcmp(variables[x], "thisquarter")) + timeperiod_type = TIMEPERIOD_THISQUARTER; + else if(!strcmp(variables[x], "lastquarter")) + timeperiod_type = TIMEPERIOD_LASTQUARTER; + else if(!strcmp(variables[x], "thisyear")) + timeperiod_type = TIMEPERIOD_THISYEAR; + else if(!strcmp(variables[x], "lastyear")) + timeperiod_type = TIMEPERIOD_LASTYEAR; + else if(!strcmp(variables[x], "last24hours")) + timeperiod_type = TIMEPERIOD_LAST24HOURS; + else if(!strcmp(variables[x], "last7days")) + timeperiod_type = TIMEPERIOD_LAST7DAYS; + else if(!strcmp(variables[x], "last31days")) + timeperiod_type = TIMEPERIOD_LAST31DAYS; + else if(!strcmp(variables[x], "custom")) + timeperiod_type = TIMEPERIOD_CUSTOM; + else + continue; + + convert_timeperiod_to_times(timeperiod_type); + compute_time_from_parts = 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 CSV output option */ + else if(!strcmp(variables[x], "csvoutput")) { + display_header = FALSE; + output_format = CSV_OUTPUT; + } + + /* we found the log entries option */ + else if(!strcmp(variables[x], "show_log_entries")) + show_log_entries = TRUE; + + /* we found the full log entries option */ + else if(!strcmp(variables[x], "full_log_entries")) + full_log_entries = TRUE; + + /* we found the get date parts option */ + else if(!strcmp(variables[x], "get_date_parts")) + get_date_parts = TRUE; + + /* we found the report type selection option */ + else if(!strcmp(variables[x], "report_type")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + if(!strcmp(variables[x], "hostgroups")) + select_hostgroups = TRUE; + else if(!strcmp(variables[x], "servicegroups")) + select_servicegroups = TRUE; + else if(!strcmp(variables[x], "hosts")) + select_hosts = TRUE; + else + select_services = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "sday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "syear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ssec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "shour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + + /* we found time argument */ + else if(!strcmp(variables[x], "emon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eyear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "emin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "esec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ehour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found the show scheduled downtime option */ + else if(!strcmp(variables[x], "showscheduleddowntime")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + show_scheduled_downtime = TRUE; + else + show_scheduled_downtime = FALSE; + } + + /* we found the report timeperiod option */ + else if(!strcmp(variables[x], "rpttimeperiod")) { + timeperiod *temp_timeperiod; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + for(temp_timeperiod = timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) { + if(!strcmp(url_encode(temp_timeperiod->name), variables[x])) { + current_timeperiod = temp_timeperiod; + break; + } + } + } + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* computes availability data for all subjects */ +void compute_availability(void) { + avail_subject *temp_subject; + time_t current_time; + + time(¤t_time); + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + compute_subject_availability(temp_subject, current_time); + compute_subject_downtime(temp_subject, current_time); + } + + return; + } + + + +/* computes availability data for a given subject */ +void compute_subject_availability(avail_subject *subject, time_t current_time) { + archived_state *temp_as; + archived_state *last_as; + time_t a; + time_t b; + int current_state = AS_NO_DATA; + int have_some_real_data = FALSE; + hoststatus *hststatus = NULL; + servicestatus *svcstatus = NULL; + int first_real_state = AS_NO_DATA; + time_t initial_assumed_time; + int initial_assumed_state = AS_NO_DATA; + int error; + + + /* if left hand of graph is after current time, we can't do anything at all.... */ + if(t1 > current_time) + return; + + /* get current state of host or service if possible */ + if(subject->type == HOST_SUBJECT) + hststatus = find_hoststatus(subject->host_name); + else + svcstatus = find_servicestatus(subject->host_name, subject->service_description); + + + /************************************/ + /* INSERT CURRENT STATE (IF WE CAN) */ + /************************************/ + + /* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */ + + /* if we don't have any data, assume current state (if possible) */ + if(subject->as_list == NULL && current_time > t1 && current_time <= t2) { + + /* we don't have any historical information, but the current time falls within the reporting period, so use */ + /* the current status of the host/service as the starting data */ + if(subject->type == HOST_SUBJECT) { + if(hststatus != NULL) { + + if(hststatus->status == HOST_DOWN) + subject->last_known_state = AS_HOST_DOWN; + else if(hststatus->status == HOST_UNREACHABLE) + subject->last_known_state = AS_HOST_UNREACHABLE; + else if(hststatus->status == HOST_UP) + subject->last_known_state = AS_HOST_UP; + else + subject->last_known_state = AS_NO_DATA; + + if(subject->last_known_state != AS_NO_DATA) { + + /* add a dummy archived state item, so something can get graphed */ + add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Host State Assumed (Faked Log Entry)", subject); + + /* use the current state as the last known real state */ + first_real_state = subject->last_known_state; + } + } + } + else { + if(svcstatus != NULL) { + + if(svcstatus->status == SERVICE_OK) + subject->last_known_state = AS_SVC_OK; + else if(svcstatus->status == SERVICE_WARNING) + subject->last_known_state = AS_SVC_WARNING; + else if(svcstatus->status == SERVICE_CRITICAL) + subject->last_known_state = AS_SVC_CRITICAL; + else if(svcstatus->status == SERVICE_UNKNOWN) + subject->last_known_state = AS_SVC_UNKNOWN; + else + subject->last_known_state = AS_NO_DATA; + + if(subject->last_known_state != AS_NO_DATA) { + + /* add a dummy archived state item, so something can get graphed */ + add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Service State Assumed (Faked Log Entry)", subject); + + /* use the current state as the last known real state */ + first_real_state = subject->last_known_state; + } + } + } + } + + + + /******************************************/ + /* INSERT FIRST ASSUMED STATE (IF WE CAN) */ + /******************************************/ + + if((subject->type == HOST_SUBJECT && initial_assumed_host_state != AS_NO_DATA) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state != AS_NO_DATA)) { + + /* see if its okay to assume initial state for this subject */ + error = FALSE; + if(subject->type == SERVICE_SUBJECT) { + if(initial_assumed_service_state != AS_SVC_OK && initial_assumed_service_state != AS_SVC_WARNING && initial_assumed_service_state != AS_SVC_UNKNOWN && initial_assumed_service_state != AS_SVC_CRITICAL && initial_assumed_service_state != AS_CURRENT_STATE) + error = TRUE; + else + initial_assumed_state = initial_assumed_service_state; + if(initial_assumed_service_state == AS_CURRENT_STATE && svcstatus == NULL) + error = TRUE; + } + else { + if(initial_assumed_host_state != AS_HOST_UP && initial_assumed_host_state != AS_HOST_DOWN && initial_assumed_host_state != AS_HOST_UNREACHABLE && initial_assumed_host_state != AS_CURRENT_STATE) + error = TRUE; + else + initial_assumed_state = initial_assumed_host_state; + if(initial_assumed_host_state == AS_CURRENT_STATE && hststatus == NULL) + error = TRUE; + } + + /* get the current state if applicable */ + if(((subject->type == HOST_SUBJECT && initial_assumed_host_state == AS_CURRENT_STATE) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state == AS_CURRENT_STATE)) && error == FALSE) { + if(subject->type == SERVICE_SUBJECT) { + switch(svcstatus->status) { + case SERVICE_OK: + initial_assumed_state = AS_SVC_OK; + break; + case SERVICE_WARNING: + initial_assumed_state = AS_SVC_WARNING; + break; + case SERVICE_UNKNOWN: + initial_assumed_state = AS_SVC_UNKNOWN; + break; + case SERVICE_CRITICAL: + initial_assumed_state = AS_SVC_CRITICAL; + break; + default: + error = TRUE; + break; + } + } + else { + switch(hststatus->status) { + case HOST_DOWN: + initial_assumed_state = AS_HOST_DOWN; + break; + case HOST_UNREACHABLE: + initial_assumed_state = AS_HOST_UNREACHABLE; + break; + case HOST_UP: + initial_assumed_state = AS_HOST_UP; + break; + default: + error = TRUE; + break; + } + } + } + + if(error == FALSE) { + + /* add this assumed state entry before any entries in the list and <= t1 */ + if(subject->as_list == NULL) + initial_assumed_time = t1; + else if(subject->as_list->time_stamp > t1) + initial_assumed_time = t1; + else + initial_assumed_time = subject->as_list->time_stamp - 1; + + if(subject->type == HOST_SUBJECT) + add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Host State Assumed (Faked Log Entry)", subject); + else + add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Service State Assumed (Faked Log Entry)", subject); + } + } + + + + + /**************************************/ + /* BAIL OUT IF WE DON'T HAVE ANYTHING */ + /**************************************/ + + have_some_real_data = FALSE; + for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { + if(temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_START && temp_as->entry_type != AS_PROGRAM_END) { + have_some_real_data = TRUE; + break; + } + } + if(have_some_real_data == FALSE) + return; + + + + + last_as = NULL; + subject->earliest_time = t2; + subject->latest_time = t1; + + +#ifdef DEBUG + printf("--- BEGINNING/MIDDLE SECTION ---
\n"); +#endif + + /**********************************/ + /* BEGINNING/MIDDLE SECTION */ + /**********************************/ + + for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { + + /* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */ + if((temp_as->time_stamp <= t1 || temp_as == subject->as_list) && (temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_END && temp_as->entry_type != AS_PROGRAM_START)) { + subject->last_known_state = temp_as->entry_type; +#ifdef DEBUG + printf("SETTING LAST KNOWN STATE=%d
\n", subject->last_known_state); +#endif + } + + /* skip this entry if it occurs before the starting point of the graph */ + if(temp_as->time_stamp <= t1) { +#ifdef DEBUG + printf("SKIPPING PRE-EVENT: %d @ %lu
\n", temp_as->entry_type, temp_as->time_stamp); +#endif + last_as = temp_as; + continue; + } + + /* graph this span if we're not on the first item */ + if(last_as != NULL) { + + a = last_as->time_stamp; + b = temp_as->time_stamp; + + /* we've already passed the last time displayed in the graph */ + if(a > t2) + break; + + /* only graph this data if its on the graph */ + else if(b > t1) { + + /* clip last time if it exceeds graph limits */ + if(b > t2) + b = t2; + + /* clip first time if it precedes graph limits */ + if(a < t1) + a = t1; + + /* save this time if its the earliest we've graphed */ + if(a < subject->earliest_time) { + subject->earliest_time = a; + subject->earliest_state = last_as->entry_type; + } + + /* save this time if its the latest we've graphed */ + if(b > subject->latest_time) { + subject->latest_time = b; + subject->latest_state = last_as->entry_type; + } + + /* compute availability times for this chunk */ + compute_subject_availability_times(last_as->entry_type, temp_as->entry_type, last_as->time_stamp, a, b, subject, temp_as); + + /* return if we've reached the end of the graph limits */ + if(b >= t2) { + last_as = temp_as; + break; + } + } + } + + + /* keep track of the last item */ + last_as = temp_as; + } + + +#ifdef DEBUG + printf("--- END SECTION ---
\n"); +#endif + + /**********************************/ + /* END SECTION */ + /**********************************/ + + if(last_as != NULL) { + + /* don't process an entry that is beyond the limits of the graph */ + if(last_as->time_stamp < t2) { + + time(¤t_time); + b = current_time; + if(b > t2) + b = t2; + + a = last_as->time_stamp; + if(a < t1) + a = t1; + + /* fake the current state (it doesn't really matter for graphing) */ + if(subject->type == HOST_SUBJECT) + current_state = AS_HOST_UP; + else + current_state = AS_SVC_OK; + + /* compute availability times for last state */ + compute_subject_availability_times(last_as->entry_type, current_state, last_as->time_stamp, a, b, subject, last_as); + } + } + + + return; + } + + +/* computes availability times */ +void compute_subject_availability_times(int first_state, int last_state, time_t real_start_time, time_t start_time, time_t end_time, avail_subject *subject, archived_state *as) { + int start_state; + int end_state; + unsigned long state_duration; + struct tm *t; + unsigned long midnight_today; + int weekday; + timerange *temp_timerange; + unsigned long temp_duration; + unsigned long temp_end; + unsigned long temp_start; + unsigned long start; + unsigned long end; + +#ifdef DEBUG + if(subject->type == HOST_SUBJECT) + printf("HOST '%s'...\n", subject->host_name); + else + printf("SERVICE '%s' ON HOST '%s'...\n", subject->service_description, subject->host_name); + + printf("COMPUTING %d->%d FROM %lu to %lu (%lu seconds) FOR %s
\n", first_state, last_state, start_time, end_time, (end_time - start_time), (subject->type == HOST_SUBJECT) ? "HOST" : "SERVICE"); +#endif + + /* clip times if necessary */ + if(start_time < t1) + start_time = t1; + if(end_time > t2) + end_time = t2; + + /* make sure this is a valid time */ + if(start_time > t2) + return; + if(end_time < t1) + return; + + /* MickeM - attempt to handle the current time_period (if any) */ + if(current_timeperiod != NULL) { + t = localtime((time_t *)&start_time); + state_duration = 0; + + /* calculate the start of the day (midnight, 00:00 hours) */ + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_isdst = -1; + midnight_today = (unsigned long)mktime(t); + weekday = t->tm_wday; + + while(midnight_today < end_time) { + temp_duration = 0; + temp_end = min(86400, end_time - midnight_today); + temp_start = 0; + if(start_time > midnight_today) + temp_start = start_time - midnight_today; +#ifdef DEBUG + printf("Matching: %ld -> %ld. (%ld -> %ld)
\n", temp_start, temp_end, midnight_today + temp_start, midnight_today + temp_end); +#endif + /* check all time ranges for this day of the week */ + for(temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + +#ifdef DEBUG + printf("
  • Matching in timerange[%d]: %d -> %d (%ld -> %ld)
    \n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end); +#endif + start = max(temp_timerange->range_start, temp_start); + end = min(temp_timerange->range_end, temp_end); + + if(start < end) { + temp_duration += end - start; +#ifdef DEBUG + printf("
  • Matched time: %ld -> %ld = %d
    \n", start, end, temp_duration); +#endif + } +#ifdef DEBUG + else + printf("
  • Ignored time: %ld -> %ld
    \n", start, end); +#endif + } + state_duration += temp_duration; + temp_start = 0; + midnight_today += 86400; + if(++weekday > 6) + weekday = 0; + } + } + + /* no report timeperiod was selected (assume 24x7) */ + else { + /* calculate time in this state */ + state_duration = (unsigned long)(end_time - start_time); + } + + /* can't graph if we don't have data... */ + if(first_state == AS_NO_DATA || last_state == AS_NO_DATA) { + subject->time_indeterminate_nodata += state_duration; + return; + } + if(first_state == AS_PROGRAM_START && (last_state == AS_PROGRAM_END || last_state == AS_PROGRAM_START)) { + if(assume_initial_states == FALSE) { + subject->time_indeterminate_nodata += state_duration; + return; + } + } + if(first_state == AS_PROGRAM_END) { + + /* added 7/24/03 */ + if(assume_states_during_notrunning == TRUE) { + first_state = subject->last_known_state; + } + else { + subject->time_indeterminate_notrunning += state_duration; + return; + } + } + + /* special case if first entry was program start */ + if(first_state == AS_PROGRAM_START) { + + if(assume_initial_states == TRUE) { + + if(assume_state_retention == TRUE) + start_state = subject->last_known_state; + + else { + if(subject->type == HOST_SUBJECT) + start_state = AS_HOST_UP; + else + start_state = AS_SVC_OK; + } + } + else + return; + } + else { + start_state = first_state; + subject->last_known_state = first_state; + } + + /* special case if last entry was program stop */ + if(last_state == AS_PROGRAM_END) + end_state = first_state; + else + end_state = last_state; + + /* save "processed state" info */ + as->processed_state = start_state; + +#ifdef DEBUG + printf("PASSED TIME CHECKS, CLIPPED VALUES: START=%lu, END=%lu\n", start_time, end_time); +#endif + + + /* add time in this state to running totals */ + switch(start_state) { + case AS_HOST_UP: + subject->time_up += state_duration; + break; + case AS_HOST_DOWN: + subject->time_down += state_duration; + break; + case AS_HOST_UNREACHABLE: + subject->time_unreachable += state_duration; + break; + case AS_SVC_OK: + subject->time_ok += state_duration; + break; + case AS_SVC_WARNING: + subject->time_warning += state_duration; + break; + case AS_SVC_UNKNOWN: + subject->time_unknown += state_duration; + break; + case AS_SVC_CRITICAL: + subject->time_critical += state_duration; + break; + default: + break; + } + + return; + } + + +/* computes downtime data for a given subject */ +void compute_subject_downtime(avail_subject *subject, time_t current_time) { + archived_state *temp_sd; + time_t start_time; + time_t end_time; + int host_downtime_depth = 0; + int service_downtime_depth = 0; + int process_chunk = FALSE; + +#ifdef DEBUG2 + printf("COMPUTE_SUBJECT_DOWNTIME\n"); +#endif + + /* if left hand of graph is after current time, we can't do anything at all.... */ + if(t1 > current_time) + return; + + /* no scheduled downtime data for subject... */ + if(subject->sd_list == NULL) + return; + + /* all data we have occurs after last time on graph... */ + if(subject->sd_list->time_stamp >= t2) + return; + + /* initialize pointer */ + temp_sd = subject->sd_list; + + /* special case if first entry is the end of scheduled downtime */ + if((temp_sd->entry_type == AS_HOST_DOWNTIME_END || temp_sd->entry_type == AS_SVC_DOWNTIME_END) && temp_sd->time_stamp > t1) { + +#ifdef DEBUG2 + printf("\tSPECIAL DOWNTIME CASE\n"); +#endif + start_time = t1; + end_time = (temp_sd->time_stamp > t2) ? t2 : temp_sd->time_stamp; + compute_subject_downtime_times(start_time, end_time, subject, NULL); + temp_sd = temp_sd->next; + } + + /* process all periods of scheduled downtime */ + for(; temp_sd != NULL; temp_sd = temp_sd->next) { + + /* we've passed graph bounds... */ + if(temp_sd->time_stamp >= t2) + break; + + if(temp_sd->entry_type == AS_HOST_DOWNTIME_START) + host_downtime_depth++; + else if(temp_sd->entry_type == AS_HOST_DOWNTIME_END) + host_downtime_depth--; + else if(temp_sd->entry_type == AS_SVC_DOWNTIME_START) + service_downtime_depth++; + else if(temp_sd->entry_type == AS_SVC_DOWNTIME_END) + service_downtime_depth--; + else + continue; + + process_chunk = FALSE; + if(temp_sd->entry_type == AS_HOST_DOWNTIME_START || temp_sd->entry_type == AS_SVC_DOWNTIME_START) + process_chunk = TRUE; + else if(subject->type == SERVICE_SUBJECT && (host_downtime_depth > 0 || service_downtime_depth > 0)) + process_chunk = TRUE; + + /* process this specific "chunk" of scheduled downtime */ + if(process_chunk == TRUE) { + + start_time = temp_sd->time_stamp; + end_time = (temp_sd->next == NULL) ? current_time : temp_sd->next->time_stamp; + + /* check time sanity */ + if(end_time <= t1) + continue; + if(start_time >= t2) + continue; + if(start_time >= end_time) + continue; + + /* clip time values */ + if(start_time < t1) + start_time = t1; + if(end_time > t2) + end_time = t2; + + compute_subject_downtime_times(start_time, end_time, subject, temp_sd); + } + } + + return; + } + + + +/* computes downtime times */ +void compute_subject_downtime_times(time_t start_time, time_t end_time, avail_subject *subject, archived_state *sd) { + archived_state *temp_as = NULL; + time_t part_start_time = 0L; + time_t part_subject_state = 0L; + int saved_status = 0; + int saved_stamp = 0; + int count = 0; + archived_state *temp_before = NULL; + archived_state *last = NULL; + +#ifdef DEBUG2 + printf("

    ENTERING COMPUTE_SUBJECT_DOWNTIME_TIMES: start=%lu, end=%lu, t1=%lu, t2=%lu

    ", start_time, end_time, t1, t2); +#endif + + /* times are weird, so bail out... */ + if(start_time > end_time) + return; + if(start_time < t1 || end_time > t2) + return; + + /* find starting point in archived state list */ + if(sd == NULL) { +#ifdef DEBUG2 + printf("

    TEMP_AS=SUBJECT->AS_LIST

    "); +#endif + temp_as = subject->as_list; + } + else if(sd->misc_ptr == NULL) { +#ifdef DEBUG2 + printf("

    TEMP_AS=SUBJECT->AS_LIST

    "); +#endif + temp_as = subject->as_list; + } + else if(sd->misc_ptr->next == NULL) { +#ifdef DEBUG2 + printf("

    TEMP_AS=SD->MISC_PTR

    "); +#endif + temp_as = sd->misc_ptr; + } + else { +#ifdef DEBUG2 + printf("

    TEMP_AS=SD->MISC_PTR->NEXT

    "); +#endif + temp_as = sd->misc_ptr->next; + } + + /* initialize values */ + part_start_time = start_time; + if(temp_as == NULL) + part_subject_state = AS_NO_DATA; + else if(temp_as->processed_state == AS_PROGRAM_START || temp_as->processed_state == AS_PROGRAM_END || temp_as->processed_state == AS_NO_DATA) { +#ifdef DEBUG2 + printf("

    ENTRY TYPE #1: %d

    ", temp_as->entry_type); +#endif + part_subject_state = AS_NO_DATA; + } + else { +#ifdef DEBUG2 + printf("

    ENTRY TYPE #2: %d

    ", temp_as->entry_type); +#endif + part_subject_state = temp_as->processed_state; + } + +#ifdef DEBUG2 + printf("

    TEMP_AS=%s

    ", (temp_as == NULL) ? "NULL" : "Not NULL"); + printf("

    SD=%s

    ", (sd == NULL) ? "NULL" : "Not NULL"); +#endif + + /* temp_as now points to first event to possibly "break" this chunk */ + for(; temp_as != NULL; temp_as = temp_as->next) { + count++; + last = temp_as; + + if(temp_before == NULL) { + if(last->time_stamp > start_time) { + if(last->time_stamp > end_time) + compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject); + else + compute_subject_downtime_part_times(start_time, last->time_stamp, part_subject_state, subject); + } + temp_before = temp_as; + saved_status = temp_as->entry_type; + saved_stamp = temp_as->time_stamp; + + /* check if first time is before schedule downtime */ + if(saved_stamp < start_time) + saved_stamp = start_time; + + continue; + } + + /* if status changed, we have to calculate */ + if(saved_status != temp_as->entry_type) { + + /* is outside schedule time, use end schdule downtime */ + if(temp_as->time_stamp > end_time) { + if(saved_stamp < start_time) + compute_subject_downtime_part_times(start_time, end_time, saved_status, subject); + else + compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject); + } + else { + if(saved_stamp < start_time) + compute_subject_downtime_part_times(start_time, temp_as->time_stamp, saved_status, subject); + else + compute_subject_downtime_part_times(saved_stamp, temp_as->time_stamp, saved_status, subject); + } + saved_status = temp_as->entry_type; + saved_stamp = temp_as->time_stamp; + } + } + + /* just one entry inside the scheduled downtime */ + if(count == 0) + compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject); + else { + /* is outside scheduled time, use end schdule downtime */ + if(last->time_stamp > end_time) + compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject); + else + compute_subject_downtime_part_times(saved_stamp, last->time_stamp, saved_status, subject); + } + + return; + } + + + +/* computes downtime times */ +void compute_subject_downtime_part_times(time_t start_time, time_t end_time, int subject_state, avail_subject *subject) { + unsigned long state_duration; + +#ifdef DEBUG2 + printf("ENTERING COMPUTE_SUBJECT_DOWNTIME_PART_TIMES\n"); +#endif + + /* times are weird */ + if(start_time > end_time) + return; + + state_duration = (unsigned long)(end_time - start_time); + + switch(subject_state) { + case AS_HOST_UP: + subject->scheduled_time_up += state_duration; + break; + case AS_HOST_DOWN: + subject->scheduled_time_down += state_duration; + break; + case AS_HOST_UNREACHABLE: + subject->scheduled_time_unreachable += state_duration; + break; + case AS_SVC_OK: + subject->scheduled_time_ok += state_duration; + break; + case AS_SVC_WARNING: + subject->scheduled_time_warning += state_duration; + break; + case AS_SVC_UNKNOWN: + subject->scheduled_time_unknown += state_duration; + break; + case AS_SVC_CRITICAL: + subject->scheduled_time_critical += state_duration; + break; + default: + subject->scheduled_time_indeterminate += state_duration; + break; + } + +#ifdef DEBUG2 + printf("\tSUBJECT DOWNTIME: Host '%s', Service '%s', State=%d, Duration=%lu, Start=%lu\n", subject->host_name, (subject->service_description == NULL) ? "NULL" : subject->service_description, subject_state, state_duration, start_time); +#endif + + return; + } + + + +/* convert current host state to archived state value */ +int convert_host_state_to_archived_state(int current_status) { + + if(current_status == HOST_UP) + return AS_HOST_UP; + if(current_status == HOST_DOWN) + return AS_HOST_DOWN; + if(current_status == HOST_UNREACHABLE) + return AS_HOST_UNREACHABLE; + + return AS_NO_DATA; + } + + +/* convert current service state to archived state value */ +int convert_service_state_to_archived_state(int current_status) { + + if(current_status == SERVICE_OK) + return AS_SVC_OK; + if(current_status == SERVICE_UNKNOWN) + return AS_SVC_UNKNOWN; + if(current_status == SERVICE_WARNING) + return AS_SVC_WARNING; + if(current_status == SERVICE_CRITICAL) + return AS_SVC_CRITICAL; + + return AS_NO_DATA; + } + + + +/* create list of subjects to collect availability data for */ +void create_subject_list(void) { + hostgroup *temp_hostgroup; + hostsmember *temp_hgmember; + servicegroup *temp_servicegroup; + servicesmember *temp_sgmember; + host *temp_host; + service *temp_service; + char *last_host_name = ""; + + /* we're displaying one or more hosts */ + if(display_type == DISPLAY_HOST_AVAIL && host_name && strcmp(host_name, "")) { + + /* we're only displaying a specific host (and summaries for all services associated with it) */ + if(show_all_hosts == FALSE) { + add_subject(HOST_SUBJECT, host_name, NULL); + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + if(!strcmp(temp_service->host_name, host_name)) + add_subject(SERVICE_SUBJECT, host_name, temp_service->description); + } + } + + /* we're displaying all hosts */ + else { + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) + add_subject(HOST_SUBJECT, temp_host->name, NULL); + } + } + + /* we're displaying a specific service */ + else if(display_type == DISPLAY_SERVICE_AVAIL && svc_description && strcmp(svc_description, "")) { + + /* we're only displaying a specific service */ + if(show_all_services == FALSE) + add_subject(SERVICE_SUBJECT, host_name, svc_description); + + /* we're displaying all services */ + else { + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) + add_subject(SERVICE_SUBJECT, temp_service->host_name, temp_service->description); + } + } + + /* we're displaying one or more hostgroups (the host members of the groups) */ + else if(display_type == DISPLAY_HOSTGROUP_AVAIL && hostgroup_name && strcmp(hostgroup_name, "")) { + + /* we're displaying all hostgroups */ + if(show_all_hostgroups == TRUE) { + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next) + add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL); + } + } + /* we're only displaying a specific hostgroup */ + else { + temp_hostgroup = find_hostgroup(hostgroup_name); + if(temp_hostgroup != NULL) { + for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next) + add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL); + } + } + } + + /* we're displaying one or more servicegroups (the host and service members of the groups) */ + else if(display_type == DISPLAY_SERVICEGROUP_AVAIL && servicegroup_name && strcmp(servicegroup_name, "")) { + + /* we're displaying all servicegroups */ + if(show_all_servicegroups == TRUE) { + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) { + add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description); + if(strcmp(last_host_name, temp_sgmember->host_name)) + add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL); + last_host_name = temp_sgmember->host_name; + } + } + } + /* we're only displaying a specific servicegroup */ + else { + temp_servicegroup = find_servicegroup(servicegroup_name); + if(temp_servicegroup != NULL) { + for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) { + add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description); + if(strcmp(last_host_name, temp_sgmember->host_name)) + add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL); + last_host_name = temp_sgmember->host_name; + } + } + } + } + + return; + } + + + +/* adds a subject */ +void add_subject(int subject_type, char *hn, char *sd) { + avail_subject *last_subject = NULL; + avail_subject *temp_subject = NULL; + avail_subject *new_subject = NULL; + int is_authorized = FALSE; + + /* bail if we've already added the subject */ + if(find_subject(subject_type, hn, sd)) + return; + + /* see if the user is authorized to see data for this host or service */ + if(subject_type == HOST_SUBJECT) + is_authorized = is_authorized_for_host(find_host(hn), ¤t_authdata); + else + is_authorized = is_authorized_for_service(find_service(hn, sd), ¤t_authdata); + if(is_authorized == FALSE) + return; + + /* allocate memory for the new entry */ + new_subject = (avail_subject *)malloc(sizeof(avail_subject)); + if(new_subject == NULL) + return; + + /* allocate memory for the host name */ + if(hn != NULL) { + new_subject->host_name = (char *)malloc(strlen(hn) + 1); + if(new_subject->host_name != NULL) + strcpy(new_subject->host_name, hn); + } + else + new_subject->host_name = NULL; + + /* allocate memory for the service description */ + if(sd != NULL) { + new_subject->service_description = (char *)malloc(strlen(sd) + 1); + if(new_subject->service_description != NULL) + strcpy(new_subject->service_description, sd); + } + else + new_subject->service_description = NULL; + + new_subject->type = subject_type; + new_subject->earliest_state = AS_NO_DATA; + new_subject->latest_state = AS_NO_DATA; + new_subject->time_up = 0L; + new_subject->time_down = 0L; + new_subject->time_unreachable = 0L; + new_subject->time_ok = 0L; + new_subject->time_warning = 0L; + new_subject->time_unknown = 0L; + new_subject->time_critical = 0L; + new_subject->scheduled_time_up = 0L; + new_subject->scheduled_time_down = 0L; + new_subject->scheduled_time_unreachable = 0L; + new_subject->scheduled_time_ok = 0L; + new_subject->scheduled_time_warning = 0L; + new_subject->scheduled_time_unknown = 0L; + new_subject->scheduled_time_critical = 0L; + new_subject->scheduled_time_indeterminate = 0L; + new_subject->time_indeterminate_nodata = 0L; + new_subject->time_indeterminate_notrunning = 0L; + new_subject->as_list = NULL; + new_subject->as_list_tail = NULL; + new_subject->sd_list = NULL; + new_subject->last_known_state = AS_NO_DATA; + + /* add the new entry to the list in memory, sorted by host name */ + last_subject = subject_list; + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + if(strcmp(new_subject->host_name, temp_subject->host_name) < 0) { + new_subject->next = temp_subject; + if(temp_subject == subject_list) + subject_list = new_subject; + else + last_subject->next = new_subject; + break; + } + else + last_subject = temp_subject; + } + if(subject_list == NULL) { + new_subject->next = NULL; + subject_list = new_subject; + } + else if(temp_subject == NULL) { + new_subject->next = NULL; + last_subject->next = new_subject; + } + + return; + } + + + +/* finds a specific subject */ +avail_subject *find_subject(int type, char *hn, char *sd) { + avail_subject *temp_subject; + + if(hn == NULL) + return NULL; + + if(type == SERVICE_SUBJECT && sd == NULL) + return NULL; + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + if(temp_subject->type != type) + continue; + if(strcmp(hn, temp_subject->host_name)) + continue; + if(type == SERVICE_SUBJECT && strcmp(sd, temp_subject->service_description)) + continue; + return temp_subject; + } + + return NULL; + } + + + +/* adds an archived state entry to all subjects */ +void add_global_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info) { + avail_subject *temp_subject; + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) + add_archived_state(entry_type, state_type, time_stamp, state_info, temp_subject); + + return; + } + + + + +/* adds an archived state entry to a specific subject */ +void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info, avail_subject *subject) { + archived_state *last_as = NULL; + archived_state *temp_as = NULL; + archived_state *new_as = NULL; + + /* allocate memory for the new entry */ + new_as = (archived_state *)malloc(sizeof(archived_state)); + if(new_as == NULL) + return; + + /* allocate memory for the state info */ + if(state_info != NULL) { + new_as->state_info = (char *)malloc(strlen(state_info) + 1); + if(new_as->state_info != NULL) + strcpy(new_as->state_info, state_info); + } + else new_as->state_info = NULL; + + /* initialize the "processed state" value - this gets modified later for most entries */ + if(entry_type != AS_PROGRAM_START && entry_type != AS_PROGRAM_END && entry_type != AS_NO_DATA) + new_as->processed_state = entry_type; + else + new_as->processed_state = AS_NO_DATA; + + new_as->entry_type = entry_type; + new_as->state_type = state_type; + new_as->time_stamp = time_stamp; + new_as->misc_ptr = NULL; + + /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */ + last_as = subject->as_list; + for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { + if(new_as->time_stamp < temp_as->time_stamp) { + new_as->next = temp_as; + if(temp_as == subject->as_list) + subject->as_list = new_as; + else + last_as->next = new_as; + break; + } + else + last_as = temp_as; + } + if(subject->as_list == NULL) { + new_as->next = NULL; + subject->as_list = new_as; + } + else if(temp_as == NULL) { + new_as->next = NULL; + last_as->next = new_as; + } + + /* update "tail" of the list - not really the tail, just last item added */ + subject->as_list_tail = new_as; + + return; + } + + +/* adds a scheduled downtime entry to a specific subject */ +void add_scheduled_downtime(int state_type, time_t time_stamp, avail_subject *subject) { + archived_state *last_sd = NULL; + archived_state *temp_sd = NULL; + archived_state *new_sd = NULL; + + /* allocate memory for the new entry */ + new_sd = (archived_state *)malloc(sizeof(archived_state)); + if(new_sd == NULL) + return; + + new_sd->state_info = NULL; + new_sd->processed_state = state_type; + new_sd->entry_type = state_type; + new_sd->time_stamp = time_stamp; + new_sd->misc_ptr = subject->as_list_tail; + + /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */ + last_sd = subject->sd_list; + for(temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) { + if(new_sd->time_stamp <= temp_sd->time_stamp) { + new_sd->next = temp_sd; + if(temp_sd == subject->sd_list) + subject->sd_list = new_sd; + else + last_sd->next = new_sd; + break; + } + else + last_sd = temp_sd; + } + if(subject->sd_list == NULL) { + new_sd->next = NULL; + subject->sd_list = new_sd; + } + else if(temp_sd == NULL) { + new_sd->next = NULL; + last_sd->next = new_sd; + } + + return; + } + + +/* frees memory allocated to all availability data */ +void free_availability_data(void) { + avail_subject *this_subject; + avail_subject *next_subject; + + for(this_subject = subject_list; this_subject != NULL;) { + next_subject = this_subject->next; + if(this_subject->host_name != NULL) + free(this_subject->host_name); + if(this_subject->service_description != NULL) + free(this_subject->service_description); + free_archived_state_list(this_subject->as_list); + free_archived_state_list(this_subject->sd_list); + free(this_subject); + this_subject = next_subject; + } + + return; + } + +/* frees memory allocated to the archived state list */ +void free_archived_state_list(archived_state *as_list) { + archived_state *this_as = NULL; + archived_state *next_as = NULL; + + for(this_as = as_list; this_as != NULL;) { + next_as = this_as->next; + if(this_as->state_info != NULL) + free(this_as->state_info); + free(this_as); + this_as = next_as; + } + + as_list = NULL; + + return; + } + + + +/* reads log files for archived state data */ +void read_archived_state_data(void) { + char filename[MAX_FILENAME_LENGTH]; + int oldest_archive = 0; + int newest_archive = 0; + int current_archive = 0; + + /* determine oldest archive to use when scanning for data (include backtracked archives as well) */ + oldest_archive = determine_archive_to_use_from_time(t1); + if(log_rotation_method != LOG_ROTATION_NONE) + oldest_archive += backtrack_archives; + + /* determine most recent archive to use when scanning for data */ + newest_archive = determine_archive_to_use_from_time(t2); + + if(oldest_archive < newest_archive) + oldest_archive = newest_archive; + + /* read in all the necessary archived logs (from most recent to earliest) */ + for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) { + +#ifdef DEBUG + printf("Reading archive #%d\n", current_archive); +#endif + + /* get the name of the log file that contains this archive */ + get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1); + +#ifdef DEBUG + printf("Archive name: '%s'\n", filename); +#endif + + /* scan the log file for archived state data */ + scan_log_file_for_archived_state_data(filename); + } + + return; + } + + + +/* grabs archives state data from a log file */ +void scan_log_file_for_archived_state_data(char *filename) { + char *input = NULL; + char *input2 = NULL; + char entry_host_name[MAX_INPUT_BUFFER]; + char entry_svc_description[MAX_INPUT_BUFFER]; + char *plugin_output = NULL; + char *temp_buffer = NULL; + time_t time_stamp; + mmapfile *thefile = NULL; + avail_subject *temp_subject = NULL; + int state_type = 0; + + if((thefile = mmap_fopen(filename)) == NULL) + return; + + while(1) { + + /* free memory */ + free(input); + free(input2); + input = NULL; + input2 = NULL; + + /* read the next line */ + if((input = mmap_fgets(thefile)) == NULL) + break; + + strip(input); + + if((input2 = strdup(input)) == NULL) + continue; + + temp_buffer = my_strtok(input2, "]"); + time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10); + + /* program starts/restarts */ + if(strstr(input, " starting...")) + add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program start"); + if(strstr(input, " restarting...")) + add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program restart"); + + /* program stops */ + if(strstr(input, " shutting down...")) + add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Normal program termination"); + if(strstr(input, "Bailing out")) + add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Abnormal program termination"); + + if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { + + /* normal host alerts and initial/current states */ + if(strstr(input, "HOST ALERT:") || strstr(input, "INITIAL HOST STATE:") || strstr(input, "CURRENT HOST STATE:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* see if there is a corresponding subject for this host */ + temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL); + if(temp_subject == NULL) + continue; + + /* state types */ + if(strstr(input, ";SOFT;")) { + if(include_soft_states == FALSE) + continue; + state_type = AS_SOFT_STATE; + } + if(strstr(input, ";HARD;")) + state_type = AS_HARD_STATE; + + /* get the plugin output */ + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + plugin_output = my_strtok(NULL, "\n"); + + if(strstr(input, ";DOWN;")) + add_archived_state(AS_HOST_DOWN, state_type, time_stamp, plugin_output, temp_subject); + else if(strstr(input, ";UNREACHABLE;")) + add_archived_state(AS_HOST_UNREACHABLE, state_type, time_stamp, plugin_output, temp_subject); + else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) + add_archived_state(AS_HOST_UP, state_type, time_stamp, plugin_output, temp_subject); + else + add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject); + } + + /* scheduled downtime notices */ + else if(strstr(input, "HOST DOWNTIME ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* see if there is a corresponding subject for this host */ + temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL); + if(temp_subject == NULL) + continue; + + if(show_scheduled_downtime == FALSE) + continue; + + if(strstr(input, ";STARTED;")) + add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject); + else + add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject); + + } + } + + if(display_type == DISPLAY_SERVICE_AVAIL || display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { + + /* normal service alerts and initial/current states */ + if(strstr(input, "SERVICE ALERT:") || strstr(input, "INITIAL SERVICE STATE:") || strstr(input, "CURRENT SERVICE STATE:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* get service description */ + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); + entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; + + /* see if there is a corresponding subject for this service */ + temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description); + if(temp_subject == NULL) + continue; + + /* state types */ + if(strstr(input, ";SOFT;")) { + if(include_soft_states == FALSE) + continue; + state_type = AS_SOFT_STATE; + } + if(strstr(input, ";HARD;")) + state_type = AS_HARD_STATE; + + /* get the plugin output */ + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + plugin_output = my_strtok(NULL, "\n"); + + if(strstr(input, ";CRITICAL;")) + add_archived_state(AS_SVC_CRITICAL, state_type, time_stamp, plugin_output, temp_subject); + else if(strstr(input, ";WARNING;")) + add_archived_state(AS_SVC_WARNING, state_type, time_stamp, plugin_output, temp_subject); + else if(strstr(input, ";UNKNOWN;")) + add_archived_state(AS_SVC_UNKNOWN, state_type, time_stamp, plugin_output, temp_subject); + else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) + add_archived_state(AS_SVC_OK, state_type, time_stamp, plugin_output, temp_subject); + else + add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject); + + } + + /* scheduled service downtime notices */ + else if(strstr(input, "SERVICE DOWNTIME ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* get service description */ + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); + entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; + + /* see if there is a corresponding subject for this service */ + temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description); + if(temp_subject == NULL) + continue; + + if(show_scheduled_downtime == FALSE) + continue; + + if(strstr(input, ";STARTED;")) + add_scheduled_downtime(AS_SVC_DOWNTIME_START, time_stamp, temp_subject); + else + add_scheduled_downtime(AS_SVC_DOWNTIME_END, time_stamp, temp_subject); + } + + /* scheduled host downtime notices */ + else if(strstr(input, "HOST DOWNTIME ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* this host downtime entry must be added to all service subjects associated with the host! */ + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != SERVICE_SUBJECT) + continue; + + if(strcmp(temp_subject->host_name, entry_host_name)) + continue; + + if(show_scheduled_downtime == FALSE) + continue; + + if(strstr(input, ";STARTED;")) + add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject); + else + add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject); + } + } + } + + } + + /* free memory and close the file */ + free(input); + free(input2); + mmap_fclose(thefile); + + return; + } + + + + +void convert_timeperiod_to_times(int type) { + time_t current_time; + struct tm *t; + + /* get the current time */ + time(¤t_time); + + t = localtime(¤t_time); + + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_isdst = -1; + + switch(type) { + case TIMEPERIOD_LAST24HOURS: + t1 = current_time - (60 * 60 * 24); + t2 = current_time; + break; + case TIMEPERIOD_TODAY: + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_YESTERDAY: + t1 = (time_t)(mktime(t) - (60 * 60 * 24)); + t2 = (time_t)mktime(t); + break; + case TIMEPERIOD_THISWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + t2 = current_time; + break; + case TIMEPERIOD_LASTWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7)); + t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + break; + case TIMEPERIOD_THISMONTH: + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTMONTH: + t->tm_mday = 1; + t2 = mktime(t); + if(t->tm_mon == 0) { + t->tm_mon = 11; + t->tm_year--; + } + else + t->tm_mon--; + t1 = mktime(t); + break; + case TIMEPERIOD_THISQUARTER: + /* not implemented */ + break; + case TIMEPERIOD_LASTQUARTER: + /* not implemented */ + break; + case TIMEPERIOD_THISYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t2 = mktime(t); + t->tm_year--; + t1 = mktime(t); + break; + case TIMEPERIOD_LAST7DAYS: + t2 = current_time; + t1 = current_time - (7 * 24 * 60 * 60); + break; + case TIMEPERIOD_LAST31DAYS: + t2 = current_time; + t1 = current_time - (31 * 24 * 60 * 60); + break; + default: + break; + } + + return; + } + + + +void compute_report_times(void) { + time_t current_time; + struct tm *st; + struct tm *et; + + /* get the current time */ + time(¤t_time); + + st = localtime(¤t_time); + + st->tm_sec = start_second; + st->tm_min = start_minute; + st->tm_hour = start_hour; + st->tm_mday = start_day; + st->tm_mon = start_month - 1; + st->tm_year = start_year - 1900; + st->tm_isdst = -1; + + t1 = mktime(st); + + et = localtime(¤t_time); + + et->tm_sec = end_second; + et->tm_min = end_minute; + et->tm_hour = end_hour; + et->tm_mday = end_day; + et->tm_mon = end_month - 1; + et->tm_year = end_year - 1900; + et->tm_isdst = -1; + + t2 = mktime(et); + } + + +/* writes log entries to screen */ +void write_log_entries(avail_subject *subject) { + archived_state *temp_as; + archived_state *temp_sd; + time_t current_time; + char start_date_time[MAX_DATETIME_LENGTH]; + char end_date_time[MAX_DATETIME_LENGTH]; + char duration[20]; + char *bgclass = ""; + char *ebgclass = ""; + char *entry_type = ""; + char *state_type = ""; + int days; + int hours; + int minutes; + int seconds; + int odd = 0; + + + if(output_format != HTML_OUTPUT) + return; + + if(show_log_entries == FALSE) + return; + + if(subject == NULL) + return; + + time(¤t_time); + + /* inject all scheduled downtime entries into the main list for display purposes */ + for(temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) { + switch(temp_sd->entry_type) { + case AS_SVC_DOWNTIME_START: + case AS_HOST_DOWNTIME_START: + entry_type = "Start of scheduled downtime"; + break; + case AS_SVC_DOWNTIME_END: + case AS_HOST_DOWNTIME_END: + entry_type = "End of scheduled downtime"; + break; + default: + entry_type = "?"; + break; + } + add_archived_state(temp_sd->entry_type, AS_NO_DATA, temp_sd->time_stamp, entry_type, subject); + } + + + printf("

    \n"); + + printf("
    %s Log Entries:
    \n", (subject->type == HOST_SUBJECT) ? "Host" : "Service"); + + printf("
    "); + if(full_log_entries == TRUE) { + full_log_entries = FALSE; + if(subject->type == HOST_SUBJECT) + host_report_url(subject->host_name, "[ View condensed log entries ]"); + else + service_report_url(subject->host_name, subject->service_description, "[ View condensed log entries ]"); + full_log_entries = TRUE; + } + else { + full_log_entries = TRUE; + if(subject->type == HOST_SUBJECT) + host_report_url(subject->host_name, "[ View full log entries ]"); + else + service_report_url(subject->host_name, subject->service_description, "[ View full log entries ]"); + full_log_entries = FALSE; + } + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + + /* write all archived state entries */ + for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { + + if(temp_as->state_type == AS_HARD_STATE) + state_type = " (HARD)"; + else if(temp_as->state_type == AS_SOFT_STATE) + state_type = " (SOFT)"; + else + state_type = ""; + + switch(temp_as->entry_type) { + case AS_NO_DATA: + if(full_log_entries == FALSE) + continue; + entry_type = "NO DATA"; + ebgclass = "INDETERMINATE"; + break; + case AS_PROGRAM_END: + if(full_log_entries == FALSE) + continue; + entry_type = "PROGRAM END"; + ebgclass = "INDETERMINATE"; + break; + case AS_PROGRAM_START: + if(full_log_entries == FALSE) + continue; + entry_type = "PROGRAM (RE)START"; + ebgclass = "INDETERMINATE"; + break; + case AS_HOST_UP: + entry_type = "HOST UP"; + ebgclass = "UP"; + break; + case AS_HOST_DOWN: + entry_type = "HOST DOWN"; + ebgclass = "DOWN"; + break; + case AS_HOST_UNREACHABLE: + entry_type = "HOST UNREACHABLE"; + ebgclass = "UNREACHABLE"; + break; + case AS_SVC_OK: + entry_type = "SERVICE OK"; + ebgclass = "OK"; + break; + case AS_SVC_UNKNOWN: + entry_type = "SERVICE UNKNOWN"; + ebgclass = "UNKNOWN"; + break; + case AS_SVC_WARNING: + entry_type = "SERVICE WARNING"; + ebgclass = "WARNING"; + break; + case AS_SVC_CRITICAL: + entry_type = "SERVICE CRITICAL"; + ebgclass = "CRITICAL"; + break; + case AS_SVC_DOWNTIME_START: + entry_type = "SERVICE DOWNTIME START"; + ebgclass = "INDETERMINATE"; + break; + case AS_SVC_DOWNTIME_END: + entry_type = "SERVICE DOWNTIME END"; + ebgclass = "INDETERMINATE"; + break; + case AS_HOST_DOWNTIME_START: + entry_type = "HOST DOWNTIME START"; + ebgclass = "INDETERMINATE"; + break; + case AS_HOST_DOWNTIME_END: + entry_type = "HOST DOWNTIME END"; + ebgclass = "INDETERMINATE"; + break; + default: + if(full_log_entries == FALSE) + continue; + entry_type = "?"; + ebgclass = "INDETERMINATE"; + } + + get_time_string(&(temp_as->time_stamp), start_date_time, sizeof(start_date_time) - 1, SHORT_DATE_TIME); + if(temp_as->next == NULL) { + get_time_string(&t2, end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME); + get_time_breakdown((time_t)(t2 - temp_as->time_stamp), &days, &hours, &minutes, &seconds); + snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds+", days, hours, minutes, seconds); + } + else { + get_time_string(&(temp_as->next->time_stamp), end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME); + get_time_breakdown((time_t)(temp_as->next->time_stamp - temp_as->time_stamp), &days, &hours, &minutes, &seconds); + snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + } + + if(odd) { + bgclass = "Odd"; + odd = 0; + } + else { + bgclass = "Even"; + odd = 1; + } + + printf("", bgclass); + printf("", bgclass, start_date_time); + printf("", bgclass, end_date_time); + printf("", bgclass, duration); + printf("", ebgclass, entry_type, state_type); + printf("", bgclass, (temp_as->state_info == NULL) ? "" : html_encode(temp_as->state_info, FALSE)); + printf("\n"); + } + + printf("
    Event Start TimeEvent End TimeEvent DurationEvent/State TypeEvent/State Information
    %s%s%s%s%s%s
    \n"); + + printf("
    \n"); + + return; + } + + + +/* display hostgroup availability */ +void display_hostgroup_availability(void) { + hostgroup *temp_hostgroup; + + /* display data for a specific hostgroup */ + if(show_all_hostgroups == FALSE) { + temp_hostgroup = find_hostgroup(hostgroup_name); + display_specific_hostgroup_availability(temp_hostgroup); + } + + /* display data for all hostgroups */ + else { + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) + display_specific_hostgroup_availability(temp_hostgroup); + } + + return; + } + + + +/* display availability for a specific hostgroup */ +void display_specific_hostgroup_availability(hostgroup *hg) { + unsigned long total_time; + unsigned long time_determinate; + unsigned long time_indeterminate; + avail_subject *temp_subject; + double percent_time_up = 0.0; + double percent_time_down = 0.0; + double percent_time_unreachable = 0.0; + double percent_time_up_known = 0.0; + double percent_time_down_known = 0.0; + double percent_time_unreachable_known = 0.0; + double percent_time_indeterminate = 0.0; + + double average_percent_time_up = 0.0; + double average_percent_time_up_known = 0.0; + double average_percent_time_down = 0.0; + double average_percent_time_down_known = 0.0; + double average_percent_time_unreachable = 0.0; + double average_percent_time_unreachable_known = 0.0; + double average_percent_time_indeterminate = 0.0; + + int current_subject = 0; + + char *bgclass = ""; + int odd = 1; + host *temp_host; + + if(hg == NULL) + return; + + /* the user isn't authorized to view this hostgroup */ + if(is_authorized_for_hostgroup(hg, ¤t_authdata) == FALSE) + return; + + /* calculate total time during period based on timeperiod used for reporting */ + total_time = calculate_total_time(t1, t2); + + printf("

    \n"); + printf("
    Hostgroup '%s' Host State Breakdowns:
    \n", hg->group_name); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != HOST_SUBJECT) + continue; + + temp_host = find_host(temp_subject->host_name); + if(temp_host == NULL) + continue; + + if(is_host_member_of_hostgroup(hg, temp_host) == FALSE) + continue; + + current_subject++; + + /* reset variables */ + percent_time_up = 0.0; + percent_time_down = 0.0; + percent_time_unreachable = 0.0; + percent_time_indeterminate = 0.0; + percent_time_up_known = 0.0; + percent_time_down_known = 0.0; + percent_time_unreachable_known = 0.0; + + time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; + time_indeterminate = total_time - time_determinate; + + if(total_time > 0) { + percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time); + percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time); + percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time); + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate); + percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate); + percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate); + } + } + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate); + + get_running_average(&average_percent_time_up, percent_time_up, current_subject); + get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject); + get_running_average(&average_percent_time_down, percent_time_down, current_subject); + get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject); + get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject); + get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject); + get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); + } + + /* average statistics */ + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + printf("", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate); + + printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ", bgclass, bgclass); + host_report_url(temp_subject->host_name, temp_subject->host_name); + printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); + printf("
    \n"); + + return; + } + + +/* display servicegroup availability */ +void display_servicegroup_availability(void) { + servicegroup *temp_servicegroup; + + /* display data for a specific servicegroup */ + if(show_all_servicegroups == FALSE) { + temp_servicegroup = find_servicegroup(servicegroup_name); + display_specific_servicegroup_availability(temp_servicegroup); + } + + /* display data for all servicegroups */ + else { + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) + display_specific_servicegroup_availability(temp_servicegroup); + } + + return; + } + + + +/* display availability for a specific servicegroup */ +void display_specific_servicegroup_availability(servicegroup *sg) { + unsigned long total_time; + unsigned long time_determinate; + unsigned long time_indeterminate; + avail_subject *temp_subject; + double percent_time_up = 0.0; + double percent_time_down = 0.0; + double percent_time_unreachable = 0.0; + double percent_time_up_known = 0.0; + double percent_time_down_known = 0.0; + double percent_time_unreachable_known = 0.0; + double percent_time_indeterminate = 0.0; + double percent_time_ok = 0.0; + double percent_time_warning = 0.0; + double percent_time_unknown = 0.0; + double percent_time_critical = 0.0; + double percent_time_ok_known = 0.0; + double percent_time_warning_known = 0.0; + double percent_time_unknown_known = 0.0; + double percent_time_critical_known = 0.0; + + double average_percent_time_up = 0.0; + double average_percent_time_up_known = 0.0; + double average_percent_time_down = 0.0; + double average_percent_time_down_known = 0.0; + double average_percent_time_unreachable = 0.0; + double average_percent_time_unreachable_known = 0.0; + double average_percent_time_ok = 0.0; + double average_percent_time_ok_known = 0.0; + double average_percent_time_unknown = 0.0; + double average_percent_time_unknown_known = 0.0; + double average_percent_time_warning = 0.0; + double average_percent_time_warning_known = 0.0; + double average_percent_time_critical = 0.0; + double average_percent_time_critical_known = 0.0; + double average_percent_time_indeterminate = 0.0; + + int current_subject = 0; + + char *bgclass = ""; + int odd = 1; + host *temp_host; + service *temp_service; + char last_host[MAX_INPUT_BUFFER]; + + if(sg == NULL) + return; + + /* the user isn't authorized to view this servicegroup */ + if(is_authorized_for_servicegroup(sg, ¤t_authdata) == FALSE) + return; + + /* calculate total time during period based on timeperiod used for reporting */ + total_time = calculate_total_time(t1, t2); + + printf("

    \n"); + printf("
    Servicegroup '%s' Host State Breakdowns:
    \n", sg->group_name); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != HOST_SUBJECT) + continue; + + temp_host = find_host(temp_subject->host_name); + if(temp_host == NULL) + continue; + + if(is_host_member_of_servicegroup(sg, temp_host) == FALSE) + continue; + + current_subject++; + + /* reset variables */ + percent_time_up = 0.0; + percent_time_down = 0.0; + percent_time_unreachable = 0.0; + percent_time_indeterminate = 0.0; + percent_time_up_known = 0.0; + percent_time_down_known = 0.0; + percent_time_unreachable_known = 0.0; + + time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; + time_indeterminate = total_time - time_determinate; + + if(total_time > 0) { + percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time); + percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time); + percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time); + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate); + percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate); + percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate); + } + } + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate); + + get_running_average(&average_percent_time_up, percent_time_up, current_subject); + get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject); + get_running_average(&average_percent_time_down, percent_time_down, current_subject); + get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject); + get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject); + get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject); + get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); + } + + /* average statistics */ + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + printf("", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate); + + printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ", bgclass, bgclass); + host_report_url(temp_subject->host_name, temp_subject->host_name); + printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    Servicegroup '%s' Service State Breakdowns:
    \n", sg->group_name); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + current_subject = 0; + average_percent_time_indeterminate = 0.0; + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != SERVICE_SUBJECT) + continue; + + temp_service = find_service(temp_subject->host_name, temp_subject->service_description); + if(temp_service == NULL) + continue; + + if(is_service_member_of_servicegroup(sg, temp_service) == FALSE) + continue; + + current_subject++; + + time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; + time_indeterminate = total_time - time_determinate; + + /* adjust indeterminate time due to insufficient data (not all was caught) */ + temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; + + /* initialize values */ + percent_time_ok = 0.0; + percent_time_warning = 0.0; + percent_time_unknown = 0.0; + percent_time_critical = 0.0; + percent_time_indeterminate = 0.0; + percent_time_ok_known = 0.0; + percent_time_warning_known = 0.0; + percent_time_unknown_known = 0.0; + percent_time_critical_known = 0.0; + + if(total_time > 0) { + percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time); + percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time); + percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time); + percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time); + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate); + percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate); + percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate); + percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate); + } + } + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate); + + strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1); + last_host[sizeof(last_host) - 1] = '\x0'; + + get_running_average(&average_percent_time_ok, percent_time_ok, current_subject); + get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject); + get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject); + get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject); + get_running_average(&average_percent_time_warning, percent_time_warning, current_subject); + get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject); + get_running_average(&average_percent_time_critical, percent_time_critical, current_subject); + get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject); + get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); + } + + /* display average stats */ + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate); + + printf("
    HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ", bgclass, bgclass); + if(strcmp(temp_subject->host_name, last_host)) + host_report_url(temp_subject->host_name, temp_subject->host_name); + printf("", bgclass); + service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description); + printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); + printf("
    \n"); + + return; + } + + +/* display host availability */ +void display_host_availability(void) { + unsigned long total_time; + unsigned long time_determinate; + unsigned long time_indeterminate; + avail_subject *temp_subject; + host *temp_host; + service *temp_service; + int days, hours, minutes, seconds; + char time_indeterminate_string[48]; + char time_determinate_string[48]; + char total_time_string[48]; + double percent_time_ok = 0.0; + double percent_time_warning = 0.0; + double percent_time_unknown = 0.0; + double percent_time_critical = 0.0; + double percent_time_indeterminate = 0.0; + double percent_time_ok_known = 0.0; + double percent_time_warning_known = 0.0; + double percent_time_unknown_known = 0.0; + double percent_time_critical_known = 0.0; + char time_up_string[48]; + char time_down_string[48]; + char time_unreachable_string[48]; + double percent_time_up = 0.0; + double percent_time_down = 0.0; + double percent_time_unreachable = 0.0; + double percent_time_up_known = 0.0; + double percent_time_down_known = 0.0; + double percent_time_unreachable_known = 0.0; + + double percent_time_up_scheduled = 0.0; + double percent_time_up_unscheduled = 0.0; + double percent_time_down_scheduled = 0.0; + double percent_time_down_unscheduled = 0.0; + double percent_time_unreachable_scheduled = 0.0; + double percent_time_unreachable_unscheduled = 0.0; + double percent_time_up_scheduled_known = 0.0; + double percent_time_up_unscheduled_known = 0.0; + double percent_time_down_scheduled_known = 0.0; + double percent_time_down_unscheduled_known = 0.0; + double percent_time_unreachable_scheduled_known = 0.0; + double percent_time_unreachable_unscheduled_known = 0.0; + char time_up_scheduled_string[48]; + char time_up_unscheduled_string[48]; + char time_down_scheduled_string[48]; + char time_down_unscheduled_string[48]; + char time_unreachable_scheduled_string[48]; + char time_unreachable_unscheduled_string[48]; + + char time_indeterminate_scheduled_string[48]; + char time_indeterminate_unscheduled_string[48]; + double percent_time_indeterminate_scheduled = 0.0; + double percent_time_indeterminate_unscheduled = 0.0; + char time_indeterminate_notrunning_string[48]; + char time_indeterminate_nodata_string[48]; + double percent_time_indeterminate_notrunning = 0.0; + double percent_time_indeterminate_nodata = 0.0; + + double average_percent_time_up = 0.0; + double average_percent_time_up_known = 0.0; + double average_percent_time_down = 0.0; + double average_percent_time_down_known = 0.0; + double average_percent_time_unreachable = 0.0; + double average_percent_time_unreachable_known = 0.0; + double average_percent_time_indeterminate = 0.0; + + double average_percent_time_ok = 0.0; + double average_percent_time_ok_known = 0.0; + double average_percent_time_unknown = 0.0; + double average_percent_time_unknown_known = 0.0; + double average_percent_time_warning = 0.0; + double average_percent_time_warning_known = 0.0; + double average_percent_time_critical = 0.0; + double average_percent_time_critical_known = 0.0; + + int current_subject = 0; + + char *bgclass = ""; + int odd = 1; + + /* calculate total time during period based on timeperiod used for reporting */ + total_time = calculate_total_time(t1, t2); + +#ifdef DEBUG + printf("Total time: '%ld' seconds
    \n", total_time); +#endif + + /* show data for a specific host */ + if(show_all_hosts == FALSE) { + + temp_subject = find_subject(HOST_SUBJECT, host_name, NULL); + if(temp_subject == NULL) + return; + + temp_host = find_host(temp_subject->host_name); + if(temp_host == NULL) + return; + + /* the user isn't authorized to view this host */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + return; + + time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; + time_indeterminate = total_time - time_determinate; + + /* adjust indeterminate time due to insufficient data (not all was caught) */ + temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; + + /* up times */ + get_time_breakdown(temp_subject->time_up, &days, &hours, &minutes, &seconds); + snprintf(time_up_string, sizeof(time_up_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds); + snprintf(time_up_scheduled_string, sizeof(time_up_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_up - temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds); + snprintf(time_up_unscheduled_string, sizeof(time_up_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* down times */ + get_time_breakdown(temp_subject->time_down, &days, &hours, &minutes, &seconds); + snprintf(time_down_string, sizeof(time_down_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds); + snprintf(time_down_scheduled_string, sizeof(time_down_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_down - temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds); + snprintf(time_down_unscheduled_string, sizeof(time_down_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* unreachable times */ + get_time_breakdown(temp_subject->time_unreachable, &days, &hours, &minutes, &seconds); + snprintf(time_unreachable_string, sizeof(time_unreachable_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds); + snprintf(time_unreachable_scheduled_string, sizeof(time_unreachable_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds); + snprintf(time_unreachable_unscheduled_string, sizeof(time_unreachable_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* indeterminate times */ + get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds); + snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + get_time_breakdown(total_time, &days, &hours, &minutes, &seconds); + snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + if(total_time > 0) { + percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time); + percent_time_up_scheduled = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)total_time); + percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled; + percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time); + percent_time_down_scheduled = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)total_time); + percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled; + percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time); + percent_time_unreachable_scheduled = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)total_time); + percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled; + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled; + percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time); + percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate); + percent_time_up_scheduled_known = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)time_determinate); + percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known; + percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate); + percent_time_down_scheduled_known = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)time_determinate); + percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known; + percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate); + percent_time_unreachable_scheduled_known = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)time_determinate); + percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known; + } + } + + printf("
    Host State Breakdowns:
    \n"); + +#ifdef USE_TRENDS + printf("

    \n"); + printf("", t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives); + printf("Host State Trends", t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives); + printf("
    \n"); + printf("

    \n"); +#endif + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* up times */ + printf(""); + printf("\n", time_up_unscheduled_string, percent_time_up, percent_time_up_known); + printf("\n", time_up_scheduled_string, percent_time_up_scheduled, percent_time_up_scheduled_known); + printf("\n", time_up_string, percent_time_up, percent_time_up_known); + + /* down times */ + printf(""); + printf("\n", time_down_unscheduled_string, percent_time_down_unscheduled, percent_time_down_unscheduled_known); + printf("\n", time_down_scheduled_string, percent_time_down_scheduled, percent_time_down_scheduled_known); + printf("\n", time_down_string, percent_time_down, percent_time_down_known); + + /* unreachable times */ + printf(""); + printf("\n", time_unreachable_unscheduled_string, percent_time_unreachable, percent_time_unreachable_known); + printf("\n", time_unreachable_scheduled_string, percent_time_unreachable_scheduled, percent_time_unreachable_scheduled_known); + printf("\n", time_unreachable_string, percent_time_unreachable, percent_time_unreachable_known); + + /* indeterminate times */ + printf(""); + printf("\n", time_indeterminate_notrunning_string, percent_time_indeterminate_notrunning); + printf("\n", time_indeterminate_nodata_string, percent_time_indeterminate_nodata); + printf("\n", time_indeterminate_string, percent_time_indeterminate); + + printf("\n"); + + printf("\n", total_time_string); + printf("
    StateType / ReasonTime%% Total Time%% Known Time
    UPUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    DOWNUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UNREACHABLEUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UndeterminedNagios Not Running%s%2.3f%%
    Insufficient Data%s%2.3f%%
    Total%s%2.3f%%
    AllTotal%s100.000%%100.000%%
    \n"); + printf("
    \n"); + + + + /* display state breakdowns for all services on this host */ + + printf("

    \n"); + printf("
    State Breakdowns For Host Services:
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != SERVICE_SUBJECT) + continue; + + temp_service = find_service(temp_subject->host_name, temp_subject->service_description); + if(temp_service == NULL) + continue; + + /* the user isn't authorized to view this service */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + current_subject++; + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + /* reset variables */ + percent_time_ok = 0.0; + percent_time_warning = 0.0; + percent_time_unknown = 0.0; + percent_time_critical = 0.0; + percent_time_indeterminate = 0.0; + percent_time_ok_known = 0.0; + percent_time_warning_known = 0.0; + percent_time_unknown_known = 0.0; + percent_time_critical_known = 0.0; + + time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; + time_indeterminate = total_time - time_determinate; + + if(total_time > 0) { + percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time); + percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time); + percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time); + percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time); + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate); + percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate); + percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate); + percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate); + } + } + + printf("\n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate); + + get_running_average(&average_percent_time_ok, percent_time_ok, current_subject); + get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject); + get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject); + get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject); + get_running_average(&average_percent_time_warning, percent_time_warning, current_subject); + get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject); + get_running_average(&average_percent_time_critical, percent_time_critical, current_subject); + get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject); + get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); + } + + /* display average stats */ + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate); + + printf("
    Service%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ", bgclass, bgclass); + service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description); + printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); + printf("
    \n"); + + + /* write log entries for the host */ + temp_subject = find_subject(HOST_SUBJECT, host_name, NULL); + write_log_entries(temp_subject); + } + + + /* display data for all hosts */ + else { + + if(output_format == HTML_OUTPUT) { + + printf("

    \n"); + printf("
    Host State Breakdowns:
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + } + + else if(output_format == CSV_OUTPUT) { + printf("HOST_NAME,"); + + printf(" TIME_UP_SCHEDULED, PERCENT_TIME_UP_SCHEDULED, PERCENT_KNOWN_TIME_UP_SCHEDULED, TIME_UP_UNSCHEDULED, PERCENT_TIME_UP_UNSCHEDULED, PERCENT_KNOWN_TIME_UP_UNSCHEDULED, TOTAL_TIME_UP, PERCENT_TOTAL_TIME_UP, PERCENT_KNOWN_TIME_UP,"); + + printf(" TIME_DOWN_SCHEDULED, PERCENT_TIME_DOWN_SCHEDULED, PERCENT_KNOWN_TIME_DOWN_SCHEDULED, TIME_DOWN_UNSCHEDULED, PERCENT_TIME_DOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_DOWN_UNSCHEDULED, TOTAL_TIME_DOWN, PERCENT_TOTAL_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN,"); + + printf(" TIME_UNREACHABLE_SCHEDULED, PERCENT_TIME_UNREACHABLE_SCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_SCHEDULED, TIME_UNREACHABLE_UNSCHEDULED, PERCENT_TIME_UNREACHABLE_UNSCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_UNSCHEDULED, TOTAL_TIME_UNREACHABLE, PERCENT_TOTAL_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE,"); + + printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); + } + + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != HOST_SUBJECT) + continue; + + temp_host = find_host(temp_subject->host_name); + if(temp_host == NULL) + continue; + + /* the user isn't authorized to view this host */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + current_subject++; + + time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; + time_indeterminate = total_time - time_determinate; + + /* adjust indeterminate time due to insufficient data (not all was caught) */ + temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; + + /* initialize values */ + percent_time_up = 0.0; + percent_time_up_scheduled = 0.0; + percent_time_up_unscheduled = 0.0; + percent_time_down = 0.0; + percent_time_down_scheduled = 0.0; + percent_time_down_unscheduled = 0.0; + percent_time_unreachable = 0.0; + percent_time_unreachable_scheduled = 0.0; + percent_time_unreachable_unscheduled = 0.0; + percent_time_indeterminate = 0.0; + percent_time_indeterminate_scheduled = 0.0; + percent_time_indeterminate_unscheduled = 0.0; + percent_time_indeterminate_notrunning = 0.0; + percent_time_indeterminate_nodata = 0.0; + percent_time_up_known = 0.0; + percent_time_up_scheduled_known = 0.0; + percent_time_up_unscheduled_known = 0.0; + percent_time_down_known = 0.0; + percent_time_down_scheduled_known = 0.0; + percent_time_down_unscheduled_known = 0.0; + percent_time_unreachable_known = 0.0; + percent_time_unreachable_scheduled_known = 0.0; + percent_time_unreachable_unscheduled_known = 0.0; + + if(total_time > 0) { + percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time); + percent_time_up_scheduled = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)total_time); + percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled; + percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time); + percent_time_down_scheduled = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)total_time); + percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled; + percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time); + percent_time_unreachable_scheduled = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)total_time); + percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled; + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled; + percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time); + percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate); + percent_time_up_scheduled_known = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)time_determinate); + percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known; + percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate); + percent_time_down_scheduled_known = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)time_determinate); + percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known; + percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate); + percent_time_unreachable_scheduled_known = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)time_determinate); + percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known; + } + } + + if(output_format == HTML_OUTPUT) { + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate); + } + else if(output_format == CSV_OUTPUT) { + + /* host name */ + printf("\"%s\",", temp_subject->host_name); + + /* up times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_up, percent_time_up_scheduled, percent_time_up_scheduled_known, temp_subject->time_up - temp_subject->scheduled_time_up, percent_time_up_unscheduled, percent_time_up_unscheduled_known, temp_subject->time_up, percent_time_up, percent_time_up_known); + + /* down times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_down, percent_time_down_scheduled, percent_time_down_scheduled_known, temp_subject->time_down - temp_subject->scheduled_time_down, percent_time_down_unscheduled, percent_time_down_unscheduled_known, temp_subject->time_down, percent_time_down, percent_time_down_known); + + /* unreachable times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_unreachable, percent_time_unreachable_scheduled, percent_time_unreachable_scheduled_known, temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, percent_time_unreachable_unscheduled, percent_time_unreachable_unscheduled_known, temp_subject->time_unreachable, percent_time_unreachable, percent_time_unreachable_known); + + /* indeterminate times */ + printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning, temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata, time_indeterminate, percent_time_indeterminate); + } + + get_running_average(&average_percent_time_up, percent_time_up, current_subject); + get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject); + get_running_average(&average_percent_time_down, percent_time_down, current_subject); + get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject); + get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject); + get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject); + get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); + } + + if(output_format == HTML_OUTPUT) { + + /* average statistics */ + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + printf("", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate); + + printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ", bgclass, bgclass); + host_report_url(temp_subject->host_name, temp_subject->host_name); + printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); + printf("
    \n"); + } + } + + return; + } + + +/* display service availability */ +void display_service_availability(void) { + unsigned long total_time; + unsigned long time_determinate; + unsigned long time_indeterminate; + avail_subject *temp_subject; + service *temp_service; + int days, hours, minutes, seconds; + char time_ok_string[48]; + char time_warning_string[48]; + char time_unknown_string[48]; + char time_critical_string[48]; + char time_indeterminate_string[48]; + char time_determinate_string[48]; + char total_time_string[48]; + double percent_time_ok = 0.0; + double percent_time_warning = 0.0; + double percent_time_unknown = 0.0; + double percent_time_critical = 0.0; + double percent_time_indeterminate = 0.0; + double percent_time_ok_known = 0.0; + double percent_time_warning_known = 0.0; + double percent_time_unknown_known = 0.0; + double percent_time_critical_known = 0.0; + + char time_critical_scheduled_string[48]; + char time_critical_unscheduled_string[48]; + double percent_time_critical_scheduled = 0.0; + double percent_time_critical_unscheduled = 0.0; + double percent_time_critical_scheduled_known = 0.0; + double percent_time_critical_unscheduled_known = 0.0; + char time_unknown_scheduled_string[48]; + char time_unknown_unscheduled_string[48]; + double percent_time_unknown_scheduled = 0.0; + double percent_time_unknown_unscheduled = 0.0; + double percent_time_unknown_scheduled_known = 0.0; + double percent_time_unknown_unscheduled_known = 0.0; + char time_warning_scheduled_string[48]; + char time_warning_unscheduled_string[48]; + double percent_time_warning_scheduled = 0.0; + double percent_time_warning_unscheduled = 0.0; + double percent_time_warning_scheduled_known = 0.0; + double percent_time_warning_unscheduled_known = 0.0; + char time_ok_scheduled_string[48]; + char time_ok_unscheduled_string[48]; + double percent_time_ok_scheduled = 0.0; + double percent_time_ok_unscheduled = 0.0; + double percent_time_ok_scheduled_known = 0.0; + double percent_time_ok_unscheduled_known = 0.0; + + double average_percent_time_ok = 0.0; + double average_percent_time_ok_known = 0.0; + double average_percent_time_unknown = 0.0; + double average_percent_time_unknown_known = 0.0; + double average_percent_time_warning = 0.0; + double average_percent_time_warning_known = 0.0; + double average_percent_time_critical = 0.0; + double average_percent_time_critical_known = 0.0; + double average_percent_time_indeterminate = 0.0; + + int current_subject = 0; + + char time_indeterminate_scheduled_string[48]; + char time_indeterminate_unscheduled_string[48]; + double percent_time_indeterminate_scheduled = 0.0; + double percent_time_indeterminate_unscheduled = 0.0; + char time_indeterminate_notrunning_string[48]; + char time_indeterminate_nodata_string[48]; + double percent_time_indeterminate_notrunning = 0.0; + double percent_time_indeterminate_nodata = 0.0; + + int odd = 1; + char *bgclass = ""; + char last_host[128] = ""; + + + /* calculate total time during period based on timeperiod used for reporting */ + total_time = calculate_total_time(t1, t2); + + /* we're only getting data for one service */ + if(show_all_services == FALSE) { + + temp_subject = find_subject(SERVICE_SUBJECT, host_name, svc_description); + if(temp_subject == NULL) + return; + + temp_service = find_service(temp_subject->host_name, temp_subject->service_description); + if(temp_service == NULL) + return; + + /* the user isn't authorized to view this service */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + return; + + time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; + time_indeterminate = total_time - time_determinate; + + /* adjust indeterminate time due to insufficient data (not all was caught) */ + temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; + + /* ok states */ + get_time_breakdown(temp_subject->time_ok, &days, &hours, &minutes, &seconds); + snprintf(time_ok_string, sizeof(time_ok_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds); + snprintf(time_ok_scheduled_string, sizeof(time_ok_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_ok - temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds); + snprintf(time_ok_unscheduled_string, sizeof(time_ok_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* warning states */ + get_time_breakdown(temp_subject->time_warning, &days, &hours, &minutes, &seconds); + snprintf(time_warning_string, sizeof(time_warning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds); + snprintf(time_warning_scheduled_string, sizeof(time_warning_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_warning - temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds); + snprintf(time_warning_unscheduled_string, sizeof(time_warning_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* unknown states */ + get_time_breakdown(temp_subject->time_unknown, &days, &hours, &minutes, &seconds); + snprintf(time_unknown_string, sizeof(time_unknown_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds); + snprintf(time_unknown_scheduled_string, sizeof(time_unknown_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_unknown - temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds); + snprintf(time_unknown_unscheduled_string, sizeof(time_unknown_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* critical states */ + get_time_breakdown(temp_subject->time_critical, &days, &hours, &minutes, &seconds); + snprintf(time_critical_string, sizeof(time_critical_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds); + snprintf(time_critical_scheduled_string, sizeof(time_critical_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_critical - temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds); + snprintf(time_critical_unscheduled_string, sizeof(time_critical_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + /* indeterminate time */ + get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds); + snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds); + snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + get_time_breakdown(total_time, &days, &hours, &minutes, &seconds); + snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); + + if(total_time > 0) { + percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time); + percent_time_ok_scheduled = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)total_time); + percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled; + percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time); + percent_time_warning_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time); + percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled; + percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time); + percent_time_unknown_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time); + percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled; + percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time); + percent_time_critical_scheduled = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)total_time); + percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled; + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled; + percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time); + percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate); + percent_time_ok_scheduled_known = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)time_determinate); + percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known; + percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate); + percent_time_warning_scheduled_known = (double)(((double)temp_subject->scheduled_time_warning * 100.0) / (double)time_determinate); + percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known; + percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate); + percent_time_unknown_scheduled_known = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)time_determinate); + percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known; + percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate); + percent_time_critical_scheduled_known = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)time_determinate); + percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known; + } + } + + printf("
    Service State Breakdowns:
    \n"); +#ifdef USE_TRENDS + printf("

    \n"); + printf("", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives); + printf("Service State Trends", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives); + printf("
    \n"); + printf("

    \n"); +#endif + + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* ok states */ + printf(""); + printf("\n", time_ok_unscheduled_string, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known); + printf("\n", time_ok_scheduled_string, percent_time_ok_scheduled, percent_time_ok_scheduled_known); + printf("\n", time_ok_string, percent_time_ok, percent_time_ok_known); + + /* warning states */ + printf(""); + printf("\n", time_warning_unscheduled_string, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known); + printf("\n", time_warning_scheduled_string, percent_time_warning_scheduled, percent_time_warning_scheduled_known); + printf("\n", time_warning_string, percent_time_warning, percent_time_warning_known); + + /* unknown states */ + printf(""); + printf("\n", time_unknown_unscheduled_string, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known); + printf("\n", time_unknown_scheduled_string, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known); + printf("\n", time_unknown_string, percent_time_unknown, percent_time_unknown_known); + + /* critical states */ + printf(""); + printf("\n", time_critical_unscheduled_string, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known); + printf("\n", time_critical_scheduled_string, percent_time_critical_scheduled, percent_time_critical_scheduled_known); + printf("\n", time_critical_string, percent_time_critical, percent_time_critical_known); + + + printf(""); + /* + printf("\n",time_indeterminate_unscheduled_string,percent_time_indeterminate_unscheduled); + printf("\n",time_indeterminate_scheduled_string,percent_time_indeterminate_scheduled); + */ + printf("\n", time_indeterminate_notrunning_string, percent_time_indeterminate_notrunning); + printf("\n", time_indeterminate_nodata_string, percent_time_indeterminate_nodata); + printf("\n", time_indeterminate_string, percent_time_indeterminate); + + printf("\n"); + printf("\n", total_time_string); + printf("
    StateType / ReasonTime%% Total Time%% Known Time
    OKUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    WARNINGUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UNKNOWNUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    CRITICALUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UndeterminedUnscheduled%s%2.3f%%
    Scheduled%s%2.3f%%
    Nagios Not Running%s%2.3f%%
    Insufficient Data%s%2.3f%%
    Total%s%2.3f%%
    AllTotal%s100.000%%100.000%%
    \n"); + printf("
    \n"); + + + write_log_entries(temp_subject); + } + + + /* display data for all services */ + else { + + if(output_format == HTML_OUTPUT) { + + printf("
    Service State Breakdowns:
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + } + else if(output_format == CSV_OUTPUT) { + printf("HOST_NAME, SERVICE_DESCRIPTION,"); + + printf(" TIME_OK_SCHEDULED, PERCENT_TIME_OK_SCHEDULED, PERCENT_KNOWN_TIME_OK_SCHEDULED, TIME_OK_UNSCHEDULED, PERCENT_TIME_OK_UNSCHEDULED, PERCENT_KNOWN_TIME_OK_UNSCHEDULED, TOTAL_TIME_OK, PERCENT_TOTAL_TIME_OK, PERCENT_KNOWN_TIME_OK,"); + + printf(" TIME_WARNING_SCHEDULED, PERCENT_TIME_WARNING_SCHEDULED, PERCENT_KNOWN_TIME_WARNING_SCHEDULED, TIME_WARNING_UNSCHEDULED, PERCENT_TIME_WARNING_UNSCHEDULED, PERCENT_KNOWN_TIME_WARNING_UNSCHEDULED, TOTAL_TIME_WARNING, PERCENT_TOTAL_TIME_WARNING, PERCENT_KNOWN_TIME_WARNING,"); + + printf(" TIME_UNKNOWN_SCHEDULED, PERCENT_TIME_UNKNOWN_SCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_SCHEDULED, TIME_UNKNOWN_UNSCHEDULED, PERCENT_TIME_UNKNOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_UNSCHEDULED, TOTAL_TIME_UNKNOWN, PERCENT_TOTAL_TIME_UNKNOWN, PERCENT_KNOWN_TIME_UNKNOWN,"); + + printf(" TIME_CRITICAL_SCHEDULED, PERCENT_TIME_CRITICAL_SCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_SCHEDULED, TIME_CRITICAL_UNSCHEDULED, PERCENT_TIME_CRITICAL_UNSCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_UNSCHEDULED, TOTAL_TIME_CRITICAL, PERCENT_TOTAL_TIME_CRITICAL, PERCENT_KNOWN_TIME_CRITICAL,"); + + printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); + } + + + for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { + + if(temp_subject->type != SERVICE_SUBJECT) + continue; + + temp_service = find_service(temp_subject->host_name, temp_subject->service_description); + if(temp_service == NULL) + continue; + + /* the user isn't authorized to view this service */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + current_subject++; + + time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; + time_indeterminate = total_time - time_determinate; + + /* adjust indeterminate time due to insufficient data (not all was caught) */ + temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; + + /* initialize values */ + percent_time_ok = 0.0; + percent_time_ok_scheduled = 0.0; + percent_time_ok_unscheduled = 0.0; + percent_time_warning = 0.0; + percent_time_warning_scheduled = 0.0; + percent_time_warning_unscheduled = 0.0; + percent_time_unknown = 0.0; + percent_time_unknown_scheduled = 0.0; + percent_time_unknown_unscheduled = 0.0; + percent_time_critical = 0.0; + percent_time_critical_scheduled = 0.0; + percent_time_critical_unscheduled = 0.0; + percent_time_indeterminate = 0.0; + percent_time_indeterminate_scheduled = 0.0; + percent_time_indeterminate_unscheduled = 0.0; + percent_time_indeterminate_notrunning = 0.0; + percent_time_indeterminate_nodata = 0.0; + percent_time_ok_known = 0.0; + percent_time_ok_scheduled_known = 0.0; + percent_time_ok_unscheduled_known = 0.0; + percent_time_warning_known = 0.0; + percent_time_warning_scheduled_known = 0.0; + percent_time_warning_unscheduled_known = 0.0; + percent_time_unknown_known = 0.0; + percent_time_unknown_scheduled_known = 0.0; + percent_time_unknown_unscheduled_known = 0.0; + percent_time_critical_known = 0.0; + percent_time_critical_scheduled_known = 0.0; + percent_time_critical_unscheduled_known = 0.0; + + if(total_time > 0) { + percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time); + percent_time_ok_scheduled = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)total_time); + percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled; + percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time); + percent_time_warning_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time); + percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled; + percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time); + percent_time_unknown_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time); + percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled; + percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time); + percent_time_critical_scheduled = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)total_time); + percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled; + percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time); + percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled; + percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time); + percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time); + if(time_determinate > 0) { + percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate); + percent_time_ok_scheduled_known = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)time_determinate); + percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known; + percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate); + percent_time_warning_scheduled_known = (double)(((double)temp_subject->scheduled_time_warning * 100.0) / (double)time_determinate); + percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known; + percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate); + percent_time_unknown_scheduled_known = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)time_determinate); + percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known; + percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate); + percent_time_critical_scheduled_known = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)time_determinate); + percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known; + } + } + + if(output_format == HTML_OUTPUT) { + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("\n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate); + } + else if(output_format == CSV_OUTPUT) { + + /* host name and service description */ + printf("\"%s\", \"%s\",", temp_subject->host_name, temp_subject->service_description); + + /* ok times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_ok, percent_time_ok_scheduled, percent_time_ok_scheduled_known, temp_subject->time_ok - temp_subject->scheduled_time_ok, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known, temp_subject->time_ok, percent_time_ok, percent_time_ok_known); + + /* warning times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_warning, percent_time_warning_scheduled, percent_time_warning_scheduled_known, temp_subject->time_warning - temp_subject->scheduled_time_warning, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known, temp_subject->time_warning, percent_time_warning, percent_time_warning_known); + + /* unknown times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_unknown, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known, temp_subject->time_unknown - temp_subject->scheduled_time_unknown, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known, temp_subject->time_unknown, percent_time_unknown, percent_time_unknown_known); + + /* critical times */ + printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_critical, percent_time_critical_scheduled, percent_time_critical_scheduled_known, temp_subject->time_critical - temp_subject->scheduled_time_critical, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known, temp_subject->time_critical, percent_time_critical, percent_time_critical_known); + + /* indeterminate times */ + printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning, temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata, time_indeterminate, percent_time_indeterminate); + } + + strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1); + last_host[sizeof(last_host) - 1] = '\x0'; + + get_running_average(&average_percent_time_ok, percent_time_ok, current_subject); + get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject); + get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject); + get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject); + get_running_average(&average_percent_time_warning, percent_time_warning, current_subject); + get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject); + get_running_average(&average_percent_time_critical, percent_time_critical, current_subject); + get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject); + get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); + } + + if(output_format == HTML_OUTPUT) { + + /* average statistics */ + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + printf("\n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate); + + printf("
    HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ", bgclass, bgclass); + if(strcmp(temp_subject->host_name, last_host)) + host_report_url(temp_subject->host_name, temp_subject->host_name); + printf("", bgclass); + service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description); + printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); + printf("
    \n"); + } + } + + return; + } + + + + +void host_report_url(char *hn, char *label) { + + printf("%s", label); + + return; + } + + +void service_report_url(char *hn, char *sd, char *label) { + + printf("%s", label); + + return; + } + + +/* calculates running average */ +void get_running_average(double *running_average, double new_value, int current_item) { + + *running_average = (((*running_average * ((double)current_item - 1.0)) + new_value) / (double)current_item); + + return; + } + + +/* used in reports where a timeperiod is selected */ +unsigned long calculate_total_time(time_t start_time, time_t end_time) { + struct tm *t; + unsigned long midnight_today; + int weekday; + unsigned long total_time; + timerange *temp_timerange; + unsigned long temp_duration; + unsigned long temp_end; + unsigned long temp_start; + unsigned long start; + unsigned long end; + + /* attempt to handle the current time_period */ + if(current_timeperiod != NULL) { + + /* "A day" is 86400 seconds */ + t = localtime(&start_time); + + /* calculate the start of the day (midnight, 00:00 hours) */ + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_isdst = -1; + midnight_today = (unsigned long)mktime(t); + weekday = t->tm_wday; + + total_time = 0; + while(midnight_today < end_time) { + temp_duration = 0; + temp_end = min(86400, t2 - midnight_today); + temp_start = 0; + if(t1 > midnight_today) + temp_start = t1 - midnight_today; + + /* check all time ranges for this day of the week */ + for(temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + start = max(temp_timerange->range_start, temp_start); + end = min(temp_timerange->range_end, temp_end); +#ifdef DEBUG + printf("
  • Matching in timerange[%d]: %d -> %d (%ld -> %ld) %d -> %d = %ld
    \n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end, start, end, end - start); +#endif + if(end > start) + temp_duration += end - start; + } + total_time += temp_duration; + temp_start = 0; + midnight_today += 86400; + if(++weekday > 6) + weekday = 0; + } + + return total_time; + } + + /* no timeperiod was selected */ + return end_time - start_time; + } diff --git a/cgi/cgiauth.c b/cgi/cgiauth.c new file mode 100644 index 0000000..f53ce97 --- /dev/null +++ b/cgi/cgiauth.c @@ -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; + } diff --git a/cgi/cgiutils.c b/cgi/cgiutils.c new file mode 100644 index 0000000..b57ad3f --- /dev/null +++ b/cgi/cgiutils.c @@ -0,0 +1,1874 @@ +/*********************************************************************** + * + * CGIUTILS.C - Common utilities for Nagios CGIs + * + * Copyright (c) 2010 Nagios Core Development Team and Community Contributors + * 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/common.h" +#include "../include/locations.h" +#include "../include/objects.h" +#include "../include/statusdata.h" + +#include "../include/cgiutils.h" + +char main_config_file[MAX_FILENAME_LENGTH]; +char log_file[MAX_FILENAME_LENGTH]; +char log_archive_path[MAX_FILENAME_LENGTH]; +char command_file[MAX_FILENAME_LENGTH]; + +char physical_html_path[MAX_FILENAME_LENGTH]; +char physical_images_path[MAX_FILENAME_LENGTH]; +char physical_ssi_path[MAX_FILENAME_LENGTH]; +char url_html_path[MAX_FILENAME_LENGTH]; +char url_docs_path[MAX_FILENAME_LENGTH]; +char url_context_help_path[MAX_FILENAME_LENGTH]; +char url_images_path[MAX_FILENAME_LENGTH]; +char url_logo_images_path[MAX_FILENAME_LENGTH]; +char url_stylesheets_path[MAX_FILENAME_LENGTH]; +char url_media_path[MAX_FILENAME_LENGTH]; +char url_js_path[MAX_FILENAME_LENGTH]; + +char *service_critical_sound = NULL; +char *service_warning_sound = NULL; +char *service_unknown_sound = NULL; +char *host_down_sound = NULL; +char *host_unreachable_sound = NULL; +char *normal_sound = NULL; +char *statusmap_background_image = NULL; +char *statuswrl_include = NULL; + +char *illegal_output_chars = NULL; + +char *notes_url_target = NULL; +char *action_url_target = NULL; + +char *ping_syntax = NULL; + +char nagios_check_command[MAX_INPUT_BUFFER] = ""; +char nagios_process_info[MAX_INPUT_BUFFER] = ""; +int nagios_process_state = STATE_OK; + +int enable_splunk_integration = FALSE; +char *splunk_url = NULL; +int lock_author_names = TRUE; + +extern time_t program_start; +extern int nagios_pid; +extern int daemon_mode; +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int enable_failure_prediction; +extern int process_performance_data; +extern time_t last_command_check; +extern time_t last_log_rotation; + +int check_external_commands = 0; + +int date_format = DATE_FORMAT_US; + +int log_rotation_method = LOG_ROTATION_NONE; + +time_t this_scheduled_log_rotation = 0L; +time_t last_scheduled_log_rotation = 0L; +time_t next_scheduled_log_rotation = 0L; + +int use_authentication = TRUE; + +int interval_length = 60; + +int show_context_help = FALSE; + +int use_pending_states = TRUE; + +int host_status_has_been_read = FALSE; +int service_status_has_been_read = FALSE; +int program_status_has_been_read = FALSE; + +int refresh_rate = DEFAULT_REFRESH_RATE; +int result_limit = 100; + +int escape_html_tags = FALSE; + +int use_ssl_authentication = FALSE; + +int default_statusmap_layout_method = 0; +int default_statuswrl_layout_method = 0; + +int color_transparency_index_r = 255; +int color_transparency_index_g = 255; +int color_transparency_index_b = 255; + +extern hostgroup *hostgroup_list; +extern contactgroup *contactgroup_list; +extern command *command_list; +extern timeperiod *timeperiod_list; +extern contact *contact_list; +extern serviceescalation *serviceescalation_list; + +extern hoststatus *hoststatus_list; +extern servicestatus *servicestatus_list; + +lifo *lifo_list = NULL; + +char encoded_url_string[2][MAX_INPUT_BUFFER]; // 2 to be able use url_encode twice +char *encoded_html_string = NULL; + +#ifdef HAVE_TZNAME +#ifdef CYGWIN +extern char *_tzname[2] __declspec(dllimport); +#else +extern char *tzname[2]; +#endif +#endif + + + +/* + * These function stubs allow us to compile a lot of the + * source-files common to cgi's and daemon without adding + * a whole bunch of #ifdef's everywhere. Note that we can't + * have them as macros, since the goal is to compile the + * source-files once. A decent linker will make the call + * a no-op anyway, so it's not a big issue + */ +void logit(int data_type, int display, const char *fmt, ...) { + return; + } +int log_debug_info(int leve, int verbosity, const char *fmt, ...) { + return 0; + } + +/********************************************************** + ***************** CLEANUP FUNCTIONS ********************** + **********************************************************/ + +/* reset all variables used by the CGIs */ +void reset_cgi_vars(void) { + + strcpy(main_config_file, ""); + + strcpy(physical_html_path, ""); + strcpy(physical_images_path, ""); + strcpy(physical_ssi_path, ""); + + strcpy(url_html_path, ""); + strcpy(url_docs_path, ""); + strcpy(url_context_help_path, ""); + strcpy(url_stylesheets_path, ""); + strcpy(url_media_path, ""); + strcpy(url_images_path, ""); + + strcpy(log_file, ""); + strcpy(log_archive_path, DEFAULT_LOG_ARCHIVE_PATH); + if(log_archive_path[strlen(log_archive_path) - 1] != '/' && strlen(log_archive_path) < sizeof(log_archive_path) - 2) + strcat(log_archive_path, "/"); + strcpy(command_file, get_cmd_file_location()); + + strcpy(nagios_check_command, ""); + strcpy(nagios_process_info, ""); + nagios_process_state = STATE_OK; + + log_rotation_method = LOG_ROTATION_NONE; + + use_authentication = TRUE; + + interval_length = 60; + + refresh_rate = DEFAULT_REFRESH_RATE; + + default_statusmap_layout_method = 0; + default_statusmap_layout_method = 0; + + service_critical_sound = NULL; + service_warning_sound = NULL; + service_unknown_sound = NULL; + host_down_sound = NULL; + host_unreachable_sound = NULL; + normal_sound = NULL; + + statusmap_background_image = NULL; + color_transparency_index_r = 255; + color_transparency_index_g = 255; + color_transparency_index_b = 255; + statuswrl_include = NULL; + + ping_syntax = NULL; + + return; + } + + + +/* free all memory for object definitions */ +void free_memory(void) { + + /* free memory for common object definitions */ + free_object_data(); + + /* free memory for status data */ + free_status_data(); + + /* free misc data */ + free(service_critical_sound); + free(service_warning_sound); + free(service_unknown_sound); + free(host_down_sound); + free(host_unreachable_sound); + free(normal_sound); + free(statusmap_background_image); + free(statuswrl_include); + free(ping_syntax); + + return; + } + + + + +/********************************************************** + *************** CONFIG FILE FUNCTIONS ******************** + **********************************************************/ + +/* read the CGI config file location from an environment variable */ +char * get_cgi_config_location(void) { + static char *cgiloc = NULL; + + if(!cgiloc) { + cgiloc = getenv("NAGIOS_CGI_CONFIG"); + if(!cgiloc) + cgiloc = DEFAULT_CGI_CONFIG_FILE; + } + + return cgiloc; + } + + +/* read the command file location from an environment variable */ +char * get_cmd_file_location(void) { + static char *cmdloc = NULL; + + if(!cmdloc) { + cmdloc = getenv("NAGIOS_COMMAND_FILE"); + if(!cmdloc) + cmdloc = DEFAULT_COMMAND_FILE; + } + return cmdloc; + } + + +/*read the CGI configuration file */ +int read_cgi_config_file(char *filename) { + char *input = NULL; + mmapfile *thefile; + char *var = NULL; + char *val = NULL; + + + if((thefile = mmap_fopen(filename)) == NULL) + return ERROR; + + while(1) { + + /* free memory */ + free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + strip(input); + + var = strtok(input, "="); + val = strtok(NULL, "\n"); + + if(var == NULL || val == NULL) + continue; + + if(!strcmp(var, "main_config_file")) { + strncpy(main_config_file, val, sizeof(main_config_file)); + main_config_file[sizeof(main_config_file) - 1] = '\x0'; + strip(main_config_file); + } + + else if(!strcmp(var, "show_context_help")) + show_context_help = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "use_pending_states")) + use_pending_states = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "use_authentication")) + use_authentication = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "nagios_check_command")) { + strncpy(nagios_check_command, val, sizeof(nagios_check_command)); + nagios_check_command[sizeof(nagios_check_command) - 1] = '\x0'; + strip(nagios_check_command); + } + + else if(!strcmp(var, "refresh_rate")) + refresh_rate = atoi(val); + + /* page limit added 2/1/2012 -MG */ + else if(!strcmp(var, "result_limit")) + result_limit = atoi(val); + + else if(!strcmp(var, "physical_html_path")) { + strncpy(physical_html_path, val, sizeof(physical_html_path)); + physical_html_path[sizeof(physical_html_path) - 1] = '\x0'; + strip(physical_html_path); + if(physical_html_path[strlen(physical_html_path) - 1] != '/' && (strlen(physical_html_path) < sizeof(physical_html_path) - 1)) + strcat(physical_html_path, "/"); + + snprintf(physical_images_path, sizeof(physical_images_path), "%simages/", physical_html_path); + physical_images_path[sizeof(physical_images_path) - 1] = '\x0'; + + snprintf(physical_ssi_path, sizeof(physical_images_path), "%sssi/", physical_html_path); + physical_ssi_path[sizeof(physical_ssi_path) - 1] = '\x0'; + } + + else if(!strcmp(var, "url_html_path")) { + + strncpy(url_html_path, val, sizeof(url_html_path)); + url_html_path[sizeof(url_html_path) - 1] = '\x0'; + + strip(url_html_path); + if(url_html_path[strlen(url_html_path) - 1] != '/' && (strlen(url_html_path) < sizeof(url_html_path) - 1)) + strcat(url_html_path, "/"); + + snprintf(url_docs_path, sizeof(url_docs_path), "%sdocs/", url_html_path); + url_docs_path[sizeof(url_docs_path) - 1] = '\x0'; + + snprintf(url_context_help_path, sizeof(url_context_help_path), "%scontexthelp/", url_html_path); + url_context_help_path[sizeof(url_context_help_path) - 1] = '\x0'; + + snprintf(url_images_path, sizeof(url_images_path), "%simages/", url_html_path); + url_images_path[sizeof(url_images_path) - 1] = '\x0'; + + snprintf(url_logo_images_path, sizeof(url_logo_images_path), "%slogos/", url_images_path); + url_logo_images_path[sizeof(url_logo_images_path) - 1] = '\x0'; + + snprintf(url_stylesheets_path, sizeof(url_stylesheets_path), "%sstylesheets/", url_html_path); + url_stylesheets_path[sizeof(url_stylesheets_path) - 1] = '\x0'; + + snprintf(url_media_path, sizeof(url_media_path), "%smedia/", url_html_path); + url_media_path[sizeof(url_media_path) - 1] = '\x0'; + + /* added JS directory 2/1/2012 -MG */ + snprintf(url_js_path, sizeof(url_js_path), "%sjs/", url_html_path); + url_js_path[sizeof(url_js_path) - 1] = '\x0'; + + } + + else if(!strcmp(var, "service_critical_sound")) + service_critical_sound = strdup(val); + + else if(!strcmp(var, "service_warning_sound")) + service_warning_sound = strdup(val); + + else if(!strcmp(var, "service_unknown_sound")) + service_unknown_sound = strdup(val); + + else if(!strcmp(var, "host_down_sound")) + host_down_sound = strdup(val); + + else if(!strcmp(var, "host_unreachable_sound")) + host_unreachable_sound = strdup(val); + + else if(!strcmp(var, "normal_sound")) + normal_sound = strdup(val); + + else if(!strcmp(var, "statusmap_background_image")) + statusmap_background_image = strdup(val); + + else if(!strcmp(var, "color_transparency_index_r")) + color_transparency_index_r = atoi(val); + + else if(!strcmp(var, "color_transparency_index_g")) + color_transparency_index_g = atoi(val); + + else if(!strcmp(var, "color_transparency_index_b")) + color_transparency_index_b = atoi(val); + + else if(!strcmp(var, "default_statusmap_layout")) + default_statusmap_layout_method = atoi(val); + + else if(!strcmp(var, "default_statuswrl_layout")) + default_statuswrl_layout_method = atoi(val); + + else if(!strcmp(var, "statuswrl_include")) + statuswrl_include = strdup(val); + + else if(!strcmp(var, "ping_syntax")) + ping_syntax = strdup(val); + + else if(!strcmp(var, "action_url_target")) + action_url_target = strdup(val); + + else if(!strcmp(var, "illegal_macro_output_chars")) + illegal_output_chars = strdup(val); + + else if(!strcmp(var, "notes_url_target")) + notes_url_target = strdup(val); + + else if(!strcmp(var, "enable_splunk_integration")) + enable_splunk_integration = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "splunk_url")) + splunk_url = strdup(val); + + else if(!strcmp(var, "escape_html_tags")) + escape_html_tags = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "lock_author_names")) + lock_author_names = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "use_ssl_authentication")) + use_ssl_authentication = (atoi(val) > 0) ? TRUE : FALSE; + } + + /* free memory and close the file */ + free(input); + mmap_fclose(thefile); + + if(!strcmp(main_config_file, "")) + return ERROR; + else + return OK; + } + + + +/* read the main configuration file */ +int read_main_config_file(char *filename) { + char *input = NULL; + char *temp_buffer; + mmapfile *thefile; + + + if((thefile = mmap_fopen(filename)) == NULL) + return ERROR; + + while(1) { + + /* free memory */ + free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + strip(input); + + if(strstr(input, "interval_length=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\x0"); + interval_length = (temp_buffer == NULL) ? 60 : atoi(temp_buffer); + } + + else if(strstr(input, "log_file=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\x0"); + strncpy(log_file, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(log_file)); + log_file[sizeof(log_file) - 1] = '\x0'; + strip(log_file); + } + + else if(strstr(input, "log_archive_path=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\n"); + strncpy(log_archive_path, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(log_archive_path)); + log_archive_path[sizeof(log_archive_path) - 1] = '\x0'; + strip(physical_html_path); + if(log_archive_path[strlen(log_archive_path) - 1] != '/' && (strlen(log_archive_path) < sizeof(log_archive_path) - 1)) + strcat(log_archive_path, "/"); + } + + else if(strstr(input, "log_rotation_method=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\x0"); + if(temp_buffer == NULL) + log_rotation_method = LOG_ROTATION_NONE; + else if(!strcmp(temp_buffer, "h")) + log_rotation_method = LOG_ROTATION_HOURLY; + else if(!strcmp(temp_buffer, "d")) + log_rotation_method = LOG_ROTATION_DAILY; + else if(!strcmp(temp_buffer, "w")) + log_rotation_method = LOG_ROTATION_WEEKLY; + else if(!strcmp(temp_buffer, "m")) + log_rotation_method = LOG_ROTATION_MONTHLY; + } + + else if(strstr(input, "command_file=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\x0"); + strncpy(command_file, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(command_file)); + command_file[sizeof(command_file) - 1] = '\x0'; + strip(command_file); + } + + else if(strstr(input, "check_external_commands=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\x0"); + check_external_commands = (temp_buffer == NULL) ? 0 : atoi(temp_buffer); + } + + else if(strstr(input, "date_format=") == input) { + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\x0"); + if(temp_buffer == NULL) + date_format = DATE_FORMAT_US; + else if(!strcmp(temp_buffer, "euro")) + date_format = DATE_FORMAT_EURO; + else if(!strcmp(temp_buffer, "iso8601")) + date_format = DATE_FORMAT_ISO8601; + else if(!strcmp(temp_buffer, "strict-iso8601")) + date_format = DATE_FORMAT_STRICT_ISO8601; + else + date_format = DATE_FORMAT_US; + } + } + + /* free memory and close the file */ + free(input); + mmap_fclose(thefile); + + return OK; + } + + + +/* read all object definitions */ +int read_all_object_configuration_data(char *config_file, int options) { + int result = OK; + + /* read in all external config data of the desired type(s) */ + result = read_object_config_data(config_file, options, FALSE, FALSE); + + return result; + } + + +/* read all status data */ +int read_all_status_data(char *config_file, int options) { + int result = OK; + + /* don't duplicate things we've already read in */ + if(program_status_has_been_read == TRUE && (options & READ_PROGRAM_STATUS)) + options -= READ_PROGRAM_STATUS; + if(host_status_has_been_read == TRUE && (options & READ_HOST_STATUS)) + options -= READ_HOST_STATUS; + if(service_status_has_been_read == TRUE && (options & READ_SERVICE_STATUS)) + options -= READ_SERVICE_STATUS; + + /* bail out if we've already read what we need */ + if(options <= 0) + return OK; + + /* read in all external status data */ + result = read_status_data(config_file, options); + + /* mark what items we've read in... */ + if(options & READ_PROGRAM_STATUS) + program_status_has_been_read = TRUE; + if(options & READ_HOST_STATUS) + host_status_has_been_read = TRUE; + if(options & READ_SERVICE_STATUS) + service_status_has_been_read = TRUE; + + return result; + } + + +/********************************************************** + ******************* LIFO FUNCTIONS *********************** + **********************************************************/ + +/* reads contents of file into the lifo struct */ +int read_file_into_lifo(char *filename) { + char *input = NULL; + mmapfile *thefile; + int lifo_result; + + if((thefile = mmap_fopen(filename)) == NULL) + return LIFO_ERROR_FILE; + + while(1) { + + free(input); + + if((input = mmap_fgets(thefile)) == NULL) + break; + + lifo_result = push_lifo(input); + + if(lifo_result != LIFO_OK) { + free_lifo_memory(); + free(input); + mmap_fclose(thefile); + return lifo_result; + } + } + + mmap_fclose(thefile); + + return LIFO_OK; + } + + +/* frees all memory allocated to lifo */ +void free_lifo_memory(void) { + lifo *temp_lifo; + lifo *next_lifo; + + if(lifo_list == NULL) + return; + + temp_lifo = lifo_list; + while(temp_lifo != NULL) { + next_lifo = temp_lifo->next; + if(temp_lifo->data != NULL) + free((void *)temp_lifo->data); + free((void *)temp_lifo); + temp_lifo = next_lifo; + } + + return; + } + + +/* adds an item to lifo */ +int push_lifo(char *buffer) { + lifo *temp_lifo; + + temp_lifo = (lifo *)malloc(sizeof(lifo)); + if(temp_lifo == NULL) + return LIFO_ERROR_MEMORY; + + if(buffer == NULL) + temp_lifo->data = (char *)strdup(""); + else + temp_lifo->data = (char *)strdup(buffer); + if(temp_lifo->data == NULL) { + free(temp_lifo); + return LIFO_ERROR_MEMORY; + } + + /* add item to front of lifo... */ + temp_lifo->next = lifo_list; + lifo_list = temp_lifo; + + return LIFO_OK; + } + + + +/* returns/clears an item from lifo */ +char *pop_lifo(void) { + lifo *temp_lifo; + char *buf; + + if(lifo_list == NULL || lifo_list->data == NULL) + return NULL; + + buf = strdup(lifo_list->data); + + temp_lifo = lifo_list->next; + + if(lifo_list->data != NULL) + free((void *)lifo_list->data); + free((void *)lifo_list); + + lifo_list = temp_lifo; + + return buf; + } + + + + +/********************************************************** + *************** MISC UTILITY FUNCTIONS ******************* + **********************************************************/ + +/* unescapes newlines in a string */ +char *unescape_newlines(char *rawbuf) { + register int x, y; + + for(x = 0, y = 0; rawbuf[x] != (char)'\x0'; x++) { + + if(rawbuf[x] == '\\') { + + /* unescape newlines */ + if(rawbuf[x + 1] == 'n') { + rawbuf[y++] = '\n'; + x++; + } + + /* unescape backslashes and other stuff */ + if(rawbuf[x + 1] != '\x0') { + rawbuf[y++] = rawbuf[x + 1]; + x++; + } + + } + else + rawbuf[y++] = rawbuf[x]; + } + rawbuf[y] = '\x0'; + + return rawbuf; + } + + +/* strips HTML and bad stuff from plugin output */ +void sanitize_plugin_output(char *buffer) { + int x = 0; + int y = 0; + int in_html = FALSE; + char *new_buffer; + + if(buffer == NULL) + return; + + new_buffer = strdup(buffer); + if(new_buffer == NULL) + return; + + /* check each character */ + for(x = 0, y = 0; buffer[x] != '\x0'; x++) { + + /* we just started an HTML tag */ + if(buffer[x] == '<') { + in_html = TRUE; + continue; + } + + /* end of an HTML tag */ + else if(buffer[x] == '>') { + in_html = FALSE; + continue; + } + + /* skip everything inside HTML tags */ + else if(in_html == TRUE) + continue; + + /* strip single and double quotes */ + else if(buffer[x] == '\'' || buffer[x] == '\"') + new_buffer[y++] = ' '; + + /* strip semicolons (replace with colons) */ + else if(buffer[x] == ';') + new_buffer[y++] = ':'; + + /* strip pipe and ampersand */ + else if(buffer[x] == '&' || buffer[x] == '|') + new_buffer[y++] = ' '; + + /* normal character */ + else + new_buffer[y++] = buffer[x]; + } + + /* terminate sanitized buffer */ + new_buffer[y++] = '\x0'; + + /* copy the sanitized buffer back to the original */ + strcpy(buffer, new_buffer); + + /* free memory allocated to the new buffer */ + free(new_buffer); + + return; + } + + + +/* get date/time string */ +void get_time_string(time_t *raw_time, char *buffer, int buffer_length, int type) { + time_t t; + struct tm *tm_ptr = NULL; + int hour = 0; + int minute = 0; + int second = 0; + int month = 0; + int day = 0; + int year = 0; + char *weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + char *tzone = ""; + + if(raw_time == NULL) + time(&t); + else + t = *raw_time; + + if(type == HTTP_DATE_TIME) + tm_ptr = gmtime(&t); + else + tm_ptr = localtime(&t); + + 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 */ + 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 style */ + else if(type == SHORT_DATE_TIME) { + if(date_format == DATE_FORMAT_EURO) + snprintf(buffer, buffer_length, "%02d-%02d-%04d %02d:%02d:%02d", tm_ptr->tm_mday, tm_ptr->tm_mon + 1, tm_ptr->tm_year + 1900, tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec); + else if(date_format == DATE_FORMAT_ISO8601 || date_format == DATE_FORMAT_STRICT_ISO8601) + snprintf(buffer, buffer_length, "%04d-%02d-%02d%c%02d:%02d:%02d", tm_ptr->tm_year + 1900, tm_ptr->tm_mon + 1, tm_ptr->tm_mday, (date_format == DATE_FORMAT_STRICT_ISO8601) ? 'T' : ' ', tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec); + else + snprintf(buffer, buffer_length, "%02d-%02d-%04d %02d:%02d:%02d", tm_ptr->tm_mon + 1, tm_ptr->tm_mday, tm_ptr->tm_year + 1900, tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec); + } + + /* 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'; + + return; + } + + +/* get time string for an interval of time */ +void get_interval_time_string(double time_units, char *buffer, int buffer_length) { + unsigned long total_seconds; + int hours = 0; + int minutes = 0; + int seconds = 0; + + total_seconds = (unsigned long)(time_units * interval_length); + hours = (int)total_seconds / 3600; + total_seconds %= 3600; + minutes = (int)total_seconds / 60; + total_seconds %= 60; + seconds = (int)total_seconds; + snprintf(buffer, buffer_length, "%dh %dm %ds", hours, minutes, seconds); + buffer[buffer_length - 1] = '\x0'; + + return; + } + + +/* encodes a string in proper URL format */ +char *url_encode(char *input) { + int len, output_len; + int x, y; + char temp_expansion[4]; + static int i = 0; + char* str = encoded_url_string[i]; + + /* initialize return string */ + strcpy(str, ""); + + if(input == NULL) + return str; + + len = (int)strlen(input); + output_len = (int)sizeof(encoded_url_string[0]); + + str[0] = '\x0'; + + for(x = 0, y = 0; x <= len && y < output_len - 1; x++) { + + /* end of string */ + if((char)input[x] == (char)'\x0') { + str[y] = '\x0'; + break; + } + + /* alpha-numeric characters and a few other characters don't get encoded */ + else if(((char)input[x] >= '0' && (char)input[x] <= '9') || ((char)input[x] >= 'A' && (char)input[x] <= 'Z') || ((char)input[x] >= (char)'a' && (char)input[x] <= (char)'z') || (char)input[x] == (char)'.' || (char)input[x] == (char)'-' || (char)input[x] == (char)'_') { + str[y] = input[x]; + y++; + } + + /* spaces are pluses */ + else if(input[x] == ' ') { + str[y] = '+'; + y++; + } + + /* anything else gets represented by its hex value */ + else { + str[y] = '\x0'; + if((int)strlen(str) < (output_len - 3)) { + sprintf(temp_expansion, "%%%02X", (unsigned char)input[x]); + strcat(str, temp_expansion); + y += 3; + } + } + } + + str[sizeof(encoded_url_string[0]) - 1] = '\x0'; + + return str; + } + + + +/* escapes a string used in HTML */ +char * html_encode(char *input, int escape_newlines) { + int len; + int output_max; + char *outstp; + wchar_t *wcinput; + wchar_t *inwcp; + size_t mbstowcs_result; + char mbtemp[ 10]; + int wctomb_result; + int x; + char temp_expansion[10]; + + /* we need up to six times the space to do the conversion */ + len = (int)strlen(input); + output_max = len * 6; + if((outstp = encoded_html_string = (char *)malloc(output_max + 1)) == NULL) + return ""; + + strcpy(encoded_html_string, ""); + + /* Convert the string to a wide character string */ + if((wcinput = malloc(len * sizeof(wchar_t))) == NULL) { + return ""; + } + if((mbstowcs_result = mbstowcs(wcinput, input, len)) < 0) { + free(wcinput); + return ""; + } + + /* Process all converted characters */ + for(x = 0, inwcp = wcinput; x < mbstowcs_result && '\0' != *inwcp; x++, inwcp++) { + + /* Most ASCII characters don't get encoded */ + if((*inwcp >= 0x20 && *inwcp <= 0x7e) && + (!('"' == *inwcp || '&' == *inwcp || '\'' == *inwcp || + '<' == *inwcp || '>' == *inwcp))) { + wctomb_result = wctomb(mbtemp, *inwcp); + if((wctomb_result > 0) && + (((outstp - encoded_html_string) + wctomb_result) < output_max)) { + strncpy(outstp, mbtemp, wctomb_result); + outstp += wctomb_result; + } + } + + /* newlines turn to
    tags */ + else if(escape_newlines == TRUE && '\n' == *inwcp) { + strncpy(outstp, "
    ", 4); + outstp += 4; + } + + else if(escape_newlines == TRUE && '\\' == *inwcp && '\n' == *(inwcp + 1)) { + strncpy(outstp, "
    ", 4); + outstp += 4; + inwcp++; /* needed so loop skips two wide characters */ + } + + /* TODO - strip all but allowed HTML tags out... */ + + else if('<' == *inwcp) { + + if(escape_html_tags == FALSE) { + wctomb_result = wctomb(mbtemp, *inwcp); + if((wctomb_result > 0) && + (((outstp - encoded_html_string) + wctomb_result) < output_max)) { + strncpy(outstp, mbtemp, wctomb_result); + outstp += wctomb_result; + } + } + else { + if(((outstp - encoded_html_string) + 4) < output_max) { + strncpy(outstp, "<", 4); + outstp += 4; + } + } + } + + else if('>' == *inwcp) { + + if(escape_html_tags == FALSE) { + wctomb_result = wctomb(mbtemp, *inwcp); + if((wctomb_result > 0) && + (((outstp - encoded_html_string) + wctomb_result) < output_max)) { + strncpy(outstp, mbtemp, wctomb_result); + outstp += wctomb_result; + } + } + else { + if(((outstp - encoded_html_string) + 4) < output_max) { + strncpy(outstp, ">", 4); + outstp += 4; + } + } + } + + /* When not escaping HTML tags, don't encode quotes or ampersands + (left and right carets are handled above */ + else if((escape_html_tags == FALSE) && ('"' == *inwcp || + '&' == *inwcp || '\'' == *inwcp)) { + wctomb_result = wctomb(mbtemp, *inwcp); + if((wctomb_result > 0) && + (((outstp - encoded_html_string) + wctomb_result) < output_max)) { + strncpy(outstp, mbtemp, wctomb_result); + outstp += wctomb_result; + } + } + + /* for simplicity, all other chars represented by their numeric value */ + else { + sprintf(temp_expansion, "&#%u;", *(unsigned int *)inwcp); + if(((outstp - encoded_html_string) + strlen(temp_expansion)) < + output_max) { + strncpy(outstp, temp_expansion, strlen(temp_expansion)); + outstp += strlen(temp_expansion); + } + } + } + + /* Null terminate the encoded string */ + *outstp = '\x0'; + encoded_html_string[ output_max - 1] = '\x0'; + + return encoded_html_string; + } + + + +/* strip > and < from string */ +void strip_html_brackets(char *buffer) { + register int x; + register int y; + register int z; + + if(buffer == NULL || buffer[0] == '\x0') + return; + + /* remove all occurances in string */ + z = (int)strlen(buffer); + for(x = 0, y = 0; x < z; x++) { + if(buffer[x] == '<' || buffer[x] == '>') + continue; + buffer[y++] = buffer[x]; + } + buffer[y++] = '\x0'; + + return; + } + + +/* escape string for html form usage */ +char *escape_string(char *input) { + int len; + int output_max; + wchar_t wctemp[1]; + size_t mbtowc_result; + char mbtemp[ 10]; + int wctomb_result; + char *stp; + char temp_expansion[10]; + + /* If they don't give us anything to do... */ + if(NULL == input) { + return ""; + } + + /* We need up to six times the space to do the conversion */ + len = (int)strlen(input); + output_max = len * 6; + if((stp = encoded_html_string = (char *)malloc(output_max + 1)) == NULL) + return ""; + + strcpy(encoded_html_string, ""); + + /* Get the first multibyte character in the input string */ + mbtowc_result = mbtowc(wctemp, input, MB_CUR_MAX); + + /* Process all characters until a null character is found */ + while(0 != mbtowc_result) { /* 0 indicates a null character was found */ + + if((size_t) - 2 == mbtowc_result) { + /* No complete multibyte character found - try at next memory + address */ + input++; + } + + else if(((size_t) - 1 == mbtowc_result) && (EILSEQ == errno)) { + /* Invalid multibyte character found - try at next memory address */ + input++; + } + + /* Alpha-numeric characters and a few other characters don't get + encoded */ + else if((*wctemp >= '0' && *wctemp <= '9') || + (*wctemp >= 'A' && *wctemp <= 'Z') || + (*wctemp >= 'a' && *wctemp <= 'z') || + ' ' == *wctemp || '-' == *wctemp || '.' == *wctemp || + '_' == *wctemp || ':' == *wctemp) { + wctomb_result = wctomb(mbtemp, wctemp[0]); + if((wctomb_result > 0) && + (((stp - encoded_html_string) + wctomb_result) < output_max)) { + strncpy(stp, mbtemp, wctomb_result); + stp += wctomb_result; + } + input += mbtowc_result; + } + + /* Encode everything else (this may be excessive) */ + else { + sprintf(temp_expansion, "&#%u;", (unsigned int)wctemp[ 0]); + if(((stp - encoded_html_string) + strlen(temp_expansion)) < + output_max) { + strncpy(stp, temp_expansion, strlen(temp_expansion)); + stp += strlen(temp_expansion); + } + input += mbtowc_result; + } + + /* Read the next character */ + mbtowc_result = mbtowc(wctemp, input, MB_CUR_MAX); + } + + /* Null terminate the encoded string */ + *stp = '\x0'; + encoded_html_string[ output_max - 1] = '\x0'; + + return encoded_html_string; + } + + +/* determines the log file we should use (from current time) */ +void get_log_archive_to_use(int archive, char *buffer, int buffer_length) { + struct tm *t; + + /* determine the time at which the log was rotated for this archive # */ + determine_log_rotation_times(archive); + + /* if we're not rotating the logs or if we want the current log, use the main one... */ + if(log_rotation_method == LOG_ROTATION_NONE || archive <= 0) { + strncpy(buffer, log_file, buffer_length); + buffer[buffer_length - 1] = '\x0'; + return; + } + + t = localtime(&this_scheduled_log_rotation); + + /* use the time that the log rotation occurred to figure out the name of the log file */ + snprintf(buffer, buffer_length, "%snagios-%02d-%02d-%d-%02d.log", log_archive_path, t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour); + buffer[buffer_length - 1] = '\x0'; + + return; + } + + + +/* determines log archive to use, given a specific time */ +int determine_archive_to_use_from_time(time_t target_time) { + time_t current_time; + int current_archive = 0; + + /* if log rotation is disabled, we don't have archives */ + if(log_rotation_method == LOG_ROTATION_NONE) + return 0; + + /* make sure target time is rational */ + current_time = time(NULL); + if(target_time >= current_time) + return 0; + + /* backtrack through archives to find the one we need for this time */ + /* start with archive of 1, subtract one when we find the right time period to compensate for current (non-rotated) log */ + for(current_archive = 1;; current_archive++) { + + /* determine time at which the log rotation occurred for this archive number */ + determine_log_rotation_times(current_archive); + + /* if the target time falls within the times encompassed by this archive, we have the right archive! */ + if(target_time >= this_scheduled_log_rotation) + return current_archive - 1; + } + + return 0; + } + + + +/* determines the log rotation times - past, present, future */ +void determine_log_rotation_times(int archive) { + struct tm *t; + int current_month; + int is_dst_now = FALSE; + time_t current_time; + + /* negative archive numbers don't make sense */ + /* if archive=0 (current log), this_scheduled_log_rotation time is set to next rotation time */ + if(archive < 0) + return; + + time(¤t_time); + t = localtime(¤t_time); + is_dst_now = (t->tm_isdst > 0) ? TRUE : FALSE; + t->tm_min = 0; + t->tm_sec = 0; + + + switch(log_rotation_method) { + + case LOG_ROTATION_HOURLY: + this_scheduled_log_rotation = mktime(t); + this_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - ((archive - 1) * 3600)); + last_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - 3600); + break; + + case LOG_ROTATION_DAILY: + t->tm_hour = 0; + this_scheduled_log_rotation = mktime(t); + this_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - ((archive - 1) * 86400)); + last_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - 86400); + break; + + case LOG_ROTATION_WEEKLY: + t->tm_hour = 0; + this_scheduled_log_rotation = mktime(t); + this_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - (86400 * t->tm_wday)); + this_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - ((archive - 1) * 604800)); + last_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - 604800); + break; + + case LOG_ROTATION_MONTHLY: + + t = localtime(¤t_time); + t->tm_mon++; + t->tm_mday = 1; + t->tm_hour = 0; + t->tm_min = 0; + t->tm_sec = 0; + for(current_month = 0; current_month <= archive; current_month++) { + if(t->tm_mon == 0) { + t->tm_mon = 11; + t->tm_year--; + } + else + t->tm_mon--; + } + last_scheduled_log_rotation = mktime(t); + + t = localtime(¤t_time); + t->tm_mon++; + t->tm_mday = 1; + t->tm_hour = 0; + t->tm_min = 0; + t->tm_sec = 0; + for(current_month = 0; current_month < archive; current_month++) { + if(t->tm_mon == 0) { + t->tm_mon = 11; + t->tm_year--; + } + else + t->tm_mon--; + } + this_scheduled_log_rotation = mktime(t); + + break; + default: + break; + } + + /* adjust this rotation time for daylight savings time */ + t = localtime(&this_scheduled_log_rotation); + if(t->tm_isdst > 0 && is_dst_now == FALSE) + this_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation - 3600); + else if(t->tm_isdst == 0 && is_dst_now == TRUE) + this_scheduled_log_rotation = (time_t)(this_scheduled_log_rotation + 3600); + + /* adjust last rotation time for daylight savings time */ + t = localtime(&last_scheduled_log_rotation); + if(t->tm_isdst > 0 && is_dst_now == FALSE) + last_scheduled_log_rotation = (time_t)(last_scheduled_log_rotation - 3600); + else if(t->tm_isdst == 0 && is_dst_now == TRUE) + last_scheduled_log_rotation = (time_t)(last_scheduled_log_rotation + 3600); + + return; + } + + + + +/********************************************************** + *************** COMMON HTML FUNCTIONS ******************** + **********************************************************/ + +void display_info_table(char *title, int refresh, authdata *current_authdata) { + time_t current_time; + char date_time[MAX_DATETIME_LENGTH]; + int result; + + /* read program status */ + result = read_all_status_data(get_cgi_config_location(), READ_PROGRAM_STATUS); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("
    %s
    \n", title); + + time(¤t_time); + get_time_string(¤t_time, date_time, (int)sizeof(date_time), LONG_DATE_TIME); + + printf("Last Updated: %s
    \n", date_time); + if(refresh == TRUE) + printf("Updated every %d seconds
    \n", refresh_rate); + + printf("Nagios® Core™ %s - www.nagios.org
    \n", PROGRAM_VERSION); + + if(current_authdata != NULL) + printf("Logged in as %s
    \n", (!strcmp(current_authdata->username, "")) ? "?" : current_authdata->username); + + if(nagios_process_state != STATE_OK) + printf("
    Warning: Monitoring process may not be running!
    Click here for more info.
    ", EXTINFO_CGI, DISPLAY_PROCESS_INFO); + + if(result == ERROR) + printf("
    Warning: Could not read program status information!
    "); + + else { + if(enable_notifications == FALSE) + printf("
    - Notifications are disabled
    "); + + if(execute_service_checks == FALSE) + printf("
    - Service checks are disabled
    "); + } + + printf("
    \n"); + + return; + } + + + +void display_nav_table(char *url, int archive) { + char date_time[MAX_DATETIME_LENGTH]; + char archive_file[MAX_INPUT_BUFFER]; + char *archive_basename; + + if(log_rotation_method != LOG_ROTATION_NONE) { + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + if(archive != 0) { + + printf("\n"); + } + else + printf("\n", url_images_path, EMPTY_ICON); + + printf("\n"); + + printf("\n"); + } + + /* get archive to use */ + get_log_archive_to_use(archive, archive_file, sizeof(archive_file) - 1); + + /* cut the pathname for security, and the remaining slash for clarity */ + archive_basename = (char *)&archive_file; + if(strrchr((char *)&archive_basename, '/') != NULL) + archive_basename = strrchr((char *)&archive_file, '/') + 1; + + /* now it's safe to print the filename */ + printf("
    \n", archive_basename); + + return; + } + + + +/* prints the additional notes or action url for a hostgroup (with macros substituted) */ +void print_extra_hostgroup_url(char *group_name, char *url) { + char input_buffer[MAX_INPUT_BUFFER] = ""; + char output_buffer[MAX_INPUT_BUFFER] = ""; + char *temp_buffer; + int in_macro = FALSE; + hostgroup *temp_hostgroup = NULL; + + if(group_name == NULL || url == NULL) + return; + + temp_hostgroup = find_hostgroup(group_name); + if(temp_hostgroup == NULL) { + printf("%s", url); + return; + } + + strncpy(input_buffer, url, sizeof(input_buffer) - 1); + input_buffer[sizeof(input_buffer) - 1] = '\x0'; + + for(temp_buffer = my_strtok(input_buffer, "$"); temp_buffer != NULL; temp_buffer = my_strtok(NULL, "$")) { + + if(in_macro == FALSE) { + if(strlen(output_buffer) + strlen(temp_buffer) < sizeof(output_buffer) - 1) { + strncat(output_buffer, temp_buffer, sizeof(output_buffer) - strlen(output_buffer) - 1); + output_buffer[sizeof(output_buffer) - 1] = '\x0'; + } + in_macro = TRUE; + } + else { + + if(strlen(output_buffer) + strlen(temp_buffer) < sizeof(output_buffer) - 1) { + + if(!strcmp(temp_buffer, "HOSTGROUPNAME")) + strncat(output_buffer, url_encode(temp_hostgroup->group_name), sizeof(output_buffer) - strlen(output_buffer) - 1); + } + + in_macro = FALSE; + } + } + + printf("%s", output_buffer); + + return; + } + + + +/* prints the additional notes or action url for a servicegroup (with macros substituted) */ +void print_extra_servicegroup_url(char *group_name, char *url) { + char input_buffer[MAX_INPUT_BUFFER] = ""; + char output_buffer[MAX_INPUT_BUFFER] = ""; + char *temp_buffer; + int in_macro = FALSE; + servicegroup *temp_servicegroup = NULL; + + if(group_name == NULL || url == NULL) + return; + + temp_servicegroup = find_servicegroup(group_name); + if(temp_servicegroup == NULL) { + printf("%s", url); + return; + } + + strncpy(input_buffer, url, sizeof(input_buffer) - 1); + input_buffer[sizeof(input_buffer) - 1] = '\x0'; + + for(temp_buffer = my_strtok(input_buffer, "$"); temp_buffer != NULL; temp_buffer = my_strtok(NULL, "$")) { + + if(in_macro == FALSE) { + if(strlen(output_buffer) + strlen(temp_buffer) < sizeof(output_buffer) - 1) { + strncat(output_buffer, temp_buffer, sizeof(output_buffer) - strlen(output_buffer) - 1); + output_buffer[sizeof(output_buffer) - 1] = '\x0'; + } + in_macro = TRUE; + } + else { + + if(strlen(output_buffer) + strlen(temp_buffer) < sizeof(output_buffer) - 1) { + + if(!strcmp(temp_buffer, "SERVICEGROUPNAME")) + strncat(output_buffer, url_encode(temp_servicegroup->group_name), sizeof(output_buffer) - strlen(output_buffer) - 1); + } + + in_macro = FALSE; + } + } + + printf("%s", output_buffer); + + return; + } + + + +/* include user-defined SSI footers or headers */ +void include_ssi_files(char *cgi_name, int type) { + char common_ssi_file[MAX_INPUT_BUFFER]; + char cgi_ssi_file[MAX_INPUT_BUFFER]; + char raw_cgi_name[MAX_INPUT_BUFFER]; + char *stripped_cgi_name; + int x; + + /* common header or footer */ + snprintf(common_ssi_file, sizeof(common_ssi_file) - 1, "%scommon-%s.ssi", physical_ssi_path, (type == SSI_HEADER) ? "header" : "footer"); + common_ssi_file[sizeof(common_ssi_file) - 1] = '\x0'; + + /* CGI-specific header or footer */ + strncpy(raw_cgi_name, cgi_name, sizeof(raw_cgi_name) - 1); + raw_cgi_name[sizeof(raw_cgi_name) - 1] = '\x0'; + stripped_cgi_name = strtok(raw_cgi_name, "."); + snprintf(cgi_ssi_file, sizeof(cgi_ssi_file) - 1, "%s%s-%s.ssi", physical_ssi_path, (stripped_cgi_name == NULL) ? "" : stripped_cgi_name, (type == SSI_HEADER) ? "header" : "footer"); + cgi_ssi_file[sizeof(cgi_ssi_file) - 1] = '\x0'; + + if(type == SSI_HEADER) { + printf("\n\n"); + include_ssi_file(common_ssi_file); + include_ssi_file(cgi_ssi_file); + } + else { + include_ssi_file(cgi_ssi_file); + include_ssi_file(common_ssi_file); + printf("\n\n"); + } + + return; + } + + + +/* include user-defined SSI footer or header */ +void include_ssi_file(char *filename) { + char buffer[MAX_INPUT_BUFFER]; + FILE *fp; + struct stat stat_result; + int call_return; + + /* if file is executable, we want to run it rather than print it */ + call_return = stat(filename, &stat_result); + + /* file is executable */ + if(call_return == 0 && (stat_result.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) { + + /* must flush output stream first so that output + from script shows up in correct place. Other choice + is to open program under pipe and copy the data from + the program to our output stream. + */ + fflush(stdout); + + /* ignore return status from system call. */ + call_return = system(filename); + + return; + } + + /* an error occurred trying to stat() the file */ + else if(call_return != 0) { + + /* Handle error conditions. Assume that standard posix error codes and errno are available. If not, comment this section out. */ + switch(errno) { + case ENOTDIR: /* - A component of the path is not a directory. */ + case ELOOP: /* Too many symbolic links encountered while traversing the path. */ + case EFAULT: /* Bad address. */ + case ENOMEM: /* Out of memory (i.e. kernel memory). */ + case ENAMETOOLONG: /* File name too long. */ + printf("
    A stat call returned %d while looking for the file %s.
    ", errno, filename); + return; + case EACCES: /* Permission denied. -- The file should be accessible by nagios. */ + printf("
    A stat call returned a permissions error(%d) while looking for the file %s.
    ", errno, filename); + return; + case ENOENT: /* A component of the path file_name does not exist, or the path is an empty string. Just return if the file doesn't exist. */ + return; + default: + return; + } + } + + fp = fopen(filename, "r"); + if(fp == NULL) + return; + + /* print all lines in the SSI file */ + while(fgets(buffer, (int)(sizeof(buffer) - 1), fp) != NULL) + printf("%s", buffer); + + fclose(fp); + + return; + } + + +/* displays an error if CGI config file could not be read */ +void cgi_config_file_error(char *config_file) { + + printf("

    Whoops!

    \n"); + + printf("

    Error: Could not open CGI config file '%s' for reading!

    \n", config_file); + + printf("

    \n"); + printf("Here are some things you should check in order to resolve this error:\n"); + printf("

    \n"); + + printf("

    \n"); + printf("

      \n"); + + printf("
    1. Make sure you've installed a CGI config file in its proper location. See the error message about for details on where the CGI is expecting to find the configuration file. A sample CGI configuration file (named cgi.cfg) can be found in the sample-config/ subdirectory of the Nagios source code distribution.\n"); + printf("
    2. Make sure the user your web server is running as has permission to read the CGI config file.\n"); + + printf("
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Make sure you read the documentation on installing and configuring Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); + printf("

    \n"); + + return; + } + + + +/* displays an error if main config file could not be read */ +void main_config_file_error(char *config_file) { + + printf("

    Whoops!

    \n"); + + printf("

    Error: Could not open main config file '%s' for reading!

    \n", config_file); + + printf("

    \n"); + printf("Here are some things you should check in order to resolve this error:\n"); + printf("

    \n"); + + printf("

    \n"); + printf("

      \n"); + + printf("
    1. Make sure you've installed a main config file in its proper location. See the error message about for details on where the CGI is expecting to find the configuration file. A sample main configuration file (named nagios.cfg) can be found in the sample-config/ subdirectory of the Nagios source code distribution.\n"); + printf("
    2. Make sure the user your web server is running as has permission to read the main config file.\n"); + + printf("
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Make sure you read the documentation on installing and configuring Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); + printf("

    \n"); + + return; + } + + +/* displays an error if object data could not be read */ +void object_data_error(void) { + + printf("

    Whoops!

    \n"); + + printf("

    Error: Could not read object configuration data!

    \n"); + + printf("

    \n"); + printf("Here are some things you should check in order to resolve this error:\n"); + printf("

    \n"); + + printf("

    \n"); + printf("

      \n"); + + printf("
    1. Verify configuration options using the -v command-line option to check for errors.\n"); + printf("
    2. Check the Nagios log file for messages relating to startup or status data errors.\n"); + + printf("
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Make sure you read the documentation on installing, configuring and running Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); + printf("

    \n"); + + return; + } + + +/* displays an error if status data could not be read */ +void status_data_error(void) { + + printf("

    Whoops!

    \n"); + + printf("

    Error: Could not read host and service status information!

    \n"); + + printf("

    \n"); + printf("The most common cause of this error message (especially for new users), is the fact that Nagios is not actually running. If Nagios is indeed not running, this is a normal error message. It simply indicates that the CGIs could not obtain the current status of hosts and services that are being monitored. If you've just installed things, make sure you read the documentation on starting Nagios.\n"); + printf("

    \n"); + + printf("

    \n"); + printf("Some other things you should check in order to resolve this error include:\n"); + printf("

    \n"); + + printf("

    \n"); + printf("

      \n"); + + printf("
    1. Check the Nagios log file for messages relating to startup or status data errors.\n"); + printf("
    2. Always verify configuration options using the -v command-line option before starting or restarting Nagios!\n"); + + printf("
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Make sure you read the documentation on installing, configuring and running Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); + printf("

    \n"); + + return; + } + + + + +/* displays context-sensitive help window */ +void display_context_help(char *chid) { + char *icon = CONTEXT_HELP_ICON1; + + if(show_context_help == FALSE) + return; + + /* change icon if necessary */ + if(!strcmp(chid, CONTEXTHELP_TAC)) + icon = CONTEXT_HELP_ICON2; + + printf("Display context-sensitive help for this screen\n", url_context_help_path, chid, url_context_help_path, chid, url_images_path, icon); + + return; + } + + + +void display_splunk_host_url(host *hst) { + + if(enable_splunk_integration == FALSE) + return; + if(hst == NULL) + return; + + printf("Splunk It\n", splunk_url, url_encode(hst->name), url_images_path, SPLUNK_SMALL_WHITE_ICON); + + return; + } + + + +void display_splunk_service_url(service *svc) { + + if(enable_splunk_integration == FALSE) + return; + if(svc == NULL) + return; + + printf("Splunk It\n", url_encode(svc->description), url_images_path, SPLUNK_SMALL_WHITE_ICON); + + return; + } + + + +void display_splunk_generic_url(char *buf, int icon) { + char *newbuf = NULL; + + if(enable_splunk_integration == FALSE) + return; + if(buf == NULL) + return; + + if((newbuf = (char *)strdup(buf)) == NULL) + return; + + strip_splunk_query_terms(newbuf); + + printf("", splunk_url, url_encode(newbuf)); + if(icon > 0) + printf("Splunk It", url_images_path, (icon == 1) ? SPLUNK_SMALL_WHITE_ICON : SPLUNK_SMALL_BLACK_ICON); + printf("\n"); + + free(newbuf); + + return; + } + + +/* strip quotes and from string */ +void strip_splunk_query_terms(char *buffer) { + register int x; + register int y; + register int z; + + if(buffer == NULL || buffer[0] == '\x0') + return; + + /* remove all occurances in string */ + z = (int)strlen(buffer); + for(x = 0, y = 0; x < z; x++) { + if(buffer[x] == '\'' || buffer[x] == '\"' || buffer[x] == ';' || buffer[x] == ':' || buffer[x] == ',' || buffer[x] == '-' || buffer[x] == '=') + buffer[y++] = ' '; + else + buffer[y++] = buffer[x]; + } + buffer[y++] = '\x0'; + + return; + } + + diff --git a/cgi/cmd.c b/cgi/cmd.c new file mode 100644 index 0000000..6fc2939 --- /dev/null +++ b/cgi/cmd.c @@ -0,0 +1,2822 @@ +/************************************************************************** + * + * CMD.C - Nagios Command CGI + * + * 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/objects.h" +#include "../include/comments.h" +#include "../include/downtime.h" + +#include "../include/cgiutils.h" +#include "../include/cgiauth.h" +#include "../include/getcgi.h" + +extern const char *extcmd_get_name(int id); + +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 command_file[MAX_FILENAME_LENGTH]; +extern char comment_file[MAX_FILENAME_LENGTH]; + +extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; + +extern int nagios_process_state; + +extern int check_external_commands; + +extern int use_authentication; + +extern int lock_author_names; + +extern scheduled_downtime *scheduled_downtime_list; +extern comment *comment_list; + +extern int date_format; + + +#define MAX_AUTHOR_LENGTH 64 +#define MAX_COMMENT_LENGTH 1024 + +#define HTML_CONTENT 0 +#define WML_CONTENT 1 + + +char *host_name = ""; +char *hostgroup_name = ""; +char *servicegroup_name = ""; +char *service_desc = ""; +char *comment_author = ""; +char *comment_data = ""; +char *start_time_string = ""; +char *end_time_string = ""; + +unsigned long comment_id = 0; +unsigned long downtime_id = 0; +int notification_delay = 0; +int schedule_delay = 0; +int persistent_comment = FALSE; +int sticky_ack = FALSE; +int send_notification = FALSE; +int force_check = FALSE; +int plugin_state = STATE_OK; +char plugin_output[MAX_INPUT_BUFFER] = ""; +char performance_data[MAX_INPUT_BUFFER] = ""; +time_t start_time = 0L; +time_t end_time = 0L; +int affect_host_and_services = FALSE; +int propagate_to_children = FALSE; +int fixed = FALSE; +unsigned long duration = 0L; +unsigned long triggered_by = 0L; +int child_options = 0; +int force_notification = 0; +int broadcast_notification = 0; + +int command_type = CMD_NONE; +int command_mode = CMDMODE_REQUEST; + +int content_type = HTML_CONTENT; + +int display_header = TRUE; + +authdata current_authdata; + +void show_command_help(int); +void request_command_data(int); +void commit_command_data(int); +int commit_command(int); +int write_command_to_file(char *); +void clean_comment_data(char *); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + +int string_to_time(char *, time_t *); + + + +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); + if(content_type == WML_CONTENT) + printf("

    Error: Could not open CGI config file!

    \n"); + else + 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); + if(content_type == WML_CONTENT) + printf("

    Error: Could not open main config file!

    \n"); + else + main_config_file_error(main_config_file); + document_footer(); + return ERROR; + } + + /* This requires the date_format parameter in the main config file */ + if(strcmp(start_time_string, "")) + string_to_time(start_time_string, &start_time); + + if(strcmp(end_time_string, "")) + string_to_time(end_time_string, &end_time); + + + /* read all object configuration data */ + result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA); + if(result == ERROR) { + document_header(FALSE); + if(content_type == WML_CONTENT) + printf("

    Error: Could not read object config data!

    \n"); + else + object_data_error(); + document_footer(); + return ERROR; + } + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* center column of the first row */ + printf("\n"); + + /* right column of the first row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + display_info_table("External Command Interface", FALSE, ¤t_authdata); + printf("\n"); + printf("\n"); + + /* display context-sensitive help */ + if(command_mode == CMDMODE_COMMIT) + display_context_help(CONTEXTHELP_CMD_COMMIT); + else + display_context_help(CONTEXTHELP_CMD_INPUT); + + printf("
    \n"); + } + + /* authorized_for_read_only should take priority */ + if(is_authorized_for_read_only(¤t_authdata) == TRUE) { + printf("

    It appears as though you do not have permission to submit the command you requested...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + document_footer(); + + /* free allocated memory */ + free_memory(); + free_object_data(); + + return OK; + } + + /* if no command was specified... */ + if(command_type == CMD_NONE) { + if(content_type == WML_CONTENT) + printf("

    Error: No command specified!

    \n"); + else + printf("

    Error: No command was specified

    \n"); + } + + /* if this is the first request for a command, present option */ + else if(command_mode == CMDMODE_REQUEST) + request_command_data(command_type); + + /* the user wants to commit the command */ + else if(command_mode == CMDMODE_COMMIT) + commit_command_data(command_type); + + document_footer(); + + /* free allocated memory */ + free_memory(); + free_object_data(); + + return OK; + } + + + +void document_header(int use_stylesheet) { + + if(content_type == WML_CONTENT) { + + printf("Content-type: text/vnd.wap.wml\r\n\r\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + } + + else { + + printf("Content-type: text/html\r\n\r\n"); + + printf("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("External Command Interface\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, COMMAND_CSS); + } + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(COMMAND_CGI, SSI_HEADER); + } + + return; + } + + +void document_footer(void) { + + if(content_type == WML_CONTENT) { + printf("\n"); + printf("\n"); + } + + else { + + /* include user SSI footer */ + include_ssi_files(COMMAND_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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 command type */ + else if(!strcmp(variables[x], "cmd_typ")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + command_type = atoi(variables[x]); + } + + /* we found the command mode */ + else if(!strcmp(variables[x], "cmd_mod")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + command_mode = atoi(variables[x]); + } + + /* we found the comment id */ + else if(!strcmp(variables[x], "com_id")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + comment_id = strtoul(variables[x], NULL, 10); + } + + /* we found the downtime id */ + else if(!strcmp(variables[x], "down_id")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + downtime_id = strtoul(variables[x], NULL, 10); + } + + /* we found the notification delay */ + else if(!strcmp(variables[x], "not_dly")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + notification_delay = atoi(variables[x]); + } + + /* we found the schedule delay */ + else if(!strcmp(variables[x], "sched_dly")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + schedule_delay = atoi(variables[x]); + } + + /* we found the comment author */ + else if(!strcmp(variables[x], "com_author")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((comment_author = (char *)strdup(variables[x])) == NULL) + comment_author = ""; + strip_html_brackets(comment_author); + } + + /* we found the comment data */ + else if(!strcmp(variables[x], "com_data")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((comment_data = (char *)strdup(variables[x])) == NULL) + comment_data = ""; + strip_html_brackets(comment_data); + } + + /* we found the host name */ + 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); + } + + /* we found the hostgroup name */ + else if(!strcmp(variables[x], "hostgroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((hostgroup_name = (char *)strdup(variables[x])) == NULL) + hostgroup_name = ""; + strip_html_brackets(hostgroup_name); + } + + /* we found the service name */ + else if(!strcmp(variables[x], "service")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((service_desc = (char *)strdup(variables[x])) == NULL) + service_desc = ""; + strip_html_brackets(service_desc); + } + + /* we found the servicegroup name */ + else if(!strcmp(variables[x], "servicegroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((servicegroup_name = (char *)strdup(variables[x])) == NULL) + servicegroup_name = ""; + strip_html_brackets(servicegroup_name); + } + + /* we got the persistence option for a comment */ + else if(!strcmp(variables[x], "persistent")) + persistent_comment = TRUE; + + /* we got the notification option for an acknowledgement */ + else if(!strcmp(variables[x], "send_notification")) + send_notification = TRUE; + + /* we got the acknowledgement type */ + else if(!strcmp(variables[x], "sticky_ack")) + sticky_ack = TRUE; + + /* we got the service check force option */ + else if(!strcmp(variables[x], "force_check")) + force_check = TRUE; + + /* we got the option to affect host and all its services */ + else if(!strcmp(variables[x], "ahas")) + affect_host_and_services = TRUE; + + /* we got the option to propagate to child hosts */ + else if(!strcmp(variables[x], "ptc")) + propagate_to_children = TRUE; + + /* we got the option for fixed downtime */ + else if(!strcmp(variables[x], "fixed")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + fixed = (atoi(variables[x]) > 0) ? TRUE : FALSE; + } + + /* we got the triggered by downtime option */ + else if(!strcmp(variables[x], "trigger")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + triggered_by = strtoul(variables[x], NULL, 10); + } + + /* we got the child options */ + else if(!strcmp(variables[x], "childoptions")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + child_options = atoi(variables[x]); + } + + /* we found the plugin output */ + else if(!strcmp(variables[x], "plugin_output")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + /* protect against buffer overflows */ + if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) { + error = TRUE; + break; + } + else + strcpy(plugin_output, variables[x]); + } + + /* we found the performance data */ + else if(!strcmp(variables[x], "performance_data")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + /* protect against buffer overflows */ + if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) { + error = TRUE; + break; + } + else + strcpy(performance_data, variables[x]); + } + + /* we found the plugin state */ + else if(!strcmp(variables[x], "plugin_state")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + plugin_state = atoi(variables[x]); + } + + /* we found the hour duration */ + else if(!strcmp(variables[x], "hours")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(atoi(variables[x]) < 0) { + error = TRUE; + break; + } + duration += (unsigned long)(atoi(variables[x]) * 3600); + } + + /* we found the minute duration */ + else if(!strcmp(variables[x], "minutes")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(atoi(variables[x]) < 0) { + error = TRUE; + break; + } + duration += (unsigned long)(atoi(variables[x]) * 60); + } + + /* we found the start time */ + else if(!strcmp(variables[x], "start_time")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + start_time_string = (char *)malloc(strlen(variables[x]) + 1); + if(start_time_string == NULL) + start_time_string = ""; + else + strcpy(start_time_string, variables[x]); + } + + /* we found the end time */ + else if(!strcmp(variables[x], "end_time")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + end_time_string = (char *)malloc(strlen(variables[x]) + 1); + if(end_time_string == NULL) + end_time_string = ""; + else + strcpy(end_time_string, variables[x]); + } + + /* we found the content type argument */ + else if(!strcmp(variables[x], "content")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + if(!strcmp(variables[x], "wml")) { + content_type = WML_CONTENT; + display_header = FALSE; + } + else + content_type = HTML_CONTENT; + } + + /* we found the forced notification option */ + else if(!strcmp(variables[x], "force_notification")) + force_notification = NOTIFICATION_OPTION_FORCED; + + /* we found the broadcast notification option */ + else if(!strcmp(variables[x], "broadcast_notification")) + broadcast_notification = NOTIFICATION_OPTION_BROADCAST; + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +void request_command_data(int cmd) { + time_t t; + char start_time[MAX_DATETIME_LENGTH]; + char buffer[MAX_INPUT_BUFFER]; + contact *temp_contact; + scheduled_downtime *temp_downtime; + + + /* get default name to use for comment author */ + temp_contact = find_contact(current_authdata.username); + if(temp_contact != NULL && temp_contact->alias != NULL) + comment_author = temp_contact->alias; + else + comment_author = current_authdata.username; + + + printf("

    You are requesting to "); + + switch(cmd) { + + case CMD_ADD_HOST_COMMENT: + case CMD_ADD_SVC_COMMENT: + printf("add a %s comment", (cmd == CMD_ADD_HOST_COMMENT) ? "host" : "service"); + break; + + case CMD_DEL_HOST_COMMENT: + case CMD_DEL_SVC_COMMENT: + printf("delete a %s comment", (cmd == CMD_DEL_HOST_COMMENT) ? "host" : "service"); + break; + + case CMD_DELAY_HOST_NOTIFICATION: + case CMD_DELAY_SVC_NOTIFICATION: + printf("delay a %s notification", (cmd == CMD_DELAY_HOST_NOTIFICATION) ? "host" : "service"); + break; + + case CMD_SCHEDULE_SVC_CHECK: + printf("schedule a service check"); + break; + + case CMD_ENABLE_SVC_CHECK: + case CMD_DISABLE_SVC_CHECK: + printf("%s active checks of a particular service", (cmd == CMD_ENABLE_SVC_CHECK) ? "enable" : "disable"); + break; + + case CMD_ENABLE_NOTIFICATIONS: + case CMD_DISABLE_NOTIFICATIONS: + printf("%s notifications", (cmd == CMD_ENABLE_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_SHUTDOWN_PROCESS: + case CMD_RESTART_PROCESS: + printf("%s the Nagios process", (cmd == CMD_SHUTDOWN_PROCESS) ? "shutdown" : "restart"); + break; + + case CMD_ENABLE_HOST_SVC_CHECKS: + case CMD_DISABLE_HOST_SVC_CHECKS: + printf("%s active checks of all services on a host", (cmd == CMD_ENABLE_HOST_SVC_CHECKS) ? "enable" : "disable"); + break; + + case CMD_SCHEDULE_HOST_SVC_CHECKS: + printf("schedule a check of all services for a host"); + break; + + case CMD_DEL_ALL_HOST_COMMENTS: + case CMD_DEL_ALL_SVC_COMMENTS: + printf("delete all comments for a %s", (cmd == CMD_DEL_ALL_HOST_COMMENTS) ? "host" : "service"); + break; + + case CMD_ENABLE_SVC_NOTIFICATIONS: + case CMD_DISABLE_SVC_NOTIFICATIONS: + printf("%s notifications for a service", (cmd == CMD_ENABLE_SVC_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOST_NOTIFICATIONS: + printf("%s notifications for a host", (cmd == CMD_ENABLE_HOST_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + printf("%s notifications for all hosts and services beyond a host", (cmd == CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + printf("%s notifications for all services on a host", (cmd == CMD_ENABLE_HOST_SVC_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ACKNOWLEDGE_HOST_PROBLEM: + case CMD_ACKNOWLEDGE_SVC_PROBLEM: + printf("acknowledge a %s problem", (cmd == CMD_ACKNOWLEDGE_HOST_PROBLEM) ? "host" : "service"); + break; + + case CMD_START_EXECUTING_SVC_CHECKS: + case CMD_STOP_EXECUTING_SVC_CHECKS: + printf("%s executing active service checks", (cmd == CMD_START_EXECUTING_SVC_CHECKS) ? "start" : "stop"); + break; + + case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: + printf("%s accepting passive service checks", (cmd == CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS) ? "start" : "stop"); + break; + + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + printf("%s accepting passive service checks for a particular service", (cmd == CMD_ENABLE_PASSIVE_SVC_CHECKS) ? "start" : "stop"); + break; + + case CMD_ENABLE_EVENT_HANDLERS: + case CMD_DISABLE_EVENT_HANDLERS: + printf("%s event handlers", (cmd == CMD_ENABLE_EVENT_HANDLERS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOST_EVENT_HANDLER: + case CMD_DISABLE_HOST_EVENT_HANDLER: + printf("%s the event handler for a particular host", (cmd == CMD_ENABLE_HOST_EVENT_HANDLER) ? "enable" : "disable"); + break; + + case CMD_ENABLE_SVC_EVENT_HANDLER: + case CMD_DISABLE_SVC_EVENT_HANDLER: + printf("%s the event handler for a particular service", (cmd == CMD_ENABLE_SVC_EVENT_HANDLER) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOST_CHECK: + case CMD_DISABLE_HOST_CHECK: + printf("%s active checks of a particular host", (cmd == CMD_ENABLE_HOST_CHECK) ? "enable" : "disable"); + break; + + case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: + case CMD_START_OBSESSING_OVER_SVC_CHECKS: + printf("%s obsessing over service checks", (cmd == CMD_STOP_OBSESSING_OVER_SVC_CHECKS) ? "stop" : "start"); + break; + + case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: + case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: + printf("remove a %s acknowledgement", (cmd == CMD_REMOVE_HOST_ACKNOWLEDGEMENT) ? "host" : "service"); + break; + + case CMD_SCHEDULE_HOST_DOWNTIME: + case CMD_SCHEDULE_SVC_DOWNTIME: + printf("schedule downtime for a particular %s", (cmd == CMD_SCHEDULE_HOST_DOWNTIME) ? "host" : "service"); + break; + + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + printf("schedule downtime for all services for a particular host"); + break; + + case CMD_PROCESS_HOST_CHECK_RESULT: + case CMD_PROCESS_SERVICE_CHECK_RESULT: + printf("submit a passive check result for a particular %s", (cmd == CMD_PROCESS_HOST_CHECK_RESULT) ? "host" : "service"); + break; + + case CMD_ENABLE_HOST_FLAP_DETECTION: + case CMD_DISABLE_HOST_FLAP_DETECTION: + printf("%s flap detection for a particular host", (cmd == CMD_ENABLE_HOST_FLAP_DETECTION) ? "enable" : "disable"); + break; + + case CMD_ENABLE_SVC_FLAP_DETECTION: + case CMD_DISABLE_SVC_FLAP_DETECTION: + printf("%s flap detection for a particular service", (cmd == CMD_ENABLE_SVC_FLAP_DETECTION) ? "enable" : "disable"); + break; + + case CMD_ENABLE_FLAP_DETECTION: + case CMD_DISABLE_FLAP_DETECTION: + printf("%s flap detection for hosts and services", (cmd == CMD_ENABLE_FLAP_DETECTION) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + printf("%s notifications for all services in a particular hostgroup", (cmd == CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + printf("%s notifications for all hosts in a particular hostgroup", (cmd == CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + printf("%s active checks of all services in a particular hostgroup", (cmd == CMD_ENABLE_HOSTGROUP_SVC_CHECKS) ? "enable" : "disable"); + break; + + case CMD_DEL_HOST_DOWNTIME: + case CMD_DEL_SVC_DOWNTIME: + printf("cancel scheduled downtime for a particular %s", (cmd == CMD_DEL_HOST_DOWNTIME) ? "host" : "service"); + break; + + case CMD_ENABLE_FAILURE_PREDICTION: + case CMD_DISABLE_FAILURE_PREDICTION: + printf("%s failure prediction for hosts and service", (cmd == CMD_ENABLE_FAILURE_PREDICTION) ? "enable" : "disable"); + break; + + case CMD_ENABLE_PERFORMANCE_DATA: + case CMD_DISABLE_PERFORMANCE_DATA: + printf("%s performance data processing for hosts and services", (cmd == CMD_ENABLE_PERFORMANCE_DATA) ? "enable" : "disable"); + break; + + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + printf("schedule downtime for all hosts in a particular hostgroup"); + break; + + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + printf("schedule downtime for all services in a particular hostgroup"); + break; + + case CMD_START_EXECUTING_HOST_CHECKS: + case CMD_STOP_EXECUTING_HOST_CHECKS: + printf("%s executing host checks", (cmd == CMD_START_EXECUTING_HOST_CHECKS) ? "start" : "stop"); + break; + + case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: + printf("%s accepting passive host checks", (cmd == CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS) ? "start" : "stop"); + break; + + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + printf("%s accepting passive checks for a particular host", (cmd == CMD_ENABLE_PASSIVE_HOST_CHECKS) ? "start" : "stop"); + break; + + case CMD_START_OBSESSING_OVER_HOST_CHECKS: + case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: + printf("%s obsessing over host checks", (cmd == CMD_START_OBSESSING_OVER_HOST_CHECKS) ? "start" : "stop"); + break; + + case CMD_SCHEDULE_HOST_CHECK: + printf("schedule a host check"); + break; + + case CMD_START_OBSESSING_OVER_SVC: + case CMD_STOP_OBSESSING_OVER_SVC: + printf("%s obsessing over a particular service", (cmd == CMD_START_OBSESSING_OVER_SVC) ? "start" : "stop"); + break; + + case CMD_START_OBSESSING_OVER_HOST: + case CMD_STOP_OBSESSING_OVER_HOST: + printf("%s obsessing over a particular host", (cmd == CMD_START_OBSESSING_OVER_HOST) ? "start" : "stop"); + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + printf("%s notifications for all services in a particular servicegroup", (cmd == CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + printf("%s notifications for all hosts in a particular servicegroup", (cmd == CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS) ? "enable" : "disable"); + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + printf("%s active checks of all services in a particular servicegroup", (cmd == CMD_ENABLE_SERVICEGROUP_SVC_CHECKS) ? "enable" : "disable"); + break; + + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + printf("schedule downtime for all hosts in a particular servicegroup"); + break; + + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + printf("schedule downtime for all services in a particular servicegroup"); + break; + + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + printf("send a custom %s notification", (cmd == CMD_SEND_CUSTOM_HOST_NOTIFICATION) ? "host" : "service"); + break; + + default: + printf("execute an unknown command. Shame on you!
    "); + return; + } + + printf("
  • \n"); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + + printf("
    Command Options
    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("
    \n", COMMAND_CGI); + printf("\n"); + + printf("\n", cmd, CMDMODE_COMMIT); + + switch(cmd) { + + case CMD_ADD_HOST_COMMENT: + case CMD_ACKNOWLEDGE_HOST_PROBLEM: + printf("\n"); + if(cmd == CMD_ACKNOWLEDGE_HOST_PROBLEM) { + printf("\n"); + printf("\n"); + } + printf("\n"); + printf("\n"); + printf("\n"); + break; + + case CMD_ADD_SVC_COMMENT: + case CMD_ACKNOWLEDGE_SVC_PROBLEM: + printf("\n"); + printf("\n"); + printf("\n"); + } + printf("\n"); + printf("\n"); + printf("\n"); + break; + + case CMD_DEL_HOST_COMMENT: + case CMD_DEL_SVC_COMMENT: + printf("\n"); + break; + + case CMD_DELAY_HOST_NOTIFICATION: + printf("\n"); + printf("\n"); + break; + + case CMD_DELAY_SVC_NOTIFICATION: + printf("\n"); + printf("\n"); + break; + + case CMD_SCHEDULE_SVC_CHECK: + case CMD_SCHEDULE_HOST_CHECK: + case CMD_SCHEDULE_HOST_SVC_CHECKS: + printf("\n"); + if(cmd == CMD_SCHEDULE_SVC_CHECK) { + printf("\n"); + } + time(&t); + get_time_string(&t, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME); + printf("\n"); + printf("\n"); + break; + + case CMD_ENABLE_SVC_CHECK: + case CMD_DISABLE_SVC_CHECK: + case CMD_DEL_ALL_SVC_COMMENTS: + case CMD_ENABLE_SVC_NOTIFICATIONS: + case CMD_DISABLE_SVC_NOTIFICATIONS: + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + case CMD_ENABLE_SVC_EVENT_HANDLER: + case CMD_DISABLE_SVC_EVENT_HANDLER: + case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: + case CMD_ENABLE_SVC_FLAP_DETECTION: + case CMD_DISABLE_SVC_FLAP_DETECTION: + case CMD_START_OBSESSING_OVER_SVC: + case CMD_STOP_OBSESSING_OVER_SVC: + printf("\n"); + printf("\n"); + break; + + case CMD_ENABLE_HOST_SVC_CHECKS: + case CMD_DISABLE_HOST_SVC_CHECKS: + case CMD_DEL_ALL_HOST_COMMENTS: + case CMD_ENABLE_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOST_NOTIFICATIONS: + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + case CMD_ENABLE_HOST_EVENT_HANDLER: + case CMD_DISABLE_HOST_EVENT_HANDLER: + case CMD_ENABLE_HOST_CHECK: + case CMD_DISABLE_HOST_CHECK: + case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: + case CMD_ENABLE_HOST_FLAP_DETECTION: + case CMD_DISABLE_HOST_FLAP_DETECTION: + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + case CMD_START_OBSESSING_OVER_HOST: + case CMD_STOP_OBSESSING_OVER_HOST: + printf("\n"); + if(cmd == CMD_ENABLE_HOST_SVC_CHECKS || cmd == CMD_DISABLE_HOST_SVC_CHECKS || cmd == CMD_ENABLE_HOST_SVC_NOTIFICATIONS || cmd == CMD_DISABLE_HOST_SVC_NOTIFICATIONS) { + printf("\n"); + } + if(cmd == CMD_ENABLE_HOST_NOTIFICATIONS || cmd == CMD_DISABLE_HOST_NOTIFICATIONS) { + printf("\n"); + } + break; + + case CMD_ENABLE_NOTIFICATIONS: + case CMD_DISABLE_NOTIFICATIONS: + case CMD_SHUTDOWN_PROCESS: + case CMD_RESTART_PROCESS: + case CMD_START_EXECUTING_SVC_CHECKS: + case CMD_STOP_EXECUTING_SVC_CHECKS: + case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_ENABLE_EVENT_HANDLERS: + case CMD_DISABLE_EVENT_HANDLERS: + case CMD_START_OBSESSING_OVER_SVC_CHECKS: + case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: + case CMD_ENABLE_FLAP_DETECTION: + case CMD_DISABLE_FLAP_DETECTION: + case CMD_ENABLE_FAILURE_PREDICTION: + case CMD_DISABLE_FAILURE_PREDICTION: + case CMD_ENABLE_PERFORMANCE_DATA: + case CMD_DISABLE_PERFORMANCE_DATA: + case CMD_START_EXECUTING_HOST_CHECKS: + case CMD_STOP_EXECUTING_HOST_CHECKS: + case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_START_OBSESSING_OVER_HOST_CHECKS: + case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: + printf(""); + break; + + case CMD_PROCESS_HOST_CHECK_RESULT: + case CMD_PROCESS_SERVICE_CHECK_RESULT: + printf("\n"); + if(cmd == CMD_PROCESS_SERVICE_CHECK_RESULT) { + printf("\n"); + } + printf("\n"); + printf("\n"); + printf("\n"); + break; + + case CMD_SCHEDULE_HOST_DOWNTIME: + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + case CMD_SCHEDULE_SVC_DOWNTIME: + + printf("\n"); + if(cmd == CMD_SCHEDULE_SVC_DOWNTIME) { + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + time(&t); + get_time_string(&t, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME); + printf("\n"); + t += (unsigned long)7200; + get_time_string(&t, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + if(cmd == CMD_SCHEDULE_HOST_DOWNTIME) { + printf("\n"); + } + + printf("\n"); + + break; + + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + printf("\n"); + if(cmd == CMD_ENABLE_HOSTGROUP_SVC_CHECKS || cmd == CMD_DISABLE_HOSTGROUP_SVC_CHECKS || cmd == CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS || cmd == CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS) { + printf("\n"); + } + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + printf("\n"); + if(cmd == CMD_ENABLE_SERVICEGROUP_SVC_CHECKS || cmd == CMD_DISABLE_SERVICEGROUP_SVC_CHECKS || cmd == CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS || cmd == CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS) { + printf("\n"); + } + break; + + case CMD_DEL_HOST_DOWNTIME: + case CMD_DEL_SVC_DOWNTIME: + printf("\n"); + break; + + + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + + if(cmd == CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) { + printf("\n"); + } + else { + printf("\n"); + } + printf("\n"); + printf("\n"); + time(&t); + get_time_string(&t, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME); + printf("\n"); + t += (unsigned long)7200; + get_time_string(&t, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME); + printf("\n"); + printf("\n"); + + printf("\n"); + if(cmd == CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME || cmd == CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) { + printf("\n"); + } + break; + + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + printf("\n"); + + if(cmd == CMD_SEND_CUSTOM_SVC_NOTIFICATION) { + printf("\n"); + } + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + break; + + default: + printf("\n"); + } + + + printf("\n"); + printf("\n"); + + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Sticky Acknowledgement:"); + printf(""); + printf("
    Send Notification:"); + printf(""); + printf("
    Persistent%s:", (cmd == CMD_ACKNOWLEDGE_HOST_PROBLEM) ? " Comment" : ""); + printf("", (cmd == CMD_ACKNOWLEDGE_HOST_PROBLEM) ? "" : "CHECKED"); + printf("
    Author (Your Name):"); + printf("", escape_string(comment_author), (lock_author_names == TRUE) ? "READONLY DISABLED" : ""); + printf("
    Comment:"); + printf("", escape_string(comment_data)); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + if(cmd == CMD_ACKNOWLEDGE_SVC_PROBLEM) { + printf("
    Sticky Acknowledgement:"); + printf(""); + printf("
    Send Notification:"); + printf(""); + printf("
    Persistent%s:", (cmd == CMD_ACKNOWLEDGE_SVC_PROBLEM) ? " Comment" : ""); + printf("", (cmd == CMD_ACKNOWLEDGE_SVC_PROBLEM) ? "" : "CHECKED"); + printf("
    Author (Your Name):"); + printf("", escape_string(comment_author), (lock_author_names == TRUE) ? "READONLY DISABLED" : ""); + printf("
    Comment:"); + printf("", escape_string(comment_data)); + printf("
    Comment ID:"); + printf("", comment_id); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Notification Delay (minutes from now):"); + printf("", notification_delay); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + printf("
    Notification Delay (minutes from now):"); + printf("", notification_delay); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + printf("
    Check Time:"); + printf("", buffer); + printf("
    Force Check:"); + printf("", (force_check == TRUE) ? "CHECKED" : ""); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    %s For Host Too:", (cmd == CMD_ENABLE_HOST_SVC_CHECKS || cmd == CMD_ENABLE_HOST_SVC_NOTIFICATIONS) ? "Enable" : "Disable"); + printf(""); + printf("
    %s Notifications For Child Hosts Too:", (cmd == CMD_ENABLE_HOST_NOTIFICATIONS) ? "Enable" : "Disable"); + printf(""); + printf("
    There are no options for this command.
    Click the 'Commit' button to submit the command.
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + printf("
    Check Result:"); + printf("\n"); + printf("
    Check Output:"); + printf(""); + printf("
    Performance Data:"); + printf(""); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + } + printf("
    Author (Your Name):"); + printf("", escape_string(comment_author), (lock_author_names == TRUE) ? "READONLY DISABLED" : ""); + printf("
    Comment:"); + printf("", escape_string(comment_data)); + printf("

    Triggered By:\n"); + printf("\n"); + printf("

    Start Time:"); + printf("", buffer); + printf("
    End Time:"); + printf("", buffer); + printf("
    Type:"); + printf("\n"); + printf("
    If Flexible, Duration:"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    HoursMinutes
    \n"); + printf("

    Child Hosts:"); + printf("\n"); + printf("

    Hostgroup Name:"); + printf("", escape_string(hostgroup_name)); + printf("
    %s For Hosts Too:", (cmd == CMD_ENABLE_HOSTGROUP_SVC_CHECKS || cmd == CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS) ? "Enable" : "Disable"); + printf(""); + printf("
    Servicegroup Name:"); + printf("", escape_string(servicegroup_name)); + printf("
    %s For Hosts Too:", (cmd == CMD_ENABLE_SERVICEGROUP_SVC_CHECKS || cmd == CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS) ? "Enable" : "Disable"); + printf(""); + printf("
    Scheduled Downtime ID:"); + printf("", downtime_id); + printf("
    Hostgroup Name:"); + printf("", escape_string(hostgroup_name)); + printf("
    Servicegroup Name:"); + printf("", escape_string(servicegroup_name)); + printf("
    Author (Your Name):"); + printf("", escape_string(comment_author), (lock_author_names == TRUE) ? "READONLY DISABLED" : ""); + printf("
    Comment:"); + printf("", escape_string(comment_data)); + printf("
    Start Time:"); + printf("", buffer); + printf("
    End Time:"); + printf("", buffer); + printf("
    Type:"); + printf("\n"); + printf("
    If Flexible, Duration:"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    HoursMinutes
    \n"); + printf("
    Schedule Downtime For Hosts Too:"); + printf(""); + printf("
    Host Name:"); + printf("", escape_string(host_name)); + printf("
    Service:"); + printf("", escape_string(service_desc)); + printf("
    Forced:"); + printf("
    Broadcast:"); + printf("
    Author (Your Name):"); + printf("", escape_string(comment_author), (lock_author_names == TRUE) ? "READONLY DISABLED" : ""); + printf("
    Comment:"); + printf("", escape_string(comment_data)); + printf("
    This should not be happening... :-(
    \n"); + printf("
    \n"); + printf("
    \n"); + + printf("
    \n"); + + /* show information about the command... */ + show_command_help(cmd); + + printf("
    \n"); + + printf("
    \n"); + printf("

    \n"); + + printf("

    Please enter all required information before committing the command.
    Required fields are marked in red.
    Failure to supply all required values will result in an error.

    "); + + return; + } + + +void commit_command_data(int cmd) { + char *error_string = NULL; + int result = OK; + int authorized = FALSE; + service *temp_service; + host *temp_host; + hostgroup *temp_hostgroup; + comment *temp_comment; + scheduled_downtime *temp_downtime; + servicegroup *temp_servicegroup = NULL; + contact *temp_contact = NULL; + + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + /* get name to use for author */ + if(lock_author_names == TRUE) { + temp_contact = find_contact(current_authdata.username); + if(temp_contact != NULL && temp_contact->alias != NULL) + comment_author = temp_contact->alias; + else + comment_author = current_authdata.username; + } + + switch(cmd) { + case CMD_ADD_HOST_COMMENT: + case CMD_ACKNOWLEDGE_HOST_PROBLEM: + + /* make sure we have author name, and comment data... */ + if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + + /* clean up the comment data */ + clean_comment_data(comment_author); + clean_comment_data(comment_data); + + /* see if the user is authorized to issue a command... */ + temp_host = find_host(host_name); + if(is_authorized_for_host_commands(temp_host, ¤t_authdata) == TRUE) + authorized = TRUE; + break; + + case CMD_ADD_SVC_COMMENT: + case CMD_ACKNOWLEDGE_SVC_PROBLEM: + + /* make sure we have author name, and comment data... */ + if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + + /* clean up the comment data */ + clean_comment_data(comment_author); + clean_comment_data(comment_data); + + /* see if the user is authorized to issue a command... */ + temp_service = find_service(host_name, service_desc); + if(is_authorized_for_service_commands(temp_service, ¤t_authdata) == TRUE) + authorized = TRUE; + break; + + case CMD_DEL_HOST_COMMENT: + case CMD_DEL_SVC_COMMENT: + + /* check the sanity of the comment id */ + if(comment_id == 0) { + if(!error_string) + error_string = strdup("Comment id cannot be 0"); + } + + /* find the comment */ + if(cmd == CMD_DEL_HOST_COMMENT) + temp_comment = find_host_comment(comment_id); + else + temp_comment = find_service_comment(comment_id); + + /* see if the user is authorized to issue a command... */ + if(cmd == CMD_DEL_HOST_COMMENT && temp_comment != NULL) { + temp_host = find_host(temp_comment->host_name); + if(is_authorized_for_host_commands(temp_host, ¤t_authdata) == TRUE) + authorized = TRUE; + } + if(cmd == CMD_DEL_SVC_COMMENT && temp_comment != NULL) { + temp_service = find_service(temp_comment->host_name, temp_comment->service_description); + if(is_authorized_for_service_commands(temp_service, ¤t_authdata) == TRUE) + authorized = TRUE; + } + + /* free comment data */ + free_comment_data(); + + break; + + case CMD_DEL_HOST_DOWNTIME: + case CMD_DEL_SVC_DOWNTIME: + + /* check the sanity of the downtime id */ + if(downtime_id == 0) { + if(!error_string) + error_string = strdup("Downtime id cannot be 0"); + } + + /* find the downtime entry */ + if(cmd == CMD_DEL_HOST_DOWNTIME) + temp_downtime = find_host_downtime(downtime_id); + else + temp_downtime = find_service_downtime(downtime_id); + + /* see if the user is authorized to issue a command... */ + if(cmd == CMD_DEL_HOST_DOWNTIME && temp_downtime != NULL) { + temp_host = find_host(temp_downtime->host_name); + if(is_authorized_for_host_commands(temp_host, ¤t_authdata) == TRUE) + authorized = TRUE; + } + if(cmd == CMD_DEL_SVC_DOWNTIME && temp_downtime != NULL) { + temp_service = find_service(temp_downtime->host_name, temp_downtime->service_description); + if(is_authorized_for_service_commands(temp_service, ¤t_authdata) == TRUE) + authorized = TRUE; + } + + /* free downtime data */ + free_downtime_data(); + + break; + + case CMD_SCHEDULE_SVC_CHECK: + case CMD_ENABLE_SVC_CHECK: + case CMD_DISABLE_SVC_CHECK: + case CMD_DEL_ALL_SVC_COMMENTS: + case CMD_ENABLE_SVC_NOTIFICATIONS: + case CMD_DISABLE_SVC_NOTIFICATIONS: + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + case CMD_ENABLE_SVC_EVENT_HANDLER: + case CMD_DISABLE_SVC_EVENT_HANDLER: + case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: + case CMD_PROCESS_SERVICE_CHECK_RESULT: + case CMD_SCHEDULE_SVC_DOWNTIME: + case CMD_DELAY_SVC_NOTIFICATION: + case CMD_ENABLE_SVC_FLAP_DETECTION: + case CMD_DISABLE_SVC_FLAP_DETECTION: + case CMD_START_OBSESSING_OVER_SVC: + case CMD_STOP_OBSESSING_OVER_SVC: + + /* make sure we have author name and comment data... */ + if(cmd == CMD_SCHEDULE_SVC_DOWNTIME) { + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + else if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + } + + /* see if the user is authorized to issue a command... */ + temp_service = find_service(host_name, service_desc); + if(is_authorized_for_service_commands(temp_service, ¤t_authdata) == TRUE) + authorized = TRUE; + + /* make sure we have passive check info (if necessary) */ + if(cmd == CMD_PROCESS_SERVICE_CHECK_RESULT && !strcmp(plugin_output, "")) { + if(!error_string) + error_string = strdup("Plugin output cannot be blank"); + } + + /* make sure we have a notification delay (if necessary) */ + if(cmd == CMD_DELAY_SVC_NOTIFICATION && notification_delay <= 0) { + if(!error_string) + error_string = strdup("Notification delay must be greater than 0"); + } + + /* clean up the comment data if scheduling downtime */ + if(cmd == CMD_SCHEDULE_SVC_DOWNTIME) { + clean_comment_data(comment_author); + clean_comment_data(comment_data); + } + + /* make sure we have check time (if necessary) */ + if(cmd == CMD_SCHEDULE_SVC_CHECK && start_time == (time_t)0) { + if(!error_string) + error_string = strdup("Start time must be non-zero or bad format has been submitted."); + } + + /* make sure we have start/end times for downtime (if necessary) */ + if(cmd == CMD_SCHEDULE_SVC_DOWNTIME && (start_time == (time_t)0 || end_time == (time_t)0 || end_time < start_time)) { + if(!error_string) + error_string = strdup("Start or end time not valid"); + } + + break; + + case CMD_ENABLE_NOTIFICATIONS: + case CMD_DISABLE_NOTIFICATIONS: + case CMD_SHUTDOWN_PROCESS: + case CMD_RESTART_PROCESS: + case CMD_START_EXECUTING_SVC_CHECKS: + case CMD_STOP_EXECUTING_SVC_CHECKS: + case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_ENABLE_EVENT_HANDLERS: + case CMD_DISABLE_EVENT_HANDLERS: + case CMD_START_OBSESSING_OVER_SVC_CHECKS: + case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: + case CMD_ENABLE_FLAP_DETECTION: + case CMD_DISABLE_FLAP_DETECTION: + case CMD_ENABLE_FAILURE_PREDICTION: + case CMD_DISABLE_FAILURE_PREDICTION: + case CMD_ENABLE_PERFORMANCE_DATA: + case CMD_DISABLE_PERFORMANCE_DATA: + case CMD_START_EXECUTING_HOST_CHECKS: + case CMD_STOP_EXECUTING_HOST_CHECKS: + case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_START_OBSESSING_OVER_HOST_CHECKS: + case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: + + /* see if the user is authorized to issue a command... */ + if(is_authorized_for_system_commands(¤t_authdata) == TRUE) + authorized = TRUE; + break; + + case CMD_ENABLE_HOST_SVC_CHECKS: + case CMD_DISABLE_HOST_SVC_CHECKS: + case CMD_DEL_ALL_HOST_COMMENTS: + case CMD_SCHEDULE_HOST_SVC_CHECKS: + case CMD_ENABLE_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOST_NOTIFICATIONS: + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + case CMD_ENABLE_HOST_EVENT_HANDLER: + case CMD_DISABLE_HOST_EVENT_HANDLER: + case CMD_ENABLE_HOST_CHECK: + case CMD_DISABLE_HOST_CHECK: + case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: + case CMD_SCHEDULE_HOST_DOWNTIME: + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + case CMD_DELAY_HOST_NOTIFICATION: + case CMD_ENABLE_HOST_FLAP_DETECTION: + case CMD_DISABLE_HOST_FLAP_DETECTION: + case CMD_PROCESS_HOST_CHECK_RESULT: + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + case CMD_SCHEDULE_HOST_CHECK: + case CMD_START_OBSESSING_OVER_HOST: + case CMD_STOP_OBSESSING_OVER_HOST: + + /* make sure we have author name and comment data... */ + if(cmd == CMD_SCHEDULE_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOST_SVC_DOWNTIME) { + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + else if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + } + + /* see if the user is authorized to issue a command... */ + temp_host = find_host(host_name); + if(is_authorized_for_host_commands(temp_host, ¤t_authdata) == TRUE) + authorized = TRUE; + + /* clean up the comment data if scheduling downtime */ + if(cmd == CMD_SCHEDULE_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOST_SVC_DOWNTIME) { + clean_comment_data(comment_author); + clean_comment_data(comment_data); + } + + /* make sure we have a notification delay (if necessary) */ + if(cmd == CMD_DELAY_HOST_NOTIFICATION && notification_delay <= 0) { + if(!error_string) + error_string = strdup("Notification delay must be greater than 0"); + } + + /* make sure we have start/end times for downtime (if necessary) */ + if((cmd == CMD_SCHEDULE_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOST_SVC_DOWNTIME) && (start_time == (time_t)0 || end_time == (time_t)0 || start_time > end_time)) { + if(!error_string) + error_string = strdup("Start or end time not valid"); + } + + /* make sure we have check time (if necessary) */ + if((cmd == CMD_SCHEDULE_HOST_CHECK || cmd == CMD_SCHEDULE_HOST_SVC_CHECKS) && start_time == (time_t)0) { + if(!error_string) + error_string = strdup("Start time must be non-zero or bad format has been submitted."); + } + + /* make sure we have passive check info (if necessary) */ + if(cmd == CMD_PROCESS_HOST_CHECK_RESULT && !strcmp(plugin_output, "")) { + if(!error_string) + error_string = strdup("Plugin output cannot be blank"); + } + + break; + + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + + /* make sure we have author and comment data */ + if(cmd == CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) { + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + else if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + } + + /* make sure we have start/end times for downtime */ + if((cmd == CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) && (start_time == (time_t)0 || end_time == (time_t)0 || start_time > end_time)) { + if(!error_string) + error_string = strdup("Start or end time not valid"); + } + + /* see if the user is authorized to issue a command... */ + temp_hostgroup = find_hostgroup(hostgroup_name); + if(is_authorized_for_hostgroup_commands(temp_hostgroup, ¤t_authdata) == TRUE) + authorized = TRUE; + + /* clean up the comment data if scheduling downtime */ + if(cmd == CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) { + clean_comment_data(comment_author); + clean_comment_data(comment_data); + } + + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + + /* make sure we have author and comment data */ + if(cmd == CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) { + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + else if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + } + + /* make sure we have start/end times for downtime */ + if((cmd == CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd == CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) && (start_time == (time_t)0 || end_time == (time_t)0 || start_time > end_time)) { + if(!error_string) + error_string = strdup("Start or end time not valid"); + } + + /* see if the user is authorized to issue a command... */ + + temp_servicegroup = find_servicegroup(servicegroup_name); + if(is_authorized_for_servicegroup_commands(temp_servicegroup, ¤t_authdata) == TRUE) + authorized = TRUE; + + break; + + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + + /* make sure we have author and comment data */ + if(!strcmp(comment_data, "")) { + if(!error_string) + error_string = strdup("Comment was not entered"); + } + else if(!strcmp(comment_author, "")) { + if(!error_string) + error_string = strdup("Author was not entered"); + } + + /* see if the user is authorized to issue a command... */ + if(cmd == CMD_SEND_CUSTOM_HOST_NOTIFICATION) { + temp_host = find_host(host_name); + if(is_authorized_for_host_commands(temp_host, ¤t_authdata) == TRUE) + authorized = TRUE; + } + else { + temp_service = find_service(host_name, service_desc); + if(is_authorized_for_service_commands(temp_service, ¤t_authdata) == TRUE) + authorized = TRUE; + } + break; + + default: + if(!error_string) error_string = strdup("An error occurred while processing your command!"); + } + + + /* to be safe, we are going to REQUIRE that the authentication functionality is enabled... */ + if(use_authentication == FALSE) { + if(content_type == WML_CONTENT) + printf("

    Error: Authentication is not enabled!

    \n"); + else { + printf("

    \n"); + printf("

    Sorry Dave, I can't let you do that...

    "); + printf("
    "); + printf("It seems that you have chosen to not use the authentication functionality of the CGIs.

    "); + printf("I don't want to be personally responsible for what may happen as a result of allowing unauthorized users to issue commands to Nagios,"); + printf("so you'll have to disable this safeguard if you are really stubborn and want to invite trouble.

    "); + printf("Read the section on CGI authentication in the HTML documentation to learn how you can enable authentication and why you should want to.\n"); + printf("
    \n"); + printf("

    \n"); + } + } + + /* the user is not authorized to issue the given command */ + else if(authorized == FALSE) { + if(content_type == WML_CONTENT) + printf("

    Error: You're not authorized to commit that command!

    \n"); + else { + printf("

    Sorry, but you are not authorized to commit the specified command.

    \n"); + printf("

    Read the section of the documentation that deals with authentication and authorization in the CGIs for more information.

    \n"); + printf("Return from whence you came

    \n"); + } + } + + /* some error occurred (data was probably missing) */ + else if(error_string) { + if(content_type == WML_CONTENT) + printf("

    %s

    \n", error_string); + else { + printf("

    %s

    \n", error_string); + free(error_string); + printf("

    Go back and verify that you entered all required information correctly.
    \n"); + printf("Return from whence you came

    \n"); + } + } + + /* if Nagios isn't checking external commands, don't do anything... */ + else if(check_external_commands == FALSE) { + if(content_type == WML_CONTENT) + printf("

    Error: Nagios is not checking external commands!

    \n"); + else { + printf("

    Sorry, but Nagios is currently not checking for external commands, so your command will not be committed!

    \n"); + printf("

    Read the documentation for information on how to enable external commands...

    \n"); + printf("Return from whence you came

    \n"); + } + } + + /* everything looks okay, so let's go ahead and commit the command... */ + else { + + /* commit the command */ + result = commit_command(cmd); + + if(result == OK) { + if(content_type == WML_CONTENT) + printf("

    Your command was submitted sucessfully...

    \n"); + else { + printf("

    Your command request was successfully submitted to Nagios for processing.

    \n"); + printf("Note: It may take a while before the command is actually processed.

    \n"); + printf("Done

    "); + } + } + else { + if(content_type == WML_CONTENT) + printf("

    An error occurred while committing your command!

    \n"); + else { + printf("

    An error occurred while attempting to commit your command for processing.

    \n"); + printf("Return from whence you came

    \n"); + } + } + } + + return; + } + +__attribute__((format(printf, 2, 3))) +static int cmd_submitf(int id, const char *fmt, ...) { + char cmd[MAX_EXTERNAL_COMMAND_LENGTH]; + const char *command; + int len, len2; + va_list ap; + + command = extcmd_get_name(id); + /* + * We disallow sending 'CHANGE' commands from the cgi's + * until we do proper session handling to prevent cross-site + * request forgery + */ + if(!command || (strlen(command) > 6 && !memcmp("CHANGE", command, 6))) + return ERROR; + + len = snprintf(cmd, sizeof(cmd) - 1, "[%lu] %s;", time(NULL), command); + if(len < 0) + return ERROR; + + if(fmt) { + va_start(ap, fmt); + len2 = vsnprintf(&cmd[len], sizeof(cmd) - len - 1, fmt, ap); + va_end(ap); + if(len2 < 0) + return ERROR; + } + + return write_command_to_file(cmd); + } + + + +/* commits a command for processing */ +int commit_command(int cmd) { + time_t current_time; + time_t scheduled_time; + time_t notification_time; + int result; + + /* get the current time */ + time(¤t_time); + + /* get the scheduled time */ + scheduled_time = current_time + (schedule_delay * 60); + + /* get the notification time */ + notification_time = current_time + (notification_delay * 60); + + /* + * these are supposed to be implanted inside the + * completed commands shipped off to nagios and + * must therefore never contain ';' + */ + if(host_name && strchr(host_name, ';')) + return ERROR; + if(service_desc && strchr(service_desc, ';')) + return ERROR; + if(comment_author && strchr(comment_author, ';')) + return ERROR; + if(hostgroup_name && strchr(hostgroup_name, ';')) + return ERROR; + if(servicegroup_name && strchr(servicegroup_name, ';')) + return ERROR; + + /* decide how to form the command line... */ + switch(cmd) { + + /* commands without arguments */ + case CMD_START_EXECUTING_SVC_CHECKS: + case CMD_STOP_EXECUTING_SVC_CHECKS: + case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: + case CMD_ENABLE_EVENT_HANDLERS: + case CMD_DISABLE_EVENT_HANDLERS: + case CMD_START_OBSESSING_OVER_SVC_CHECKS: + case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: + case CMD_ENABLE_FLAP_DETECTION: + case CMD_DISABLE_FLAP_DETECTION: + case CMD_ENABLE_FAILURE_PREDICTION: + case CMD_DISABLE_FAILURE_PREDICTION: + case CMD_ENABLE_PERFORMANCE_DATA: + case CMD_DISABLE_PERFORMANCE_DATA: + case CMD_START_EXECUTING_HOST_CHECKS: + case CMD_STOP_EXECUTING_HOST_CHECKS: + case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: + case CMD_START_OBSESSING_OVER_HOST_CHECKS: + case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: + result = cmd_submitf(cmd, NULL); + break; + + /** simple host commands **/ + case CMD_ENABLE_HOST_FLAP_DETECTION: + case CMD_DISABLE_HOST_FLAP_DETECTION: + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + case CMD_START_OBSESSING_OVER_HOST: + case CMD_STOP_OBSESSING_OVER_HOST: + case CMD_DEL_ALL_HOST_COMMENTS: + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + case CMD_ENABLE_HOST_EVENT_HANDLER: + case CMD_DISABLE_HOST_EVENT_HANDLER: + case CMD_ENABLE_HOST_CHECK: + case CMD_DISABLE_HOST_CHECK: + case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: + result = cmd_submitf(cmd, "%s", host_name); + break; + + /** simple service commands **/ + case CMD_ENABLE_SVC_FLAP_DETECTION: + case CMD_DISABLE_SVC_FLAP_DETECTION: + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + case CMD_START_OBSESSING_OVER_SVC: + case CMD_STOP_OBSESSING_OVER_SVC: + case CMD_DEL_ALL_SVC_COMMENTS: + case CMD_ENABLE_SVC_NOTIFICATIONS: + case CMD_DISABLE_SVC_NOTIFICATIONS: + case CMD_ENABLE_SVC_EVENT_HANDLER: + case CMD_DISABLE_SVC_EVENT_HANDLER: + case CMD_ENABLE_SVC_CHECK: + case CMD_DISABLE_SVC_CHECK: + case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: + result = cmd_submitf(cmd, "%s;%s", host_name, service_desc); + break; + + case CMD_ADD_HOST_COMMENT: + result = cmd_submitf(cmd, "%s;%d;%s;%s", host_name, persistent_comment, comment_author, comment_data); + break; + + case CMD_ADD_SVC_COMMENT: + result = cmd_submitf(cmd, "%s;%s;%d;%s;%s", host_name, service_desc, persistent_comment, comment_author, comment_data); + break; + + case CMD_DEL_HOST_COMMENT: + case CMD_DEL_SVC_COMMENT: + result = cmd_submitf(cmd, "%lu", comment_id); + break; + + case CMD_DELAY_HOST_NOTIFICATION: + result = cmd_submitf(cmd, "%s;%lu", host_name, notification_time); + break; + + case CMD_DELAY_SVC_NOTIFICATION: + result = cmd_submitf(cmd, "%s;%s;%lu", host_name, service_desc, notification_time); + break; + + case CMD_SCHEDULE_SVC_CHECK: + case CMD_SCHEDULE_FORCED_SVC_CHECK: + if(force_check == TRUE) + cmd = CMD_SCHEDULE_FORCED_SVC_CHECK; + result = cmd_submitf(cmd, "%s;%s;%lu", host_name, service_desc, start_time); + break; + + case CMD_DISABLE_NOTIFICATIONS: + case CMD_ENABLE_NOTIFICATIONS: + case CMD_SHUTDOWN_PROCESS: + case CMD_RESTART_PROCESS: + result = cmd_submitf(cmd, "%lu", scheduled_time); + break; + + case CMD_ENABLE_HOST_SVC_CHECKS: + case CMD_DISABLE_HOST_SVC_CHECKS: + result = cmd_submitf(cmd, "%s", host_name); + if(affect_host_and_services == TRUE) { + cmd = (cmd == CMD_ENABLE_HOST_SVC_CHECKS) ? CMD_ENABLE_HOST_CHECK : CMD_DISABLE_HOST_CHECK; + result |= cmd_submitf(cmd, "%s", host_name); + } + break; + + case CMD_SCHEDULE_HOST_SVC_CHECKS: + if(force_check == TRUE) + cmd = CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS; + result = cmd_submitf(cmd, "%s;%lu", host_name, scheduled_time); + break; + + case CMD_ENABLE_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOST_NOTIFICATIONS: + if(propagate_to_children == TRUE) + cmd = (cmd == CMD_ENABLE_HOST_NOTIFICATIONS) ? CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS : CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS; + result = cmd_submitf(cmd, "%s", host_name); + break; + + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + result = cmd_submitf(cmd, "%s", host_name); + if(affect_host_and_services == TRUE) { + cmd = (cmd == CMD_ENABLE_HOST_SVC_NOTIFICATIONS) ? CMD_ENABLE_HOST_NOTIFICATIONS : CMD_DISABLE_HOST_NOTIFICATIONS; + result |= cmd_submitf(cmd, "%s", host_name); + } + break; + + case CMD_ACKNOWLEDGE_HOST_PROBLEM: + result = cmd_submitf(cmd, "%s;%d;%d;%d;%s;%s", host_name, (sticky_ack == TRUE) ? ACKNOWLEDGEMENT_STICKY : ACKNOWLEDGEMENT_NORMAL, send_notification, persistent_comment, comment_author, comment_data); + break; + + case CMD_ACKNOWLEDGE_SVC_PROBLEM: + result = cmd_submitf(cmd, "%s;%s;%d;%d;%d;%s;%s", host_name, service_desc, (sticky_ack == TRUE) ? ACKNOWLEDGEMENT_STICKY : ACKNOWLEDGEMENT_NORMAL, send_notification, persistent_comment, comment_author, comment_data); + break; + + case CMD_PROCESS_SERVICE_CHECK_RESULT: + result = cmd_submitf(cmd, "%s;%s;%d;%s|%s", host_name, service_desc, plugin_state, plugin_output, performance_data); + break; + + case CMD_PROCESS_HOST_CHECK_RESULT: + result = cmd_submitf(cmd, "%s;%d;%s|%s", host_name, plugin_state, plugin_output, performance_data); + break; + + case CMD_SCHEDULE_HOST_DOWNTIME: + if(child_options == 1) + cmd = CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME; + else if(child_options == 2) + cmd = CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME; + + result = cmd_submitf(cmd, "%s;%lu;%lu;%d;%lu;%lu;%s;%s", host_name, start_time, end_time, fixed, triggered_by, duration, comment_author, comment_data); + break; + + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + result = cmd_submitf(cmd, "%s;%lu;%lu;%d;%lu;%lu;%s;%s", host_name, start_time, end_time, fixed, triggered_by, duration, comment_author, comment_data); + break; + + case CMD_SCHEDULE_SVC_DOWNTIME: + result = cmd_submitf(cmd, "%s;%s;%lu;%lu;%d;%lu;%lu;%s;%s", host_name, service_desc, start_time, end_time, fixed, triggered_by, duration, comment_author, comment_data); + break; + + case CMD_DEL_HOST_DOWNTIME: + case CMD_DEL_SVC_DOWNTIME: + result = cmd_submitf(cmd, "%lu", downtime_id); + break; + + case CMD_SCHEDULE_HOST_CHECK: + if(force_check == TRUE) + cmd = CMD_SCHEDULE_FORCED_HOST_CHECK; + result = cmd_submitf(cmd, "%s;%lu", host_name, start_time); + break; + + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + result = cmd_submitf(cmd, "%s;%d;%s;%s", host_name, (force_notification | broadcast_notification), comment_author, comment_data); + break; + + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + result = cmd_submitf(cmd, "%s;%s;%d;%s;%s", host_name, service_desc, (force_notification | broadcast_notification), comment_author, comment_data); + break; + + + /***** HOSTGROUP COMMANDS *****/ + + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + result = cmd_submitf(cmd, "%s", hostgroup_name); + if(affect_host_and_services == TRUE) { + cmd = (cmd == CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS) ? CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS : CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS; + result |= cmd_submitf(cmd, "%s", hostgroup_name); + } + break; + + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + result = cmd_submitf(cmd, "%s", hostgroup_name); + break; + + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + result = cmd_submitf(cmd, "%s", hostgroup_name); + if(affect_host_and_services == TRUE) { + cmd = (cmd == CMD_ENABLE_HOSTGROUP_SVC_CHECKS) ? CMD_ENABLE_HOSTGROUP_HOST_CHECKS : CMD_DISABLE_HOSTGROUP_HOST_CHECKS; + result |= cmd_submitf(cmd, "%s", hostgroup_name); + } + break; + + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + result = cmd_submitf(cmd, "%s;%lu;%lu;%d;0;%lu;%s;%s", hostgroup_name, start_time, end_time, fixed, duration, comment_author, comment_data); + break; + + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + result = cmd_submitf(cmd, "%s;%lu;%lu;%d;0;%lu;%s;%s", hostgroup_name, start_time, end_time, fixed, duration, comment_author, comment_data); + if(affect_host_and_services == TRUE) + result |= cmd_submitf(CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME, "%s;%lu;%lu;%d;0;%lu;%s;%s", hostgroup_name, start_time, end_time, fixed, duration, comment_author, comment_data); + break; + + + /***** SERVICEGROUP COMMANDS *****/ + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + result = cmd_submitf(cmd, "%s", servicegroup_name); + if(affect_host_and_services == TRUE) { + cmd = (cmd == CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS) ? CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS : CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS; + result |= cmd_submitf(cmd, "%s", servicegroup_name); + } + break; + + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + result = cmd_submitf(cmd, "%s", servicegroup_name); + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + result = cmd_submitf(cmd, "%s", servicegroup_name); + if(affect_host_and_services == TRUE) { + cmd = (cmd == CMD_ENABLE_SERVICEGROUP_SVC_CHECKS) ? CMD_ENABLE_SERVICEGROUP_HOST_CHECKS : CMD_DISABLE_SERVICEGROUP_HOST_CHECKS; + result |= cmd_submitf(cmd, "%s", servicegroup_name); + } + break; + + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + result = cmd_submitf(cmd, "%s;%lu;%lu;%d;0;%lu;%s;%s", servicegroup_name, start_time, end_time, fixed, duration, comment_author, comment_data); + break; + + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + result = cmd_submitf(cmd, "%s;%lu;%lu;%d;0;%lu;%s;%s", servicegroup_name, start_time, end_time, fixed, duration, comment_author, comment_data); + if(affect_host_and_services == TRUE) + result |= cmd_submitf(CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME, "%s;%lu;%lu;%d;0;%lu;%s;%s", servicegroup_name, start_time, end_time, fixed, duration, comment_author, comment_data); + break; + + default: + return ERROR; + break; + } + + return result; + } + + + +/* write a command entry to the command file */ +int write_command_to_file(char *cmd) { + FILE *fp; + struct stat statbuf; + + /* + * Commands are not allowed to have newlines in them, as + * that allows malicious users to hand-craft requests that + * bypass the access-restrictions. + */ + if(!cmd || !*cmd || strchr(cmd, '\n')) + return ERROR; + + /* bail out if the external command file doesn't exist */ + if(stat(command_file, &statbuf)) { + + if(content_type == WML_CONTENT) + printf("

    Error: Could not stat() external command file!

    \n"); + else { + printf("

    Error: Could not stat() command file '%s'!

    \n", command_file); + printf("

    "); + printf("The external command file may be missing, Nagios may not be running, and/or Nagios may not be checking external commands.\n"); + printf("

    \n"); + } + + return ERROR; + } + + /* open the command for writing (since this is a pipe, it will really be appended) */ + fp = fopen(command_file, "w"); + if(fp == NULL) { + + if(content_type == WML_CONTENT) + printf("

    Error: Could not open command file for update!

    \n"); + else { + printf("

    Error: Could not open command file '%s' for update!

    \n", command_file); + printf("

    "); + printf("The permissions on the external command file and/or directory may be incorrect. Read the FAQs on how to setup proper permissions.\n"); + printf("

    \n"); + } + + return ERROR; + } + + /* write the command to file */ + fprintf(fp, "%s\n", cmd); + + /* flush buffer */ + fflush(fp); + + fclose(fp); + + return OK; + } + + +/* strips out semicolons from comment data */ +void clean_comment_data(char *buffer) { + int x; + int y; + + y = (int)strlen(buffer); + + for(x = 0; x < y; x++) { + if(buffer[x] == ';') + buffer[x] = ' '; + } + + return; + } + + +/* display information about a command */ +void show_command_help(cmd) { + + printf("
    Command Description
    \n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + + /* decide what information to print out... */ + switch(cmd) { + + case CMD_ADD_HOST_COMMENT: + printf("This command is used to add a comment for the specified host. If you work with other administrators, you may find it useful to share information about a host\n"); + printf("that is having problems if more than one of you may be working on it. If you do not check the 'persistent' option, the comment will be automatically be deleted\n"); + printf("the next time Nagios is restarted.\n"); + break; + + case CMD_ADD_SVC_COMMENT: + printf("This command is used to add a comment for the specified service. If you work with other administrators, you may find it useful to share information about a host\n"); + printf("or service that is having problems if more than one of you may be working on it. If you do not check the 'persistent' option, the comment will automatically be\n"); + printf("deleted the next time Nagios is restarted.\n"); + break; + + case CMD_DEL_HOST_COMMENT: + printf("This command is used to delete a specific host comment.\n"); + break; + + case CMD_DEL_SVC_COMMENT: + printf("This command is used to delete a specific service comment.\n"); + break; + + case CMD_DELAY_HOST_NOTIFICATION: + printf("This command is used to delay the next problem notification that is sent out for the specified host. The notification delay will be disregarded if\n"); + printf("the host changes state before the next notification is scheduled to be sent out. This command has no effect if the host is currently UP.\n"); + break; + + case CMD_DELAY_SVC_NOTIFICATION: + printf("This command is used to delay the next problem notification that is sent out for the specified service. The notification delay will be disregarded if\n"); + printf("the service changes state before the next notification is scheduled to be sent out. This command has no effect if the service is currently in an OK state.\n"); + break; + + case CMD_SCHEDULE_SVC_CHECK: + printf("This command is used to schedule the next check of a particular service. Nagios will re-queue the service to be checked at the time you specify.\n"); + printf("If you select the force check option, Nagios will force a check of the service regardless of both what time the scheduled check occurs and whether or not checks are enabled for the service.\n"); + break; + + case CMD_ENABLE_SVC_CHECK: + printf("This command is used to enable active checks of a service.\n"); + break; + + case CMD_DISABLE_SVC_CHECK: + printf("This command is used to disable active checks of a service.\n"); + break; + + case CMD_DISABLE_NOTIFICATIONS: + printf("This command is used to disable host and service notifications on a program-wide basis.\n"); + break; + + case CMD_ENABLE_NOTIFICATIONS: + printf("This command is used to enable host and service notifications on a program-wide basis.\n"); + break; + + case CMD_SHUTDOWN_PROCESS: + printf("This command is used to shutdown the Nagios process. Note: Once the Nagios has been shutdown, it cannot be restarted via the web interface!\n"); + break; + + case CMD_RESTART_PROCESS: + printf("This command is used to restart the Nagios process. Executing a restart command is equivalent to sending the process a HUP signal.\n"); + printf("All information will be flushed from memory, the configuration files will be re-read, and Nagios will start monitoring with the new configuration information.\n"); + break; + + case CMD_ENABLE_HOST_SVC_CHECKS: + printf("This command is used to enable active checks of all services associated with the specified host. This does not enable checks of the host unless you check the 'Enable for host too' option.\n"); + break; + + case CMD_DISABLE_HOST_SVC_CHECKS: + printf("This command is used to disable active checks of all services associated with the specified host. When a service is disabled Nagios will not monitor the service. Doing this will prevent any notifications being sent out for\n"); + printf("the specified service while it is disabled. In order to have Nagios check the service in the future you will have to re-enable the service.\n"); + printf("Note that disabling service checks may not necessarily prevent notifications from being sent out about the host which those services are associated with. This does not disable checks of the host unless you check the 'Disable for host too' option.\n"); + break; + + case CMD_SCHEDULE_HOST_SVC_CHECKS: + printf("This command is used to scheduled the next check of all services on the specified host. If you select the force check option, Nagios will force a check of all services on the host regardless of both what time the scheduled checks occur and whether or not checks are enabled for those services.\n"); + break; + + case CMD_DEL_ALL_HOST_COMMENTS: + printf("This command is used to delete all comments associated with the specified host.\n"); + break; + + case CMD_DEL_ALL_SVC_COMMENTS: + printf("This command is used to delete all comments associated with the specified service.\n"); + break; + + case CMD_ENABLE_SVC_NOTIFICATIONS: + printf("This command is used to enable notifications for the specified service. Notifications will only be sent out for the\n"); + printf("service state types you defined in your service definition.\n"); + break; + + case CMD_DISABLE_SVC_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for the specified service. You will have to re-enable notifications\n"); + printf("for this service before any alerts can be sent out in the future.\n"); + break; + + case CMD_ENABLE_HOST_NOTIFICATIONS: + printf("This command is used to enable notifications for the specified host. Notifications will only be sent out for the\n"); + printf("host state types you defined in your host definition. Note that this command does not enable notifications\n"); + printf("for services associated with this host.\n"); + break; + + case CMD_DISABLE_HOST_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for the specified host. You will have to re-enable notifications for this host\n"); + printf("before any alerts can be sent out in the future. Note that this command does not disable notifications for services associated with this host.\n"); + break; + + case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + printf("This command is used to enable notifications for all hosts and services that lie \"beyond\" the specified host\n"); + printf("(from the view of Nagios).\n"); + break; + + case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: + printf("This command is used to temporarily prevent notifications from being sent out for all hosts and services that lie\n"); + printf("\"beyond\" the specified host (from the view of Nagios).\n"); + break; + + case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: + printf("This command is used to enable notifications for all services on the specified host. Notifications will only be sent out for the\n"); + printf("service state types you defined in your service definition. This does not enable notifications for the host unless you check the 'Enable for host too' option.\n"); + break; + + case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for all services on the specified host. You will have to re-enable notifications for\n"); + printf("all services associated with this host before any alerts can be sent out in the future. This does not prevent notifications from being sent out about the host unless you check the 'Disable for host too' option.\n"); + break; + + case CMD_ACKNOWLEDGE_HOST_PROBLEM: + printf("This command is used to acknowledge a host problem. When a host problem is acknowledged, future notifications about problems are temporarily disabled until the host changes from its current state.\n"); + printf("If you want acknowledgement to disable notifications until the host recovers, check the 'Sticky Acknowledgement' checkbox.\n"); + printf("Contacts for this host will receive a notification about the acknowledgement, so they are aware that someone is working on the problem. Additionally, a comment will also be added to the host.\n"); + printf("Make sure to enter your name and fill in a brief description of what you are doing in the comment field. If you would like the host comment to remain once the acknowledgement is removed, check\n"); + printf("the 'Persistent Comment' checkbox. If you do not want an acknowledgement notification sent out to the appropriate contacts, uncheck the 'Send Notification' checkbox.\n"); + break; + + case CMD_ACKNOWLEDGE_SVC_PROBLEM: + printf("This command is used to acknowledge a service problem. When a service problem is acknowledged, future notifications about problems are temporarily disabled until the service changes from its current state.\n"); + printf("If you want acknowledgement to disable notifications until the service recovers, check the 'Sticky Acknowledgement' checkbox.\n"); + printf("Contacts for this service will receive a notification about the acknowledgement, so they are aware that someone is working on the problem. Additionally, a comment will also be added to the service.\n"); + printf("Make sure to enter your name and fill in a brief description of what you are doing in the comment field. If you would like the service comment to remain once the acknowledgement is removed, check\n"); + printf("the 'Persistent Comment' checkbox. If you do not want an acknowledgement notification sent out to the appropriate contacts, uncheck the 'Send Notification' checkbox.\n"); + break; + + case CMD_START_EXECUTING_SVC_CHECKS: + printf("This command is used to resume execution of active service checks on a program-wide basis. Individual services which are disabled will still not be checked.\n"); + break; + + case CMD_STOP_EXECUTING_SVC_CHECKS: + printf("This command is used to temporarily stop Nagios from actively executing any service checks. This will have the side effect of preventing any notifications from being sent out (for any and all services and hosts).\n"); + printf("Service checks will not be executed again until you issue a command to resume service check execution.\n"); + break; + + case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: + printf("This command is used to make Nagios start accepting passive service check results that it finds in the external command file\n"); + break; + + case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: + printf("This command is use to make Nagios stop accepting passive service check results that it finds in the external command file. All passive check results that are found will be ignored.\n"); + break; + + case CMD_ENABLE_PASSIVE_SVC_CHECKS: + printf("This command is used to allow Nagios to accept passive service check results that it finds in the external command file for this particular service.\n"); + break; + + case CMD_DISABLE_PASSIVE_SVC_CHECKS: + printf("This command is used to stop Nagios accepting passive service check results that it finds in the external command file for this particular service. All passive check results that are found for this service will be ignored.\n"); + break; + + case CMD_ENABLE_EVENT_HANDLERS: + printf("This command is used to allow Nagios to run host and service event handlers.\n"); + break; + + case CMD_DISABLE_EVENT_HANDLERS: + printf("This command is used to temporarily prevent Nagios from running any host or service event handlers.\n"); + break; + + case CMD_ENABLE_SVC_EVENT_HANDLER: + printf("This command is used to allow Nagios to run the service event handler for a particular service when necessary (if one is defined).\n"); + break; + + case CMD_DISABLE_SVC_EVENT_HANDLER: + printf("This command is used to temporarily prevent Nagios from running the service event handler for a particular service.\n"); + break; + + case CMD_ENABLE_HOST_EVENT_HANDLER: + printf("This command is used to allow Nagios to run the host event handler for a particular service when necessary (if one is defined).\n"); + break; + + case CMD_DISABLE_HOST_EVENT_HANDLER: + printf("This command is used to temporarily prevent Nagios from running the host event handler for a particular host.\n"); + break; + + case CMD_ENABLE_HOST_CHECK: + printf("This command is used to enable active checks of this host.\n"); + break; + + case CMD_DISABLE_HOST_CHECK: + printf("This command is used to temporarily prevent Nagios from actively checking the status of a particular host. If Nagios needs to check the status of this host, it will assume that it is in the same state that it was in before checks were disabled.\n"); + break; + + case CMD_START_OBSESSING_OVER_SVC_CHECKS: + printf("This command is used to have Nagios start obsessing over service checks. Read the documentation on distributed monitoring for more information on this.\n"); + break; + + case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: + printf("This command is used stop Nagios from obsessing over service checks.\n"); + break; + + case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: + printf("This command is used to remove an acknowledgement for a particular host problem. Once the acknowledgement is removed, notifications may start being\n"); + printf("sent out about the host problem. \n"); + break; + + case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: + printf("This command is used to remove an acknowledgement for a particular service problem. Once the acknowledgement is removed, notifications may start being\n"); + printf("sent out about the service problem.\n"); + break; + + case CMD_PROCESS_SERVICE_CHECK_RESULT: + printf("This command is used to submit a passive check result for a particular service. It is particularly useful for resetting security-related services to OK states once they have been dealt with.\n"); + break; + + case CMD_PROCESS_HOST_CHECK_RESULT: + printf("This command is used to submit a passive check result for a particular host.\n"); + break; + + case CMD_SCHEDULE_HOST_DOWNTIME: + printf("This command is used to schedule downtime for a particular host. During the specified downtime, Nagios will not send notifications out about the host.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for this host as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when the host goes down or becomes unreachable (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed downtime.\n"); + break; + + case CMD_SCHEDULE_HOST_SVC_DOWNTIME: + printf("This command is used to schedule downtime for all services on a particular host. During the specified downtime, Nagios will not send notifications out about the host.\n"); + printf("Normally, a host in downtime will not send alerts about any services in a failed state. This option will explicitly set downtime for all services for this host.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for this host as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when the host goes down or becomes unreachable (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed downtime.\n"); + break; + + case CMD_SCHEDULE_SVC_DOWNTIME: + printf("This command is used to schedule downtime for a particular service. During the specified downtime, Nagios will not send notifications out about the service.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for this service as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when the service enters a non-OK state (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed downtime.\n"); + break; + + case CMD_ENABLE_HOST_FLAP_DETECTION: + printf("This command is used to enable flap detection for a specific host. If flap detection is disabled on a program-wide basis, this will have no effect,\n"); + break; + + case CMD_DISABLE_HOST_FLAP_DETECTION: + printf("This command is used to disable flap detection for a specific host.\n"); + break; + + case CMD_ENABLE_SVC_FLAP_DETECTION: + printf("This command is used to enable flap detection for a specific service. If flap detection is disabled on a program-wide basis, this will have no effect,\n"); + break; + + case CMD_DISABLE_SVC_FLAP_DETECTION: + printf("This command is used to disable flap detection for a specific service.\n"); + break; + + case CMD_ENABLE_FLAP_DETECTION: + printf("This command is used to enable flap detection for hosts and services on a program-wide basis. Individual hosts and services may have flap detection disabled.\n"); + break; + + case CMD_DISABLE_FLAP_DETECTION: + printf("This command is used to disable flap detection for hosts and services on a program-wide basis.\n"); + break; + + case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: + printf("This command is used to enable notifications for all services in the specified hostgroup. Notifications will only be sent out for the\n"); + printf("service state types you defined in your service definitions. This does not enable notifications for the hosts in this hostgroup unless you check the 'Enable for hosts too' option.\n"); + break; + + case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for all services in the specified hostgroup. You will have to re-enable notifications for\n"); + printf("all services in this hostgroup before any alerts can be sent out in the future. This does not prevent notifications from being sent out about the hosts in this hostgroup unless you check the 'Disable for hosts too' option.\n"); + break; + + case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: + printf("This command is used to enable notifications for all hosts in the specified hostgroup. Notifications will only be sent out for the\n"); + printf("host state types you defined in your host definitions.\n"); + break; + + case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for all hosts in the specified hostgroup. You will have to re-enable notifications for\n"); + printf("all hosts in this hostgroup before any alerts can be sent out in the future.\n"); + break; + + case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: + printf("This command is used to enable active checks of all services in the specified hostgroup. This does not enable active checks of the hosts in the hostgroup unless you check the 'Enable for hosts too' option.\n"); + break; + + case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: + printf("This command is used to disable active checks of all services in the specified hostgroup. This does not disable checks of the hosts in the hostgroup unless you check the 'Disable for hosts too' option.\n"); + break; + + case CMD_DEL_HOST_DOWNTIME: + printf("This command is used to cancel active or pending scheduled downtime for the specified host.\n"); + break; + + case CMD_DEL_SVC_DOWNTIME: + printf("This command is used to cancel active or pending scheduled downtime for the specified service.\n"); + break; + + case CMD_ENABLE_FAILURE_PREDICTION: + printf("This command is used to enable failure prediction for hosts and services on a program-wide basis. Individual hosts and services may have failure prediction disabled.\n"); + break; + + case CMD_DISABLE_FAILURE_PREDICTION: + printf("This command is used to disable failure prediction for hosts and services on a program-wide basis.\n"); + break; + + case CMD_ENABLE_PERFORMANCE_DATA: + printf("This command is used to enable the processing of performance data for hosts and services on a program-wide basis. Individual hosts and services may have performance data processing disabled.\n"); + break; + + case CMD_DISABLE_PERFORMANCE_DATA: + printf("This command is used to disable the processing of performance data for hosts and services on a program-wide basis.\n"); + break; + + case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: + printf("This command is used to schedule downtime for all hosts in a particular hostgroup. During the specified downtime, Nagios will not send notifications out about the hosts.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for the hosts as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a host goes down or becomes unreachable (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); + break; + + case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: + printf("This command is used to schedule downtime for all services in a particular hostgroup. During the specified downtime, Nagios will not send notifications out about the services.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for the services as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a service enters a non-OK state (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); + printf("Note that scheduling downtime for services does not automatically schedule downtime for the hosts those services are associated with. If you want to also schedule downtime for all hosts in the hostgroup, check the 'Schedule downtime for hosts too' option.\n"); + break; + + case CMD_START_EXECUTING_HOST_CHECKS: + printf("This command is used to enable active host checks on a program-wide basis.\n"); + break; + + case CMD_STOP_EXECUTING_HOST_CHECKS: + printf("This command is used to disable active host checks on a program-wide basis.\n"); + break; + + case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: + printf("This command is used to have Nagios start obsessing over host checks. Read the documentation on distributed monitoring for more information on this.\n"); + break; + + case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: + printf("This command is used to stop Nagios from obsessing over host checks.\n"); + break; + + case CMD_ENABLE_PASSIVE_HOST_CHECKS: + printf("This command is used to allow Nagios to accept passive host check results that it finds in the external command file for a particular host.\n"); + break; + + case CMD_DISABLE_PASSIVE_HOST_CHECKS: + printf("This command is used to stop Nagios from accepting passive host check results that it finds in the external command file for a particular host. All passive check results that are found for this host will be ignored.\n"); + break; + + case CMD_START_OBSESSING_OVER_HOST_CHECKS: + printf("This command is used to have Nagios start obsessing over host checks. Read the documentation on distributed monitoring for more information on this.\n"); + break; + + case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: + printf("This command is used to stop Nagios from obsessing over host checks.\n"); + break; + + case CMD_SCHEDULE_HOST_CHECK: + printf("This command is used to schedule the next check of a particular host. Nagios will re-queue the host to be checked at the time you specify.\n"); + printf("If you select the force check option, Nagios will force a check of the host regardless of both what time the scheduled check occurs and whether or not checks are enabled for the host.\n"); + break; + + case CMD_START_OBSESSING_OVER_SVC: + printf("This command is used to have Nagios start obsessing over a particular service.\n"); + break; + + case CMD_STOP_OBSESSING_OVER_SVC: + printf("This command is used to stop Nagios from obsessing over a particular service.\n"); + break; + + case CMD_START_OBSESSING_OVER_HOST: + printf("This command is used to have Nagios start obsessing over a particular host.\n"); + break; + + case CMD_STOP_OBSESSING_OVER_HOST: + printf("This command is used to stop Nagios from obsessing over a particular host.\n"); + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + printf("This command is used to enable notifications for all services in the specified servicegroup. Notifications will only be sent out for the\n"); + printf("service state types you defined in your service definitions. This does not enable notifications for the hosts in this servicegroup unless you check the 'Enable for hosts too' option.\n"); + break; + + case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for all services in the specified servicegroup. You will have to re-enable notifications for\n"); + printf("all services in this servicegroup before any alerts can be sent out in the future. This does not prevent notifications from being sent out about the hosts in this servicegroup unless you check the 'Disable for hosts too' option.\n"); + break; + + case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + printf("This command is used to enable notifications for all hosts in the specified servicegroup. Notifications will only be sent out for the\n"); + printf("host state types you defined in your host definitions.\n"); + break; + + case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: + printf("This command is used to prevent notifications from being sent out for all hosts in the specified servicegroup. You will have to re-enable notifications for\n"); + printf("all hosts in this servicegroup before any alerts can be sent out in the future.\n"); + break; + + case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: + printf("This command is used to enable active checks of all services in the specified servicegroup. This does not enable active checks of the hosts in the servicegroup unless you check the 'Enable for hosts too' option.\n"); + break; + + case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: + printf("This command is used to disable active checks of all services in the specified servicegroup. This does not disable checks of the hosts in the servicegroup unless you check the 'Disable for hosts too' option.\n"); + break; + + case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: + printf("This command is used to schedule downtime for all hosts in a particular servicegroup. During the specified downtime, Nagios will not send notifications out about the hosts.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for the hosts as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a host goes down or becomes unreachable (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); + break; + + case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: + printf("This command is used to schedule downtime for all services in a particular servicegroup. During the specified downtime, Nagios will not send notifications out about the services.\n"); + printf("When the scheduled downtime expires, Nagios will send out notifications for the services as it normally would. Scheduled downtimes are preserved\n"); + printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); + printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); + printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a service enters a non-OK state (sometime between the\n"); + printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); + printf("Note that scheduling downtime for services does not automatically schedule downtime for the hosts those services are associated with. If you want to also schedule downtime for all hosts in the servicegroup, check the 'Schedule downtime for hosts too' option.\n"); + break; + + case CMD_SEND_CUSTOM_HOST_NOTIFICATION: + case CMD_SEND_CUSTOM_SVC_NOTIFICATION: + printf("This command is used to send a custom notification about the specified %s. Useful in emergencies when you need to notify admins of an issue regarding a monitored system or service.\n", (cmd == CMD_SEND_CUSTOM_HOST_NOTIFICATION) ? "host" : "service"); + printf("Custom notifications normally follow the regular notification logic in Nagios. Selecting the Forced option will force the notification to be sent out, regardless of the time restrictions, whether or not notifications are enabled, etc. Selecting the Broadcast option causes the notification to be sent out to all normal (non-escalated) and escalated contacts. These options allow you to override the normal notification logic if you need to get an important message out.\n"); + break; + + default: + printf("Sorry, but no information is available for this command."); + } + + printf("
    \n"); + + return; + } + + + +/* converts a time string to a UNIX timestamp, respecting the date_format option */ +int string_to_time(char *buffer, time_t *t) { + struct tm lt; + int ret = 0; + + + /* Initialize some variables just in case they don't get parsed + by the sscanf() call. A better solution is to also check the + CGI input for validity, but this should suffice to prevent + strange problems if the input is not valid. + Jan 15 2003 Steve Bonds */ + lt.tm_mon = 0; + lt.tm_mday = 1; + lt.tm_year = 1900; + lt.tm_hour = 0; + lt.tm_min = 0; + lt.tm_sec = 0; + lt.tm_wday = 0; + lt.tm_yday = 0; + + + if(date_format == DATE_FORMAT_EURO) + ret = sscanf(buffer, "%02d-%02d-%04d %02d:%02d:%02d", <.tm_mday, <.tm_mon, <.tm_year, <.tm_hour, <.tm_min, <.tm_sec); + else if(date_format == DATE_FORMAT_ISO8601 || date_format == DATE_FORMAT_STRICT_ISO8601) + ret = sscanf(buffer, "%04d-%02d-%02d%*[ T]%02d:%02d:%02d", <.tm_year, <.tm_mon, <.tm_mday, <.tm_hour, <.tm_min, <.tm_sec); + else + ret = sscanf(buffer, "%02d-%02d-%04d %02d:%02d:%02d", <.tm_mon, <.tm_mday, <.tm_year, <.tm_hour, <.tm_min, <.tm_sec); + + if(ret != 6) + return ERROR; + + lt.tm_mon--; + lt.tm_year -= 1900; + + /* tell mktime() to try and compute DST automatically */ + lt.tm_isdst = -1; + + *t = mktime(<); + + return OK; + } diff --git a/cgi/config.c b/cgi/config.c new file mode 100644 index 0000000..ae1c693 --- /dev/null +++ b/cgi/config.c @@ -0,0 +1,2483 @@ +/*********************************************************************** + * + * CONFIG.C - Nagios Configuration CGI (View Only) + * + * Copyright (c) 1999-2009 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 05-15-2009 + * + * This CGI program will display various configuration information. + * + * + * 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/macros.h" +#include "../include/cgiutils.h" +#include "../include/cgiauth.h" +#include "../include/getcgi.h" + +static nagios_macros *mac; + +extern char main_config_file[MAX_FILENAME_LENGTH]; +extern char url_html_path[MAX_FILENAME_LENGTH]; +extern char url_docs_path[MAX_FILENAME_LENGTH]; +extern char url_images_path[MAX_FILENAME_LENGTH]; +extern char url_logo_images_path[MAX_FILENAME_LENGTH]; +extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; + +extern host *host_list; +extern service *service_list; +extern hostgroup *hostgroup_list; +extern servicegroup *servicegroup_list; +extern contactgroup *contactgroup_list; +extern command *command_list; +extern timeperiod *timeperiod_list; +extern contact *contact_list; +extern servicedependency *servicedependency_list; +extern serviceescalation *serviceescalation_list; +extern hostdependency *hostdependency_list; +extern hostescalation *hostescalation_list; + + +#define DISPLAY_NONE 0 +#define DISPLAY_HOSTS 1 +#define DISPLAY_HOSTGROUPS 2 +#define DISPLAY_CONTACTS 3 +#define DISPLAY_CONTACTGROUPS 4 +#define DISPLAY_SERVICES 5 +#define DISPLAY_TIMEPERIODS 6 +#define DISPLAY_COMMANDS 7 +#define DISPLAY_HOSTGROUPESCALATIONS 8 /* no longer implemented */ +#define DISPLAY_SERVICEDEPENDENCIES 9 +#define DISPLAY_SERVICEESCALATIONS 10 +#define DISPLAY_HOSTDEPENDENCIES 11 +#define DISPLAY_HOSTESCALATIONS 12 +#define DISPLAY_SERVICEGROUPS 15 +#define DISPLAY_COMMAND_EXPANSION 16211 + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + +void display_options(void); + +void display_hosts(void); +void display_hostgroups(void); +void display_servicegroups(void); +void display_contacts(void); +void display_contactgroups(void); +void display_services(void); +void display_timeperiods(void); +void display_commands(void); +void display_servicedependencies(void); +void display_serviceescalations(void); +void display_hostdependencies(void); +void display_hostescalations(void); +void display_command_expansion(void); + +void unauthorized_message(void); + + +authdata current_authdata; + +int display_type = DISPLAY_NONE; +char to_expand[MAX_COMMAND_BUFFER]; +char hashed_color[8]; + +int embedded = FALSE; + +void print_expand_input(int type) { + char *seldesc = ""; + + if(type == DISPLAY_COMMAND_EXPANSION) return; /* Has its own form, w/ larger */ + else if(type == DISPLAY_SERVICES) { + seldesc = " Services Named or on Host"; + } + else if(type == DISPLAY_SERVICEDEPENDENCIES) { + seldesc = " Dependencies with Host"; + } + else if(type == DISPLAY_SERVICEESCALATIONS) { + seldesc = " Escalations on Host"; + } + else if(type == DISPLAY_HOSTDEPENDENCIES) { + seldesc = " Dependencies on/of Host"; + } + else if(type == DISPLAY_HOSTESCALATIONS) { + seldesc = " Escalations for Host"; + } + printf("Show Only%s:\n", seldesc); + printf("", html_encode(to_expand, FALSE)); + } + +int main(void) { + int result = OK; + mac = get_global_macros(); + + /* 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; + } + + /* initialize macros */ + init_macros(); + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + display_info_table("Configuration", FALSE, ¤t_authdata); + printf("\n"); + + if(display_type != DISPLAY_NONE) { + + printf("
    \n", CONFIG_CGI); + printf("\n"); + + printf("\n"); + printf("\n"); + + print_expand_input(display_type); + + printf("\n"); + printf("
    Object Type:
    "); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + } + + /* display context-sensitive help */ + switch(display_type) { + case DISPLAY_HOSTS: + display_context_help(CONTEXTHELP_CONFIG_HOSTS); + break; + case DISPLAY_HOSTGROUPS: + display_context_help(CONTEXTHELP_CONFIG_HOSTGROUPS); + break; + case DISPLAY_SERVICEGROUPS: + display_context_help(CONTEXTHELP_CONFIG_SERVICEGROUPS); + break; + case DISPLAY_CONTACTS: + display_context_help(CONTEXTHELP_CONFIG_CONTACTS); + break; + case DISPLAY_CONTACTGROUPS: + display_context_help(CONTEXTHELP_CONFIG_CONTACTGROUPS); + break; + case DISPLAY_SERVICES: + display_context_help(CONTEXTHELP_CONFIG_SERVICES); + break; + case DISPLAY_TIMEPERIODS: + display_context_help(CONTEXTHELP_CONFIG_TIMEPERIODS); + break; + case DISPLAY_COMMANDS: + display_context_help(CONTEXTHELP_CONFIG_COMMANDS); + break; + case DISPLAY_SERVICEDEPENDENCIES: + display_context_help(CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES); + break; + case DISPLAY_SERVICEESCALATIONS: + display_context_help(CONTEXTHELP_CONFIG_HOSTESCALATIONS); + break; + case DISPLAY_HOSTDEPENDENCIES: + display_context_help(CONTEXTHELP_CONFIG_HOSTDEPENDENCIES); + break; + case DISPLAY_HOSTESCALATIONS: + display_context_help(CONTEXTHELP_CONFIG_HOSTESCALATIONS); + break; + case DISPLAY_COMMAND_EXPANSION: + /* Reusing DISPLAY_COMMANDS help until further notice */ + display_context_help(CONTEXTHELP_CONFIG_COMMANDS); + break; + default: + display_context_help(CONTEXTHELP_CONFIG_MENU); + break; + } + + printf("
    \n"); + + + switch(display_type) { + case DISPLAY_HOSTS: + display_hosts(); + break; + case DISPLAY_HOSTGROUPS: + display_hostgroups(); + break; + case DISPLAY_SERVICEGROUPS: + display_servicegroups(); + break; + case DISPLAY_CONTACTS: + display_contacts(); + break; + case DISPLAY_CONTACTGROUPS: + display_contactgroups(); + break; + case DISPLAY_SERVICES: + display_services(); + break; + case DISPLAY_TIMEPERIODS: + display_timeperiods(); + break; + case DISPLAY_COMMANDS: + display_commands(); + break; + case DISPLAY_SERVICEDEPENDENCIES: + display_servicedependencies(); + break; + case DISPLAY_SERVICEESCALATIONS: + display_serviceescalations(); + break; + case DISPLAY_HOSTDEPENDENCIES: + display_hostdependencies(); + break; + case DISPLAY_HOSTESCALATIONS: + display_hostescalations(); + break; + case DISPLAY_COMMAND_EXPANSION: + display_command_expansion(); + break; + default: + display_options(); + break; + } + + document_footer(); + + return OK; + } + + + + +void document_header(int use_stylesheet) { + char date_time[MAX_DATETIME_LENGTH]; + time_t t; + + if(embedded == TRUE) + return; + + time(&t); + get_time_string(&t, date_time, sizeof(date_time), HTTP_DATE_TIME); + + printf("Cache-Control: no-store\r\n"); + printf("Pragma: no-cache\r\n"); + printf("Last-Modified: %s\r\n", date_time); + printf("Expires: %s\r\n", date_time); + printf("Content-type: text/html\r\n\r\n"); + + printf("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("\n"); + printf("Configuration\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, CONFIG_CSS); + } + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(CONFIG_CGI, SSI_HEADER); + + return; + } + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + /* include user SSI footer */ + include_ssi_files(CONFIG_CGI, SSI_FOOTER); + + printf("\n"); + printf("\n"); + + return; + } + + +int process_cgivars(void) { + char **variables; + int error = FALSE; + int x; + + variables = getcgivars(); + to_expand[0] = '\0'; + + 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 configuration type argument */ + else if(!strcmp(variables[x], "type")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + /* what information should we display? */ + if(!strcmp(variables[x], "hosts")) + display_type = DISPLAY_HOSTS; + else if(!strcmp(variables[x], "hostgroups")) + display_type = DISPLAY_HOSTGROUPS; + else if(!strcmp(variables[x], "servicegroups")) + display_type = DISPLAY_SERVICEGROUPS; + else if(!strcmp(variables[x], "contacts")) + display_type = DISPLAY_CONTACTS; + else if(!strcmp(variables[x], "contactgroups")) + display_type = DISPLAY_CONTACTGROUPS; + else if(!strcmp(variables[x], "services")) + display_type = DISPLAY_SERVICES; + else if(!strcmp(variables[x], "timeperiods")) + display_type = DISPLAY_TIMEPERIODS; + else if(!strcmp(variables[x], "commands")) + display_type = DISPLAY_COMMANDS; + else if(!strcmp(variables[x], "servicedependencies")) + display_type = DISPLAY_SERVICEDEPENDENCIES; + else if(!strcmp(variables[x], "serviceescalations")) + display_type = DISPLAY_SERVICEESCALATIONS; + else if(!strcmp(variables[x], "hostdependencies")) + display_type = DISPLAY_HOSTDEPENDENCIES; + else if(!strcmp(variables[x], "hostescalations")) + display_type = DISPLAY_HOSTESCALATIONS; + else if(!strcmp(variables[x], "command")) + display_type = DISPLAY_COMMAND_EXPANSION; + + /* we found the embed option */ + else if(!strcmp(variables[x], "embedded")) + embedded = TRUE; + } + + /* we found the string-to-expand argument */ + else if(!strcmp(variables[x], "expand")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + strncpy(to_expand, variables[x], MAX_COMMAND_BUFFER); + to_expand[MAX_COMMAND_BUFFER - 1] = '\0'; + } + + + /* we received an invalid argument */ + else + error = TRUE; + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +void display_hosts(void) { + host *temp_host = NULL; + hostsmember *temp_hostsmember = NULL; + contactsmember *temp_contactsmember = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + char *processed_string = NULL; + int options = 0; + int odd = 0; + char time_string[16]; + char *bg_class = ""; + int contact = 0; + + /* see if user is authorized to view host information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Host%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("\n"); + + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the hosts... */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) if(((*to_expand) == '\0') || !strcmp(to_expand, temp_host->name)) { + + /* grab macros */ + grab_host_macros_r(mac, temp_host); + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("\n", bg_class, + url_encode(temp_host->name), CONFIG_CGI, url_encode(temp_host->name), html_encode(temp_host->name, FALSE)); + printf("\n", bg_class, html_encode(temp_host->alias, FALSE)); + printf("\n", bg_class, html_encode(temp_host->address, FALSE)); + + printf("\n"); + + printf("\n", bg_class, temp_host->max_attempts); + + get_interval_time_string(temp_host->check_interval, time_string, sizeof(time_string)); + printf("\n", bg_class, time_string); + + get_interval_time_string(temp_host->retry_interval, time_string, sizeof(time_string)); + printf("\n", bg_class, time_string); + + printf("\n",CONFIG_CGI,url_encode(strtok(temp_host->host_check_command,"!")),html_encode(temp_host->host_check_command,FALSE)); */ + printf("%s\n", CONFIG_CGI, url_encode(temp_host->host_check_command), html_encode(temp_host->host_check_command, FALSE)); + printf("\n"); + + printf("\n"); + + printf("\n", bg_class, (temp_host->obsess_over_host == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_host->checks_enabled == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_host->accept_passive_host_checks == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_host->check_freshness == TRUE) ? "Yes" : "No"); + + printf("\n"); + + printf("\n"); + + get_interval_time_string(temp_host->notification_interval, time_string, sizeof(time_string)); + printf("\n", bg_class, (temp_host->notification_interval == 0) ? "No Re-notification" : html_encode(time_string, FALSE)); + + get_interval_time_string(temp_host->first_notification_delay, time_string, sizeof(time_string)); + printf("\n", bg_class, time_string); + + printf("\n"); + + printf("\n"); + + printf("\n",CONFIG_CGI,url_encode(strtok(temp_host->event_handler,"!")),html_encode(temp_host->event_handler,FALSE)); */ + printf("%s\n", CONFIG_CGI, url_encode(temp_host->event_handler), html_encode(temp_host->event_handler, FALSE)); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n", bg_class, (temp_host->failure_prediction_options == NULL) ? " " : html_encode(temp_host->failure_prediction_options, FALSE)); + + printf("", bg_class, (temp_host->notes == NULL) ? " " : html_encode(temp_host->notes, FALSE)); + + printf("", bg_class, (temp_host->notes_url == NULL) ? " " : html_encode(temp_host->notes_url, FALSE)); + + printf("", bg_class, (temp_host->action_url == NULL) ? " " : html_encode(temp_host->action_url, FALSE)); + + if(temp_host->have_2d_coords == FALSE) + printf("", bg_class); + else + printf("", bg_class, temp_host->x_2d, temp_host->y_2d); + + if(temp_host->have_3d_coords == FALSE) + printf("", bg_class); + else + printf("", bg_class, temp_host->x_3d, temp_host->y_3d, temp_host->z_3d); + + if(temp_host->statusmap_image == NULL) + printf("", bg_class); + else + printf("", bg_class, url_logo_images_path, temp_host->statusmap_image, html_encode(temp_host->statusmap_image, FALSE)); + + if(temp_host->vrml_image == NULL) + printf("", bg_class); + else + printf("", bg_class, url_logo_images_path, temp_host->vrml_image, html_encode(temp_host->vrml_image, FALSE)); + + if(temp_host->icon_image == NULL) + printf("", bg_class); + else { + process_macros_r(mac, temp_host->icon_image, &processed_string, 0); + printf("", bg_class, url_logo_images_path, processed_string, html_encode(temp_host->icon_image, FALSE)); + free(processed_string); + } + + printf("", bg_class, (temp_host->icon_image_alt == NULL) ? " " : html_encode(temp_host->icon_image_alt, FALSE)); + + printf("\n"); + + printf("\n"); + } + + printf("
    Host NameAlias/DescriptionAddressParent HostsMax. Check AttemptsCheck IntervalRetry IntervalHost Check CommandCheck PeriodObsess OverEnable Active ChecksEnable Passive ChecksCheck FreshnessFreshness ThresholdDefault Contacts/GroupsNotification IntervalFirst Notification DelayNotification OptionsNotification PeriodEvent HandlerEnable Event HandlerStalking OptionsEnable Flap DetectionLow Flap ThresholdHigh Flap ThresholdFlap Detection OptionsProcess Performance DataEnable Failure PredictionFailure Prediction OptionsNotesNotes URLAction URL2-D Coords3-D CoordsStatusmap ImageVRML ImageLogo ImageImage AltRetention Options
    %s%s%s", bg_class); + for(temp_hostsmember = temp_host->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if(temp_hostsmember != temp_host->parent_hosts) + printf(", "); + + printf("%s\n", CONFIG_CGI, url_encode(temp_hostsmember->host_name), html_encode(temp_hostsmember->host_name, FALSE)); + } + if(temp_host->parent_hosts == NULL) + printf(" "); + printf("%d%s%s", bg_class); + if(temp_host->host_check_command == NULL) + printf(" "); + else + /* printf("%s", bg_class); + if(temp_host->check_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_host->check_period), html_encode(temp_host->check_period, FALSE)); + printf("%s%s%s%s", bg_class); + if(temp_host->freshness_threshold == 0) + printf("Auto-determined value\n"); + else + printf("%d seconds\n", temp_host->freshness_threshold); + printf("", bg_class); + + /* find all the contacts for this host... */ + contact = 0; + for(temp_contactsmember = temp_host->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + contact++; + if(contact > 1) + printf(", "); + + printf("%s\n", CONFIG_CGI, url_encode(temp_contactsmember->contact_name), html_encode(temp_contactsmember->contact_name, FALSE)); + } + for(temp_contactgroupsmember = temp_host->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_contactgroupsmember->group_name), html_encode(temp_contactgroupsmember->group_name, FALSE)); + } + if(contact == 0) + printf(" "); + printf("%s%s", bg_class); + options = 0; + if(temp_host->notify_on_down == TRUE) { + options = 1; + printf("Down"); + } + if(temp_host->notify_on_unreachable == TRUE) { + printf("%sUnreachable", (options) ? ", " : ""); + options = 1; + } + if(temp_host->notify_on_recovery == TRUE) { + printf("%sRecovery", (options) ? ", " : ""); + options = 1; + } + if(temp_host->notify_on_flapping == TRUE) { + printf("%sFlapping", (options) ? ", " : ""); + options = 1; + } + if(temp_host->notify_on_downtime == TRUE) { + printf("%sDowntime", (options) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("", bg_class); + if(temp_host->notification_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_host->notification_period), html_encode(temp_host->notification_period, FALSE)); + printf("", bg_class); + if(temp_host->event_handler == NULL) + printf(" "); + else + /* printf("%s", bg_class); + printf("%s\n", (temp_host->event_handler_enabled == TRUE) ? "Yes" : "No"); + printf("", bg_class); + options = 0; + if(temp_host->stalk_on_up == TRUE) { + options = 1; + printf("Up"); + } + if(temp_host->stalk_on_down == TRUE) { + printf("%sDown", (options) ? ", " : ""); + options = 1; + } + if(temp_host->stalk_on_unreachable == TRUE) { + printf("%sUnreachable", (options) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("", bg_class); + printf("%s\n", (temp_host->flap_detection_enabled == TRUE) ? "Yes" : "No"); + printf("", bg_class); + if(temp_host->low_flap_threshold == 0.0) + printf("Program-wide value\n"); + else + printf("%3.1f%%\n", temp_host->low_flap_threshold); + printf("", bg_class); + if(temp_host->high_flap_threshold == 0.0) + printf("Program-wide value\n"); + else + printf("%3.1f%%\n", temp_host->high_flap_threshold); + printf("", bg_class); + options = 0; + if(temp_host->flap_detection_on_up == TRUE) { + options = 1; + printf("Up"); + } + if(temp_host->flap_detection_on_down == TRUE) { + printf("%sDown", (options) ? ", " : ""); + options = 1; + } + if(temp_host->flap_detection_on_unreachable == TRUE) { + printf("%sUnreachable", (options) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("", bg_class); + printf("%s\n", (temp_host->process_performance_data == TRUE) ? "Yes" : "No"); + printf("", bg_class); + printf("%s\n", (temp_host->failure_prediction_enabled == TRUE) ? "Yes" : "No"); + printf("%s%s%s%s %d,%d %.2f,%.2f,%.2f  %s  %s  %s%s", bg_class); + options = 0; + if(temp_host->retain_status_information == TRUE) { + options = 1; + printf("Status Information"); + } + if(temp_host->retain_nonstatus_information == TRUE) { + printf("%sNon-Status Information", (options == 1) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_hostgroups(void) { + hostgroup *temp_hostgroup; + hostsmember *temp_hostsmember; + int odd = 0; + char *bg_class = ""; + + /* see if user is authorized to view hostgroup information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Host Group%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the hostgroups... */ + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_hostgroup->group_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("", bg_class, html_encode(temp_hostgroup->group_name, FALSE)); + + printf("\n", bg_class, html_encode(temp_hostgroup->alias, FALSE)); + + printf("\n"); + + printf("", bg_class, (temp_hostgroup->notes == NULL) ? " " : html_encode(temp_hostgroup->notes, FALSE)); + + printf("", bg_class, (temp_hostgroup->notes_url == NULL) ? " " : html_encode(temp_hostgroup->notes_url, FALSE)); + + printf("", bg_class, (temp_hostgroup->action_url == NULL) ? " " : html_encode(temp_hostgroup->action_url, FALSE)); + + printf("\n"); + } + + printf("
    Group NameDescriptionHost MembersNotesNotes URLAction URL
    %s%s", bg_class); + + /* find all the hosts that are members of this hostgroup... */ + for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + if(temp_hostsmember != temp_hostgroup->members) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_hostsmember->host_name), html_encode(temp_hostsmember->host_name, FALSE)); + } + printf("%s%s%s
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_servicegroups(void) { + servicegroup *temp_servicegroup; + servicesmember *temp_servicesmember; + int odd = 0; + char *bg_class = ""; + + /* see if user is authorized to view servicegroup information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Service Group%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the servicegroups... */ + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_servicegroup->group_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("", bg_class, html_encode(temp_servicegroup->group_name, FALSE)); + + printf("\n", bg_class, html_encode(temp_servicegroup->alias, FALSE)); + + printf("\n"); + + printf("", bg_class, (temp_servicegroup->notes == NULL) ? " " : html_encode(temp_servicegroup->notes, FALSE)); + + printf("", bg_class, (temp_servicegroup->notes_url == NULL) ? " " : html_encode(temp_servicegroup->notes_url, FALSE)); + + printf("", bg_class, (temp_servicegroup->action_url == NULL) ? " " : html_encode(temp_servicegroup->action_url, FALSE)); + + printf("\n"); + } + + printf("
    Group NameDescriptionService MembersNotesNotes URLAction URL
    %s%s", bg_class); + + /* find all the services that are members of this servicegroup... */ + for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + + printf("%s%s / ", (temp_servicesmember == temp_servicegroup->members) ? "" : ", ", CONFIG_CGI, url_encode(temp_servicesmember->host_name), html_encode(temp_servicesmember->host_name, FALSE)); + + printf("%s\n", url_encode(temp_servicesmember->service_description), html_encode(temp_servicesmember->service_description, FALSE)); + } + + printf("%s%s%s
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_contacts(void) { + contact *temp_contact; + commandsmember *temp_commandsmember; + int odd = 0; + int options; + int found; + char *bg_class = ""; + + /* see if user is authorized to view contact information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Contact%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all contacts... */ + for(temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_contact->name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("\n", bg_class, url_encode(temp_contact->name), html_encode(temp_contact->name, FALSE)); + printf("\n", bg_class, html_encode(temp_contact->alias, FALSE)); + printf("\n", bg_class, (temp_contact->email == NULL) ? " " : url_encode(temp_contact->email), (temp_contact->email == NULL) ? " " : html_encode(temp_contact->email, FALSE)); + printf("\n", bg_class, (temp_contact->pager == NULL) ? " " : html_encode(temp_contact->pager, FALSE)); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + } + + printf("
    Contact NameAliasEmail AddressPager Address/NumberService Notification OptionsHost Notification OptionsService Notification PeriodHost Notification PeriodService Notification CommandsHost Notification CommandsRetention Options
    %s%s%s%s", bg_class); + options = 0; + if(temp_contact->notify_on_service_unknown == TRUE) { + options = 1; + printf("Unknown"); + } + if(temp_contact->notify_on_service_warning == TRUE) { + printf("%sWarning", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_service_critical == TRUE) { + printf("%sCritical", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_service_recovery == TRUE) { + printf("%sRecovery", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_service_flapping == TRUE) { + printf("%sFlapping", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_service_downtime == TRUE) { + printf("%sDowntime", (options) ? ", " : ""); + options = 1; + } + if(!options) + printf("None"); + printf("", bg_class); + options = 0; + if(temp_contact->notify_on_host_down == TRUE) { + options = 1; + printf("Down"); + } + if(temp_contact->notify_on_host_unreachable == TRUE) { + printf("%sUnreachable", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_host_recovery == TRUE) { + printf("%sRecovery", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_host_flapping == TRUE) { + printf("%sFlapping", (options) ? ", " : ""); + options = 1; + } + if(temp_contact->notify_on_host_downtime == TRUE) { + printf("%sDowntime", (options) ? ", " : ""); + options = 1; + } + if(!options) + printf("None"); + printf("\n", bg_class); + if(temp_contact->service_notification_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_contact->service_notification_period), html_encode(temp_contact->service_notification_period, FALSE)); + printf("\n", bg_class); + if(temp_contact->host_notification_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_contact->host_notification_period), html_encode(temp_contact->host_notification_period, FALSE)); + printf("", bg_class); + found = FALSE; + for(temp_commandsmember = temp_contact->service_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) { + + if(temp_commandsmember != temp_contact->service_notification_commands) + printf(", "); + + /* printf("%s",CONFIG_CGI,url_encode(strtok(temp_commandsmember->command,"!")),html_encode(temp_commandsmember->command,FALSE)); */ + printf("%s", CONFIG_CGI, url_encode(temp_commandsmember->command), html_encode(temp_commandsmember->command, FALSE)); + + found = TRUE; + } + if(found == FALSE) + printf("None"); + printf("", bg_class); + found = FALSE; + for(temp_commandsmember = temp_contact->host_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) { + + if(temp_commandsmember != temp_contact->host_notification_commands) + printf(", "); + + /* printf("%s",CONFIG_CGI,url_encode(strtok(temp_commandsmember->command,"!")),html_encode(temp_commandsmember->command,FALSE)); */ + printf("%s", CONFIG_CGI, url_encode(temp_commandsmember->command), html_encode(temp_commandsmember->command, FALSE)); + + found = TRUE; + } + if(found == FALSE) + printf("None"); + printf("", bg_class); + options = 0; + if(temp_contact->retain_status_information == TRUE) { + options = 1; + printf("Status Information"); + } + if(temp_contact->retain_nonstatus_information == TRUE) { + printf("%sNon-Status Information", (options == 1) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_contactgroups(void) { + contactgroup *temp_contactgroup; + contactsmember *temp_contactsmember; + int odd = 0; + char *bg_class = ""; + + /* see if user is authorized to view contactgroup information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + + printf("

    Contact Group%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + /* check all the contact groups... */ + for(temp_contactgroup = contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_contactgroup->group_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("\n", bg_class, url_encode(temp_contactgroup->group_name), html_encode(temp_contactgroup->group_name, FALSE)); + printf("\n", bg_class, html_encode(temp_contactgroup->alias, FALSE)); + + /* find all the contact who are members of this contact group... */ + printf("\n"); + + printf("\n"); + } + + printf("
    Group NameDescriptionContact Members
    %s%s", bg_class); + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + + if(temp_contactsmember != temp_contactgroup->members) + printf(", "); + + printf("%s\n", CONFIG_CGI, url_encode(temp_contactsmember->contact_name), html_encode(temp_contactsmember->contact_name, FALSE)); + } + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_services(void) { + service *temp_service = NULL; + contactsmember *temp_contactsmember = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + char *processed_string = NULL; + char command_line[MAX_INPUT_BUFFER]; + char *command_name = ""; + int options; + int odd = 0; + char time_string[16]; + char *bg_class; + int contact = 0; + + + /* see if user is authorized to view service information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Service%s%s

    \n", + (*to_expand == '\0' ? "s" : "s Named or on Host "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the services... */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) + if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_service->host_name)) || (!strcmp(to_expand, temp_service->description))) { + + /* grab macros */ + grab_service_macros_r(mac, temp_service); + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("\n", CONFIG_CGI, url_encode(temp_service->host_name), html_encode(temp_service->host_name, FALSE)); + + printf("\n", bg_class, html_encode(temp_service->description, FALSE)); + + printf("\n", bg_class, temp_service->max_attempts); + + get_interval_time_string(temp_service->check_interval, time_string, sizeof(time_string)); + printf("\n", bg_class, time_string); + get_interval_time_string(temp_service->retry_interval, time_string, sizeof(time_string)); + printf("\n", bg_class, time_string); + + strncpy(command_line, temp_service->service_check_command, sizeof(command_line)); + command_line[sizeof(command_line) - 1] = '\x0'; + command_name = strtok(strdup(command_line), "!"); + + /* printf("\n",bg_class,CONFIG_CGI,url_encode(command_name),html_encode(command_line,FALSE)); */ + printf("\n", bg_class, CONFIG_CGI, url_encode(command_line), html_encode(command_line, FALSE)); + free(command_name); + printf("\n"); + + printf("\n", bg_class, (temp_service->parallelize == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_service->is_volatile == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_service->obsess_over_service == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_service->checks_enabled == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_service->accept_passive_service_checks == TRUE) ? "Yes" : "No"); + + printf("\n", bg_class, (temp_service->check_freshness == TRUE) ? "Yes" : "No"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + get_interval_time_string(temp_service->notification_interval, time_string, sizeof(time_string)); + printf("\n", bg_class, (temp_service->notification_interval == 0) ? "No Re-notification" : html_encode(time_string, FALSE)); + + get_interval_time_string(temp_service->first_notification_delay, time_string, sizeof(time_string)); + printf("\n", bg_class, time_string); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n", bg_class, (temp_service->failure_prediction_options == NULL) ? " " : html_encode(temp_service->failure_prediction_options, FALSE)); + + printf("", bg_class, (temp_service->notes == NULL) ? " " : html_encode(temp_service->notes, FALSE)); + + printf("", bg_class, (temp_service->notes_url == NULL) ? " " : html_encode(temp_service->notes_url, FALSE)); + + printf("", bg_class, (temp_service->action_url == NULL) ? " " : html_encode(temp_service->action_url, FALSE)); + + if(temp_service->icon_image == NULL) + printf("", bg_class); + else { + process_macros_r(mac, temp_service->icon_image, &processed_string, 0); + printf("", bg_class, url_logo_images_path, processed_string, html_encode(temp_service->icon_image, FALSE)); + free(processed_string); + } + + printf("", bg_class, (temp_service->icon_image_alt == NULL) ? " " : html_encode(temp_service->icon_image_alt, FALSE)); + + printf("\n"); + + printf("\n"); + } + + printf("
    Service
    HostDescriptionMax. Check AttemptsNormal Check IntervalRetry Check InteralCheck CommandCheck PeriodParallelizeVolatileObsess OverEnable Active ChecksEnable Passive ChecksCheck FreshnessFreshness ThresholdDefault Contacts/GroupsEnable NotificationsNotification IntervalFirst Notification DelayNotification OptionsNotification PeriodEvent HandlerEnable Event HandlerStalking OptionsEnable Flap DetectionLow Flap ThresholdHigh Flap ThresholdFlap Detection OptionsProcess Performance DataEnable Failure PredictionFailure Prediction OptionsNotesNotes URLAction URLLogo ImageImage AltRetention Options
    ", url_encode(temp_service->description)); + printf("%s%s%d%s%s%s%s", bg_class); + if(temp_service->check_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_service->check_period), html_encode(temp_service->check_period, FALSE)); + printf("%s%s%s%s%s%s", bg_class); + if(temp_service->freshness_threshold == 0) + printf("Auto-determined value\n"); + else + printf("%d seconds\n", temp_service->freshness_threshold); + printf("", bg_class); + contact = 0; + for(temp_contactsmember = temp_service->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s", CONFIG_CGI, url_encode(temp_contactsmember->contact_name), html_encode(temp_contactsmember->contact_name, FALSE)); + } + for(temp_contactgroupsmember = temp_service->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_contactgroupsmember->group_name), html_encode(temp_contactgroupsmember->group_name, FALSE)); + } + if(contact == 0) + printf(" "); + printf("", bg_class); + printf("%s\n", (temp_service->notifications_enabled == TRUE) ? "Yes" : "No"); + printf("%s%s", bg_class); + options = 0; + if(temp_service->notify_on_unknown == TRUE) { + options = 1; + printf("Unknown"); + } + if(temp_service->notify_on_warning == TRUE) { + printf("%sWarning", (options) ? ", " : ""); + options = 1; + } + if(temp_service->notify_on_critical == TRUE) { + printf("%sCritical", (options) ? ", " : ""); + options = 1; + } + if(temp_service->notify_on_recovery == TRUE) { + printf("%sRecovery", (options) ? ", " : ""); + options = 1; + } + if(temp_service->notify_on_flapping == TRUE) { + printf("%sFlapping", (options) ? ", " : ""); + options = 1; + } + if(temp_service->notify_on_downtime == TRUE) { + printf("%sDowntime", (options) ? ", " : ""); + options = 1; + } + if(!options) + printf("None"); + printf("", bg_class); + if(temp_service->notification_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_service->notification_period), html_encode(temp_service->notification_period, FALSE)); + printf("", bg_class); + if(temp_service->event_handler == NULL) + printf(" "); + else + /* printf("%s",CONFIG_CGI,url_encode(strtok(temp_service->event_handler,"!")),html_encode(temp_service->event_handler,FALSE)); */ + printf("%s", CONFIG_CGI, url_encode(temp_service->event_handler), html_encode(temp_service->event_handler, FALSE)); + printf("", bg_class); + printf("%s\n", (temp_service->event_handler_enabled == TRUE) ? "Yes" : "No"); + printf("", bg_class); + options = 0; + if(temp_service->stalk_on_ok == TRUE) { + options = 1; + printf("Ok"); + } + if(temp_service->stalk_on_warning == TRUE) { + printf("%sWarning", (options) ? ", " : ""); + options = 1; + } + if(temp_service->stalk_on_unknown == TRUE) { + printf("%sUnknown", (options) ? ", " : ""); + options = 1; + } + if(temp_service->stalk_on_critical == TRUE) { + printf("%sCritical", (options) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("", bg_class); + printf("%s\n", (temp_service->flap_detection_enabled == TRUE) ? "Yes" : "No"); + printf("", bg_class); + if(temp_service->low_flap_threshold == 0.0) + printf("Program-wide value\n"); + else + printf("%3.1f%%\n", temp_service->low_flap_threshold); + printf("", bg_class); + if(temp_service->high_flap_threshold == 0.0) + printf("Program-wide value\n"); + else + printf("%3.1f%%\n", temp_service->high_flap_threshold); + printf("", bg_class); + options = 0; + if(temp_service->flap_detection_on_ok == TRUE) { + options = 1; + printf("Ok"); + } + if(temp_service->flap_detection_on_warning == TRUE) { + printf("%sWarning", (options) ? ", " : ""); + options = 1; + } + if(temp_service->flap_detection_on_unknown == TRUE) { + printf("%sUnknown", (options) ? ", " : ""); + options = 1; + } + if(temp_service->flap_detection_on_critical == TRUE) { + printf("%sCritical", (options) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("", bg_class); + printf("%s\n", (temp_service->process_performance_data == TRUE) ? "Yes" : "No"); + printf("", bg_class); + printf("%s\n", (temp_service->failure_prediction_enabled == TRUE) ? "Yes" : "No"); + printf("%s%s%s%s  %s%s", bg_class); + options = 0; + if(temp_service->retain_status_information == TRUE) { + options = 1; + printf("Status Information"); + } + if(temp_service->retain_nonstatus_information == TRUE) { + printf("%sNon-Status Information", (options == 1) ? ", " : ""); + options = 1; + } + if(options == 0) + printf("None"); + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_timeperiods(void) { + timerange *temp_timerange = NULL; + daterange *temp_daterange = NULL; + timeperiod *temp_timeperiod = NULL; + timeperiodexclusion *temp_timeperiodexclusion = NULL; + char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}; + char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}; + int odd = 0; + int day = 0; + int x = 0; + char *bg_class = ""; + char timestring[10]; + int hours = 0; + int minutes = 0; + int seconds = 0; + int line = 0; + int item = 0; + + /* see if user is authorized to view time period information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Time Period%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + /* check all the time periods... */ + for(temp_timeperiod = timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_timeperiod->name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("\n", bg_class, url_encode(temp_timeperiod->name), html_encode(temp_timeperiod->name, FALSE)); + printf("\n", bg_class, html_encode(temp_timeperiod->alias, FALSE)); + + printf(""); + + printf("\n"); + printf("\n"); + } + } + for(day = 0; day < 7; day++) { + + if(temp_timeperiod->days[day] == NULL) + continue; + + line++; + + if(line > 1) + printf("\n"); + printf("\n"); + } + + if(line == 0) { + printf("\n"); + printf("\n"); + } + } + + printf("
    NameAlias/DescriptionExclusionsDays/DatesTimes
    %s%s", bg_class); + item = 0; + for(temp_timeperiodexclusion = temp_timeperiod->exclusions; temp_timeperiodexclusion != NULL; temp_timeperiodexclusion = temp_timeperiodexclusion->next) { + item++; + printf("%s%s", (item == 1) ? "" : ", ", url_encode(temp_timeperiodexclusion->timeperiod_name), html_encode(temp_timeperiodexclusion->timeperiod_name, FALSE)); + } + printf("", bg_class); + + line = 0; + for(x = 0; x < DATERANGE_TYPES; x++) { + for(temp_daterange = temp_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) { + + line++; + + if(line > 1) + printf("
    \n", bg_class); + + switch(temp_daterange->type) { + case DATERANGE_CALENDAR_DATE: + printf("%d-%02d-%02d", temp_daterange->syear, temp_daterange->smon + 1, temp_daterange->smday); + if((temp_daterange->smday != temp_daterange->emday) || (temp_daterange->smon != temp_daterange->emon) || (temp_daterange->syear != temp_daterange->eyear)) + printf(" - %d-%02d-%02d", temp_daterange->eyear, temp_daterange->emon + 1, temp_daterange->emday); + if(temp_daterange->skip_interval > 1) + printf(" / %d", temp_daterange->skip_interval); + break; + case DATERANGE_MONTH_DATE: + printf("%s %d", months[temp_daterange->smon], temp_daterange->smday); + if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->smday != temp_daterange->emday)) { + printf(" - %s %d", months[temp_daterange->emon], temp_daterange->emday); + if(temp_daterange->skip_interval > 1) + printf(" / %d", temp_daterange->skip_interval); + } + break; + case DATERANGE_MONTH_DAY: + printf("day %d", temp_daterange->smday); + if(temp_daterange->smday != temp_daterange->emday) { + printf(" - %d", temp_daterange->emday); + if(temp_daterange->skip_interval > 1) + printf(" / %d", temp_daterange->skip_interval); + } + break; + case DATERANGE_MONTH_WEEK_DAY: + printf("%s %d %s", days[temp_daterange->swday], temp_daterange->swday_offset, months[temp_daterange->smon]); + if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) { + printf(" - %s %d %s", days[temp_daterange->ewday], temp_daterange->ewday_offset, months[temp_daterange->emon]); + if(temp_daterange->skip_interval > 1) + printf(" / %d", temp_daterange->skip_interval); + } + break; + case DATERANGE_WEEK_DAY: + printf("%s %d", days[temp_daterange->swday], temp_daterange->swday_offset); + if((temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) { + printf(" - %s %d", days[temp_daterange->ewday], temp_daterange->ewday_offset); + if(temp_daterange->skip_interval > 1) + printf(" / %d", temp_daterange->skip_interval); + } + break; + default: + break; + } + + printf("\n", bg_class); + + for(temp_timerange = temp_daterange->times; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + + if(temp_timerange != temp_daterange->times) + printf(", "); + + hours = temp_timerange->range_start / 3600; + minutes = (temp_timerange->range_start - (hours * 3600)) / 60; + seconds = temp_timerange->range_start - (hours * 3600) - (minutes * 60); + snprintf(timestring, sizeof(timestring) - 1, "%02d:%02d:%02d", hours, minutes, seconds); + timestring[sizeof(timestring) - 1] = '\x0'; + printf("%s - ", timestring); + + hours = temp_timerange->range_end / 3600; + minutes = (temp_timerange->range_end - (hours * 3600)) / 60; + seconds = temp_timerange->range_end - (hours * 3600) - (minutes * 60); + snprintf(timestring, sizeof(timestring) - 1, "%02d:%02d:%02d", hours, minutes, seconds); + timestring[sizeof(timestring) - 1] = '\x0'; + printf("%s", timestring); + } + + printf("
    \n", bg_class); + + printf("%s", days[day]); + + printf("\n", bg_class); + + for(temp_timerange = temp_timeperiod->days[day]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { + + if(temp_timerange != temp_timeperiod->days[day]) + printf(", "); + + hours = temp_timerange->range_start / 3600; + minutes = (temp_timerange->range_start - (hours * 3600)) / 60; + seconds = temp_timerange->range_start - (hours * 3600) - (minutes * 60); + snprintf(timestring, sizeof(timestring) - 1, "%02d:%02d:%02d", hours, minutes, seconds); + timestring[sizeof(timestring) - 1] = '\x0'; + printf("%s - ", timestring); + + hours = temp_timerange->range_end / 3600; + minutes = (temp_timerange->range_end - (hours * 3600)) / 60; + seconds = temp_timerange->range_end - (hours * 3600) - (minutes * 60); + snprintf(timestring, sizeof(timestring) - 1, "%02d:%02d:%02d", hours, minutes, seconds); + timestring[sizeof(timestring) - 1] = '\x0'; + printf("%s", timestring); + } + + printf(" 
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_commands(void) { + command *temp_command; + int odd = 0; + char *bg_class = ""; + + /* see if user is authorized to view command information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Command%s%s

    \n", + (*to_expand == '\0' ? "s" : " "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("\n"); + printf("\n"); + + /* check all commands */ + for(temp_command = command_list; temp_command != NULL; temp_command = temp_command->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_command->name))) { + + if(odd) { + odd = 0; + bg_class = "dataEven"; + } + else { + odd = 1; + bg_class = "dataOdd"; + } + + printf("\n", bg_class); + + printf("\n", bg_class, url_encode(temp_command->name), html_encode(temp_command->name, FALSE)); + printf("\n", bg_class, html_encode(temp_command->command_line, FALSE)); + + printf("\n"); + } + + printf("
    Command NameCommand Line
    %s%s
    \n"); + printf("

    \n"); + + return; + } + + + +void display_servicedependencies(void) { + servicedependency *temp_sd; + int odd = 0; + int options; + char *bg_class = ""; + + /* see if user is authorized to view hostgroup information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Service Dependencie%s%s

    \n", + (*to_expand == '\0' ? "s" : "s Involving Host "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the service dependencies... */ + for(temp_sd = servicedependency_list; temp_sd != NULL; temp_sd = temp_sd->next) + if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_sd->dependent_host_name)) || (!strcmp(to_expand, temp_sd->host_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("", bg_class, CONFIG_CGI, url_encode(temp_sd->dependent_host_name), html_encode(temp_sd->dependent_host_name, FALSE)); + + printf("\n", url_encode(temp_sd->dependent_service_description), html_encode(temp_sd->dependent_service_description, FALSE)); + + printf("", bg_class, CONFIG_CGI, url_encode(temp_sd->host_name), html_encode(temp_sd->host_name, FALSE)); + + printf("\n", url_encode(temp_sd->service_description), html_encode(temp_sd->service_description, FALSE)); + + printf("", bg_class, (temp_sd->dependency_type == NOTIFICATION_DEPENDENCY) ? "Notification" : "Check Execution"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + } + + printf("
    Dependent ServiceMaster Service
    HostServiceHostServiceDependency TypeDependency PeriodDependency Failure Options
    %s%s%s%s%s", bg_class); + if(temp_sd->dependency_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_sd->dependency_period), html_encode(temp_sd->dependency_period, FALSE)); + printf("", bg_class); + options = FALSE; + if(temp_sd->fail_on_ok == TRUE) { + printf("Ok"); + options = TRUE; + } + if(temp_sd->fail_on_warning == TRUE) { + printf("%sWarning", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_sd->fail_on_unknown == TRUE) { + printf("%sUnknown", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_sd->fail_on_critical == TRUE) { + printf("%sCritical", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_sd->fail_on_pending == TRUE) { + printf("%sPending", (options == TRUE) ? ", " : ""); + options = TRUE; + } + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_serviceescalations(void) { + serviceescalation *temp_se = NULL; + contactsmember *temp_contactsmember = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + char time_string[16] = ""; + int options = FALSE; + int odd = 0; + char *bg_class = ""; + int contact = 0; + + /* see if user is authorized to view hostgroup information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Service Escalation%s%s

    \n", + (*to_expand == '\0' ? "s" : "s on Host "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the service escalations... */ + for(temp_se = serviceescalation_list; temp_se != NULL; temp_se = temp_se->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_se->host_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("", bg_class, CONFIG_CGI, url_encode(temp_se->host_name), html_encode(temp_se->host_name, FALSE)); + + printf("\n", url_encode(temp_se->description), html_encode(temp_se->description, FALSE)); + + printf("\n"); + + printf("", bg_class, temp_se->first_notification); + + printf("\n"); + + get_interval_time_string(temp_se->notification_interval, time_string, sizeof(time_string)); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + } + + printf("
    Service
    HostDescriptionContacts/GroupsFirst NotificationLast NotificationNotification IntervalEscalation PeriodEscalation Options
    %s%s", bg_class); + contact = 0; + for(temp_contactsmember = temp_se->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_contactsmember->contact_name), html_encode(temp_contactsmember->contact_name, FALSE)); + } + for(temp_contactgroupsmember = temp_se->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_contactgroupsmember->group_name), html_encode(temp_contactgroupsmember->group_name, FALSE)); + } + if(contact == 0) + printf(" "); + printf("%d", bg_class); + if(temp_se->last_notification == 0) + printf("Infinity"); + else + printf("%d", temp_se->last_notification); + printf("", bg_class); + if(temp_se->notification_interval == 0.0) + printf("Notify Only Once (No Re-notification)"); + else + printf("%s", time_string); + printf("", bg_class); + if(temp_se->escalation_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_se->escalation_period), html_encode(temp_se->escalation_period, FALSE)); + printf("", bg_class); + options = FALSE; + if(temp_se->escalate_on_warning == TRUE) { + printf("%sWarning", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_se->escalate_on_unknown == TRUE) { + printf("%sUnknown", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_se->escalate_on_critical == TRUE) { + printf("%sCritical", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_se->escalate_on_recovery == TRUE) { + printf("%sRecovery", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(options == FALSE) + printf("None"); + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_hostdependencies(void) { + hostdependency *temp_hd; + int odd = 0; + int options; + char *bg_class = ""; + + /* see if user is authorized to view hostdependency information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Host Dependencie%s%s

    \n", + (*to_expand == '\0' ? "s" : "s Involving Host "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the host dependencies... */ + for(temp_hd = hostdependency_list; temp_hd != NULL; temp_hd = temp_hd->next) + if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_hd->dependent_host_name)) || (!strcmp(to_expand, temp_hd->host_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("", bg_class, CONFIG_CGI, url_encode(temp_hd->dependent_host_name), html_encode(temp_hd->dependent_host_name, FALSE)); + + printf("", bg_class, CONFIG_CGI, url_encode(temp_hd->host_name), html_encode(temp_hd->host_name, FALSE)); + + printf("", bg_class, (temp_hd->dependency_type == NOTIFICATION_DEPENDENCY) ? "Notification" : "Check Execution"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + } + + printf("
    Dependent HostMaster HostDependency TypeDependency PeriodDependency Failure Options
    %s%s%s", bg_class); + if(temp_hd->dependency_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_hd->dependency_period), html_encode(temp_hd->dependency_period, FALSE)); + printf("", bg_class); + options = FALSE; + if(temp_hd->fail_on_up == TRUE) { + printf("Up"); + options = TRUE; + } + if(temp_hd->fail_on_down == TRUE) { + printf("%sDown", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_hd->fail_on_unreachable == TRUE) { + printf("%sUnreachable", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_hd->fail_on_pending == TRUE) { + printf("%sPending", (options == TRUE) ? ", " : ""); + options = TRUE; + } + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_hostescalations(void) { + hostescalation *temp_he = NULL; + contactsmember *temp_contactsmember = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + char time_string[16] = ""; + int options = FALSE; + int odd = 0; + char *bg_class = ""; + int contact = 0; + + /* see if user is authorized to view hostgroup information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Host Escalation%s%s

    \n", + (*to_expand == '\0' ? "s" : "s for Host "), (*to_expand == '\0' ? "" : html_encode(to_expand, FALSE))); + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + /* check all the host escalations... */ + for(temp_he = hostescalation_list; temp_he != NULL; temp_he = temp_he->next) if(((*to_expand) == '\0') || (!strcmp(to_expand, temp_he->host_name))) { + + if(odd) { + odd = 0; + bg_class = "dataOdd"; + } + else { + odd = 1; + bg_class = "dataEven"; + } + + printf("\n", bg_class); + + printf("", bg_class, CONFIG_CGI, url_encode(temp_he->host_name), html_encode(temp_he->host_name, FALSE)); + + printf("\n"); + + printf("", bg_class, temp_he->first_notification); + + printf("\n"); + + get_interval_time_string(temp_he->notification_interval, time_string, sizeof(time_string)); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + } + + printf("
    HostContacts/GroupsFirst NotificationLast NotificationNotification IntervalEscalation PeriodEscalation Options
    %s", bg_class); + contact = 0; + for(temp_contactsmember = temp_he->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_contactsmember->contact_name), html_encode(temp_contactsmember->contact_name, FALSE)); + } + for(temp_contactgroupsmember = temp_he->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { + contact++; + if(contact > 1) + printf(", "); + printf("%s\n", CONFIG_CGI, url_encode(temp_contactgroupsmember->group_name), html_encode(temp_contactgroupsmember->group_name, FALSE)); + } + if(contact == 0) + printf(" "); + printf("%d", bg_class); + if(temp_he->last_notification == 0) + printf("Infinity"); + else + printf("%d", temp_he->last_notification); + printf("", bg_class); + if(temp_he->notification_interval == 0.0) + printf("Notify Only Once (No Re-notification)"); + else + printf("%s", time_string); + printf("", bg_class); + if(temp_he->escalation_period == NULL) + printf(" "); + else + printf("%s", CONFIG_CGI, url_encode(temp_he->escalation_period), html_encode(temp_he->escalation_period, FALSE)); + printf("", bg_class); + options = FALSE; + if(temp_he->escalate_on_down == TRUE) { + printf("%sDown", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_he->escalate_on_unreachable == TRUE) { + printf("%sUnreachable", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(temp_he->escalate_on_recovery == TRUE) { + printf("%sRecovery", (options == TRUE) ? ", " : ""); + options = TRUE; + } + if(options == FALSE) + printf("None"); + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void unauthorized_message(void) { + + printf("

    It appears as though you do not have permission to view the configuration information you requested...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + + + +char *hash_color(int i) { + char c; + + /* This is actually optimized for MAX_COMMAND_ARGUMENTS==32 ... */ + + if((i % 32) < 16) { + if((i % 32) < 8) c = '7'; + else c = '4'; + } + else { + if((i % 32) < 24) c = '6'; + else c = '5'; + } + + /* Computation for standard case */ + hashed_color[0] = '#'; + hashed_color[1] = hashed_color[2] = ((i % 2) ? c : '0'); + hashed_color[3] = hashed_color[4] = (((i / 2) % 2) ? c : '0'); + hashed_color[5] = hashed_color[6] = (((i / 4) % 2) ? c : '0'); + hashed_color[7] = '\0'; + + /* Override shades of grey */ + if((i % 8) == 7) hashed_color[1] = hashed_color[3] = '0'; + if((i % 8) == 0) hashed_color[2] = hashed_color[3] = hashed_color[4] = hashed_color[6] = c; + + return(hashed_color); + } + +void display_command_expansion(void) { + command *temp_command; + int odd = 0; + char *bg_class = ""; + int i, j; + char *c, *cc; + char commandline[MAX_COMMAND_BUFFER]; + char *command_args[MAX_COMMAND_ARGUMENTS]; + int arg_count[MAX_COMMAND_ARGUMENTS], + lead_space[MAX_COMMAND_ARGUMENTS], + trail_space[MAX_COMMAND_ARGUMENTS]; + + /* see if user is authorized to view command information... */ + if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) { + unauthorized_message(); + return; + } + + printf("

    Command Expansion

    \n"); + + /* Parse to_expand into parts */ + for(i = 0; i < MAX_COMMAND_ARGUMENTS; i++) command_args[i] = NULL; + for(i = 0, command_args[0] = cc = c = strdup(to_expand); c && ((*c) != '\0') && (i < MAX_COMMAND_ARGUMENTS); c++, cc++) { + if((*c) == '\\') c++; + else if((*c) == '!') { + (*cc) = '\0'; + cc = c++; + command_args[++i] = (c--); + } + (*cc) = (*c); + } + if((*c) == '\0')(*cc) = '\0'; + /* Precompute indexes of dangling whitespace */ + for(i = 0; i < MAX_COMMAND_ARGUMENTS; i++) { + for(cc = command_args[i], lead_space[i] = 0; cc && isspace(*cc); cc++, lead_space[i]++) ; + trail_space[i] = 0; + for(; cc && ((*cc) != '\0'); cc++) if(isspace(*cc)) trail_space[i]++; + else trail_space[i] = 0; + } + + printf("

    \n"); + printf("\n"); + printf("\n"); + + if((*to_expand) != '\0') { + arg_count[0] = 0; + + printf("\n"); + + /* check all commands */ + for(temp_command = command_list; temp_command != NULL; temp_command = temp_command->next) { + + if(!strcmp(temp_command->name, command_args[0])) { + + arg_count[0]++; + + if(odd) { + odd = 0; + bg_class = "dataEven"; + } + else { + odd = 1; + bg_class = "dataOdd"; + } + + printf("\n", bg_class); + + printf("\n", bg_class, url_encode(temp_command->name), html_encode(temp_command->name, FALSE)); + printf("\n", bg_class, html_encode(temp_command->command_line, FALSE)); + + printf("\n\n", bg_class); + + for(i = 1; i < MAX_COMMAND_ARGUMENTS; i++) arg_count[i] = 0; + + printf("\n", bg_class); + printf("\n"); + + for(i = 1; (i < MAX_COMMAND_ARGUMENTS) && (command_args[i]); i++) { + if(arg_count[i] == 0) { + printf("\n", bg_class, bg_class); + printf("\n", bg_class, i, hash_color(i), + ((lead_space[i] > 0) || (trail_space[i] > 0) ? "‍" : ""), html_encode(command_args[i], FALSE), + ((lead_space[i] > 0) || (trail_space[i] > 0) ? "‍" : "")); + } + else if(arg_count[i] > 1) { + printf("\n", bg_class, bg_class, i); + printf("\n", bg_class, i, hash_color(i), + ((lead_space[i] > 0) || (trail_space[i] > 0) ? "‍" : ""), html_encode(command_args[i], FALSE), + ((lead_space[i] > 0) || (trail_space[i] > 0) ? "‍" : "")); + } + if((lead_space[i] > 0) || (trail_space[i] > 0)) { + printf("\n", bg_class, bg_class); + printf("\n"); + } + } + } + + } + + if(!arg_count[0]) { + printf("\n", html_encode(command_args[0], FALSE)); + } + } + + printf("\n"); + printf("\n"); + + printf("
    Command NameCommand Line
    To expand:%s", escape_string(command_args[0])); + for(i = 1; (i < MAX_COMMAND_ARGUMENTS) && command_args[i]; i++) + printf("!%s", hash_color(i), escape_string(command_args[i])); + printf("\n
    %s%s
    ->", bg_class); + strncpy(commandline, temp_command->command_line, MAX_COMMAND_BUFFER); + commandline[MAX_COMMAND_BUFFER - 1] = '\0'; + for(c = commandline; c && (cc = strstr(c, "$"));) { + (*(cc++)) = '\0'; + printf("%s", html_encode(c, FALSE)); + if((*cc) == '$') { + /* Escaped '$' */ + printf("$"); + c = (++cc); + } + else if(strncmp("ARG", cc, 3)) { + /* Non-$ARGn$ macro */ + c = strstr(cc, "$"); + if(c)(*(c++)) = '\0'; + printf("$%s%s", html_encode(cc, FALSE), (c ? "$" : "")); + if(!c) printf(" (not properly terminated)"); + } + else { + /* $ARGn$ macro */ + for(c = (cc += 3); isdigit(*c); c++) ; + if(((*c) == '\0') || ((*c) == '$')) { + /* Index is numeric */ + i = atoi(cc); + if((i > 0) && (i <= MAX_COMMAND_ARGUMENTS)) { + arg_count[i]++; + if(command_args[i]) { + if(*(command_args[i]) != '\0') printf("%s%s%s", + hash_color(i), ((lead_space[i] > 0) || (trail_space[i] > 0) ? "‍" : ""), + html_encode(command_args[i], FALSE), ((lead_space[i] > 0) || (trail_space[i] > 0) ? "‍" : "")); + else printf("(empty)"); + } + else printf("(undefined)"); + } + else printf("(not a valid $ARGn$ index: %u)", i); + if((*c) != '\0') c++; + else printf(" (not properly terminated)"); + } + else { + /* Syntax err in index */ + c = strstr(cc, "$"); + printf("(not an $ARGn$ index: "%s")", html_encode(strtok(cc, "$"), FALSE)); + if(c) c++; + } + } + } + if(c) printf("%s", html_encode(c, FALSE)); + + printf("
    unused:$ARG%u$=%s%s%s
    used %u x:$ARG%u$=%s%s%s
    dangling whitespace:$ARG%u$=", bg_class, i); + for(c = command_args[i], j = 0; c && isspace(*c); c++, j++) + /* TODO: As long as the hyperlinks change all whitespace into actual spaces, + we'll output "[WS]" (whitespace) instead of "[SP]"(ace). */ + /* if ((*c)==' ') printf("[SP]"); */ + if((*c) == ' ') printf("[WS]"); + else if((*c) == '\f') printf("[FF]"); + else if((*c) == '\n') printf("[LF]"); + else if((*c) == '\r') printf("[CR]"); + else if((*c) == '\t') printf("[HT]"); + else if((*c) == '\v') printf("[VT]"); + else printf("[0x%x]", *c); + printf("", hash_color(i)); + for(; c && ((*c) != '\0') && (j < strlen(command_args[i]) - trail_space[i]); c++, j++) putchar(*c); + printf(""); + for(; c && ((*c) != '\0'); c++) + /* TODO: As long as the hyperlinks change all whitespace into actual spaces, + we'll output "[WS]" (whitespace) instead of "[SP]"(ace). */ + /* if ((*c)==' ') printf("[SP]"); */ + if((*c) == ' ') printf("[WS]"); + else if((*c) == '\f') printf("[FF]"); + else if((*c) == '\n') printf("[LF]"); + else if((*c) == '\r') printf("[CR]"); + else if((*c) == '\t') printf("[HT]"); + else if((*c) == '\v') printf("[VT]"); + else printf("[0x%x]", *c); + printf("
    Error:No\n"); + printf("command "%s" found

    Enter the command_check definition from a host or service definition and press Go to see the expansion of the command
    To expand:\n", html_encode(to_expand, FALSE)); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +void display_options(void) { + + printf("

    \n"); + + printf("
    Select Type of Config Data You Wish To View
    \n"); + + printf("

    \n"); + + printf("
    \n", CONFIG_CGI); + + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("
    Object Type:
    "); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("
    \n"); + + return; + } diff --git a/cgi/extcmd_list.c b/cgi/extcmd_list.c new file mode 100644 index 0000000..86b0ea3 --- /dev/null +++ b/cgi/extcmd_list.c @@ -0,0 +1,223 @@ +#include +#include +#include +#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 diff --git a/cgi/extinfo.c b/cgi/extinfo.c new file mode 100644 index 0000000..e2a5fda --- /dev/null +++ b/cgi/extinfo.c @@ -0,0 +1,3200 @@ +/************************************************************************** + * + * EXTINFO.C - Nagios Extended Information CGI + * + * Copyright (c) 1999-2009 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 06-17-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. + *************************************************************************/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/macros.h" +#include "../include/comments.h" +#include "../include/downtime.h" +#include "../include/statusdata.h" + +#include "../include/cgiutils.h" +#include "../include/getcgi.h" +#include "../include/cgiauth.h" + +static nagios_macros *mac; + +extern char nagios_check_command[MAX_INPUT_BUFFER]; +extern char nagios_process_info[MAX_INPUT_BUFFER]; +extern int nagios_process_state; +extern int refresh_rate; + +extern time_t program_start; +extern int nagios_pid; +extern int daemon_mode; +extern time_t last_command_check; +extern time_t last_log_rotation; +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int enable_flap_detection; +extern int enable_failure_prediction; +extern int process_performance_data; + +extern int buffer_stats[1][3]; +extern int program_stats[MAX_CHECK_STATS_TYPES][3]; + +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_docs_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]; + +extern int enable_splunk_integration; + +extern char *notes_url_target; +extern char *action_url_target; + +extern comment *comment_list; +extern scheduled_downtime *scheduled_downtime_list; +extern hoststatus *hoststatus_list; +extern servicestatus *servicestatus_list; +extern hostgroup *hostgroup_list; +extern servicegroup *servicegroup_list; + + +#define MAX_MESSAGE_BUFFER 4096 + +#define HEALTH_WARNING_PERCENTAGE 85 +#define HEALTH_CRITICAL_PERCENTAGE 75 + +/* SORTDATA structure */ +typedef struct sortdata_struct { + int is_service; + servicestatus *svcstatus; + hoststatus *hststatus; + struct sortdata_struct *next; + } sortdata; + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + +void show_process_info(void); +void show_host_info(void); +void show_service_info(void); +void show_all_comments(void); +void show_performance_data(void); +void show_hostgroup_info(void); +void show_servicegroup_info(void); +void show_all_downtime(void); +void show_scheduling_queue(void); +void display_comments(int); + +int sort_data(int, int); +int compare_sortdata_entries(int, int, sortdata *, sortdata *); +void free_sortdata_list(void); + +authdata current_authdata; + +sortdata *sortdata_list = NULL; + +char *host_name = ""; +char *hostgroup_name = ""; +char *servicegroup_name = ""; +char *service_desc = ""; + +int display_type = DISPLAY_PROCESS_INFO; + +int sort_type = SORT_ASCENDING; +int sort_option = SORT_NEXTCHECKTIME; + +int embedded = FALSE; +int display_header = TRUE; + + + +int main(void) { + int result = OK; + int found = FALSE; + char temp_buffer[MAX_INPUT_BUFFER] = ""; + char *processed_string = NULL; + host *temp_host = NULL; + hostsmember *temp_parenthost = NULL; + hostgroup *temp_hostgroup = NULL; + service *temp_service = NULL; + servicegroup *temp_servicegroup = NULL; + + mac = get_global_macros(); + + /* 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; + } + + /* initialize macros */ + init_macros(); + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* middle column of top row */ + printf("\n"); + + /* right column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + + if(display_type == DISPLAY_HOST_INFO) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Information"); + else if(display_type == DISPLAY_SERVICE_INFO) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Information"); + else if(display_type == DISPLAY_COMMENTS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "All Host and Service Comments"); + else if(display_type == DISPLAY_PERFORMANCE) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Performance Information"); + else if(display_type == DISPLAY_HOSTGROUP_INFO) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Hostgroup Information"); + else if(display_type == DISPLAY_SERVICEGROUP_INFO) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Servicegroup Information"); + else if(display_type == DISPLAY_DOWNTIME) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "All Host and Service Scheduled Downtime"); + else if(display_type == DISPLAY_SCHEDULING_QUEUE) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Check Scheduling Queue"); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Nagios Process Information"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + display_info_table(temp_buffer, TRUE, ¤t_authdata); + + /* find the host */ + if(display_type == DISPLAY_HOST_INFO || display_type == DISPLAY_SERVICE_INFO) { + + temp_host = find_host(host_name); + grab_host_macros_r(mac, temp_host); + + if(display_type == DISPLAY_SERVICE_INFO) { + temp_service = find_service(host_name, service_desc); + grab_service_macros_r(mac, temp_service); + } + + /* write some Javascript helper functions */ + if(temp_host != NULL) { + printf("\n"); + } + } + + /* find the hostgroup */ + else if(display_type == DISPLAY_HOSTGROUP_INFO) { + temp_hostgroup = find_hostgroup(hostgroup_name); + grab_hostgroup_macros_r(mac, temp_hostgroup); + } + + /* find the servicegroup */ + else if(display_type == DISPLAY_SERVICEGROUP_INFO) { + temp_servicegroup = find_servicegroup(servicegroup_name); + grab_servicegroup_macros_r(mac, temp_servicegroup); + } + + if((display_type == DISPLAY_HOST_INFO && temp_host != NULL) || (display_type == DISPLAY_SERVICE_INFO && temp_host != NULL && temp_service != NULL) || (display_type == DISPLAY_HOSTGROUP_INFO && temp_hostgroup != NULL) || (display_type == DISPLAY_SERVICEGROUP_INFO && temp_servicegroup != NULL)) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + printf("\n"); + + if((display_type == DISPLAY_HOST_INFO && temp_host != NULL) || (display_type == DISPLAY_SERVICE_INFO && temp_host != NULL && temp_service != NULL) || (display_type == DISPLAY_HOSTGROUP_INFO && temp_hostgroup != NULL) || (display_type == DISPLAY_SERVICEGROUP_INFO && temp_servicegroup != NULL)) { + + if(display_type == DISPLAY_HOST_INFO) { + printf("
    Host
    \n"); + printf("
    %s
    \n", temp_host->alias); + printf("
    (%s)

    \n", temp_host->name); + + if(temp_host->parent_hosts != NULL) { + /* print all parent hosts */ + printf("
    Parents:
    \n"); + for(temp_parenthost = temp_host->parent_hosts; temp_parenthost != NULL; temp_parenthost = temp_parenthost->next) + printf("\n", STATUS_CGI, url_encode(temp_parenthost->host_name), temp_parenthost->host_name); + printf("
    "); + } + + printf("
    Member of
    "); + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == TRUE) { + if(found == TRUE) + printf(", "); + printf("%s", STATUS_CGI, url_encode(temp_hostgroup->group_name), temp_hostgroup->group_name); + found = TRUE; + } + } + + if(found == FALSE) + printf("No hostgroups"); + printf("

    \n"); + printf("
    %s
    \n", temp_host->address); + } + if(display_type == DISPLAY_SERVICE_INFO) { + printf("
    Service
    %s
    On Host
    \n", service_desc); + printf("
    %s
    \n", temp_host->alias); + printf("
    (%s)

    \n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name), temp_host->name); + printf("
    Member of
    "); + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + if(is_service_member_of_servicegroup(temp_servicegroup, temp_service) == TRUE) { + if(found == TRUE) + printf(", "); + printf("%s", STATUS_CGI, url_encode(temp_servicegroup->group_name), temp_servicegroup->group_name); + found = TRUE; + } + } + + if(found == FALSE) + printf("No servicegroups."); + printf("

    \n"); + + printf("
    %s
    \n", temp_host->address); + } + if(display_type == DISPLAY_HOSTGROUP_INFO) { + printf("
    Hostgroup
    \n"); + printf("
    %s
    \n", temp_hostgroup->alias); + printf("
    (%s)
    \n", temp_hostgroup->group_name); + if(temp_hostgroup->notes != NULL) { + process_macros_r(mac, temp_hostgroup->notes, &processed_string, 0); + printf("

    %s

    ", processed_string); + free(processed_string); + } + } + if(display_type == DISPLAY_SERVICEGROUP_INFO) { + printf("
    Servicegroup
    \n"); + printf("
    %s
    \n", temp_servicegroup->alias); + printf("
    (%s)
    \n", temp_servicegroup->group_name); + if(temp_servicegroup->notes != NULL) { + process_macros_r(mac, temp_servicegroup->notes, &processed_string, 0); + printf("

    %s

    ", processed_string); + free(processed_string); + } + } + + if(display_type == DISPLAY_SERVICE_INFO) { + if(temp_service->icon_image != NULL) { + printf("%s
    ", (temp_service->icon_image_alt == NULL) ? "" : temp_service->icon_image_alt, (temp_service->icon_image_alt == NULL) ? "" : temp_service->icon_image_alt); + } + if(temp_service->icon_image_alt != NULL) + printf("( %s )\n", temp_service->icon_image_alt); + if(temp_service->notes != NULL) { + process_macros_r(mac, temp_service->notes, &processed_string, 0); + printf("

    %s

    \n", processed_string); + free(processed_string); + } + } + + if(display_type == DISPLAY_HOST_INFO) { + if(temp_host->icon_image != NULL) { + printf("%s
    ", (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); + } + if(temp_host->icon_image_alt != NULL) + printf("( %s )\n", temp_host->icon_image_alt); + if(temp_host->notes != NULL) { + process_macros_r(mac, temp_host->notes, &processed_string, 0); + printf("

    %s

    \n", processed_string); + free(processed_string); + } + } + } + + printf("
    \n"); + + if(display_type == DISPLAY_HOST_INFO && temp_host != NULL) { + printf("\n"); + if(temp_host->action_url != NULL && strcmp(temp_host->action_url, "")) { + printf("\n"); + } + if(temp_host->notes_url != NULL && strcmp(temp_host->notes_url, "")) { + printf("\n"); + } + printf("
    \n"); + printf("Perform Additional Actions On This Host\n", (action_url_target == NULL) ? "_blank" : action_url_target, url_images_path, ACTION_ICON); + printf("
    Extra Actions

    \n"); + printf("
    \n"); + printf("View Additional Notes For This Host\n", (notes_url_target == NULL) ? "_blank" : notes_url_target, url_images_path, NOTES_ICON); + printf("
    Extra Notes

    \n"); + printf("
    \n"); + } + + else if(display_type == DISPLAY_SERVICE_INFO && temp_service != NULL) { + printf("
    \n"); + if(temp_service->action_url != NULL && strcmp(temp_service->action_url, "")) { + printf("Perform Additional Actions On This Service\n", (action_url_target == NULL) ? "_blank" : action_url_target, url_images_path, ACTION_ICON); + printf("
    Extra Actions

    \n"); + } + if(temp_service->notes_url != NULL && strcmp(temp_service->notes_url, "")) { + printf("View Additional Notes For This Service\n", (notes_url_target == NULL) ? "_blank" : notes_url_target, url_images_path, NOTES_ICON); + printf("
    Extra Notes

    \n"); + } + printf("
    \n"); + } + + if(display_type == DISPLAY_HOSTGROUP_INFO && temp_hostgroup != NULL) { + printf("\n"); + if(temp_hostgroup->action_url != NULL && strcmp(temp_hostgroup->action_url, "")) { + printf("\n"); + } + if(temp_hostgroup->notes_url != NULL && strcmp(temp_hostgroup->notes_url, "")) { + printf("\n"); + } + printf("
    \n"); + printf("Perform Additional Actions On This Hostgroup\n", (action_url_target == NULL) ? "_blank" : action_url_target, url_images_path, ACTION_ICON); + printf("
    Extra Actions

    \n"); + printf("
    \n"); + printf("View Additional Notes For This Hostgroup\n", (notes_url_target == NULL) ? "_blank" : notes_url_target, url_images_path, NOTES_ICON); + printf("
    Extra Notes

    \n"); + printf("
    \n"); + } + + else if(display_type == DISPLAY_SERVICEGROUP_INFO && temp_servicegroup != NULL) { + printf("\n"); + if(temp_servicegroup->action_url != NULL && strcmp(temp_servicegroup->action_url, "")) { + printf("Perform Additional Actions On This Servicegroup\n", (action_url_target == NULL) ? "_blank" : action_url_target, url_images_path, ACTION_ICON); + printf("
    Extra Actions

    \n"); + } + if(temp_servicegroup->notes_url != NULL && strcmp(temp_servicegroup->notes_url, "")) { + printf("View Additional Notes For This Servicegroup\n", (notes_url_target == NULL) ? "_blank" : notes_url_target, url_images_path, NOTES_ICON); + printf("
    Extra Notes

    \n"); + } + printf("
    \n"); + } + + /* display context-sensitive help */ + if(display_type == DISPLAY_HOST_INFO) + display_context_help(CONTEXTHELP_EXT_HOST); + else if(display_type == DISPLAY_SERVICE_INFO) + display_context_help(CONTEXTHELP_EXT_SERVICE); + else if(display_type == DISPLAY_HOSTGROUP_INFO) + display_context_help(CONTEXTHELP_EXT_HOSTGROUP); + else if(display_type == DISPLAY_SERVICEGROUP_INFO) + display_context_help(CONTEXTHELP_EXT_SERVICEGROUP); + else if(display_type == DISPLAY_PROCESS_INFO) + display_context_help(CONTEXTHELP_EXT_PROCESS); + else if(display_type == DISPLAY_PERFORMANCE) + display_context_help(CONTEXTHELP_EXT_PERFORMANCE); + else if(display_type == DISPLAY_COMMENTS) + display_context_help(CONTEXTHELP_EXT_COMMENTS); + else if(display_type == DISPLAY_DOWNTIME) + display_context_help(CONTEXTHELP_EXT_DOWNTIME); + else if(display_type == DISPLAY_SCHEDULING_QUEUE) + display_context_help(CONTEXTHELP_EXT_QUEUE); + + printf("
    \n"); + + } + + printf("
    \n"); + + if(display_type == DISPLAY_HOST_INFO) + show_host_info(); + else if(display_type == DISPLAY_SERVICE_INFO) + show_service_info(); + else if(display_type == DISPLAY_COMMENTS) + show_all_comments(); + else if(display_type == DISPLAY_PERFORMANCE) + show_performance_data(); + else if(display_type == DISPLAY_HOSTGROUP_INFO) + show_hostgroup_info(); + else if(display_type == DISPLAY_SERVICEGROUP_INFO) + show_servicegroup_info(); + else if(display_type == DISPLAY_DOWNTIME) + show_all_downtime(); + else if(display_type == DISPLAY_SCHEDULING_QUEUE) + show_scheduling_queue(); + else + show_process_info(); + + document_footer(); + + /* free all allocated memory */ + free_memory(); + free_comment_data(); + free_downtime_data(); + + 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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Extended Information\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("", url_stylesheets_path, COMMON_CSS); + printf("", url_stylesheets_path, EXTINFO_CSS); + } + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(EXTINFO_CGI, SSI_HEADER); + + return; + } + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + /* include user SSI footer */ + include_ssi_files(EXTINFO_CGI, SSI_FOOTER); + + printf("\n"); + printf("\n"); + + return; + } + + +int process_cgivars(void) { + char **variables; + int error = FALSE; + int temp_type; + 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 display type */ + else if(!strcmp(variables[x], "type")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + temp_type = atoi(variables[x]); + if(temp_type == DISPLAY_HOST_INFO) + display_type = DISPLAY_HOST_INFO; + else if(temp_type == DISPLAY_SERVICE_INFO) + display_type = DISPLAY_SERVICE_INFO; + else if(temp_type == DISPLAY_COMMENTS) + display_type = DISPLAY_COMMENTS; + else if(temp_type == DISPLAY_PERFORMANCE) + display_type = DISPLAY_PERFORMANCE; + else if(temp_type == DISPLAY_HOSTGROUP_INFO) + display_type = DISPLAY_HOSTGROUP_INFO; + else if(temp_type == DISPLAY_SERVICEGROUP_INFO) + display_type = DISPLAY_SERVICEGROUP_INFO; + else if(temp_type == DISPLAY_DOWNTIME) + display_type = DISPLAY_DOWNTIME; + else if(temp_type == DISPLAY_SCHEDULING_QUEUE) + display_type = DISPLAY_SCHEDULING_QUEUE; + else + display_type = DISPLAY_PROCESS_INFO; + } + + /* we found the host name */ + else if(!strcmp(variables[x], "host")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + host_name = strdup(variables[x]); + if(host_name == NULL) + host_name = ""; + strip_html_brackets(host_name); + } + + /* we found the hostgroup name */ + else if(!strcmp(variables[x], "hostgroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + hostgroup_name = strdup(variables[x]); + if(hostgroup_name == NULL) + hostgroup_name = ""; + strip_html_brackets(hostgroup_name); + } + + /* we found the service name */ + else if(!strcmp(variables[x], "service")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + service_desc = strdup(variables[x]); + if(service_desc == NULL) + service_desc = ""; + strip_html_brackets(service_desc); + } + + /* we found the servicegroup name */ + else if(!strcmp(variables[x], "servicegroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + servicegroup_name = strdup(variables[x]); + if(servicegroup_name == NULL) + servicegroup_name = ""; + strip_html_brackets(servicegroup_name); + } + + /* we found the sort type argument */ + else if(!strcmp(variables[x], "sorttype")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + sort_type = atoi(variables[x]); + } + + /* we found the sort option argument */ + else if(!strcmp(variables[x], "sortoption")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + sort_option = atoi(variables[x]); + } + + /* 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; + } + + + +void show_process_info(void) { + char date_time[MAX_DATETIME_LENGTH]; + time_t current_time; + unsigned long run_time; + char run_time_string[24]; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + /* make sure the user has rights to view system information */ + if(is_authorized_for_system_information(¤t_authdata) == FALSE) { + + printf("

    It appears as though you do not have permission to view process information...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + printf("
    \n"); + printf("
    \n"); + + printf("\n"); + printf("
    \n"); + + printf("
    Process Information
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + /* program version */ + printf("\n", PROGRAM_VERSION); + + /* program start time */ + get_time_string(&program_start, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", date_time); + + /* total running time */ + time(¤t_time); + run_time = (unsigned long)(current_time - program_start); + get_time_breakdown(run_time, &days, &hours, &minutes, &seconds); + sprintf(run_time_string, "%dd %dh %dm %ds", days, hours, minutes, seconds); + printf("\n", run_time_string); + + /* last external check */ + get_time_string(&last_command_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (last_command_check == (time_t)0) ? "N/A" : date_time); + + /* last log file rotation */ + get_time_string(&last_log_rotation, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (last_log_rotation == (time_t)0) ? "N/A" : date_time); + + /* PID */ + printf("\n", nagios_pid); + + /* notifications enabled */ + printf("\n", (enable_notifications == TRUE) ? "ENABLED" : "DISABLED", (enable_notifications == TRUE) ? "YES" : "NO"); + + /* service check execution enabled */ + printf("\n", (execute_service_checks == TRUE) ? "ENABLED" : "DISABLED", (execute_service_checks == TRUE) ? "YES" : "NO"); + + /* passive service check acceptance */ + printf("\n", (accept_passive_service_checks == TRUE) ? "ENABLED" : "DISABLED", (accept_passive_service_checks == TRUE) ? "YES" : "NO"); + + /* host check execution enabled */ + printf("\n", (execute_host_checks == TRUE) ? "ENABLED" : "DISABLED", (execute_host_checks == TRUE) ? "YES" : "NO"); + + /* passive host check acceptance */ + printf("\n", (accept_passive_host_checks == TRUE) ? "ENABLED" : "DISABLED", (accept_passive_host_checks == TRUE) ? "YES" : "NO"); + + /* event handlers enabled */ + printf("\n", (enable_event_handlers == TRUE) ? "Yes" : "No"); + + /* obsessing over services */ + printf("\n", (obsess_over_services == TRUE) ? "Yes" : "No"); + + /* obsessing over hosts */ + printf("\n", (obsess_over_hosts == TRUE) ? "Yes" : "No"); + + /* flap detection enabled */ + printf("\n", (enable_flap_detection == TRUE) ? "Yes" : "No"); + +#ifdef PREDICT_FAILURES + /* failure prediction enabled */ + printf("\n", (enable_failure_prediction == TRUE) ? "Yes" : "No"); +#endif + + /* process performance data */ + printf("\n", (process_performance_data == TRUE) ? "Yes" : "No"); + +#ifdef USE_OLDCRUD + /* daemon mode */ + printf("\n", (daemon_mode == TRUE) ? "Yes" : "No"); +#endif + + printf("
    Program Version:%s
    Program Start Time:%s
    Total Running Time:%s
    Last External Command Check:%s
    Last Log File Rotation:%s
    Nagios PID%d
    Notifications Enabled?
      %s  
    Service Checks Being Executed?
      %s  
    Passive Service Checks Being Accepted?
      %s  
    Host Checks Being Executed?
      %s  
    Passive Host Checks Being Accepted?
      %s  
    Event Handlers Enabled?%s
    Obsessing Over Services?%s
    Obsessing Over Hosts?%s
    Flap Detection Enabled?%s
    Failure Prediction Enabled?%s
    Performance Data Being Processed?%s
    Running As A Daemon?%s
    \n"); + printf("
    \n"); + + + printf("
    \n"); + + printf("
    Process Commands
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + + if(nagios_process_state == STATE_OK) { + printf("\n"); + +#ifndef DUMMY_INSTALL + printf("\n", url_images_path, STOP_ICON, COMMAND_CGI, CMD_SHUTDOWN_PROCESS); + printf("\n", url_images_path, RESTART_ICON, COMMAND_CGI, CMD_RESTART_PROCESS); +#endif + + if(enable_notifications == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_NOTIFICATIONS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_NOTIFICATIONS); + + if(execute_service_checks == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_EXECUTING_SVC_CHECKS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_EXECUTING_SVC_CHECKS); + + if(accept_passive_service_checks == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS); + + if(execute_host_checks == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_EXECUTING_HOST_CHECKS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_EXECUTING_HOST_CHECKS); + + if(accept_passive_host_checks == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS); + + if(enable_event_handlers == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_EVENT_HANDLERS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_EVENT_HANDLERS); + + if(obsess_over_services == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_OBSESSING_OVER_SVC_CHECKS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_OBSESSING_OVER_SVC_CHECKS); + + if(obsess_over_hosts == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_OBSESSING_OVER_HOST_CHECKS); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_OBSESSING_OVER_HOST_CHECKS); + + if(enable_flap_detection == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_FLAP_DETECTION); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_FLAP_DETECTION); + +#ifdef PREDICT_FAILURES + if(enable_failure_prediction == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_FAILURE_PREDICTION); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_FAILURE_PREDICTION); +#endif + if(process_performance_data == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_PERFORMANCE_DATA); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_PERFORMANCE_DATA); + + printf("
    Shutdown the Nagios ProcessShutdown the Nagios process
    Restart the Nagios ProcessRestart the Nagios process
    Disable NotificationsDisable notifications
    Enable NotificationsEnable notifications
    Stop Executing Service ChecksStop executing service checks
    Start Executing Service ChecksStart executing service checks
    Stop Accepting Passive Service ChecksStop accepting passive service checks
    Start Accepting Passive Service ChecksStart accepting passive service checks
    Stop Executing Host ChecksStop executing host checks
    Start Executing Host ChecksStart executing host checks
    Stop Accepting Passive Host ChecksStop accepting passive host checks
    Start Accepting Passive Host ChecksStart accepting passive host checks
    Disable Event HandlersDisable event handlers
    Enable Event HandlersEnable event handlers
    Stop Obsessing Over ServicesStop obsessing over services
    Start Obsessing Over ServicesStart obsessing over services
    Stop Obsessing Over HostsStop obsessing over hosts
    Start Obsessing Over HostsStart obsessing over hosts
    Disable Flap DetectionDisable flap detection
    Enable Flap DetectionEnable flap detection
    Disable Failure PredictionDisable failure prediction
    Enable Failure PredictionEnable failure prediction
    Disable Performance DataDisable performance data
    Enable Performance DataEnable performance data
    \n"); + } + else { + printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...\n"); + if(!strcmp(nagios_check_command, "")) { + printf("

    \n"); + printf("Hint: It looks as though you have not defined a command for checking the process state by supplying a value for the nagios_check_command option in the CGI configuration file.
    \n"); + printf("Read the documentation for more information on checking the status of the Nagios process in the CGIs.\n"); + } + printf("
    \n"); + } + + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + } + + +void show_host_info(void) { + hoststatus *temp_hoststatus; + host *temp_host; + char date_time[MAX_DATETIME_LENGTH]; + char state_duration[48]; + char status_age[48]; + char state_string[MAX_INPUT_BUFFER]; + char *bg_class = ""; + char *buf = NULL; + int days; + int hours; + int minutes; + int seconds; + time_t current_time; + time_t t; + int duration_error = FALSE; + + + /* get host info */ + temp_host = find_host(host_name); + + /* make sure the user has rights to view host information */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) { + + printf("

    It appears as though you do not have permission to view information for this host...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + /* get host status info */ + temp_hoststatus = find_hoststatus(host_name); + + /* make sure host information exists */ + if(temp_host == NULL) { + printf("

    Error: Host Not Found!

    >"); + return; + } + if(temp_hoststatus == NULL) { + printf("

    Error: Host Status Information Not Found!
    \n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + printf("
    Host State Information
    \n"); + + if(temp_hoststatus->has_been_checked == FALSE) + printf("

    This host has not yet been checked, so status information is not available.

    \n"); + + else { + + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + current_time = time(NULL); + t = 0; + duration_error = FALSE; + if(temp_hoststatus->last_state_change == (time_t)0) { + if(program_start > current_time) + duration_error = TRUE; + else + t = current_time - program_start; + } + else { + if(temp_hoststatus->last_state_change > current_time) + duration_error = TRUE; + else + t = current_time - temp_hoststatus->last_state_change; + } + get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds); + if(duration_error == TRUE) + snprintf(state_duration, sizeof(state_duration) - 1, "???"); + else + 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'; + + if(temp_hoststatus->status == HOST_UP) { + strcpy(state_string, "UP"); + bg_class = "hostUP"; + } + else if(temp_hoststatus->status == HOST_DOWN) { + strcpy(state_string, "DOWN"); + bg_class = "hostDOWN"; + } + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + strcpy(state_string, "UNREACHABLE"); + bg_class = "hostUNREACHABLE"; + } + + printf("\n", bg_class, state_string, state_duration, (temp_hoststatus->problem_has_been_acknowledged == TRUE) ? "  (Has been acknowledged)" : ""); + + printf("\n"); + + printf("\n", (temp_hoststatus->perf_data == NULL) ? "" : html_encode(temp_hoststatus->perf_data, TRUE)); + + printf("\n", (temp_hoststatus->state_type == HARD_STATE) ? "HARD" : "SOFT"); + + get_time_string(&temp_hoststatus->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", date_time); + + printf("\n", (temp_hoststatus->check_type == HOST_CHECK_ACTIVE) ? "ACTIVE" : "PASSIVE"); + + printf("\n"); + + get_time_string(&temp_hoststatus->next_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_hoststatus->checks_enabled && temp_hoststatus->next_check != (time_t)0 && temp_hoststatus->should_be_scheduled == TRUE) ? date_time : "N/A"); + + get_time_string(&temp_hoststatus->last_state_change, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_hoststatus->last_state_change == (time_t)0) ? "N/A" : date_time); + + get_time_string(&temp_hoststatus->last_notification, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_hoststatus->last_notification == (time_t)0) ? "N/A" : date_time, temp_hoststatus->current_notification_number); + + printf("\n"); + + printf("\n", (temp_hoststatus->scheduled_downtime_depth > 0) ? "ACTIVE" : "INACTIVE", (temp_hoststatus->scheduled_downtime_depth > 0) ? "YES" : "NO"); + + t = 0; + duration_error = FALSE; + if(temp_hoststatus->last_check > current_time) + duration_error = TRUE; + else + /*t=current_time-temp_hoststatus->last_check;*/ + t = current_time - temp_hoststatus->last_update; + get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds); + if(duration_error == TRUE) + snprintf(status_age, sizeof(status_age) - 1, "???"); + else if(temp_hoststatus->last_check == (time_t)0) + snprintf(status_age, sizeof(status_age) - 1, "N/A"); + else + snprintf(status_age, sizeof(status_age) - 1, "%2dd %2dh %2dm %2ds", days, hours, minutes, seconds); + status_age[sizeof(status_age) - 1] = '\x0'; + + get_time_string(&temp_hoststatus->last_update, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_hoststatus->last_update == (time_t)0) ? "N/A" : date_time, status_age); + + printf("
    Host Status:
      %s  
     (for %s)%s
    Status Information:%s", (temp_hoststatus->plugin_output == NULL) ? "" : html_encode(temp_hoststatus->plugin_output, TRUE)); + if(enable_splunk_integration == TRUE) { + printf("  "); + asprintf(&buf, "%s %s", temp_host->name, temp_hoststatus->plugin_output); + display_splunk_generic_url(buf, 1); + free(buf); + } + if(temp_hoststatus->long_plugin_output != NULL) + printf("
    %s", html_encode(temp_hoststatus->long_plugin_output, TRUE)); + printf("
    Performance Data:%s
    Current Attempt:%d/%d", temp_hoststatus->current_attempt, temp_hoststatus->max_attempts); + printf("  (%s state)
    Last Check Time:%s
    Check Type:%s
    Check Latency / Duration:"); + if(temp_hoststatus->check_type == HOST_CHECK_ACTIVE) + printf("%.3f", temp_hoststatus->latency); + else + printf("N/A"); + printf(" / %.3f seconds", temp_hoststatus->execution_time); + printf("
    Next Scheduled Active Check:  %s
    Last State Change:%s
    Last Notification:%s (notification %d)
    Is This Host Flapping?"); + if(temp_hoststatus->flap_detection_enabled == FALSE || enable_flap_detection == FALSE) + printf("N/A"); + else + printf("
      %s  
     (%3.2f%% state change)", (temp_hoststatus->is_flapping == TRUE) ? "" : "not", (temp_hoststatus->is_flapping == TRUE) ? "YES" : "NO", temp_hoststatus->percent_state_change); + printf("
    In Scheduled Downtime?
      %s  
    Last Update:%s  (%s ago)
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n", (temp_hoststatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_hoststatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_hoststatus->accept_passive_host_checks == TRUE) ? "ENABLED" : "DISABLED", (temp_hoststatus->accept_passive_host_checks) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_hoststatus->obsess_over_host == TRUE) ? "ENABLED" : "DISABLED", (temp_hoststatus->obsess_over_host) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_hoststatus->notifications_enabled) ? "ENABLED" : "DISABLED", (temp_hoststatus->notifications_enabled) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_hoststatus->event_handler_enabled) ? "ENABLED" : "DISABLED", (temp_hoststatus->event_handler_enabled) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_hoststatus->flap_detection_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_hoststatus->flap_detection_enabled == TRUE) ? "ENABLED" : "DISABLED"); + + printf("
    Active Checks:
      %s  
    Passive Checks:
      %s  
    Obsessing:
      %s  
    Notifications:
      %s  
    Event Handler:
      %s  
    Flap Detection:
      %s  
    \n"); + printf("
    \n"); + + printf("
    \n"); + } + + printf("
    \n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + printf("
    Host Commands
    \n"); + + printf("
    \n"); + + if(nagios_process_state == STATE_OK && is_authorized_for_read_only(¤t_authdata) == FALSE) { + + printf("\n"); +#ifdef USE_STATUSMAP + printf("\n", url_images_path, STATUSMAP_ICON, STATUSMAP_CGI, url_encode(host_name)); +#endif + if(temp_hoststatus->checks_enabled == TRUE) { + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOST_CHECK, url_encode(host_name)); + } + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOST_CHECK, url_encode(host_name)); + printf("\n", url_images_path, DELAY_ICON, COMMAND_CGI, CMD_SCHEDULE_HOST_CHECK, url_encode(host_name), (temp_hoststatus->checks_enabled == TRUE) ? "&force_check" : ""); + + if(temp_hoststatus->accept_passive_host_checks == TRUE) { + printf("\n", url_images_path, PASSIVE_ICON, COMMAND_CGI, CMD_PROCESS_HOST_CHECK_RESULT, url_encode(host_name)); + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_PASSIVE_HOST_CHECKS, url_encode(host_name)); + } + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_PASSIVE_HOST_CHECKS, url_encode(host_name)); + + if(temp_hoststatus->obsess_over_host == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_STOP_OBSESSING_OVER_HOST, url_encode(host_name)); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_START_OBSESSING_OVER_HOST, url_encode(host_name)); + + if(temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE) { + if(temp_hoststatus->problem_has_been_acknowledged == FALSE) + printf("\n", url_images_path, ACKNOWLEDGEMENT_ICON, COMMAND_CGI, CMD_ACKNOWLEDGE_HOST_PROBLEM, url_encode(host_name)); + else + printf("\n", url_images_path, REMOVE_ACKNOWLEDGEMENT_ICON, COMMAND_CGI, CMD_REMOVE_HOST_ACKNOWLEDGEMENT, url_encode(host_name)); + } + + if(temp_hoststatus->notifications_enabled == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOST_NOTIFICATIONS, url_encode(host_name)); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOST_NOTIFICATIONS, url_encode(host_name)); + + printf("\n", url_images_path, NOTIFICATION_ICON, COMMAND_CGI, CMD_SEND_CUSTOM_HOST_NOTIFICATION, url_encode(host_name)); + + if(temp_hoststatus->status != HOST_UP) + printf("\n", url_images_path, DELAY_ICON, COMMAND_CGI, CMD_DELAY_HOST_NOTIFICATION, url_encode(host_name)); + + printf("\n", url_images_path, DOWNTIME_ICON, COMMAND_CGI, CMD_SCHEDULE_HOST_DOWNTIME, url_encode(host_name)); + + printf("\n", url_images_path, DOWNTIME_ICON, COMMAND_CGI, CMD_SCHEDULE_HOST_SVC_DOWNTIME, url_encode(host_name)); + + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOST_SVC_NOTIFICATIONS, url_encode(host_name)); + + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOST_SVC_NOTIFICATIONS, url_encode(host_name)); + + printf("\n", url_images_path, DELAY_ICON, COMMAND_CGI, CMD_SCHEDULE_HOST_SVC_CHECKS, url_encode(host_name)); + + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOST_SVC_CHECKS, url_encode(host_name)); + + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOST_SVC_CHECKS, url_encode(host_name)); + + if(temp_hoststatus->event_handler_enabled == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOST_EVENT_HANDLER, url_encode(host_name)); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOST_EVENT_HANDLER, url_encode(host_name)); + if(temp_hoststatus->flap_detection_enabled == TRUE) + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOST_FLAP_DETECTION, url_encode(host_name)); + else + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOST_FLAP_DETECTION, url_encode(host_name)); + + printf("
    Locate Host On MapLocate host on map
    Disable Active Checks Of This HostDisable active checks of this host
    Enable Active Checks Of This HostEnable active checks of this host
    Re-schedule Next Host CheckRe-schedule the next check of this host
    Submit Passive Check Result For This HostSubmit passive check result for this host
    Stop Accepting Passive Checks For This HostStop accepting passive checks for this host
    Start Accepting Passive Checks For This HostStart accepting passive checks for this host
    Stop Obsessing Over This HostStop obsessing over this host
    Start Obsessing Over This HostStart obsessing over this host
    Acknowledge This Host ProblemAcknowledge this host problem
    Remove Problem AcknowledgementRemove problem acknowledgement
    Disable Notifications For This HostDisable notifications for this host
    Enable Notifications For This HostEnable notifications for this host
    Send Custom NotificationSend custom host notification
    Delay Next Host NotificationDelay next host notification
    Schedule Downtime For This HostSchedule downtime for this host
    Schedule Downtime For All Services On This HostSchedule downtime for all services on this host
    Disable Notifications For All Services On This HostDisable notifications for all services on this host
    Enable Notifications For All Services On This HostEnable notifications for all services on this host
    Schedule A Check Of All Services On This HostSchedule a check of all services on this host
    Disable Checks Of All Services On This HostDisable checks of all services on this host
    Enable Checks Of All Services On This HostEnable checks of all services on this host
    Disable Event Handler For This HostDisable event handler for this host
    Enable Event Handler For This HostEnable event handler for this host
    Disable Flap Detection For This HostDisable flap detection for this host
    Enable Flap Detection For This HostEnable flap detection for this host
    \n"); + } + else if(is_authorized_for_read_only(¤t_authdata) == TRUE) { + printf("
    Your account does not have permissions to execute commands.
    \n"); + } + else { + printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); + printf("Click here to view Nagios process information
    \n", EXTINFO_CGI, DISPLAY_PROCESS_INFO); + } + printf("
    \n"); + + printf("
    \n"); + + if(is_authorized_for_read_only(¤t_authdata) == FALSE) { + /* display comments */ + display_comments(HOST_COMMENT); + } + printf("
    \n"); + printf("
    \n"); + + return; + } + + +void show_service_info(void) { + service *temp_service; + char date_time[MAX_DATETIME_LENGTH]; + char status_age[48]; + char state_duration[48]; + servicestatus *temp_svcstatus; + char state_string[MAX_INPUT_BUFFER]; + char *bg_class = ""; + char *buf = NULL; + int days; + int hours; + int minutes; + int seconds; + time_t t; + time_t current_time; + int duration_error = FALSE; + + /* find the service */ + temp_service = find_service(host_name, service_desc); + + /* make sure the user has rights to view service information */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) { + + printf("

    It appears as though you do not have permission to view information for this service...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + /* get service status info */ + temp_svcstatus = find_servicestatus(host_name, service_desc); + + /* make sure service information exists */ + if(temp_service == NULL) { + printf("

    Error: Service Not Found!

    "); + return; + } + if(temp_svcstatus == NULL) { + printf("

    Error: Service Status Not Found!

    "); + return; + } + + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("
    \n"); + + printf("
    Service State Information
    \n"); + + if(temp_svcstatus->has_been_checked == FALSE) + printf("

    This service has not yet been checked, so status information is not available.

    \n"); + + else { + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + + current_time = time(NULL); + t = 0; + duration_error = FALSE; + if(temp_svcstatus->last_state_change == (time_t)0) { + if(program_start > current_time) + duration_error = TRUE; + else + t = current_time - program_start; + } + else { + if(temp_svcstatus->last_state_change > current_time) + duration_error = TRUE; + else + t = current_time - temp_svcstatus->last_state_change; + } + get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds); + if(duration_error == TRUE) + snprintf(state_duration, sizeof(state_duration) - 1, "???"); + else + snprintf(state_duration, sizeof(state_duration) - 1, "%2dd %2dh %2dm %2ds%s", days, hours, minutes, seconds, (temp_svcstatus->last_state_change == (time_t)0) ? "+" : ""); + state_duration[sizeof(state_duration) - 1] = '\x0'; + + if(temp_svcstatus->status == SERVICE_OK) { + strcpy(state_string, "OK"); + bg_class = "serviceOK"; + } + else if(temp_svcstatus->status == SERVICE_WARNING) { + strcpy(state_string, "WARNING"); + bg_class = "serviceWARNING"; + } + else if(temp_svcstatus->status == SERVICE_CRITICAL) { + strcpy(state_string, "CRITICAL"); + bg_class = "serviceCRITICAL"; + } + else { + strcpy(state_string, "UNKNOWN"); + bg_class = "serviceUNKNOWN"; + } + printf("\n", bg_class, state_string, state_duration, (temp_svcstatus->problem_has_been_acknowledged == TRUE) ? "  (Has been acknowledged)" : ""); + + printf("\n"); + + printf("\n", (temp_svcstatus->perf_data == NULL) ? "" : html_encode(temp_svcstatus->perf_data, TRUE)); + + printf("\n", (temp_svcstatus->state_type == HARD_STATE) ? "HARD" : "SOFT"); + + get_time_string(&temp_svcstatus->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", date_time); + + printf("\n", (temp_svcstatus->check_type == SERVICE_CHECK_ACTIVE) ? "ACTIVE" : "PASSIVE"); + + printf("\n"); + + get_time_string(&temp_svcstatus->next_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_svcstatus->checks_enabled && temp_svcstatus->next_check != (time_t)0 && temp_svcstatus->should_be_scheduled == TRUE) ? date_time : "N/A"); + + get_time_string(&temp_svcstatus->last_state_change, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_svcstatus->last_state_change == (time_t)0) ? "N/A" : date_time); + + get_time_string(&temp_svcstatus->last_notification, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_svcstatus->last_notification == (time_t)0) ? "N/A" : date_time, temp_svcstatus->current_notification_number); + + printf("\n"); + + printf("\n", (temp_svcstatus->scheduled_downtime_depth > 0) ? "ACTIVE" : "INACTIVE", (temp_svcstatus->scheduled_downtime_depth > 0) ? "YES" : "NO"); + + t = 0; + duration_error = FALSE; + if(temp_svcstatus->last_check > current_time) + duration_error = TRUE; + else + /*t=current_time-temp_svcstatus->last_check;*/ + t = current_time - temp_svcstatus->last_update; + get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds); + if(duration_error == TRUE) + snprintf(status_age, sizeof(status_age) - 1, "???"); + else if(temp_svcstatus->last_check == (time_t)0) + snprintf(status_age, sizeof(status_age) - 1, "N/A"); + else + snprintf(status_age, sizeof(status_age) - 1, "%2dd %2dh %2dm %2ds", days, hours, minutes, seconds); + status_age[sizeof(status_age) - 1] = '\x0'; + + get_time_string(&temp_svcstatus->last_update, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("\n", (temp_svcstatus->last_update == (time_t)0) ? "N/A" : date_time, status_age); + + + printf("
    Current Status:
      %s  
     (for %s)%s
    Status Information:%s", (temp_svcstatus->plugin_output == NULL) ? "" : html_encode(temp_svcstatus->plugin_output, TRUE)); + if(enable_splunk_integration == TRUE) { + printf("  "); + asprintf(&buf, "%s %s %s", temp_service->host_name, temp_service->description, temp_svcstatus->plugin_output); + display_splunk_generic_url(buf, 1); + free(buf); + } + if(temp_svcstatus->long_plugin_output != NULL) + printf("
    %s", html_encode(temp_svcstatus->long_plugin_output, TRUE)); + printf("
    Performance Data:%s
    Current Attempt:%d/%d", temp_svcstatus->current_attempt, temp_svcstatus->max_attempts); + printf("  (%s state)
    Last Check Time:%s
    Check Type:%s
    Check Latency / Duration:"); + if(temp_svcstatus->check_type == SERVICE_CHECK_ACTIVE) + printf("%.3f", temp_svcstatus->latency); + else + printf("N/A"); + printf(" / %.3f seconds", temp_svcstatus->execution_time); + printf("
    Next Scheduled Check:  %s
    Last State Change:%s
    Last Notification:%s (notification %d)
    Is This Service Flapping?"); + if(temp_svcstatus->flap_detection_enabled == FALSE || enable_flap_detection == FALSE) + printf("N/A"); + else + printf("
      %s  
     (%3.2f%% state change)", (temp_svcstatus->is_flapping == TRUE) ? "" : "not", (temp_svcstatus->is_flapping == TRUE) ? "YES" : "NO", temp_svcstatus->percent_state_change); + printf("
    In Scheduled Downtime?
      %s  
    Last Update:%s  (%s ago)
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n", (temp_svcstatus->checks_enabled) ? "ENABLED" : "DISABLED", (temp_svcstatus->checks_enabled) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_svcstatus->accept_passive_service_checks == TRUE) ? "ENABLED" : "DISABLED", (temp_svcstatus->accept_passive_service_checks) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_svcstatus->obsess_over_service == TRUE) ? "ENABLED" : "DISABLED", (temp_svcstatus->obsess_over_service) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_svcstatus->notifications_enabled) ? "ENABLED" : "DISABLED", (temp_svcstatus->notifications_enabled) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_svcstatus->event_handler_enabled) ? "ENABLED" : "DISABLED", (temp_svcstatus->event_handler_enabled) ? "ENABLED" : "DISABLED"); + + printf("\n", (temp_svcstatus->flap_detection_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_svcstatus->flap_detection_enabled == TRUE) ? "ENABLED" : "DISABLED"); + + + printf("
    Active Checks:
      %s  
    Passive Checks:
      %s  
    Obsessing:
      %s  
    Notifications:
      %s  
    Event Handler:
      %s  
    Flap Detection:
      %s  
    \n"); + printf("
    \n"); + + printf("
    \n"); + } + + + printf("
    \n"); + printf("\n"); + + printf("\n"); + + printf("
    \n"); + + printf("
    Service Commands
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + + if(nagios_process_state == STATE_OK && is_authorized_for_read_only(¤t_authdata) == FALSE) { + printf("\n"); + + if(temp_svcstatus->checks_enabled) { + + printf("\n", url_encode(service_desc)); + } + else { + printf("\n", url_encode(service_desc)); + } + printf("\n", url_encode(service_desc), (temp_svcstatus->checks_enabled == TRUE) ? "&force_check" : ""); + + if(temp_svcstatus->accept_passive_service_checks == TRUE) { + printf("\n", url_encode(service_desc)); + + printf("\n", url_encode(service_desc)); + } + else { + printf("\n", url_encode(service_desc)); + } + + if(temp_svcstatus->obsess_over_service == TRUE) { + printf("\n", url_encode(service_desc)); + } + else { + printf("\n", url_encode(service_desc)); + } + + if((temp_svcstatus->status == SERVICE_WARNING || temp_svcstatus->status == SERVICE_UNKNOWN || temp_svcstatus->status == SERVICE_CRITICAL) && temp_svcstatus->state_type == HARD_STATE) { + if(temp_svcstatus->problem_has_been_acknowledged == FALSE) { + printf("\n", url_encode(service_desc)); + } + else { + printf("\n", url_encode(service_desc)); + } + } + if(temp_svcstatus->notifications_enabled == TRUE) { + printf("\n", url_encode(service_desc)); + if(temp_svcstatus->status != SERVICE_OK) { + printf("\n", url_encode(service_desc)); + } + } + else { + printf("\n", url_encode(service_desc)); + } + + printf("\n", url_encode(service_desc)); + + printf("\n", url_encode(service_desc)); + + /* + printf("\n",url_encode(service_desc)); + */ + + if(temp_svcstatus->event_handler_enabled == TRUE) { + printf("\n", url_encode(service_desc)); + } + else { + printf("\n", url_encode(service_desc)); + } + + if(temp_svcstatus->flap_detection_enabled == TRUE) { + printf("\n", url_encode(service_desc)); + } + else { + printf("\n", url_encode(service_desc)); + } + + printf("
    Disable Active Checks Of This ServiceDisable active checks of this service
    Enable Active Checks Of This ServiceEnable active checks of this service
    Re-schedule Next Service CheckRe-schedule the next check of this service
    Submit Passive Check Result For This ServiceSubmit passive check result for this service
    Stop Accepting Passive Checks For This ServiceStop accepting passive checks for this service
    Start Accepting Passive Checks For This ServiceStart accepting passive checks for this service
    Stop Obsessing Over This ServiceStop obsessing over this service
    Start Obsessing Over This ServiceStart obsessing over this service
    Acknowledge This Service ProblemAcknowledge this service problem
    Remove Problem AcknowledgementRemove problem acknowledgement
    Disable Notifications For This ServiceDisable notifications for this service
    Delay Next Service NotificationDelay next service notification
    Enable Notifications For This ServiceEnable notifications for this service
    Send Custom NotificationSend custom service notification
    Schedule Downtime For This ServiceSchedule downtime for this service
    Cancel Scheduled Downtime For This ServiceCancel scheduled downtime for this service
    Disable Event Handler For This ServiceDisable event handler for this service
    Enable Event Handler For This ServiceEnable event handler for this service
    Disable Flap Detection For This ServiceDisable flap detection for this service
    Enable Flap Detection For This ServiceEnable flap detection for this service
    \n"); + } + else if(is_authorized_for_read_only(¤t_authdata) == TRUE) { + printf("
    Your account does not have permissions to execute commands.
    \n"); + } + else { + printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); + printf("Click here to view Nagios process information
    \n", EXTINFO_CGI, DISPLAY_PROCESS_INFO); + } + + printf("
    \n"); + + printf("

    \n"); + + if(is_authorized_for_read_only(¤t_authdata) == FALSE) { + /* display comments */ + display_comments(SERVICE_COMMENT); + } + printf("
    \n"); + printf("
    \n"); + + return; + } + + + + +void show_hostgroup_info(void) { + hostgroup *temp_hostgroup; + + + /* get hostgroup info */ + temp_hostgroup = find_hostgroup(hostgroup_name); + + /* make sure the user has rights to view hostgroup information */ + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == FALSE) { + + printf("

    It appears as though you do not have permission to view information for this hostgroup...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + /* make sure hostgroup information exists */ + if(temp_hostgroup == NULL) { + printf("

    Error: Hostgroup Not Found!

    "); + return; + } + + + printf("
    \n"); + printf("\n"); + printf("\n"); + + + /* top left panel */ + printf("\n"); + printf("\n"); + + /* left bottom panel */ + printf("\n"); + printf("
    \n"); + + /* right top panel */ + printf("\n"); + + printf("
    Hostgroup Commands
    \n"); + + if(nagios_process_state == STATE_OK && is_authorized_for_read_only(¤t_authdata) == FALSE) { + + printf("\n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + + printf("\n", url_images_path, DOWNTIME_ICON, COMMAND_CGI, CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME, url_encode(hostgroup_name)); + + printf("\n", url_images_path, DOWNTIME_ICON, COMMAND_CGI, CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME, url_encode(hostgroup_name)); + + printf("\n", url_images_path, NOTIFICATION_ICON, COMMAND_CGI, CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS, url_encode(hostgroup_name)); + + printf("\n", url_images_path, NOTIFICATIONS_DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS, url_encode(hostgroup_name)); + + printf("\n", url_images_path, NOTIFICATION_ICON, COMMAND_CGI, CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS, url_encode(hostgroup_name)); + + printf("\n", url_images_path, NOTIFICATIONS_DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS, url_encode(hostgroup_name)); + + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_HOSTGROUP_SVC_CHECKS, url_encode(hostgroup_name)); + + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_HOSTGROUP_SVC_CHECKS, url_encode(hostgroup_name)); + + printf("
    Schedule Downtime For All Hosts In This HostgroupSchedule downtime for all hosts in this hostgroup
    Schedule Downtime For All Services In This HostgroupSchedule downtime for all services in this hostgroup
    Enable Notifications For All Hosts In This HostgroupEnable notifications for all hosts in this hostgroup
    Disable Notifications For All Hosts In This HostgroupDisable notifications for all hosts in this hostgroup
    Enable Notifications For All Services In This HostgroupEnable notifications for all services in this hostgroup
    Disable Notifications For All Services In This HostgroupDisable notifications for all services in this hostgroup
    Enable Active Checks Of All Services In This HostgroupEnable active checks of all services in this hostgroup
    Disable Active Checks Of All Services In This HostgroupDisable active checks of all services in this hostgroup
    \n"); + + printf("
    \n"); + } + else if(is_authorized_for_read_only(¤t_authdata) == TRUE) { + printf("
    Your account does not have permissions to execute commands.
    \n"); + } + else { + printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); + printf("Click here to view Nagios process information
    \n", EXTINFO_CGI, DISPLAY_PROCESS_INFO); + } + + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + + printf("\n"); + + printf("\n"); + + + + return; + } + + + + +void show_servicegroup_info() { + servicegroup *temp_servicegroup; + + + /* get servicegroup info */ + temp_servicegroup = find_servicegroup(servicegroup_name); + + /* make sure the user has rights to view servicegroup information */ + if(is_authorized_for_servicegroup(temp_servicegroup, ¤t_authdata) == FALSE) { + + printf("

    It appears as though you do not have permission to view information for this servicegroup...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + /* make sure servicegroup information exists */ + if(temp_servicegroup == NULL) { + printf("

    Error: Servicegroup Not Found!

    "); + return; + } + + + printf("
    \n"); + printf("\n"); + printf("\n"); + + + /* top left panel */ + printf("\n"); + printf("\n"); + + /* left bottom panel */ + printf("\n"); + printf("
    \n"); + + /* right top panel */ + printf("\n"); + + printf("
    Servicegroup Commands
    \n"); + + if(nagios_process_state == STATE_OK) { + + printf("\n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + + printf("\n", url_images_path, DOWNTIME_ICON, COMMAND_CGI, CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME, url_encode(servicegroup_name)); + + printf("\n", url_images_path, DOWNTIME_ICON, COMMAND_CGI, CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME, url_encode(servicegroup_name)); + + printf("\n", url_images_path, NOTIFICATION_ICON, COMMAND_CGI, CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS, url_encode(servicegroup_name)); + + printf("\n", url_images_path, NOTIFICATIONS_DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS, url_encode(servicegroup_name)); + + printf("\n", url_images_path, NOTIFICATION_ICON, COMMAND_CGI, CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS, url_encode(servicegroup_name)); + + printf("\n", url_images_path, NOTIFICATIONS_DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS, url_encode(servicegroup_name)); + + printf("\n", url_images_path, ENABLED_ICON, COMMAND_CGI, CMD_ENABLE_SERVICEGROUP_SVC_CHECKS, url_encode(servicegroup_name)); + + printf("\n", url_images_path, DISABLED_ICON, COMMAND_CGI, CMD_DISABLE_SERVICEGROUP_SVC_CHECKS, url_encode(servicegroup_name)); + + printf("
    Schedule Downtime For All Hosts In This ServicegroupSchedule downtime for all hosts in this servicegroup
    Schedule Downtime For All Services In This ServicegroupSchedule downtime for all services in this servicegroup
    Enable Notifications For All Hosts In This ServicegroupEnable notifications for all hosts in this servicegroup
    Disable Notifications For All Hosts In This ServicegroupDisable notifications for all hosts in this servicegroup
    Enable Notifications For All Services In This ServicegroupEnable notifications for all services in this servicegroup
    Disable Notifications For All Services In This ServicegroupDisable notifications for all services in this servicegroup
    Enable Active Checks Of All Services In This ServicegroupEnable active checks of all services in this servicegroup
    Disable Active Checks Of All Services In This ServicegroupDisable active checks of all services in this servicegroup
    \n"); + + printf("
    \n"); + } + else { + printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); + printf("Click here to view Nagios process information
    \n", EXTINFO_CGI, DISPLAY_PROCESS_INFO); + } + + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + + printf("\n"); + + printf("\n"); + + + return; + } + + + +/* shows all service and host comments */ +void show_all_comments(void) { + int total_comments = 0; + char *bg_class = ""; + int odd = 0; + char date_time[MAX_DATETIME_LENGTH]; + comment *temp_comment; + host *temp_host; + service *temp_service; + char *comment_type; + char expire_time[MAX_DATETIME_LENGTH]; + + + if(is_authorized_for_read_only(¤t_authdata) == TRUE) { + printf("
    Your account does not have permissions to view comments.
    \n"); + return; + } + + + printf("
    \n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + printf("
    Host Comments
    \n"); + + printf("\n"); + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* display all the host comments */ + for(temp_comment = comment_list, total_comments = 0; temp_comment != NULL; temp_comment = temp_comment->next) { + + if(temp_comment->comment_type != HOST_COMMENT) + continue; + + temp_host = find_host(temp_comment->host_name); + + /* make sure the user has rights to view host information */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + total_comments++; + + if(odd) { + odd = 0; + bg_class = "commentOdd"; + } + else { + odd = 1; + bg_class = "commentEven"; + } + + switch(temp_comment->entry_type) { + case USER_COMMENT: + comment_type = "User"; + break; + case DOWNTIME_COMMENT: + comment_type = "Scheduled Downtime"; + break; + case FLAPPING_COMMENT: + comment_type = "Flap Detection"; + break; + case ACKNOWLEDGEMENT_COMMENT: + comment_type = "Acknowledgement"; + break; + default: + comment_type = "?"; + } + + get_time_string(&temp_comment->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + get_time_string(&temp_comment->expire_time, expire_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class); + printf("", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_comment->host_name), temp_comment->host_name); + printf("", bg_class, date_time, bg_class, temp_comment->author, bg_class, temp_comment->comment_data, bg_class, temp_comment->comment_id, bg_class, (temp_comment->persistent) ? "Yes" : "No", bg_class, comment_type, bg_class, (temp_comment->expires == TRUE) ? expire_time : "N/A"); + printf("", COMMAND_CGI, CMD_DEL_HOST_COMMENT, temp_comment->comment_id, url_images_path, DELETE_ICON); + printf("\n"); + } + + if(total_comments == 0) + printf(""); + + printf("
    Host NameEntry TimeAuthorCommentComment IDPersistentTypeExpiresActions
    %s%s%s%s%ld%s%s%sDelete This Comment
    There are no host comments
    \n"); + printf("
    \n"); + + printf("


    \n"); + + + printf("\n"); + printf("
    Service Comments
    \n"); + + printf("\n"); + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* display all the service comments */ + for(temp_comment = comment_list, total_comments = 0; temp_comment != NULL; temp_comment = temp_comment->next) { + + if(temp_comment->comment_type != SERVICE_COMMENT) + continue; + + temp_service = find_service(temp_comment->host_name, temp_comment->service_description); + + /* make sure the user has rights to view service information */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + total_comments++; + + if(odd) { + odd = 0; + bg_class = "commentOdd"; + } + else { + odd = 1; + bg_class = "commentEven"; + } + + switch(temp_comment->entry_type) { + case USER_COMMENT: + comment_type = "User"; + break; + case DOWNTIME_COMMENT: + comment_type = "Scheduled Downtime"; + break; + case FLAPPING_COMMENT: + comment_type = "Flap Detection"; + break; + case ACKNOWLEDGEMENT_COMMENT: + comment_type = "Acknowledgement"; + break; + default: + comment_type = "?"; + } + + get_time_string(&temp_comment->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + get_time_string(&temp_comment->expire_time, expire_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class); + printf("", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_comment->host_name), temp_comment->host_name); + printf("", url_encode(temp_comment->service_description), temp_comment->service_description); + printf("", bg_class, date_time, bg_class, temp_comment->author, bg_class, temp_comment->comment_data, bg_class, temp_comment->comment_id, bg_class, (temp_comment->persistent) ? "Yes" : "No", bg_class, comment_type, bg_class, (temp_comment->expires == TRUE) ? expire_time : "N/A"); + printf("", COMMAND_CGI, CMD_DEL_SVC_COMMENT, temp_comment->comment_id, url_images_path, DELETE_ICON); + printf("\n"); + } + + if(total_comments == 0) + printf(""); + + printf("
    Host NameServiceEntry TimeAuthorCommentComment IDPersistentTypeExpiresActions
    %s%s%s%s%s%ld%s%s%sDelete This Comment
    There are no service comments
    \n"); + printf("
    \n"); + + return; + } + + + +void show_performance_data(void) { + service *temp_service = NULL; + servicestatus *temp_servicestatus = NULL; + host *temp_host = NULL; + hoststatus *temp_hoststatus = NULL; + int total_active_service_checks = 0; + int total_passive_service_checks = 0; + double min_service_execution_time = 0.0; + double max_service_execution_time = 0.0; + double total_service_execution_time = 0.0; + int have_min_service_execution_time = FALSE; + int have_max_service_execution_time = FALSE; + double min_service_latency = 0.0; + double max_service_latency = 0.0; + double long total_service_latency = 0.0; + int have_min_service_latency = FALSE; + int have_max_service_latency = FALSE; + double min_host_latency = 0.0; + double max_host_latency = 0.0; + double total_host_latency = 0.0; + int have_min_host_latency = FALSE; + int have_max_host_latency = FALSE; + double min_service_percent_change_a = 0.0; + double max_service_percent_change_a = 0.0; + double total_service_percent_change_a = 0.0; + int have_min_service_percent_change_a = FALSE; + int have_max_service_percent_change_a = FALSE; + double min_service_percent_change_b = 0.0; + double max_service_percent_change_b = 0.0; + double total_service_percent_change_b = 0.0; + int have_min_service_percent_change_b = FALSE; + int have_max_service_percent_change_b = FALSE; + int active_service_checks_1min = 0; + int active_service_checks_5min = 0; + int active_service_checks_15min = 0; + int active_service_checks_1hour = 0; + int active_service_checks_start = 0; + int active_service_checks_ever = 0; + int passive_service_checks_1min = 0; + int passive_service_checks_5min = 0; + int passive_service_checks_15min = 0; + int passive_service_checks_1hour = 0; + int passive_service_checks_start = 0; + int passive_service_checks_ever = 0; + int total_active_host_checks = 0; + int total_passive_host_checks = 0; + double min_host_execution_time = 0.0; + double max_host_execution_time = 0.0; + double total_host_execution_time = 0.0; + int have_min_host_execution_time = FALSE; + int have_max_host_execution_time = FALSE; + double min_host_percent_change_a = 0.0; + double max_host_percent_change_a = 0.0; + double total_host_percent_change_a = 0.0; + int have_min_host_percent_change_a = FALSE; + int have_max_host_percent_change_a = FALSE; + double min_host_percent_change_b = 0.0; + double max_host_percent_change_b = 0.0; + double total_host_percent_change_b = 0.0; + int have_min_host_percent_change_b = FALSE; + int have_max_host_percent_change_b = FALSE; + int active_host_checks_1min = 0; + int active_host_checks_5min = 0; + int active_host_checks_15min = 0; + int active_host_checks_1hour = 0; + int active_host_checks_start = 0; + int active_host_checks_ever = 0; + int passive_host_checks_1min = 0; + int passive_host_checks_5min = 0; + int passive_host_checks_15min = 0; + int passive_host_checks_1hour = 0; + int passive_host_checks_start = 0; + int passive_host_checks_ever = 0; + time_t current_time; + + + time(¤t_time); + + /* check all services */ + for(temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) { + + /* find the service */ + temp_service = find_service(temp_servicestatus->host_name, temp_servicestatus->description); + + /* make sure the user has rights to view service information */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + /* is this an active or passive check? */ + if(temp_servicestatus->check_type == SERVICE_CHECK_ACTIVE) { + + total_active_service_checks++; + + total_service_execution_time += temp_servicestatus->execution_time; + if(have_min_service_execution_time == FALSE || temp_servicestatus->execution_time < min_service_execution_time) { + have_min_service_execution_time = TRUE; + min_service_execution_time = temp_servicestatus->execution_time; + } + if(have_max_service_execution_time == FALSE || temp_servicestatus->execution_time > max_service_execution_time) { + have_max_service_execution_time = TRUE; + max_service_execution_time = temp_servicestatus->execution_time; + } + + total_service_percent_change_a += temp_servicestatus->percent_state_change; + if(have_min_service_percent_change_a == FALSE || temp_servicestatus->percent_state_change < min_service_percent_change_a) { + have_min_service_percent_change_a = TRUE; + min_service_percent_change_a = temp_servicestatus->percent_state_change; + } + if(have_max_service_percent_change_a == FALSE || temp_servicestatus->percent_state_change > max_service_percent_change_a) { + have_max_service_percent_change_a = TRUE; + max_service_percent_change_a = temp_servicestatus->percent_state_change; + } + + total_service_latency += temp_servicestatus->latency; + if(have_min_service_latency == FALSE || temp_servicestatus->latency < min_service_latency) { + have_min_service_latency = TRUE; + min_service_latency = temp_servicestatus->latency; + } + if(have_max_service_latency == FALSE || temp_servicestatus->latency > max_service_latency) { + have_max_service_latency = TRUE; + max_service_latency = temp_servicestatus->latency; + } + + if(temp_servicestatus->last_check >= (current_time - 60)) + active_service_checks_1min++; + if(temp_servicestatus->last_check >= (current_time - 300)) + active_service_checks_5min++; + if(temp_servicestatus->last_check >= (current_time - 900)) + active_service_checks_15min++; + if(temp_servicestatus->last_check >= (current_time - 3600)) + active_service_checks_1hour++; + if(temp_servicestatus->last_check >= program_start) + active_service_checks_start++; + if(temp_servicestatus->last_check != (time_t)0) + active_service_checks_ever++; + } + + else { + total_passive_service_checks++; + + total_service_percent_change_b += temp_servicestatus->percent_state_change; + if(have_min_service_percent_change_b == FALSE || temp_servicestatus->percent_state_change < min_service_percent_change_b) { + have_min_service_percent_change_b = TRUE; + min_service_percent_change_b = temp_servicestatus->percent_state_change; + } + if(have_max_service_percent_change_b == FALSE || temp_servicestatus->percent_state_change > max_service_percent_change_b) { + have_max_service_percent_change_b = TRUE; + max_service_percent_change_b = temp_servicestatus->percent_state_change; + } + + if(temp_servicestatus->last_check >= (current_time - 60)) + passive_service_checks_1min++; + if(temp_servicestatus->last_check >= (current_time - 300)) + passive_service_checks_5min++; + if(temp_servicestatus->last_check >= (current_time - 900)) + passive_service_checks_15min++; + if(temp_servicestatus->last_check >= (current_time - 3600)) + passive_service_checks_1hour++; + if(temp_servicestatus->last_check >= program_start) + passive_service_checks_start++; + if(temp_servicestatus->last_check != (time_t)0) + passive_service_checks_ever++; + } + } + + /* check all hosts */ + for(temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) { + + /* find the host */ + temp_host = find_host(temp_hoststatus->host_name); + + /* make sure the user has rights to view host information */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + /* is this an active or passive check? */ + if(temp_hoststatus->check_type == HOST_CHECK_ACTIVE) { + + total_active_host_checks++; + + total_host_execution_time += temp_hoststatus->execution_time; + if(have_min_host_execution_time == FALSE || temp_hoststatus->execution_time < min_host_execution_time) { + have_min_host_execution_time = TRUE; + min_host_execution_time = temp_hoststatus->execution_time; + } + if(have_max_host_execution_time == FALSE || temp_hoststatus->execution_time > max_host_execution_time) { + have_max_host_execution_time = TRUE; + max_host_execution_time = temp_hoststatus->execution_time; + } + + total_host_percent_change_a += temp_hoststatus->percent_state_change; + if(have_min_host_percent_change_a == FALSE || temp_hoststatus->percent_state_change < min_host_percent_change_a) { + have_min_host_percent_change_a = TRUE; + min_host_percent_change_a = temp_hoststatus->percent_state_change; + } + if(have_max_host_percent_change_a == FALSE || temp_hoststatus->percent_state_change > max_host_percent_change_a) { + have_max_host_percent_change_a = TRUE; + max_host_percent_change_a = temp_hoststatus->percent_state_change; + } + + total_host_latency += temp_hoststatus->latency; + if(have_min_host_latency == FALSE || temp_hoststatus->latency < min_host_latency) { + have_min_host_latency = TRUE; + min_host_latency = temp_hoststatus->latency; + } + if(have_max_host_latency == FALSE || temp_hoststatus->latency > max_host_latency) { + have_max_host_latency = TRUE; + max_host_latency = temp_hoststatus->latency; + } + + if(temp_hoststatus->last_check >= (current_time - 60)) + active_host_checks_1min++; + if(temp_hoststatus->last_check >= (current_time - 300)) + active_host_checks_5min++; + if(temp_hoststatus->last_check >= (current_time - 900)) + active_host_checks_15min++; + if(temp_hoststatus->last_check >= (current_time - 3600)) + active_host_checks_1hour++; + if(temp_hoststatus->last_check >= program_start) + active_host_checks_start++; + if(temp_hoststatus->last_check != (time_t)0) + active_host_checks_ever++; + } + + else { + total_passive_host_checks++; + + total_host_percent_change_b += temp_hoststatus->percent_state_change; + if(have_min_host_percent_change_b == FALSE || temp_hoststatus->percent_state_change < min_host_percent_change_b) { + have_min_host_percent_change_b = TRUE; + min_host_percent_change_b = temp_hoststatus->percent_state_change; + } + if(have_max_host_percent_change_b == FALSE || temp_hoststatus->percent_state_change > max_host_percent_change_b) { + have_max_host_percent_change_b = TRUE; + max_host_percent_change_b = temp_hoststatus->percent_state_change; + } + + if(temp_hoststatus->last_check >= (current_time - 60)) + passive_host_checks_1min++; + if(temp_hoststatus->last_check >= (current_time - 300)) + passive_host_checks_5min++; + if(temp_hoststatus->last_check >= (current_time - 900)) + passive_host_checks_15min++; + if(temp_hoststatus->last_check >= (current_time - 3600)) + passive_host_checks_1hour++; + if(temp_hoststatus->last_check >= program_start) + passive_host_checks_start++; + if(temp_hoststatus->last_check != (time_t)0) + passive_host_checks_ever++; + } + } + + + printf("
    \n"); + + + printf("
    Program-Wide Performance Information
    \n"); + + printf("\n"); + + + /***** ACTIVE SERVICE CHECKS *****/ + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + + /***** PASSIVE SERVICE CHECKS *****/ + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + + /***** ACTIVE HOST CHECKS *****/ + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + + /***** PASSIVE HOST CHECKS *****/ + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + + + /***** CHECK STATS *****/ + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + + + /***** BUFFER STATS *****/ + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + + + printf("
    Services Actively Checked:
    \n"); + + /* fake this so we don't divide by zero for just showing the table */ + if(total_active_service_checks == 0) + total_active_service_checks = 1; + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("", active_service_checks_1min, (double)(((double)active_service_checks_1min * 100.0) / (double)total_active_service_checks)); + printf("", active_service_checks_5min, (double)(((double)active_service_checks_5min * 100.0) / (double)total_active_service_checks)); + printf("", active_service_checks_15min, (double)(((double)active_service_checks_15min * 100.0) / (double)total_active_service_checks)); + printf("", active_service_checks_1hour, (double)(((double)active_service_checks_1hour * 100.0) / (double)total_active_service_checks)); + printf("", active_service_checks_start, (double)(((double)active_service_checks_start * 100.0) / (double)total_active_service_checks)); + + printf("
    Time FrameServices Checked
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + + printf("\n", min_service_execution_time, max_service_execution_time, (double)((double)total_service_execution_time / (double)total_active_service_checks)); + + printf("\n", min_service_latency, max_service_latency, (double)((double)total_service_latency / (double)total_active_service_checks)); + + printf("\n", min_service_percent_change_a, max_service_percent_change_a, (double)((double)total_service_percent_change_a / (double)total_active_service_checks)); + + printf("
    MetricMin.Max.Average
    Check Execution Time:  %.2f sec%.2f sec%.3f sec
    Check Latency:%.2f sec%.2f sec%.3f sec
    Percent State Change:%.2f%%%.2f%%%.2f%%
    \n"); + printf("
    \n"); + + + printf("
    Services Passively Checked:
    \n"); + + + /* fake this so we don't divide by zero for just showing the table */ + if(total_passive_service_checks == 0) + total_passive_service_checks = 1; + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("", passive_service_checks_1min, (double)(((double)passive_service_checks_1min * 100.0) / (double)total_passive_service_checks)); + printf("", passive_service_checks_5min, (double)(((double)passive_service_checks_5min * 100.0) / (double)total_passive_service_checks)); + printf("", passive_service_checks_15min, (double)(((double)passive_service_checks_15min * 100.0) / (double)total_passive_service_checks)); + printf("", passive_service_checks_1hour, (double)(((double)passive_service_checks_1hour * 100.0) / (double)total_passive_service_checks)); + printf("", passive_service_checks_start, (double)(((double)passive_service_checks_start * 100.0) / (double)total_passive_service_checks)); + + printf("
    Time FrameServices Checked
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n", min_service_percent_change_b, max_service_percent_change_b, (double)((double)total_service_percent_change_b / (double)total_passive_service_checks)); + + printf("
    MetricMin.Max.Average
    Percent State Change:  %.2f%%%.2f%%%.2f%%
    \n"); + printf("
    \n"); + + printf("
    Hosts Actively Checked:
    \n"); + + /* fake this so we don't divide by zero for just showing the table */ + if(total_active_host_checks == 0) + total_active_host_checks = 1; + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("", active_host_checks_1min, (double)(((double)active_host_checks_1min * 100.0) / (double)total_active_host_checks)); + printf("", active_host_checks_5min, (double)(((double)active_host_checks_5min * 100.0) / (double)total_active_host_checks)); + printf("", active_host_checks_15min, (double)(((double)active_host_checks_15min * 100.0) / (double)total_active_host_checks)); + printf("", active_host_checks_1hour, (double)(((double)active_host_checks_1hour * 100.0) / (double)total_active_host_checks)); + printf("", active_host_checks_start, (double)(((double)active_host_checks_start * 100.0) / (double)total_active_host_checks)); + + printf("
    Time FrameHosts Checked
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + + printf("\n", min_host_execution_time, max_host_execution_time, (double)((double)total_host_execution_time / (double)total_active_host_checks)); + + printf("\n", min_host_latency, max_host_latency, (double)((double)total_host_latency / (double)total_active_host_checks)); + + printf("\n", min_host_percent_change_a, max_host_percent_change_a, (double)((double)total_host_percent_change_a / (double)total_active_host_checks)); + + printf("
    MetricMin.Max.Average
    Check Execution Time:  %.2f sec%.2f sec%.3f sec
    Check Latency:%.2f sec%.2f sec%.3f sec
    Percent State Change:%.2f%%%.2f%%%.2f%%
    \n"); + printf("
    \n"); + + + printf("
    Hosts Passively Checked:
    \n"); + + + /* fake this so we don't divide by zero for just showing the table */ + if(total_passive_host_checks == 0) + total_passive_host_checks = 1; + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("", passive_host_checks_1min, (double)(((double)passive_host_checks_1min * 100.0) / (double)total_passive_host_checks)); + printf("", passive_host_checks_5min, (double)(((double)passive_host_checks_5min * 100.0) / (double)total_passive_host_checks)); + printf("", passive_host_checks_15min, (double)(((double)passive_host_checks_15min * 100.0) / (double)total_passive_host_checks)); + printf("", passive_host_checks_1hour, (double)(((double)passive_host_checks_1hour * 100.0) / (double)total_passive_host_checks)); + printf("", passive_host_checks_start, (double)(((double)passive_host_checks_start * 100.0) / (double)total_passive_host_checks)); + + printf("
    Time FrameHosts Checked
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n", min_host_percent_change_b, max_host_percent_change_b, (double)((double)total_host_percent_change_b / (double)total_passive_host_checks)); + + printf("
    MetricMin.Max.Average
    Percent State Change:  %.2f%%%.2f%%%.2f%%
    \n"); + printf("
    \n"); + + printf("
    Check Statistics:
    \n"); + + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("", program_stats[ACTIVE_SCHEDULED_HOST_CHECK_STATS][0], program_stats[ACTIVE_SCHEDULED_HOST_CHECK_STATS][1], program_stats[ACTIVE_SCHEDULED_HOST_CHECK_STATS][2]); + printf("", program_stats[ACTIVE_ONDEMAND_HOST_CHECK_STATS][0], program_stats[ACTIVE_ONDEMAND_HOST_CHECK_STATS][1], program_stats[ACTIVE_ONDEMAND_HOST_CHECK_STATS][2]); + printf("", program_stats[PARALLEL_HOST_CHECK_STATS][0], program_stats[PARALLEL_HOST_CHECK_STATS][1], program_stats[PARALLEL_HOST_CHECK_STATS][2]); + printf("", program_stats[SERIAL_HOST_CHECK_STATS][0], program_stats[SERIAL_HOST_CHECK_STATS][1], program_stats[SERIAL_HOST_CHECK_STATS][2]); + printf("", program_stats[ACTIVE_CACHED_HOST_CHECK_STATS][0], program_stats[ACTIVE_CACHED_HOST_CHECK_STATS][1], program_stats[ACTIVE_CACHED_HOST_CHECK_STATS][2]); + printf("", program_stats[PASSIVE_HOST_CHECK_STATS][0], program_stats[PASSIVE_HOST_CHECK_STATS][1], program_stats[PASSIVE_HOST_CHECK_STATS][2]); + + printf("", program_stats[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS][0], program_stats[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS][1], program_stats[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS][2]); + printf("", program_stats[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS][0], program_stats[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS][1], program_stats[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS][2]); + printf("", program_stats[ACTIVE_CACHED_SERVICE_CHECK_STATS][0], program_stats[ACTIVE_CACHED_SERVICE_CHECK_STATS][1], program_stats[ACTIVE_CACHED_SERVICE_CHECK_STATS][2]); + printf("", program_stats[PASSIVE_SERVICE_CHECK_STATS][0], program_stats[PASSIVE_SERVICE_CHECK_STATS][1], program_stats[PASSIVE_SERVICE_CHECK_STATS][2]); + + printf("", program_stats[EXTERNAL_COMMAND_STATS][0], program_stats[EXTERNAL_COMMAND_STATS][1], program_stats[EXTERNAL_COMMAND_STATS][2]); + + printf("
    TypeLast 1 MinLast 5 MinLast 15 Min
    Active Scheduled Host Checks%d%d%d
    Active On-Demand Host Checks%d%d%d
    Parallel Host Checks%d%d%d
    Serial Host Checks%d%d%d
    Cached Host Checks%d%d%d
    Passive Host Checks%d%d%d
    Active Scheduled Service Checks%d%d%d
    Active On-Demand Service Checks%d%d%d
    Cached Service Checks%d%d%d
    Passive Service Checks%d%d%d
    External Commands%d%d%d
    \n"); + printf("
    \n"); + + printf("
    Buffer Usage:
    \n"); + + + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("", buffer_stats[0][1], buffer_stats[0][2], buffer_stats[0][0]); + + printf("
    TypeIn UseMax UsedTotal Available
    External Commands %d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + + + printf("
    \n"); + + return; + } + + + +void display_comments(int type) { + host *temp_host = NULL; + service *temp_service = NULL; + int total_comments = 0; + int display_comment = FALSE; + char *bg_class = ""; + int odd = 1; + char date_time[MAX_DATETIME_LENGTH]; + comment *temp_comment; + char *comment_type; + char expire_time[MAX_DATETIME_LENGTH]; + + + /* find the host or service */ + if(type == HOST_COMMENT) { + temp_host = find_host(host_name); + if(temp_host == NULL) + return; + } + else { + temp_service = find_service(host_name, service_desc); + if(temp_service == NULL) + return; + } + + + printf("\n"); + printf("
    %s Comments
    \n", (type == HOST_COMMENT) ? "Host" : "Service"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("
    ", url_images_path, COMMENT_ICON); + if(type == HOST_COMMENT) + printf("", COMMAND_CGI, CMD_ADD_HOST_COMMENT, url_encode(host_name)); + else { + printf("", url_encode(service_desc)); + } + printf("Add a new comment", url_images_path, DELETE_ICON); + if(type == HOST_COMMENT) + printf("", COMMAND_CGI, CMD_DEL_ALL_HOST_COMMENTS, url_encode(host_name)); + else { + printf("", url_encode(service_desc)); + } + printf("Delete all comments
    \n"); + //printf("
    \n"); + + + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* check all the comments to see if they apply to this host or service */ + /* Comments are displayed in the order they are read from the status.dat file */ + for(temp_comment = get_first_comment_by_host(host_name); temp_comment != NULL; temp_comment = get_next_comment_by_host(host_name, temp_comment)) { + + display_comment = FALSE; + + if(type == HOST_COMMENT && temp_comment->comment_type == HOST_COMMENT) + display_comment = TRUE; + + else if(type == SERVICE_COMMENT && temp_comment->comment_type == SERVICE_COMMENT && !strcmp(temp_comment->service_description, service_desc)) + display_comment = TRUE; + + if(display_comment == TRUE) { + + if(odd) { + odd = 0; + bg_class = "commentOdd"; + } + else { + odd = 1; + bg_class = "commentEven"; + } + + switch(temp_comment->entry_type) { + case USER_COMMENT: + comment_type = "User"; + break; + case DOWNTIME_COMMENT: + comment_type = "Scheduled Downtime"; + break; + case FLAPPING_COMMENT: + comment_type = "Flap Detection"; + break; + case ACKNOWLEDGEMENT_COMMENT: + comment_type = "Acknowledgement"; + break; + default: + comment_type = "?"; + } + + get_time_string(&temp_comment->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + get_time_string(&temp_comment->expire_time, expire_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class); + printf("", bg_class, date_time, bg_class, temp_comment->author, bg_class, temp_comment->comment_data, bg_class, temp_comment->comment_id, bg_class, (temp_comment->persistent) ? "Yes" : "No", bg_class, comment_type, bg_class, (temp_comment->expires == TRUE) ? expire_time : "N/A"); + printf("", COMMAND_CGI, (type == HOST_COMMENT) ? CMD_DEL_HOST_COMMENT : CMD_DEL_SVC_COMMENT, temp_comment->comment_id, url_images_path, DELETE_ICON); + printf("\n"); + + total_comments++; + } + } + + /* see if this host or service has any comments associated with it */ + if(total_comments == 0) + printf("", (type == HOST_COMMENT) ? 9 : 10, (type == HOST_COMMENT) ? "host" : "service"); + + printf("
    Entry TimeAuthorCommentComment IDPersistentTypeExpiresActions
    %s%s%s%lu%s%s%sDelete This Comment
    This %s has no comments associated with it
    \n"); + + return; + } + + + + +/* shows all service and host scheduled downtime */ +void show_all_downtime(void) { + int total_downtime = 0; + char *bg_class = ""; + int odd = 0; + char date_time[MAX_DATETIME_LENGTH]; + scheduled_downtime *temp_downtime; + host *temp_host; + service *temp_service; + int days; + int hours; + int minutes; + int seconds; + + + printf("
    \n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + printf("
    Scheduled Host Downtime
    \n"); + + printf("\n"); + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* display all the host downtime */ + for(temp_downtime = scheduled_downtime_list, total_downtime = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + + if(temp_downtime->type != HOST_DOWNTIME) + continue; + + temp_host = find_host(temp_downtime->host_name); + + /* make sure the user has rights to view host information */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + total_downtime++; + + if(odd) { + odd = 0; + bg_class = "downtimeOdd"; + } + else { + odd = 1; + bg_class = "downtimeEven"; + } + + printf("", bg_class); + printf("", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_downtime->host_name), temp_downtime->host_name); + get_time_string(&temp_downtime->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class, date_time); + printf("", bg_class, (temp_downtime->author == NULL) ? "N/A" : temp_downtime->author); + printf("", bg_class, (temp_downtime->comment == NULL) ? "N/A" : temp_downtime->comment); + get_time_string(&temp_downtime->start_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class, date_time); + get_time_string(&temp_downtime->end_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class, date_time); + printf("", bg_class, (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible"); + get_time_breakdown(temp_downtime->duration, &days, &hours, &minutes, &seconds); + printf("", bg_class, days, hours, minutes, seconds); + printf("", bg_class, temp_downtime->downtime_id); + printf("\n"); + printf("", COMMAND_CGI, CMD_DEL_HOST_DOWNTIME, temp_downtime->downtime_id, url_images_path, DELETE_ICON); + printf("\n"); + } + + if(total_downtime == 0) + printf(""); + + printf("
    Host NameEntry TimeAuthorCommentStart TimeEnd TimeTypeDurationDowntime IDTrigger IDActions
    %s%s%s%s%s%s%s%dd %dh %dm %ds%lu", bg_class); + if(temp_downtime->triggered_by == 0) + printf("N/A"); + else + printf("%lu", temp_downtime->triggered_by); + printf("Delete/Cancel This Scheduled Downtime Entry
    There are no hosts with scheduled downtime
    \n"); + printf("
    \n"); + + printf("


    \n"); + + + printf("\n"); + printf("
    Scheduled Service Downtime
    \n"); + + printf("\n"); + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + /* display all the service downtime */ + for(temp_downtime = scheduled_downtime_list, total_downtime = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + + if(temp_downtime->type != SERVICE_DOWNTIME) + continue; + + temp_service = find_service(temp_downtime->host_name, temp_downtime->service_description); + + /* make sure the user has rights to view service information */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + total_downtime++; + + if(odd) { + odd = 0; + bg_class = "downtimeOdd"; + } + else { + odd = 1; + bg_class = "downtimeEven"; + } + + printf("", bg_class); + printf("", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_downtime->host_name), temp_downtime->host_name); + printf("", url_encode(temp_downtime->service_description), temp_downtime->service_description); + get_time_string(&temp_downtime->entry_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class, date_time); + printf("", bg_class, (temp_downtime->author == NULL) ? "N/A" : temp_downtime->author); + printf("", bg_class, (temp_downtime->comment == NULL) ? "N/A" : temp_downtime->comment); + get_time_string(&temp_downtime->start_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class, date_time); + get_time_string(&temp_downtime->end_time, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bg_class, date_time); + printf("", bg_class, (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible"); + get_time_breakdown(temp_downtime->duration, &days, &hours, &minutes, &seconds); + printf("", bg_class, days, hours, minutes, seconds); + printf("", bg_class, temp_downtime->downtime_id); + printf("\n"); + printf("", COMMAND_CGI, CMD_DEL_SVC_DOWNTIME, temp_downtime->downtime_id, url_images_path, DELETE_ICON); + printf("\n"); + } + + if(total_downtime == 0) + printf(""); + + printf("
    Host NameServiceEntry TimeAuthorCommentStart TimeEnd TimeTypeDurationDowntime IDTrigger IDActions
    %s%s%s%s%s%s%s%s%dd %dh %dm %ds%lu", bg_class); + if(temp_downtime->triggered_by == 0) + printf("N/A"); + else + printf("%lu", temp_downtime->triggered_by); + printf("Delete/Cancel This Scheduled Downtime Entry
    There are no services with scheduled downtime
    \n"); + printf("
    \n"); + + return; + } + + + +/* shows check scheduling queue */ +void show_scheduling_queue(void) { + sortdata *temp_sortdata; + servicestatus *temp_svcstatus = NULL; + hoststatus *temp_hststatus = NULL; + char date_time[MAX_DATETIME_LENGTH]; + char temp_url[MAX_INPUT_BUFFER]; + int odd = 0; + char *bgclass = ""; + + + /* make sure the user has rights to view system information */ + if(is_authorized_for_system_information(¤t_authdata) == FALSE) { + + printf("

    It appears as though you do not have permission to view process information...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + + return; + } + + /* sort hosts and services */ + sort_data(sort_type, sort_option); + + printf("
    Entries sorted by "); + if(sort_option == SORT_HOSTNAME) + printf("host name"); + else if(sort_option == SORT_SERVICENAME) + printf("service name"); + else if(sort_option == SORT_SERVICESTATUS) + printf("service status"); + else if(sort_option == SORT_LASTCHECKTIME) + printf("last check time"); + else if(sort_option == SORT_NEXTCHECKTIME) + printf("next check time"); + printf(" (%s)\n", (sort_type == SORT_ASCENDING) ? "ascending" : "descending"); + printf("
    \n"); + + printf("

    \n"); + printf("

    \n"); + printf("\n"); + printf(""); + + snprintf(temp_url, sizeof(temp_url) - 1, "%s?type=%d", EXTINFO_CGI, DISPLAY_SCHEDULING_QUEUE); + temp_url[sizeof(temp_url) - 1] = '\x0'; + + printf("", temp_url, SORT_ASCENDING, SORT_HOSTNAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_HOSTNAME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_SERVICENAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_SERVICENAME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_LASTCHECKTIME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_LASTCHECKTIME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_NEXTCHECKTIME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_NEXTCHECKTIME, url_images_path, DOWN_ARROW_ICON); + + + printf("\n"); + + + /* display all services and hosts */ + for(temp_sortdata = sortdata_list; temp_sortdata != NULL; temp_sortdata = temp_sortdata->next) { + + /* skip hosts and services that shouldn't be scheduled */ + if(temp_sortdata->is_service == TRUE) { + temp_svcstatus = temp_sortdata->svcstatus; + if(temp_svcstatus->should_be_scheduled == FALSE) { + /* passive-only checks should appear if they're being forced */ + if(!(temp_svcstatus->checks_enabled == FALSE && temp_svcstatus->next_check != (time_t)0L && (temp_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION))) + continue; + } + } + else { + temp_hststatus = temp_sortdata->hststatus; + if(temp_hststatus->should_be_scheduled == FALSE) { + /* passive-only checks should appear if they're being forced */ + if(!(temp_hststatus->checks_enabled == FALSE && temp_hststatus->next_check != (time_t)0L && (temp_hststatus->check_options & CHECK_OPTION_FORCE_EXECUTION))) + continue; + } + } + + if(odd) { + odd = 0; + bgclass = "Even"; + } + else { + odd = 1; + bgclass = "Odd"; + } + + printf("", bgclass); + + /* get the service status */ + if(temp_sortdata->is_service == TRUE) { + + printf("", bgclass, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_svcstatus->host_name), temp_svcstatus->host_name); + + printf("", url_encode(temp_svcstatus->description), temp_svcstatus->description); + + get_time_string(&temp_svcstatus->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bgclass, (temp_svcstatus->last_check == (time_t)0) ? "N/A" : date_time); + + get_time_string(&temp_svcstatus->next_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bgclass, (temp_svcstatus->next_check == (time_t)0) ? "N/A" : date_time); + + printf(""); + + printf("", (temp_svcstatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_svcstatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED"); + + printf("\n"); + } + + /* get the host status */ + else { + + printf("", bgclass, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hststatus->host_name), temp_hststatus->host_name); + + printf("", bgclass); + + get_time_string(&temp_hststatus->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bgclass, (temp_hststatus->last_check == (time_t)0) ? "N/A" : date_time); + + get_time_string(&temp_hststatus->next_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bgclass, (temp_hststatus->next_check == (time_t)0) ? "N/A" : date_time); + + printf(""); + + printf("", (temp_hststatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED", (temp_hststatus->checks_enabled == TRUE) ? "ENABLED" : "DISABLED"); + + printf("\n"); + } + + printf("\n"); + + } + + printf("
    Host Sort by host name (ascending)Sort by host name (descending)Service Sort by service name (ascending)Sort by service name (descending)Last Check Sort by last check time (ascending)Sort by last check time (descending)Next Check Sort by next check time (ascending)Sort by next check time (descending)TypeActive ChecksActions
    %s%s%s%s", bgclass); + if(temp_svcstatus->check_options == CHECK_OPTION_NONE) + printf("Normal "); + else { + if(temp_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION) + printf("Forced "); + if(temp_svcstatus->check_options & CHECK_OPTION_FRESHNESS_CHECK) + printf("Freshness "); + if(temp_svcstatus->check_options & CHECK_OPTION_ORPHAN_CHECK) + printf("Orphan "); + } + printf("%s", bgclass); + if(temp_svcstatus->checks_enabled == TRUE) { + printf("Disable Active Checks Of This Service\n", url_encode(temp_svcstatus->description), url_images_path, DISABLED_ICON); + } + else { + printf("Enable Active Checks Of This Service\n", url_encode(temp_svcstatus->description), url_images_path, ENABLED_ICON); + } + printf("Re-schedule This Service Check\n", url_encode(temp_svcstatus->description), (temp_svcstatus->checks_enabled == TRUE) ? "&force_check" : "", url_images_path, DELAY_ICON); + printf("%s %s%s", bgclass); + if(temp_hststatus->check_options == CHECK_OPTION_NONE) + printf("Normal "); + else { + if(temp_hststatus->check_options & CHECK_OPTION_FORCE_EXECUTION) + printf("Forced "); + if(temp_hststatus->check_options & CHECK_OPTION_FRESHNESS_CHECK) + printf("Freshness "); + if(temp_hststatus->check_options & CHECK_OPTION_ORPHAN_CHECK) + printf("Orphan "); + } + printf("%s", bgclass); + if(temp_hststatus->checks_enabled == TRUE) { + printf("Disable Active Checks Of This Host\n", url_images_path, DISABLED_ICON); + } + else { + printf("Enable Active Checks Of This Host\n", url_images_path, ENABLED_ICON); + } + printf("Re-schedule This Host Check\n", url_images_path, DELAY_ICON); + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + + /* free memory allocated to sorted data list */ + free_sortdata_list(); + + return; + } + + + +/* sorts host and service data */ +int sort_data(int s_type, int s_option) { + sortdata *new_sortdata; + sortdata *last_sortdata; + sortdata *temp_sortdata; + servicestatus *temp_svcstatus; + hoststatus *temp_hststatus; + + if(s_type == SORT_NONE) + return ERROR; + + /* sort all service status entries */ + for(temp_svcstatus = servicestatus_list; temp_svcstatus != NULL; temp_svcstatus = temp_svcstatus->next) { + + /* allocate memory for a new sort structure */ + new_sortdata = (sortdata *)malloc(sizeof(sortdata)); + if(new_sortdata == NULL) + return ERROR; + + new_sortdata->is_service = TRUE; + new_sortdata->svcstatus = temp_svcstatus; + new_sortdata->hststatus = NULL; + + last_sortdata = sortdata_list; + for(temp_sortdata = sortdata_list; temp_sortdata != NULL; temp_sortdata = temp_sortdata->next) { + + if(compare_sortdata_entries(s_type, s_option, new_sortdata, temp_sortdata) == TRUE) { + new_sortdata->next = temp_sortdata; + if(temp_sortdata == sortdata_list) + sortdata_list = new_sortdata; + else + last_sortdata->next = new_sortdata; + break; + } + else + last_sortdata = temp_sortdata; + } + + if(sortdata_list == NULL) { + new_sortdata->next = NULL; + sortdata_list = new_sortdata; + } + else if(temp_sortdata == NULL) { + new_sortdata->next = NULL; + last_sortdata->next = new_sortdata; + } + } + + /* sort all host status entries */ + for(temp_hststatus = hoststatus_list; temp_hststatus != NULL; temp_hststatus = temp_hststatus->next) { + + /* allocate memory for a new sort structure */ + new_sortdata = (sortdata *)malloc(sizeof(sortdata)); + if(new_sortdata == NULL) + return ERROR; + + new_sortdata->is_service = FALSE; + new_sortdata->svcstatus = NULL; + new_sortdata->hststatus = temp_hststatus; + + last_sortdata = sortdata_list; + for(temp_sortdata = sortdata_list; temp_sortdata != NULL; temp_sortdata = temp_sortdata->next) { + + if(compare_sortdata_entries(s_type, s_option, new_sortdata, temp_sortdata) == TRUE) { + new_sortdata->next = temp_sortdata; + if(temp_sortdata == sortdata_list) + sortdata_list = new_sortdata; + else + last_sortdata->next = new_sortdata; + break; + } + else + last_sortdata = temp_sortdata; + } + + if(sortdata_list == NULL) { + new_sortdata->next = NULL; + sortdata_list = new_sortdata; + } + else if(temp_sortdata == NULL) { + new_sortdata->next = NULL; + last_sortdata->next = new_sortdata; + } + } + + return OK; + } + + +int compare_sortdata_entries(int s_type, int s_option, sortdata *new_sortdata, sortdata *temp_sortdata) { + hoststatus *temp_hststatus = NULL; + servicestatus *temp_svcstatus = NULL; + time_t last_check[2]; + time_t next_check[2]; + int current_attempt[2]; + int status[2]; + char *host_name[2]; + char *service_description[2]; + + if(new_sortdata->is_service == TRUE) { + temp_svcstatus = new_sortdata->svcstatus; + last_check[0] = temp_svcstatus->last_check; + next_check[0] = temp_svcstatus->next_check; + status[0] = temp_svcstatus->status; + host_name[0] = temp_svcstatus->host_name; + service_description[0] = temp_svcstatus->description; + current_attempt[0] = temp_svcstatus->current_attempt; + } + else { + temp_hststatus = new_sortdata->hststatus; + last_check[0] = temp_hststatus->last_check; + next_check[0] = temp_hststatus->next_check; + status[0] = temp_hststatus->status; + host_name[0] = temp_hststatus->host_name; + service_description[0] = ""; + current_attempt[0] = temp_hststatus->current_attempt; + } + if(temp_sortdata->is_service == TRUE) { + temp_svcstatus = temp_sortdata->svcstatus; + last_check[1] = temp_svcstatus->last_check; + next_check[1] = temp_svcstatus->next_check; + status[1] = temp_svcstatus->status; + host_name[1] = temp_svcstatus->host_name; + service_description[1] = temp_svcstatus->description; + current_attempt[1] = temp_svcstatus->current_attempt; + } + else { + temp_hststatus = temp_sortdata->hststatus; + last_check[1] = temp_hststatus->last_check; + next_check[1] = temp_hststatus->next_check; + status[1] = temp_hststatus->status; + host_name[1] = temp_hststatus->host_name; + service_description[1] = ""; + current_attempt[1] = temp_hststatus->current_attempt; + } + + if(s_type == SORT_ASCENDING) { + + if(s_option == SORT_LASTCHECKTIME) { + if(last_check[0] <= last_check[1]) + return TRUE; + else + return FALSE; + } + if(s_option == SORT_NEXTCHECKTIME) { + if(next_check[0] <= next_check[1]) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_CURRENTATTEMPT) { + if(current_attempt[0] <= current_attempt[1]) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICESTATUS) { + if(status[0] <= status[1]) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTNAME) { + if(strcasecmp(host_name[0], host_name[1]) < 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICENAME) { + if(strcasecmp(service_description[0], service_description[1]) < 0) + return TRUE; + else + return FALSE; + } + } + else { + if(s_option == SORT_LASTCHECKTIME) { + if(last_check[0] > last_check[1]) + return TRUE; + else + return FALSE; + } + if(s_option == SORT_NEXTCHECKTIME) { + if(next_check[0] > next_check[1]) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_CURRENTATTEMPT) { + if(current_attempt[0] > current_attempt[1]) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICESTATUS) { + if(status[0] > status[1]) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTNAME) { + if(strcasecmp(host_name[0], host_name[1]) > 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICENAME) { + if(strcasecmp(service_description[0], service_description[1]) > 0) + return TRUE; + else + return FALSE; + } + } + + return TRUE; + } + + + +/* free all memory allocated to the sortdata structures */ +void free_sortdata_list(void) { + sortdata *this_sortdata; + sortdata *next_sortdata; + + /* free memory for the sortdata list */ + for(this_sortdata = sortdata_list; this_sortdata != NULL; this_sortdata = next_sortdata) { + next_sortdata = this_sortdata->next; + free(this_sortdata); + } + + return; + } + diff --git a/cgi/getcgi.c b/cgi/getcgi.c new file mode 100644 index 0000000..967317e --- /dev/null +++ b/cgi/getcgi.c @@ -0,0 +1,517 @@ +/****************************************** + * + * GETCGI.C - Nagios CGI Input Routines + * + * Last Modified: 05-15-2006 + * + *****************************************/ + +#include "../include/config.h" +#include "../include/getcgi.h" +#include +#include + + +#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; + } diff --git a/cgi/histogram.c b/cgi/histogram.c new file mode 100644 index 0000000..1095314 --- /dev/null +++ b/cgi/histogram.c @@ -0,0 +1,2481 @@ +/************************************************************************** + * + * HISTOGRAM.C - Nagios Alert Histogram CGI + * + * Copyright (c) 2001-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-15-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *************************************************************************/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/statusdata.h" + +#include "../include/cgiutils.h" +#include "../include/getcgi.h" +#include "../include/cgiauth.h" + +#include /* Boutell's GD library function */ +#include /* GD library small font definition */ + + +/*#define DEBUG 1*/ + + +#define HISTOGRAM_IMAGE "histogram.png" + +/* archived state types */ +#define AS_NO_DATA 0 +#define AS_PROGRAM_START 1 +#define AS_PROGRAM_END 2 +#define AS_HOST_UP 3 +#define AS_HOST_DOWN 4 +#define AS_HOST_UNREACHABLE 5 +#define AS_SVC_OK 6 +#define AS_SVC_UNKNOWN 7 +#define AS_SVC_WARNING 8 +#define AS_SVC_CRITICAL 9 + + +/* display types */ +#define DISPLAY_HOST_HISTOGRAM 0 +#define DISPLAY_SERVICE_HISTOGRAM 1 +#define DISPLAY_NO_HISTOGRAM 2 + +/* input types */ +#define GET_INPUT_NONE 0 +#define GET_INPUT_TARGET_TYPE 1 +#define GET_INPUT_HOST_TARGET 2 +#define GET_INPUT_SERVICE_TARGET 3 +#define GET_INPUT_OPTIONS 4 + +/* breakdown types */ +#define BREAKDOWN_MONTHLY 0 +#define BREAKDOWN_DAY_OF_MONTH 1 +#define BREAKDOWN_DAY_OF_WEEK 2 +#define BREAKDOWN_HOURLY 3 + +/* modes */ +#define CREATE_HTML 0 +#define CREATE_IMAGE 1 + +/* standard report times */ +#define TIMEPERIOD_CUSTOM 0 +#define TIMEPERIOD_TODAY 1 +#define TIMEPERIOD_YESTERDAY 2 +#define TIMEPERIOD_THISWEEK 3 +#define TIMEPERIOD_LASTWEEK 4 +#define TIMEPERIOD_THISMONTH 5 +#define TIMEPERIOD_LASTMONTH 6 +#define TIMEPERIOD_THISQUARTER 7 +#define TIMEPERIOD_LASTQUARTER 8 +#define TIMEPERIOD_THISYEAR 9 +#define TIMEPERIOD_LASTYEAR 10 +#define TIMEPERIOD_LAST24HOURS 11 +#define TIMEPERIOD_LAST7DAYS 12 +#define TIMEPERIOD_LAST31DAYS 13 + + +#define MAX_ARCHIVE_SPREAD 65 +#define MAX_ARCHIVE 65 +#define MAX_ARCHIVE_BACKTRACKS 60 + +#define DRAWING_WIDTH 550 +#define DRAWING_HEIGHT 195 +#define DRAWING_X_OFFSET 60 +#define DRAWING_Y_OFFSET 235 + +#define GRAPH_HOST_UP 1 +#define GRAPH_HOST_DOWN 2 +#define GRAPH_HOST_UNREACHABLE 4 +#define GRAPH_SERVICE_OK 8 +#define GRAPH_SERVICE_WARNING 16 +#define GRAPH_SERVICE_UNKNOWN 32 +#define GRAPH_SERVICE_CRITICAL 64 + +#define GRAPH_HOST_PROBLEMS 6 +#define GRAPH_HOST_ALL 7 + +#define GRAPH_SERVICE_PROBLEMS 112 +#define GRAPH_SERVICE_ALL 120 + +#define GRAPH_EVERYTHING 255 + + +#define GRAPH_SOFT_STATETYPES 1 +#define GRAPH_HARD_STATETYPES 2 +#define GRAPH_ALL_STATETYPES 3 + + + + +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 char physical_images_path[MAX_FILENAME_LENGTH]; + +extern int log_rotation_method; + +extern host *host_list; +extern service *service_list; + + + +authdata current_authdata; + + +typedef struct timeslice_data_struct { + unsigned long service_ok; + unsigned long host_up; + unsigned long service_critical; + unsigned long host_down; + unsigned long service_unknown; + unsigned long host_unreachable; + unsigned long service_warning; + } timeslice_data; + + +timeslice_data *tsdata; + + +void convert_timeperiod_to_times(int); +void compute_report_times(void); +void graph_all_histogram_data(void); +void add_archived_state(int, time_t); +void read_archived_state_data(void); +void scan_log_file_for_archived_state_data(char *); +void draw_line(int, int, int, int, int); +void draw_dashed_line(int, int, int, int, int); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + + +time_t t1; +time_t t2; + +int start_second = 0; +int start_minute = 0; +int start_hour = 0; +int start_day = 1; +int start_month = 1; +int start_year = 2000; +int end_second = 0; +int end_minute = 0; +int end_hour = 24; +int end_day = 1; +int end_month = 1; +int end_year = 2000; + +int display_type = DISPLAY_NO_HISTOGRAM; +int mode = CREATE_HTML; +int input_type = GET_INPUT_NONE; +int timeperiod_type = TIMEPERIOD_LAST24HOURS; +int breakdown_type = BREAKDOWN_HOURLY; +int compute_time_from_parts = FALSE; + +int initial_states_logged = FALSE; +int assume_state_retention = TRUE; +int new_states_only = FALSE; + +int last_state = AS_NO_DATA; +int program_restart_has_occurred = FALSE; + +int graph_events = GRAPH_EVERYTHING; +int graph_statetypes = GRAPH_HARD_STATETYPES; + +int embedded = FALSE; +int display_header = TRUE; + +char *host_name = ""; +char *svc_description = ""; + +gdImagePtr histogram_image = 0; +int color_white = 0; +int color_black = 0; +int color_red = 0; +int color_darkred = 0; +int color_green = 0; +int color_yellow = 0; +int color_orange = 0; +int color_lightgray = 0; +FILE *image_file = NULL; + +int backtrack_archives = 0; +int earliest_archive = 0; +time_t earliest_time; +time_t latest_time; + +int image_width = 900; +int image_height = 320; + +int total_buckets = 96; + + + +int main(int argc, char **argv) { + int result = OK; + char temp_buffer[MAX_INPUT_BUFFER]; + char image_template[MAX_INPUT_BUFFER]; + char start_timestring[MAX_INPUT_BUFFER]; + char end_timestring[MAX_INPUT_BUFFER]; + host *temp_host; + service *temp_service; + int is_authorized = TRUE; + int found = FALSE; + int days, hours, minutes, seconds; + char *first_service = NULL; + int x; + time_t t3; + time_t current_time; + struct tm *t; + + /* initialize time period to last 24 hours */ + time(&t2); + t1 = (time_t)(t2 - (60 * 60 * 24)); + + /* get the arguments passed in the URL */ + 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) { + if(mode == CREATE_HTML) { + 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) { + if(mode == CREATE_HTML) { + 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) { + if(mode == CREATE_HTML) { + 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) { + if(mode == CREATE_HTML) { + document_header(FALSE); + status_data_error(); + document_footer(); + } + free_memory(); + return ERROR; + } + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + if(compute_time_from_parts == TRUE) + compute_report_times(); + + /* make sure times are sane, otherwise swap them */ + if(t2 < t1) { + t3 = t2; + t2 = t1; + t1 = t3; + } + + + if(mode == CREATE_HTML && display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* center column of top row */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + + if(display_type == DISPLAY_HOST_HISTOGRAM) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Alert Histogram"); + else if(display_type == DISPLAY_SERVICE_HISTOGRAM) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Alert Histogram"); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host and Service Alert Histogram"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + display_info_table(temp_buffer, FALSE, ¤t_authdata); + + if(display_type != DISPLAY_NO_HISTOGRAM && input_type == GET_INPUT_NONE) { + + printf("\n"); + printf("\n"); + printf("\n"); + } + + printf("\n"); + + if(display_type != DISPLAY_NO_HISTOGRAM && input_type == GET_INPUT_NONE) { + + printf("
    \n"); + if(display_type == DISPLAY_HOST_HISTOGRAM) + printf("Host '%s'", host_name); + else if(display_type == DISPLAY_SERVICE_HISTOGRAM) + printf("Service '%s' On Host '%s'", svc_description, host_name); + printf("
    \n"); + + printf("
    \n"); + + printf("%s Event Histogram\n", url_images_path, TRENDS_ICON, (display_type == DISPLAY_HOST_HISTOGRAM) ? "Host" : "Service", (display_type == DISPLAY_HOST_HISTOGRAM) ? "Host" : "Service"); + + printf("
    \n"); + + get_time_string(&t1, start_timestring, sizeof(start_timestring) - 1, SHORT_DATE_TIME); + get_time_string(&t2, end_timestring, sizeof(end_timestring) - 1, SHORT_DATE_TIME); + printf("
    %s to %s
    \n", start_timestring, end_timestring); + + get_time_breakdown((time_t)(t2 - t1), &days, &hours, &minutes, &seconds); + printf("
    Duration: %dd %dh %dm %ds
    \n", days, hours, minutes, seconds); + } + + printf("
    \n"); + + printf("
    \n", HISTOGRAM_CGI); + printf("\n"); + + if(display_type != DISPLAY_NO_HISTOGRAM && input_type == GET_INPUT_NONE) { + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + } + + /* display context-sensitive help */ + printf("\n"); + + printf("
    Report period:Assume state retention:
    \n"); + + printf("\n", (unsigned long)t1); + printf("\n", (unsigned long)t2); + printf("\n", escape_string(host_name)); + if(display_type == DISPLAY_SERVICE_HISTOGRAM) + printf("\n", escape_string(svc_description)); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    Breakdown type:Initial states logged:
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    Events to graph:Ignore repeated states:
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    State types to graph:
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + if(display_type != DISPLAY_NO_HISTOGRAM && input_type == GET_INPUT_NONE) { + if(display_type == DISPLAY_HOST_HISTOGRAM) + display_context_help(CONTEXTHELP_HISTOGRAM_HOST); + else + display_context_help(CONTEXTHELP_HISTOGRAM_SERVICE); + } + else if(display_type == DISPLAY_NO_HISTOGRAM || input_type != GET_INPUT_NONE) { + if(input_type == GET_INPUT_NONE) + display_context_help(CONTEXTHELP_HISTOGRAM_MENU1); + else if(input_type == GET_INPUT_TARGET_TYPE) + display_context_help(CONTEXTHELP_HISTOGRAM_MENU1); + else if(input_type == GET_INPUT_HOST_TARGET) + display_context_help(CONTEXTHELP_HISTOGRAM_MENU2); + else if(input_type == GET_INPUT_SERVICE_TARGET) + display_context_help(CONTEXTHELP_HISTOGRAM_MENU3); + else if(input_type == GET_INPUT_OPTIONS) + display_context_help(CONTEXTHELP_HISTOGRAM_MENU4); + } + printf("
    \n"); + printf("
    \n"); + + printf("
    \n"); + } + + /* check authorization... */ + if(display_type == DISPLAY_HOST_HISTOGRAM) { + temp_host = find_host(host_name); + if(temp_host == NULL || is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + is_authorized = FALSE; + } + else if(display_type == DISPLAY_SERVICE_HISTOGRAM) { + temp_service = find_service(host_name, svc_description); + if(temp_service == NULL || is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + is_authorized = FALSE; + } + if(is_authorized == FALSE) { + + if(mode == CREATE_HTML) + printf("

    It appears as though you are not authorized to view information for the specified %s...

    \n", (display_type == DISPLAY_HOST_HISTOGRAM) ? "host" : "service"); + + document_footer(); + free_memory(); + return ERROR; + } + + if(display_type != DISPLAY_NO_HISTOGRAM && input_type == GET_INPUT_NONE) { + + /* print URL to image */ + if(mode == CREATE_HTML) { + + printf("

    \n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + } + + /* read and process state data */ + else { + + /* allocate memory */ + tsdata = NULL; + if(breakdown_type == BREAKDOWN_MONTHLY) + total_buckets = 12; + else if(breakdown_type == BREAKDOWN_DAY_OF_MONTH) + total_buckets = 31; + else if(breakdown_type == BREAKDOWN_DAY_OF_WEEK) + total_buckets = 7; + else + total_buckets = 96; + + tsdata = (timeslice_data *)malloc(sizeof(timeslice_data) * total_buckets); + if(tsdata == NULL) + return ERROR; + + for(x = 0; x < total_buckets; x++) { + tsdata[x].service_ok = 0L; + tsdata[x].service_unknown = 0L; + tsdata[x].service_warning = 0L; + tsdata[x].service_critical = 0L; + tsdata[x].host_up = 0L; + tsdata[x].host_down = 0L; + tsdata[x].host_unreachable = 0L; + } + + /* read in all necessary archived state data */ + read_archived_state_data(); + +#ifdef DEBUG + printf("Done reading archived state data.\n"); +#endif + + /* location of image template */ + snprintf(image_template, sizeof(image_template) - 1, "%s/%s", physical_images_path, HISTOGRAM_IMAGE); + image_template[sizeof(image_template) - 1] = '\x0'; + + /* allocate buffer for storing image */ + image_file = fopen(image_template, "r"); + if(image_file != NULL) { + histogram_image = gdImageCreateFromPng(image_file); + fclose(image_file); + } + if(histogram_image == NULL) + histogram_image = gdImageCreate(image_width, image_height); + if(histogram_image == NULL) { +#ifdef DEBUG + printf("Error: Could not allocate memory for image\n"); +#endif + return ERROR; + } + + /* allocate colors used for drawing */ + color_white = gdImageColorAllocate(histogram_image, 255, 255, 255); + color_black = gdImageColorAllocate(histogram_image, 0, 0, 0); + color_red = gdImageColorAllocate(histogram_image, 255, 0, 0); + color_darkred = gdImageColorAllocate(histogram_image, 128, 0, 0); + color_green = gdImageColorAllocate(histogram_image, 0, 128, 0); + color_yellow = gdImageColorAllocate(histogram_image, 176, 178, 20); + color_orange = gdImageColorAllocate(histogram_image, 255, 100, 25); + color_lightgray = gdImageColorAllocate(histogram_image, 192, 192, 192); + + /* set transparency index */ + gdImageColorTransparent(histogram_image, color_white); + + /* make sure the graphic is interlaced */ + gdImageInterlace(histogram_image, 1); + +#ifdef DEBUG + printf("Starting to graph data...\n"); +#endif + + /* graph archived state histogram data */ + graph_all_histogram_data(); + +#ifdef DEBUG + printf("Done graphing data.\n"); +#endif + + /* use STDOUT for writing the image data... */ + image_file = stdout; + +#ifdef DEBUG + image_file = fopen("/tmp/histogram.png", "w"); +#endif + + /* write the image to to STDOUT */ + gdImagePng(histogram_image, image_file); + +#ifdef DEBUG + fclose(image_file); +#endif + + /* free memory allocated to image */ + gdImageDestroy(histogram_image); + + /* free memory allocated for data */ + free(tsdata); + } + } + + + /* show user a selection of hosts and services to choose from... */ + if(display_type == DISPLAY_NO_HISTOGRAM || input_type != GET_INPUT_NONE) { + + /* ask the user for what host they want a report for */ + if(input_type == GET_INPUT_HOST_TARGET) { + + printf("

    \n"); + printf("
    Step 2: Select Host
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", HISTOGRAM_CGI); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Host:\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + /* ask the user for what service they want a report for */ + else if(input_type == GET_INPUT_SERVICE_TARGET) { + + printf("\n"); + + + printf("

    \n"); + printf("
    Step 2: Select Service
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", HISTOGRAM_CGI); + printf("\n"); + printf("\n", (first_service == NULL) ? "unknown" : (char *)escape_string(first_service)); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Service:\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + /* ask the user for report range and options */ + else if(input_type == GET_INPUT_OPTIONS) { + + time(¤t_time); + t = localtime(¤t_time); + + start_day = 1; + start_year = t->tm_year + 1900; + end_day = t->tm_mday; + end_year = t->tm_year + 1900; + + printf("

    \n"); + printf("
    Step 3: Select Report Options
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", HISTOGRAM_CGI); + printf("\n", escape_string(host_name)); + if(display_type == DISPLAY_SERVICE_HISTOGRAM) + printf("\n", escape_string(svc_description)); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Report Period:\n"); + printf("\n"); + printf("
    If Custom Report Period...
    Start Date (Inclusive):"); + printf("\n "); + printf(" ", start_day); + printf("", start_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    End Date (Inclusive):"); + printf("\n "); + printf(" ", end_day); + printf("", end_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("

    Statistics Breakdown:\n"); + printf("\n"); + printf("
    Events To Graph:\n"); + printf("\n"); + printf("
    State Types To Graph:\n"); + printf("\n"); + printf("
    Assume State Retention:\n"); + printf("\n"); + printf("
    Initial States Logged:\n"); + printf("\n"); + printf("
    Ignore Repeated States:\n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + /* as the user whether they want a graph for a host or service */ + else { + printf("

    \n"); + printf("
    Step 1: Select Report Type
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", HISTOGRAM_CGI); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Type:\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + } + + document_footer(); + + /* free all other 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; + + if(mode == CREATE_HTML) { + 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)0; + 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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios Histogram\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, HISTOGRAM_CSS); + } + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(HISTOGRAM_CGI, SSI_HEADER); + + printf("
    \n"); + } + + else { + 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: image/png\r\n\r\n"); + } + + return; + } + + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + if(mode == CREATE_HTML) { + + /* include user SSI footer */ + include_ssi_files(HISTOGRAM_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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")) { + 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_HOST_HISTOGRAM; + } + + /* we found the node width 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_SERVICE_HISTOGRAM; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t1")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t1 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t2")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t2 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + } + + /* we found the image creation option */ + else if(!strcmp(variables[x], "createimage")) { + mode = CREATE_IMAGE; + } + + /* we found the backtrack archives argument */ + else if(!strcmp(variables[x], "backtrack")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + backtrack_archives = atoi(variables[x]); + if(backtrack_archives < 0) + backtrack_archives = 0; + if(backtrack_archives > MAX_ARCHIVE_BACKTRACKS) + backtrack_archives = MAX_ARCHIVE_BACKTRACKS; + } + + /* we found the standard timeperiod argument */ + else if(!strcmp(variables[x], "timeperiod")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "today")) + timeperiod_type = TIMEPERIOD_TODAY; + else if(!strcmp(variables[x], "yesterday")) + timeperiod_type = TIMEPERIOD_YESTERDAY; + else if(!strcmp(variables[x], "thisweek")) + timeperiod_type = TIMEPERIOD_THISWEEK; + else if(!strcmp(variables[x], "lastweek")) + timeperiod_type = TIMEPERIOD_LASTWEEK; + else if(!strcmp(variables[x], "thismonth")) + timeperiod_type = TIMEPERIOD_THISMONTH; + else if(!strcmp(variables[x], "lastmonth")) + timeperiod_type = TIMEPERIOD_LASTMONTH; + else if(!strcmp(variables[x], "thisquarter")) + timeperiod_type = TIMEPERIOD_THISQUARTER; + else if(!strcmp(variables[x], "lastquarter")) + timeperiod_type = TIMEPERIOD_LASTQUARTER; + else if(!strcmp(variables[x], "thisyear")) + timeperiod_type = TIMEPERIOD_THISYEAR; + else if(!strcmp(variables[x], "lastyear")) + timeperiod_type = TIMEPERIOD_LASTYEAR; + else if(!strcmp(variables[x], "last24hours")) + timeperiod_type = TIMEPERIOD_LAST24HOURS; + else if(!strcmp(variables[x], "last7days")) + timeperiod_type = TIMEPERIOD_LAST7DAYS; + else if(!strcmp(variables[x], "last31days")) + timeperiod_type = TIMEPERIOD_LAST31DAYS; + else if(!strcmp(variables[x], "custom")) + timeperiod_type = TIMEPERIOD_CUSTOM; + else + timeperiod_type = TIMEPERIOD_TODAY; + + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + convert_timeperiod_to_times(timeperiod_type); + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "sday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "syear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ssec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "shour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + + /* we found time argument */ + else if(!strcmp(variables[x], "emon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eyear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "emin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "esec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ehour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* 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 input option */ + else if(!strcmp(variables[x], "input")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "gethost")) + input_type = GET_INPUT_HOST_TARGET; + else if(!strcmp(variables[x], "getservice")) + input_type = GET_INPUT_SERVICE_TARGET; + else if(!strcmp(variables[x], "getoptions")) + input_type = GET_INPUT_OPTIONS; + else + input_type = GET_INPUT_TARGET_TYPE; + } + + /* we found the graph states option */ + else if(!strcmp(variables[x], "graphevents")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + graph_events = atoi(variables[x]); + } + + /* we found the graph state types option */ + else if(!strcmp(variables[x], "graphstatetypes")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + graph_statetypes = atoi(variables[x]); + } + + /* we found the breakdown option */ + else if(!strcmp(variables[x], "breakdown")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "monthly")) + breakdown_type = BREAKDOWN_MONTHLY; + else if(!strcmp(variables[x], "dayofmonth")) + breakdown_type = BREAKDOWN_DAY_OF_MONTH; + else if(!strcmp(variables[x], "dayofweek")) + breakdown_type = BREAKDOWN_DAY_OF_WEEK; + else + breakdown_type = BREAKDOWN_HOURLY; + } + + /* we found the assume state retention option */ + else if(!strcmp(variables[x], "assumestateretention")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_state_retention = TRUE; + else + assume_state_retention = FALSE; + } + + /* we found the initial states logged option */ + else if(!strcmp(variables[x], "initialstateslogged")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + initial_states_logged = TRUE; + else + initial_states_logged = FALSE; + + } + + /* we found the new states only option */ + else if(!strcmp(variables[x], "newstatesonly")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + new_states_only = TRUE; + else + new_states_only = FALSE; + + } + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* graphs histogram data */ +void graph_all_histogram_data(void) { + int pixel_x; + int pixel_y; + int last_pixel_y; + int current_bucket; + int actual_bucket; + unsigned long max_value; + double x_scaling_factor; + double y_scaling_factor; + double x_units; + double y_units; + int current_unit; + int actual_unit; + char temp_buffer[MAX_INPUT_BUFFER]; + int string_width; + int string_height; + char *days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + char *months[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + char start_time[MAX_INPUT_BUFFER]; + char end_time[MAX_INPUT_BUFFER]; + + unsigned long state1_max = 0L; + unsigned long state1_min = 0L; + int have_state1_min = FALSE; + unsigned long state1_sum = 0L; + double state1_avg = 0.0; + unsigned long state2_max = 0L; + unsigned long state2_min = 0L; + int have_state2_min = FALSE; + unsigned long state2_sum = 0L; + double state2_avg = 0.0; + unsigned long state3_max = 0L; + unsigned long state3_min = 0L; + int have_state3_min = FALSE; + unsigned long state3_sum = 0L; + double state3_avg = 0.0; + unsigned long state4_max = 0L; + unsigned long state4_min = 0L; + int have_state4_min = FALSE; + unsigned long state4_sum = 0L; + double state4_avg = 0.0; + + +#ifdef DEBUG + printf("Total Buckets: %d\n", total_buckets); +#endif + + /* determine max value in the buckets (for scaling) */ + max_value = 0L; + for(current_bucket = 0; current_bucket < total_buckets; current_bucket++) { + if(tsdata[current_bucket].service_ok > max_value) + max_value = tsdata[current_bucket].service_ok; + if(tsdata[current_bucket].service_warning > max_value) + max_value = tsdata[current_bucket].service_warning; + if(tsdata[current_bucket].service_unknown > max_value) + max_value = tsdata[current_bucket].service_unknown; + if(tsdata[current_bucket].service_critical > max_value) + max_value = tsdata[current_bucket].service_critical; + if(tsdata[current_bucket].host_up > max_value) + max_value = tsdata[current_bucket].host_up; + if(tsdata[current_bucket].host_down > max_value) + max_value = tsdata[current_bucket].host_down; + if(tsdata[current_bucket].host_unreachable > max_value) + max_value = tsdata[current_bucket].host_unreachable; + } + +#ifdef DEBUG + printf("Done determining max bucket values\n"); + printf("MAX_VALUE=%lu\n", max_value); + printf("DRAWING_HEIGHT=%lu\n", DRAWING_HEIGHT); +#endif + + /* min number of values to graph */ + if(max_value < 10) + max_value = 10; +#ifdef DEBUG + printf("ADJUSTED MAX_VALUE=%lu\n", max_value); +#endif + + /* determine y scaling factor */ + /*y_scaling_factor=floor((double)DRAWING_HEIGHT/(double)max_value);*/ + y_scaling_factor = (double)((double)DRAWING_HEIGHT / (double)max_value); + + /* determine x scaling factor */ + x_scaling_factor = (double)((double)DRAWING_WIDTH / (double)total_buckets); + + /* determine y units resolution - we want a max of about 10 y grid lines */ + /* + y_units=(double)((double)DRAWING_HEIGHT/19.0); + y_units=ceil(y_units/y_scaling_factor)*y_scaling_factor; + */ + y_units = ceil(19.0 / y_scaling_factor); + + /* determine x units resolution */ + if(breakdown_type == BREAKDOWN_HOURLY) + x_units = (double)((double)DRAWING_WIDTH / (double)(total_buckets / 4.0)); + else + x_units = x_scaling_factor; + +#ifdef DEBUG + printf("DRAWING_WIDTH: %d\n", DRAWING_WIDTH); + printf("DRAWING_HEIGHT: %d\n", DRAWING_HEIGHT); + printf("max_value: %lu\n", max_value); + printf("x_scaling_factor: %.3f\n", x_scaling_factor); + printf("y_scaling_factor: %.3f\n", y_scaling_factor); + printf("x_units: %.3f\n", x_units); + printf("y_units: %.3f\n", y_units); + printf("y units to draw: %.3f\n", ((double)max_value / y_units)); +#endif + + string_height = gdFontSmall->h; + +#ifdef DEBUG + printf("Starting to draw Y grid lines...\n"); +#endif + + /* draw y grid lines */ + if(max_value > 0) { + for(current_unit = 1; (current_unit * y_units * y_scaling_factor) <= DRAWING_HEIGHT; current_unit++) { + draw_dashed_line(DRAWING_X_OFFSET, DRAWING_Y_OFFSET - (current_unit * y_units * y_scaling_factor), DRAWING_X_OFFSET + DRAWING_WIDTH, DRAWING_Y_OFFSET - (current_unit * y_units * y_scaling_factor), color_lightgray); +#ifdef DEBUG + printf(" Drawing Y unit #%d @ %d\n", current_unit, (int)(current_unit * y_units * y_scaling_factor)); +#endif + } + } + +#ifdef DEBUG + printf("Starting to draw X grid lines...\n"); +#endif + + /* draw x grid lines */ + for(current_unit = 1; (int)(current_unit * x_units) <= DRAWING_WIDTH; current_unit++) + draw_dashed_line(DRAWING_X_OFFSET + (int)(current_unit * x_units), DRAWING_Y_OFFSET, DRAWING_X_OFFSET + (int)(current_unit * x_units), DRAWING_Y_OFFSET - DRAWING_HEIGHT, color_lightgray); + +#ifdef DEBUG + printf("Starting to draw grid units...\n"); +#endif + + /* draw y units */ + if(max_value > 0) { + for(current_unit = 0; (current_unit * y_units * y_scaling_factor) <= DRAWING_HEIGHT; current_unit++) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%d", (int)(current_unit * y_units)); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET - string_width - 5, DRAWING_Y_OFFSET - (current_unit * y_units * y_scaling_factor) - (string_height / 2), (unsigned char *)temp_buffer, color_black); + } + } + + /* draw x units */ + for(current_unit = 0, actual_unit = 0; (int)(current_unit * x_units) <= DRAWING_WIDTH; current_unit++, actual_unit++) { + + if(actual_unit >= total_buckets) + actual_unit = 0; + + if(breakdown_type == BREAKDOWN_MONTHLY) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s", months[actual_unit]); + else if(breakdown_type == BREAKDOWN_DAY_OF_MONTH) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%d", actual_unit + 1); + else if(breakdown_type == BREAKDOWN_DAY_OF_WEEK) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s", days[actual_unit]); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%02d:00", (actual_unit == 24) ? 0 : actual_unit); + + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + + gdImageStringUp(histogram_image, gdFontSmall, DRAWING_X_OFFSET + (current_unit * x_units) - (string_height / 2), DRAWING_Y_OFFSET + 5 + string_width, (unsigned char *)temp_buffer, color_black); + } + + /* draw y unit measure */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Number of Events"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageStringUp(histogram_image, gdFontSmall, 0, DRAWING_Y_OFFSET - (DRAWING_HEIGHT / 2) + (string_width / 2), (unsigned char *)temp_buffer, color_black); + + /* draw x unit measure */ + if(breakdown_type == BREAKDOWN_MONTHLY) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Month"); + else if(breakdown_type == BREAKDOWN_DAY_OF_MONTH) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Day of the Month"); + else if(breakdown_type == BREAKDOWN_DAY_OF_WEEK) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Day of the Week"); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Hour of the Day (15 minute increments)"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + (DRAWING_WIDTH / 2) - (string_width / 2), DRAWING_Y_OFFSET + 70, (unsigned char *)temp_buffer, color_black); + + /* draw title */ + snprintf(start_time, sizeof(start_time) - 1, "%s", ctime(&t1)); + start_time[sizeof(start_time) - 1] = '\x0'; + start_time[strlen(start_time) - 1] = '\x0'; + snprintf(end_time, sizeof(end_time) - 1, "%s", ctime(&t2)); + end_time[sizeof(end_time) - 1] = '\x0'; + end_time[strlen(end_time) - 1] = '\x0'; + + if(display_type == DISPLAY_HOST_HISTOGRAM) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Event History For Host '%s'", host_name); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Event History For Service '%s' On Host '%s'", svc_description, host_name); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + (DRAWING_WIDTH / 2) - (string_width / 2), 0, (unsigned char *)temp_buffer, color_black); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s to %s", start_time, end_time); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + (DRAWING_WIDTH / 2) - (string_width / 2), string_height + 5, (unsigned char *)temp_buffer, color_black); + + +#ifdef DEBUG + printf("About to starting graphing (total_buckets=%d)...\n", total_buckets); +#endif + + + /* graph service states */ + if(display_type == DISPLAY_HOST_HISTOGRAM) { + + /* graph host recoveries */ + if(graph_events & GRAPH_HOST_UP) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].host_up * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_green); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state1_min == FALSE || tsdata[actual_bucket].host_up < state1_min) { + state1_min = tsdata[actual_bucket].host_up; + have_state1_min = TRUE; + } + if(state1_max == 0 || tsdata[actual_bucket].host_up > state1_max) + state1_max = tsdata[actual_bucket].host_up; + state1_sum += tsdata[actual_bucket].host_up; + } + } + } + +#ifdef DEBUG + printf("Done graphing HOST UP states...\n"); +#endif + + /* graph host down states */ + if(graph_events & GRAPH_HOST_DOWN) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].host_down * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_red); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state2_min == FALSE || tsdata[actual_bucket].host_down < state2_min) { + state2_min = tsdata[actual_bucket].host_down; + have_state2_min = TRUE; + } + if(state2_max == 0 || tsdata[actual_bucket].host_down > state2_max) + state2_max = tsdata[actual_bucket].host_down; + state2_sum += tsdata[actual_bucket].host_down; + } + } + } + +#ifdef DEBUG + printf("Done graphing HOST DOWN states...\n"); +#endif + + /* graph host unreachable states */ + if(graph_events & GRAPH_HOST_UNREACHABLE) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].host_unreachable * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_darkred); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state3_min == FALSE || tsdata[actual_bucket].host_unreachable < state3_min) { + state3_min = tsdata[actual_bucket].host_unreachable; + have_state3_min = TRUE; + } + if(state3_max == 0 || tsdata[actual_bucket].host_unreachable > state3_max) + state3_max = tsdata[actual_bucket].host_unreachable; + state3_sum += tsdata[actual_bucket].host_unreachable; + } + } + } + +#ifdef DEBUG + printf("Done graphing HOST UNREACHABLE states...\n"); +#endif + + } + + /* graph service states */ + else { + + /* graph service recoveries */ + if(graph_events & GRAPH_SERVICE_OK) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].service_ok * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_green); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state1_min == FALSE || tsdata[actual_bucket].service_ok < state1_min) { + state1_min = tsdata[actual_bucket].service_ok; + have_state1_min = TRUE; + } + if(state1_max == 0 || tsdata[actual_bucket].service_ok > state1_max) + state1_max = tsdata[actual_bucket].service_ok; + state1_sum += tsdata[actual_bucket].service_ok; + } + } + } + + /* graph service warning states */ + if(graph_events & GRAPH_SERVICE_WARNING) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].service_warning * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_yellow); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state2_min == FALSE || tsdata[actual_bucket].service_warning < state2_min) { + state2_min = tsdata[actual_bucket].service_warning; + have_state2_min = TRUE; + } + if(state2_max == 0 || tsdata[actual_bucket].service_warning > state2_max) + state2_max = tsdata[actual_bucket].service_warning; + state2_sum += tsdata[actual_bucket].service_warning; + } + } + } + + /* graph service unknown states */ + if(graph_events & GRAPH_SERVICE_UNKNOWN) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].service_unknown * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_orange); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state3_min == FALSE || tsdata[actual_bucket].service_unknown < state3_min) { + state3_min = tsdata[actual_bucket].service_unknown; + have_state3_min = TRUE; + } + if(state3_max == 0 || tsdata[actual_bucket].service_unknown > state3_max) + state3_max = tsdata[actual_bucket].service_unknown; + state3_sum += tsdata[actual_bucket].service_unknown; + } + } + } + + /* graph service critical states */ + if(graph_events & GRAPH_SERVICE_CRITICAL) { + + last_pixel_y = 0; + for(current_bucket = 0, actual_bucket = 0; current_bucket <= total_buckets; current_bucket++, actual_bucket++) { + + if(actual_bucket >= total_buckets) + actual_bucket = 0; + + pixel_x = (int)(current_bucket * x_scaling_factor); + + pixel_y = (int)(tsdata[actual_bucket].service_critical * y_scaling_factor); + + if(current_bucket > 0 && !(last_pixel_y == 0 && pixel_y == 0)) + draw_line(DRAWING_X_OFFSET + pixel_x - (int)x_scaling_factor, DRAWING_Y_OFFSET - last_pixel_y, DRAWING_X_OFFSET + pixel_x, DRAWING_Y_OFFSET - pixel_y, color_red); + + last_pixel_y = pixel_y; + + if(current_bucket < total_buckets) { + if(have_state4_min == FALSE || tsdata[actual_bucket].service_critical < state4_min) { + state4_min = tsdata[actual_bucket].service_critical; + have_state4_min = TRUE; + } + if(state4_max == 0 || tsdata[actual_bucket].service_critical > state4_max) + state4_max = tsdata[actual_bucket].service_critical; + state4_sum += tsdata[actual_bucket].service_critical; + } + } + } + } + +#ifdef DEBUG + printf("Done graphing states...\n"); +#endif + + /* draw graph boundaries */ + draw_line(DRAWING_X_OFFSET, DRAWING_Y_OFFSET, DRAWING_X_OFFSET, DRAWING_Y_OFFSET - DRAWING_HEIGHT, color_black); + draw_line(DRAWING_X_OFFSET + DRAWING_WIDTH, DRAWING_Y_OFFSET, DRAWING_X_OFFSET + DRAWING_WIDTH, DRAWING_Y_OFFSET - DRAWING_HEIGHT, color_black); + draw_line(DRAWING_X_OFFSET, DRAWING_Y_OFFSET, DRAWING_X_OFFSET + DRAWING_WIDTH, DRAWING_Y_OFFSET, color_black); + + + /* graph stats */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "EVENT TYPE"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 15, DRAWING_Y_OFFSET - DRAWING_HEIGHT, (unsigned char *)temp_buffer, color_black); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, " MIN MAX SUM AVG"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 115, DRAWING_Y_OFFSET - DRAWING_HEIGHT, (unsigned char *)temp_buffer, color_black); + + draw_line(DRAWING_X_OFFSET + DRAWING_WIDTH + 15, DRAWING_Y_OFFSET - DRAWING_HEIGHT + string_height + 2, DRAWING_X_OFFSET + DRAWING_WIDTH + 275, DRAWING_Y_OFFSET - DRAWING_HEIGHT + string_height + 2, color_black); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Recovery (%s):", (display_type == DISPLAY_SERVICE_HISTOGRAM) ? "Ok" : "Up"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 15, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 1), (unsigned char *)temp_buffer, color_green); + + state1_avg = (double)((double)state1_sum / (double)total_buckets); + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%5lu %5lu %5lu %.2f", state1_min, state1_max, state1_sum, state1_avg); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 115, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 1), (unsigned char *)temp_buffer, color_black); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s:", (display_type == DISPLAY_SERVICE_HISTOGRAM) ? "Warning" : "Down"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 15, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 2), (unsigned char *)temp_buffer, (display_type == DISPLAY_SERVICE_HISTOGRAM) ? color_yellow : color_red); + + state2_avg = (double)((double)state2_sum / (double)total_buckets); + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%5lu %5lu %5lu %.2f", state2_min, state2_max, state2_sum, state2_avg); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 115, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 2), (unsigned char *)temp_buffer, color_black); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s:", (display_type == DISPLAY_SERVICE_HISTOGRAM) ? "Unknown" : "Unreachable"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 15, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 3), (unsigned char *)temp_buffer, (display_type == DISPLAY_SERVICE_HISTOGRAM) ? color_orange : color_darkred); + + state3_avg = (double)((double)state3_sum / (double)total_buckets); + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%5lu %5lu %5lu %.2f", state3_min, state3_max, state3_sum, state3_avg); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 115, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 3), (unsigned char *)temp_buffer, color_black); + + if(display_type == DISPLAY_SERVICE_HISTOGRAM) { + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Critical:"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 15, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 4), (unsigned char *)temp_buffer, color_red); + + state4_avg = (double)((double)state4_sum / (double)total_buckets); + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%5lu %5lu %5lu %.2f", state4_min, state4_max, state4_sum, state4_avg); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(histogram_image, gdFontSmall, DRAWING_X_OFFSET + DRAWING_WIDTH + 115, DRAWING_Y_OFFSET - DRAWING_HEIGHT + ((string_height + 5) * 4), (unsigned char *)temp_buffer, color_black); + } + + return; + } + + +/* adds an archived state entry */ +void add_archived_state(int state_type, time_t time_stamp) { + struct tm *our_time; + int bucket; + int skip_state = FALSE; + +#ifdef DEBUG2 + printf("NEW ENTRY: last=%d this=%d\n", last_state, state_type); +#endif + + /* don't record program starts/stops, just make a note that one occurred */ + if(state_type == AS_PROGRAM_START || state_type == AS_PROGRAM_END) { +#ifdef DEBUG2 + printf("Recording a program start: %d\n", state_type); +#endif + program_restart_has_occurred = TRUE; + return; + } + + /* see if we should even take into account this event */ + if(program_restart_has_occurred == TRUE) { + +#ifdef DEBUG2 + printf("program_restart_has_occurred: last=%d this=%d\n", last_state, state_type); +#endif + + if(initial_states_logged == TRUE) { + if(state_type == AS_SVC_OK && last_state == AS_SVC_OK) + skip_state = TRUE; + if(state_type == AS_HOST_UP && last_state == AS_HOST_UP) + skip_state = TRUE; + } + + if(assume_state_retention == TRUE && initial_states_logged == TRUE) { + if(state_type == AS_SVC_WARNING && last_state == AS_SVC_WARNING) + skip_state = TRUE; + if(state_type == AS_SVC_UNKNOWN && last_state == AS_SVC_UNKNOWN) + skip_state = TRUE; + if(state_type == AS_SVC_CRITICAL && last_state == AS_SVC_CRITICAL) + skip_state = TRUE; + if(state_type == AS_HOST_DOWN && last_state == AS_HOST_DOWN) + skip_state = TRUE; + if(state_type == AS_HOST_UNREACHABLE && last_state == AS_HOST_UNREACHABLE) + skip_state = TRUE; + } + + if(skip_state == TRUE) { + program_restart_has_occurred = FALSE; +#ifdef DEBUG2 + printf("Skipping state...\n"); +#endif + return; + } + } + + /* reset program restart variable */ + program_restart_has_occurred = FALSE; + + /* are we only processing new states */ + if(new_states_only == TRUE && state_type == last_state) { +#ifdef DEBUG2 + printf("Skipping state (not a new state)...\n"); +#endif + return; + } + +#ifdef DEBUG2 + printf("GOODSTATE: %d @ %lu\n", state_type, (unsigned long)time_stamp); +#endif + + + + our_time = localtime(&time_stamp); + + /* calculate the correct bucket to dump the data into */ + if(breakdown_type == BREAKDOWN_MONTHLY) + bucket = our_time->tm_mon; + + else if(breakdown_type == BREAKDOWN_DAY_OF_MONTH) + bucket = our_time->tm_mday - 1; + + else if(breakdown_type == BREAKDOWN_DAY_OF_WEEK) + bucket = our_time->tm_wday; + + else + bucket = (our_time->tm_hour * 4) + (our_time->tm_min / 15); + +#ifdef DEBUG2 + printf("\tBucket=%d\n", bucket); +#endif + + /* save the data in the correct bucket */ + if(state_type == AS_SVC_OK) + tsdata[bucket].service_ok++; + else if(state_type == AS_SVC_UNKNOWN) + tsdata[bucket].service_unknown++; + else if(state_type == AS_SVC_WARNING) + tsdata[bucket].service_warning++; + else if(state_type == AS_SVC_CRITICAL) + tsdata[bucket].service_critical++; + else if(state_type == AS_HOST_UP) + tsdata[bucket].host_up++; + else if(state_type == AS_HOST_DOWN) + tsdata[bucket].host_down++; + else if(state_type == AS_HOST_UNREACHABLE) + tsdata[bucket].host_unreachable++; + + /* record last state type */ + last_state = state_type; + + return; + } + + + +/* reads log files for archived state data */ +void read_archived_state_data(void) { + char filename[MAX_FILENAME_LENGTH]; + int newest_archive = 0; + int oldest_archive = 0; + int current_archive; + +#ifdef DEBUG2 + printf("Determining archives to use...\n"); +#endif + + /* determine earliest archive to use */ + oldest_archive = determine_archive_to_use_from_time(t1); + if(log_rotation_method != LOG_ROTATION_NONE) + oldest_archive += backtrack_archives; + + /* determine most recent archive to use */ + newest_archive = determine_archive_to_use_from_time(t2); + + if(oldest_archive < newest_archive) + oldest_archive = newest_archive; + +#ifdef DEBUG2 + printf("Oldest archive: %d\n", oldest_archive); + printf("Newest archive: %d\n", newest_archive); +#endif + + /* read in all the necessary archived logs */ + for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) { + + /* get the name of the log file that contains this archive */ + get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1); + +#ifdef DEBUG2 + printf("\tCurrent archive: %d (%s)\n", current_archive, filename); +#endif + + /* scan the log file for archived state data */ + scan_log_file_for_archived_state_data(filename); + } + + return; + } + + + +/* grabs archives state data from a log file */ +void scan_log_file_for_archived_state_data(char *filename) { + char *input = NULL; + char *input2 = NULL; + char entry_host_name[MAX_INPUT_BUFFER]; + char entry_svc_description[MAX_INPUT_BUFFER]; + char *temp_buffer; + time_t time_stamp; + mmapfile *thefile; + + /* print something so browser doesn't time out */ + if(mode == CREATE_HTML) { + printf(" "); + fflush(NULL); + } + + if((thefile = mmap_fopen(filename)) == NULL) { +#ifdef DEBUG2 + printf("Could not open file '%s' for reading.\n", filename); +#endif + return; + } + +#ifdef DEBUG2 + printf("Scanning log file '%s' for archived state data...\n", filename); +#endif + + while(1) { + + /* free memory */ + free(input); + free(input2); + input = NULL; + input2 = NULL; + + /* read the next line */ + if((input = mmap_fgets(thefile)) == NULL) + break; + + strip(input); + + if((input2 = strdup(input)) == NULL) + continue; + + temp_buffer = my_strtok(input2, "]"); + time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10); + + /* program starts/restarts */ + if(strstr(input, " starting...")) + add_archived_state(AS_PROGRAM_START, time_stamp); + if(strstr(input, " restarting...")) + add_archived_state(AS_PROGRAM_START, time_stamp); + + /* program stops */ + if(strstr(input, " shutting down...")) + add_archived_state(AS_PROGRAM_END, time_stamp); + if(strstr(input, "Bailing out")) + add_archived_state(AS_PROGRAM_END, time_stamp); + + if(display_type == DISPLAY_HOST_HISTOGRAM) { + if(strstr(input, "HOST ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + if(strcmp(host_name, entry_host_name)) + continue; + + /* skip soft states if necessary */ + if(!(graph_statetypes & GRAPH_SOFT_STATETYPES) && strstr(input, ";SOFT;")) + continue; + + /* skip hard states if necessary */ + if(!(graph_statetypes & GRAPH_HARD_STATETYPES) && strstr(input, ";HARD;")) + continue; + + if(strstr(input, ";DOWN;")) + add_archived_state(AS_HOST_DOWN, time_stamp); + else if(strstr(input, ";UNREACHABLE;")) + add_archived_state(AS_HOST_UNREACHABLE, time_stamp); + else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) + add_archived_state(AS_HOST_UP, time_stamp); + } + } + if(display_type == DISPLAY_SERVICE_HISTOGRAM) { + if(strstr(input, "SERVICE ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + if(strcmp(host_name, entry_host_name)) + continue; + + /* get service description */ + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); + entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; + + if(strcmp(svc_description, entry_svc_description)) + continue; + + /* skip soft states if necessary */ + if(!(graph_statetypes & GRAPH_SOFT_STATETYPES) && strstr(input, ";SOFT;")) + continue; + + /* skip hard states if necessary */ + if(!(graph_statetypes & GRAPH_HARD_STATETYPES) && strstr(input, ";HARD;")) + continue; + + if(strstr(input, ";CRITICAL;")) + add_archived_state(AS_SVC_CRITICAL, time_stamp); + else if(strstr(input, ";WARNING;")) + add_archived_state(AS_SVC_WARNING, time_stamp); + else if(strstr(input, ";UNKNOWN;")) + add_archived_state(AS_SVC_UNKNOWN, time_stamp); + else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) + add_archived_state(AS_SVC_OK, time_stamp); + } + } + + } + + /* free memory and close the file */ + free(input); + free(input2); + mmap_fclose(thefile); + + return; + } + + + + +void convert_timeperiod_to_times(int type) { + time_t current_time; + struct tm *t; + + /* get the current time */ + time(¤t_time); + + t = localtime(¤t_time); + + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_isdst = -1; + + switch(type) { + case TIMEPERIOD_LAST24HOURS: + t1 = current_time - (60 * 60 * 24); + t2 = current_time; + break; + case TIMEPERIOD_TODAY: + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_YESTERDAY: + t1 = (time_t)(mktime(t) - (60 * 60 * 24)); + t2 = (time_t)mktime(t); + break; + case TIMEPERIOD_THISWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + t2 = current_time; + break; + case TIMEPERIOD_LASTWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7)); + t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + break; + case TIMEPERIOD_THISMONTH: + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTMONTH: + t->tm_mday = 1; + t2 = mktime(t); + if(t->tm_mon == 0) { + t->tm_mon = 11; + t->tm_year--; + } + else + t->tm_mon--; + t1 = mktime(t); + break; + case TIMEPERIOD_THISQUARTER: + break; + case TIMEPERIOD_LASTQUARTER: + break; + case TIMEPERIOD_THISYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t2 = mktime(t); + t->tm_year--; + t1 = mktime(t); + break; + case TIMEPERIOD_LAST7DAYS: + t2 = current_time; + t1 = current_time - (7 * 24 * 60 * 60); + break; + case TIMEPERIOD_LAST31DAYS: + t2 = current_time; + t1 = current_time - (31 * 24 * 60 * 60); + break; + default: + break; + } + + return; + } + + + +void compute_report_times(void) { + time_t current_time; + struct tm *st; + struct tm *et; + + /* get the current time */ + time(¤t_time); + + st = localtime(¤t_time); + + st->tm_sec = start_second; + st->tm_min = start_minute; + st->tm_hour = start_hour; + st->tm_mday = start_day; + st->tm_mon = start_month - 1; + st->tm_year = start_year - 1900; + st->tm_isdst = -1; + + t1 = mktime(st); + + et = localtime(¤t_time); + + et->tm_sec = end_second; + et->tm_min = end_minute; + et->tm_hour = end_hour; + et->tm_mday = end_day; + et->tm_mon = end_month - 1; + et->tm_year = end_year - 1900; + et->tm_isdst = -1; + + t2 = mktime(et); + } + + + +/* draws a solid line */ +void draw_line(int x1, int y1, int x2, int y2, int color) { + int styleSolid[1]; + + styleSolid[0] = color; + + /* sets current style to a solid line */ + gdImageSetStyle(histogram_image, styleSolid, 1); + + /* draws a line (dashed) */ + gdImageLine(histogram_image, x1, y1, x2, y2, gdStyled); + + return; + } + + +/* draws a dashed line */ +void draw_dashed_line(int x1, int y1, int x2, int y2, int color) { + int styleDashed[6]; + + styleDashed[0] = color; + styleDashed[1] = color; + styleDashed[2] = gdTransparent; + styleDashed[3] = gdTransparent; + styleDashed[4] = gdTransparent; + styleDashed[5] = gdTransparent; + + /* sets current style to a solid line */ + gdImageSetStyle(histogram_image, styleDashed, 6); + + /* draws a line (dashed) */ + gdImageLine(histogram_image, x1, y1, x2, y2, gdStyled); + + return; + } diff --git a/cgi/history.c b/cgi/history.c new file mode 100644 index 0000000..2e8eee7 --- /dev/null +++ b/cgi/history.c @@ -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("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + + /* middle column of top row */ + printf("\n"); + + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \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("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    \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("
    \n"); + printf("
    \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("
    \n"); + + printf("
    \n", HISTORY_CGI); + printf("\n"); + printf("\n", (show_all_hosts == TRUE) ? "all" : escape_string(host_name)); + if(display_type == DISPLAY_SERVICES) + printf("\n", escape_string(svc_description)); + printf("\n", log_archive); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n") + ; + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("", (display_flapping_alerts == FALSE) ? "checked" : ""); + printf("\n"); + printf("\n"); + printf("", (display_downtime_alerts == FALSE) ? "checked" : ""); + printf("\n"); + + printf("\n"); + printf("", (display_system_messages == FALSE) ? "checked" : ""); + printf("\n"); + printf("\n"); + printf("", (use_lifo == FALSE) ? "checked" : ""); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + /* display context-sensitive help */ + printf("\n"); + printf("\n"); + printf("\n"); + + printf("
    State type options:
    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(":
    Hide Flapping Alerts
    Hide Downtime Alerts
    Hide Process Messages
    Older Entries First
    \n"); + display_context_help(CONTEXTHELP_HISTORY); + printf("
    \n"); + printf("
    \n"); + + printf("
    \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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios History\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, HISTORY_CSS); + } + + printf("\n"); + printf("\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("\n"); + printf("\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("

    Not enough memory to reverse log file - displaying history in natural order...

    \n"); + } + else if(result == LIFO_ERROR_FILE) { + printf("

    Error: Cannot open log file '%s' for reading!


    ", log_file_to_use); + return; + } + use_lifo = FALSE; + } + } + + if(use_lifo == FALSE) { + + if((thefile = mmap_fopen(log_file_to_use)) == NULL) { + printf("

    Error: Cannot open log file '%s' for reading!


    ", log_file_to_use); + return; + } + } + + printf("

    \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("

    \n"); + printf("
    \n"); + printf(""); + printf(""); + printf("", current_message_date); + printf(""); + printf("

    %s
    \n"); + printf("
    \n"); + printf("
    \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("%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("
    \n"); + + found_line = TRUE; + } + } + + /* free memory */ + free(entry_host_name); + entry_host_name = NULL; + free(entry_service_desc); + entry_service_desc = NULL; + } + + printf("

    \n"); + + if(found_line == FALSE) { + printf("
    \n"); + printf("

    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

    ", (log_archive == 0) ? "the current" : "this archived"); + } + + printf("
    \n"); + + my_free(input); + my_free(input2); + + if(use_lifo == TRUE) + free_lifo_memory(); + else + mmap_fclose(thefile); + + return; + } diff --git a/cgi/notifications.c b/cgi/notifications.c new file mode 100644 index 0000000..633e1f2 --- /dev/null +++ b/cgi/notifications.c @@ -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("\n"); + printf("\n"); + + /* left column of top row */ + printf("\n"); + + + /* middle column of top row */ + printf("\n"); + + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \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("\n"); + printf("\n"); + printf("\n"); + } + + printf("\n"); + + printf("
    \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("
    \n"); + printf("
    \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("
    \n"); + + printf("
    \n", NOTIFICATIONS_CGI); + if(query_type == FIND_SERVICE) { + printf("\n", escape_string(query_host_name)); + printf("\n", escape_string(query_svc_description)); + } + else + printf("\n", (query_type == FIND_HOST) ? "host" : "contact", (query_type == FIND_HOST) ? escape_string(query_host_name) : escape_string(query_contact_name)); + printf("\n", log_archive); + printf("\n"); + printf("\n"); + if(query_type == FIND_SERVICE) + printf(""); + else + printf("", (find_all == TRUE) ? "all" : "this", (query_type == FIND_HOST) ? "host" : "contact", (find_all == TRUE) ? "s" : ""); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("", (use_lifo == FALSE) ? "checked" : ""); + printf("\n"); + printf("\n"); + + /* display context-sensitive help */ + printf("\n"); + + printf("
    Notification detail level for this service:Notification detail level for %s %s%s:
    Older Entries First:
    \n"); + display_context_help(CONTEXTHELP_NOTIFICATIONS); + printf("
    \n"); + printf("
    \n"); + + printf("
    \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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Alert Notifications\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, NOTIFICATIONS_CSS); + } + + printf("\n"); + + printf("\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("\n"); + printf("\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("

    Not enough memory to reverse log file - displaying notifications in natural order...

    "); + } + else if(result == LIFO_ERROR_FILE) { + printf("

    Error: Cannot open log file '%s' for reading!

    ", log_file_to_use); + return; + } + use_lifo = FALSE; + } + } + + if(use_lifo == FALSE) { + + if((thefile = mmap_fopen(log_file_to_use)) == NULL) { + printf("

    Error: Cannot open log file '%s' for reading!

    ", log_file_to_use); + return; + } + } + + printf("

    \n"); + printf("

    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\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("\n"); + } + else { + odd = 1; + printf("\n"); + } + printf("\n", (odd) ? "Even" : "Odd", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(host_name), host_name); + if(notification_type == SERVICE_NOTIFICATION) { + printf("\n", url_encode(service_name), service_name); + } + else + printf("\n", (odd) ? "Even" : "Odd"); + printf("\n", alert_level_class, alert_level); + printf("\n", (odd) ? "Even" : "Odd", date_time); + printf("\n", (odd) ? "Even" : "Odd", CONFIG_CGI, url_encode(contact_name), contact_name); + printf("\n", (odd) ? "Even" : "Odd", CONFIG_CGI, url_encode(method_name), method_name); + printf("\n", (odd) ? "Even" : "Odd", html_encode(temp_buffer, FALSE)); + printf("\n"); + } + } + } + + + printf("
    HostServiceTypeTimeContactNotification CommandInformation
    %s%sN/A%s%s%s%s%s
    \n"); + + printf("
    \n"); + printf("

    \n"); + + if(total_notifications == 0) { + printf("

    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

    ", (log_archive == 0) ? "the current" : "this archived"); + } + + free(input); + + if(use_lifo == TRUE) + free_lifo_memory(); + else + mmap_fclose(thefile); + + return; + } diff --git a/cgi/outages.c b/cgi/outages.c new file mode 100644 index 0000000..ee274ba --- /dev/null +++ b/cgi/outages.c @@ -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("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* middle column of top row */ + printf("\n"); + + /* right column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + display_info_table("Network Outages", TRUE, ¤t_authdata); + printf("\n"); + printf("\n"); + + /* display context-sensitive help */ + display_context_help(CONTEXTHELP_OUTAGES); + + printf("
    \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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Network Outages\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("", url_stylesheets_path, COMMON_CSS); + printf("", url_stylesheets_path, OUTAGES_CSS); + } + + printf("\n"); + + printf("\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("\n"); + printf("\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("

    It appears as though you do not have permission to view information you requested...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \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("

    \n"); + printf("
    Blocking Outages
    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\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("\n", bg_class); + + printf("\n", bg_class, temp_hostoutage->severity); + printf("\n", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hostoutage->hst->name), temp_hostoutage->hst->name); + printf("\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("\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("\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("\n", bg_class, state_duration); + + printf("\n", bg_class, temp_hostoutage->affected_child_hosts); + printf("\n", bg_class, temp_hostoutage->affected_child_services); + + printf("\n"); + + printf("\n"); + } + + printf("
    SeverityHostStateNotesState Duration# Hosts Affected# Services AffectedActions
    %d%s%s%sN/A%s%d%d", bg_class); + printf("View status detail for this host\n", STATUS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUS_DETAIL_ICON); +#ifdef USE_STATUSMAP + printf("View status map for this host and its children\n", STATUSMAP_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUSMAP_ICON); +#endif +#ifdef USE_STATUSWRL + printf("View 3-D status map for this host and its children\n", STATUSWORLD_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUSWORLD_ICON); +#endif +#ifdef USE_TRENDS + printf("View trends for this host\n", TRENDS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, TRENDS_ICON); +#endif + printf("View alert history for this host\n", HISTORY_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, HISTORY_ICON); + printf("View notifications for this host\n", NOTIFICATIONS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, NOTIFICATION_ICON); + printf("
    \n"); + + printf("

    \n"); + + if(total_entries == 0) + printf("
    %d Blocking Outages Displayed
    \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; + } diff --git a/cgi/showlog.c b/cgi/showlog.c new file mode 100644 index 0000000..d249326 --- /dev/null +++ b/cgi/showlog.c @@ -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("\n"); + printf("\n"); + + /* left column of top table - info box */ + printf("\n"); + + /* middle column of top table - log file navigation options */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + display_info_table((log_rotation_method == LOG_ROTATION_NONE || log_archive == 0) ? "Current Event Log" : "Archived Event Log", FALSE, ¤t_authdata); + printf("\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("\n"); + + printf("
    \n", SHOWLOG_CGI); + printf("\n", log_archive); + printf("\n"); + printf(""); + printf("", (use_lifo == FALSE) ? "checked" : ""); + printf("\n"); + printf(""); + printf("\n"); + printf("\n"); + + /* display context-sensitive help */ + printf("\n"); + printf("\n"); + printf("\n"); + + printf("
    Older Entries First:
    \n"); + display_context_help(CONTEXTHELP_LOG); + printf("
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("

    \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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios Log File\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, SHOWLOG_CSS); + } + + printf("\n"); + printf("\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("\n"); + printf("\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("
    \n"); + printf("
    It appears as though you do not have permission to view the log file...


    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    and check the authorization options in your CGI configuration file.
    \n"); + printf("
    \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("

    Not enough memory to reverse log file - displaying log in natural order...

    "); + 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("
    \n"); + printf("

    Error: Could not open log file '%s' for reading!

    ", log_file_to_use); + printf("
    \n"); + error = TRUE; + } + } + + if(error == FALSE) { + + printf("

    \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("
    \n"); + printf("
    \n"); + printf(""); + printf(""); + printf("", current_message_date); + printf(""); + printf("

    %s
    \n"); + printf("
    \n"); + printf("
    \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("%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("
    \n"); + } + + printf("

    \n"); + printf("
    \n"); + + free(input); + + if(use_lifo == FALSE) + mmap_fclose(thefile); + } + + if(use_lifo == TRUE) + free_lifo_memory(); + + return OK; + } + diff --git a/cgi/status.c b/cgi/status.c new file mode 100644 index 0000000..849d938 --- /dev/null +++ b/cgi/status.c @@ -0,0 +1,5469 @@ +/************************************************************************** + * + * STATUS.C - Nagios Status CGI + * + * Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 08-05-2020 + * + * 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 Tthis 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/macros.h" +#include "../include/statusdata.h" + +#include "../include/cgiutils.h" +#include "../include/getcgi.h" +#include "../include/cgiauth.h" + +extern int refresh_rate; +extern int result_limit; +extern time_t program_start; + +extern char main_config_file[MAX_FILENAME_LENGTH]; +extern char url_html_path[MAX_FILENAME_LENGTH]; +extern char url_docs_path[MAX_FILENAME_LENGTH]; +extern char url_images_path[MAX_FILENAME_LENGTH]; +extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; +extern char url_logo_images_path[MAX_FILENAME_LENGTH]; +extern char url_media_path[MAX_FILENAME_LENGTH]; +extern char url_js_path[MAX_FILENAME_LENGTH]; +extern char log_file[MAX_FILENAME_LENGTH]; + +extern char *service_critical_sound; +extern char *service_warning_sound; +extern char *service_unknown_sound; +extern char *host_down_sound; +extern char *host_unreachable_sound; +extern char *normal_sound; + +extern char *notes_url_target; +extern char *action_url_target; + +extern int suppress_alert_window; + +extern int enable_splunk_integration; + +extern host *host_list; +extern service *service_list; +extern hostgroup *hostgroup_list; +extern servicegroup *servicegroup_list; +extern hoststatus *hoststatus_list; +extern servicestatus *servicestatus_list; + +static nagios_macros *mac; + +#define MAX_MESSAGE_BUFFER 4096 + +#define DISPLAY_HOSTS 0 +#define DISPLAY_HOSTGROUPS 1 +#define DISPLAY_SERVICEGROUPS 2 + +#define STYLE_OVERVIEW 0 +#define STYLE_DETAIL 1 +#define STYLE_SUMMARY 2 +#define STYLE_GRID 3 +#define STYLE_HOST_DETAIL 4 + + +/* HOSTSORT structure */ +typedef struct hostsort_struct { + hoststatus *hststatus; + struct hostsort_struct *next; + } hostsort; + +/* SERVICESORT structure */ +typedef struct servicesort_struct { + servicestatus *svcstatus; + struct servicesort_struct *next; + } servicesort; + +hostsort *hostsort_list = NULL; +servicesort *servicesort_list = NULL; + +int sort_services(int, int); /* sorts services */ +int sort_hosts(int, int); /* sorts hosts */ +int compare_servicesort_entries(int, int, servicesort *, servicesort *); /* compares service sort entries */ +int compare_hostsort_entries(int, int, hostsort *, hostsort *); /* compares host sort entries */ +void free_servicesort_list(void); +void free_hostsort_list(void); + +void show_host_status_totals(void); +void show_service_status_totals(void); +void show_service_detail(void); +void show_host_detail(void); +void show_servicegroup_overviews(void); +void show_servicegroup_overview(servicegroup *); +void show_servicegroup_summaries(void); +void show_servicegroup_summary(servicegroup *, int); +void show_servicegroup_host_totals_summary(servicegroup *); +void show_servicegroup_service_totals_summary(servicegroup *); +void show_servicegroup_grids(void); +void show_servicegroup_grid(servicegroup *); +void show_hostgroup_overviews(void); +void show_hostgroup_overview(hostgroup *); +void show_servicegroup_hostgroup_member_overview(hoststatus *, int, void *); +void show_servicegroup_hostgroup_member_service_status_totals(char *, void *); +void show_hostgroup_summaries(void); +void show_hostgroup_summary(hostgroup *, int); +void show_hostgroup_host_totals_summary(hostgroup *); +void show_hostgroup_service_totals_summary(hostgroup *); +void show_hostgroup_grids(void); +void show_hostgroup_grid(hostgroup *); + +void show_filters(void); +void create_pagenumbers(int total_entries, int visible_entries, char *temp_url, int type_service); +void create_page_limiter(int result_limit, char *temp_url); + +int passes_host_properties_filter(hoststatus *); +int passes_service_properties_filter(servicestatus *); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + + +authdata current_authdata; +time_t current_time; + +char alert_message[MAX_MESSAGE_BUFFER]; +char *host_name = NULL; +char *host_filter = NULL; +char *hostgroup_name = NULL; +char *servicegroup_name = NULL; +char *service_filter = NULL; +int host_alert = FALSE; +int show_all_hosts = TRUE; +int show_all_hostgroups = TRUE; +int show_all_servicegroups = TRUE; +int display_type = DISPLAY_HOSTS; +int overview_columns = 3; +int max_grid_width = 8; +int group_style_type = STYLE_OVERVIEW; +int navbar_search = FALSE; + +/* experimental paging feature */ +int temp_result_limit; +int page_start; +int limit_results = TRUE; + + +int service_status_types = SERVICE_PENDING | SERVICE_OK | SERVICE_UNKNOWN | SERVICE_WARNING | SERVICE_CRITICAL; +int all_service_status_types = SERVICE_PENDING | SERVICE_OK | SERVICE_UNKNOWN | SERVICE_WARNING | SERVICE_CRITICAL; + +int host_status_types = HOST_PENDING | HOST_UP | HOST_DOWN | HOST_UNREACHABLE; +int all_host_status_types = HOST_PENDING | HOST_UP | HOST_DOWN | HOST_UNREACHABLE; + +int all_service_problems = SERVICE_UNKNOWN | SERVICE_WARNING | SERVICE_CRITICAL; +int all_host_problems = HOST_DOWN | HOST_UNREACHABLE; + +unsigned long host_properties = 0L; +unsigned long service_properties = 0L; + + + + +int sort_type = SORT_NONE; +int sort_option = SORT_HOSTNAME; + +int problem_hosts_down = 0; +int problem_hosts_unreachable = 0; +int problem_services_critical = 0; +int problem_services_warning = 0; +int problem_services_unknown = 0; + +int embedded = FALSE; +int display_header = TRUE; + + + +int main(void) { + int result = OK; + char *sound = NULL; + host *temp_host = NULL; + hostgroup *temp_hostgroup = NULL; + servicegroup *temp_servicegroup = NULL; + int regex_i = 1, i = 0; + int len; + + mac = get_global_macros(); + + time(¤t_time); + + /* 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; + } + + /* initialize macros */ + init_macros(); + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + /* if a navbar search was performed, find the host by name, address or partial name */ + if(navbar_search == TRUE) { + if(host_name != NULL && NULL != strstr(host_name, "*")) { + /* allocate for 3 extra chars, ^, $ and \0 */ + host_filter = malloc(sizeof(char) * (strlen(host_name) * 2 + 3)); + len = strlen(host_name); + for(i = 0; i < len; i++, regex_i++) { + if(host_name[i] == '*') { + host_filter[regex_i++] = '.'; + host_filter[regex_i] = '*'; + } + else + host_filter[regex_i] = host_name[i]; + } + host_filter[0] = '^'; + host_filter[regex_i++] = '$'; + host_filter[regex_i] = '\0'; + } + else { + if((temp_host = find_host(host_name)) == NULL) { + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + if(!strcmp(host_name, temp_host->address)) { + free(host_name); + host_name = strdup(temp_host->name); + break; + } + } + if(temp_host == NULL) { + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + if((strstr(temp_host->name, host_name) == temp_host->name) || !strncasecmp(temp_host->name, host_name, strlen(host_name))) { + free(host_name); + host_name = strdup(temp_host->name); + break; + } + } + } + } + /* last effort, search hostgroups then servicegroups */ + if(temp_host == NULL) { + if((temp_hostgroup = find_hostgroup(host_name)) != NULL) { + display_type = DISPLAY_HOSTGROUPS; + show_all_hostgroups = FALSE; + free(host_name); + hostgroup_name = strdup(temp_hostgroup->group_name); + } + else if((temp_servicegroup = find_servicegroup(host_name)) != NULL) { + display_type = DISPLAY_SERVICEGROUPS; + show_all_servicegroups = FALSE; + free(host_name); + servicegroup_name = strdup(temp_servicegroup->group_name); + } + } + } + } + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* middle column of top row */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* display context-sensitive help */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + + /* info table */ + display_info_table("Current Network Status", TRUE, ¤t_authdata); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + show_host_status_totals(); + printf("\n"); + show_service_status_totals(); + printf("\n"); + if(display_type == DISPLAY_HOSTS) + display_context_help(CONTEXTHELP_STATUS_DETAIL); + else if(display_type == DISPLAY_SERVICEGROUPS) { + if(group_style_type == STYLE_HOST_DETAIL) + display_context_help(CONTEXTHELP_STATUS_DETAIL); + else if(group_style_type == STYLE_OVERVIEW) + display_context_help(CONTEXTHELP_STATUS_SGOVERVIEW); + else if(group_style_type == STYLE_SUMMARY) + display_context_help(CONTEXTHELP_STATUS_SGSUMMARY); + else if(group_style_type == STYLE_GRID) + display_context_help(CONTEXTHELP_STATUS_SGGRID); + } + else { + if(group_style_type == STYLE_HOST_DETAIL) + display_context_help(CONTEXTHELP_STATUS_HOST_DETAIL); + else if(group_style_type == STYLE_OVERVIEW) + display_context_help(CONTEXTHELP_STATUS_HGOVERVIEW); + else if(group_style_type == STYLE_SUMMARY) + display_context_help(CONTEXTHELP_STATUS_HGSUMMARY); + else if(group_style_type == STYLE_GRID) + display_context_help(CONTEXTHELP_STATUS_HGGRID); + } + printf("
    \n"); + } + + + /* embed sound tag if necessary... */ + if(problem_hosts_unreachable > 0 && host_unreachable_sound != NULL) + sound = host_unreachable_sound; + else if(problem_hosts_down > 0 && host_down_sound != NULL) + sound = host_down_sound; + else if(problem_services_critical > 0 && service_critical_sound != NULL) + sound = service_critical_sound; + else if(problem_services_warning > 0 && service_warning_sound != NULL) + sound = service_warning_sound; + else if(problem_services_unknown > 0 && service_unknown_sound != NULL) + sound = service_unknown_sound; + else if(problem_services_unknown == 0 && problem_services_warning == 0 && problem_services_critical == 0 && problem_hosts_down == 0 && problem_hosts_unreachable == 0 && normal_sound != NULL) + sound = normal_sound; + if(sound != NULL) { + printf("", url_media_path, sound); + printf("", url_media_path, sound); + printf(""); + printf(""); + printf(""); + } + + + /* bottom portion of screen - service or hostgroup detail */ + if(display_type == DISPLAY_HOSTS) + show_service_detail(); + else if(display_type == DISPLAY_SERVICEGROUPS) { + if(group_style_type == STYLE_OVERVIEW) + show_servicegroup_overviews(); + else if(group_style_type == STYLE_SUMMARY) + show_servicegroup_summaries(); + else if(group_style_type == STYLE_GRID) + show_servicegroup_grids(); + else if(group_style_type == STYLE_HOST_DETAIL) + show_host_detail(); + else + show_service_detail(); + } + else { + if(group_style_type == STYLE_OVERVIEW) + show_hostgroup_overviews(); + else if(group_style_type == STYLE_SUMMARY) + show_hostgroup_summaries(); + else if(group_style_type == STYLE_GRID) + show_hostgroup_grids(); + else if(group_style_type == STYLE_HOST_DETAIL) + show_host_detail(); + else + show_service_detail(); + } + + document_footer(); + + /* free all allocated memory */ + free_memory(); + free_comment_data(); + + /* free memory allocated to the sort lists */ + free_servicesort_list(); + free_hostsort_list(); + + return OK; + } + + +void document_header(int use_stylesheet) { + char date_time[MAX_DATETIME_LENGTH]; + time_t expire_time; + + printf("Cache-Control: no-store\r\n"); + printf("Pragma: no-cache\r\n"); + printf("Refresh: %d\r\n", refresh_rate); + + 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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Current Network Status\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, STATUS_CSS); + } + + /* added jquery library 1/31/2012 */ + printf("\n", url_js_path, JQUERY_JS); + /* JS function to append content to elements on page */ + printf("\n"); + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(STATUS_CGI, SSI_HEADER); + + return; + } + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + /* include user SSI footer */ + include_ssi_files(STATUS_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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 navbar search argument */ + else if(!strcmp(variables[x], "navbarsearch")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + navbar_search = TRUE; + } + + /* we found the hostgroup argument */ + else if(!strcmp(variables[x], "hostgroup")) { + display_type = DISPLAY_HOSTGROUPS; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + hostgroup_name = (char *)strdup(variables[x]); + strip_html_brackets(hostgroup_name); + + if(hostgroup_name != NULL && !strcmp(hostgroup_name, "all")) + show_all_hostgroups = TRUE; + else + show_all_hostgroups = FALSE; + } + + /* we found the servicegroup argument */ + else if(!strcmp(variables[x], "servicegroup")) { + display_type = DISPLAY_SERVICEGROUPS; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + servicegroup_name = strdup(variables[x]); + strip_html_brackets(servicegroup_name); + + if(servicegroup_name != NULL && !strcmp(servicegroup_name, "all")) + show_all_servicegroups = TRUE; + else + show_all_servicegroups = FALSE; + } + + /* we found the host argument */ + else if(!strcmp(variables[x], "host")) { + display_type = DISPLAY_HOSTS; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + host_name = strdup(variables[x]); + strip_html_brackets(host_name); + + if(host_name != NULL && !strcmp(host_name, "all")) + show_all_hosts = TRUE; + else + show_all_hosts = FALSE; + } + + /* we found the columns argument */ + else if(!strcmp(variables[x], "columns")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + overview_columns = atoi(variables[x]); + if(overview_columns <= 0) + overview_columns = 1; + } + + /* we found the service status type argument */ + else if(!strcmp(variables[x], "servicestatustypes")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + service_status_types = atoi(variables[x]); + } + + /* we found the host status type argument */ + else if(!strcmp(variables[x], "hoststatustypes")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + host_status_types = atoi(variables[x]); + } + + /* we found the service properties argument */ + else if(!strcmp(variables[x], "serviceprops")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + service_properties = strtoul(variables[x], NULL, 10); + } + + /* we found the host properties argument */ + else if(!strcmp(variables[x], "hostprops")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + host_properties = strtoul(variables[x], NULL, 10); + } + + /* we found the host or service group style argument */ + else if(!strcmp(variables[x], "style")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "overview")) + group_style_type = STYLE_OVERVIEW; + else if(!strcmp(variables[x], "detail")) + group_style_type = STYLE_DETAIL; + else if(!strcmp(variables[x], "summary")) + group_style_type = STYLE_SUMMARY; + else if(!strcmp(variables[x], "grid")) + group_style_type = STYLE_GRID; + else if(!strcmp(variables[x], "hostdetail")) + group_style_type = STYLE_HOST_DETAIL; + else + group_style_type = STYLE_DETAIL; + } + + /* we found the sort type argument */ + else if(!strcmp(variables[x], "sorttype")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + sort_type = atoi(variables[x]); + } + + /* we found the sort option argument */ + else if(!strcmp(variables[x], "sortoption")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + sort_option = atoi(variables[x]); + } + + /* 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; + + /* servicefilter cgi var */ + else if(!strcmp(variables[x], "servicefilter")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + service_filter = strdup(variables[x]); + strip_html_brackets(service_filter); + } + + /* experimental page limit feature */ + else if(!strcmp(variables[x], "start")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + page_start = atoi(variables[x]); + } + else if(!strcmp(variables[x], "limit")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + temp_result_limit = atoi(variables[x]); + if(temp_result_limit == 0) + limit_results = FALSE; + else + limit_results = TRUE; + } + + } + + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* display table with service status totals... */ +void show_service_status_totals(void) { + int total_ok = 0; + int total_warning = 0; + int total_unknown = 0; + int total_critical = 0; + int total_pending = 0; + int total_services = 0; + int total_problems = 0; + servicestatus *temp_servicestatus; + service *temp_service; + host *temp_host; + int count_service; + + + /* check the status of all services... */ + for(temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) { + + /* find the host and service... */ + temp_host = find_host(temp_servicestatus->host_name); + temp_service = find_service(temp_servicestatus->host_name, temp_servicestatus->description); + + /* make sure user has rights to see this service... */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + count_service = 0; + + if(display_type == DISPLAY_HOSTS && (show_all_hosts == TRUE || !strcmp(host_name, temp_servicestatus->host_name))) + count_service = 1; + else if(display_type == DISPLAY_SERVICEGROUPS && (show_all_servicegroups == TRUE || (is_service_member_of_servicegroup(find_servicegroup(servicegroup_name), temp_service) == TRUE))) + count_service = 1; + else if(display_type == DISPLAY_HOSTGROUPS && (show_all_hostgroups == TRUE || (is_host_member_of_hostgroup(find_hostgroup(hostgroup_name), temp_host) == TRUE))) + count_service = 1; + + if(count_service) { + + if(temp_servicestatus->status == SERVICE_CRITICAL) { + total_critical++; + if(temp_servicestatus->problem_has_been_acknowledged == FALSE && (temp_servicestatus->checks_enabled == TRUE || temp_servicestatus->accept_passive_service_checks == TRUE) && temp_servicestatus->notifications_enabled == TRUE && temp_servicestatus->scheduled_downtime_depth == 0) + problem_services_critical++; + } + else if(temp_servicestatus->status == SERVICE_WARNING) { + total_warning++; + if(temp_servicestatus->problem_has_been_acknowledged == FALSE && (temp_servicestatus->checks_enabled == TRUE || temp_servicestatus->accept_passive_service_checks == TRUE) && temp_servicestatus->notifications_enabled == TRUE && temp_servicestatus->scheduled_downtime_depth == 0) + problem_services_warning++; + } + else if(temp_servicestatus->status == SERVICE_UNKNOWN) { + total_unknown++; + if(temp_servicestatus->problem_has_been_acknowledged == FALSE && (temp_servicestatus->checks_enabled == TRUE || temp_servicestatus->accept_passive_service_checks == TRUE) && temp_servicestatus->notifications_enabled == TRUE && temp_servicestatus->scheduled_downtime_depth == 0) + problem_services_unknown++; + } + else if(temp_servicestatus->status == SERVICE_OK) + total_ok++; + else if(temp_servicestatus->status == SERVICE_PENDING) + total_pending++; + else + total_ok++; + } + } + + total_services = total_ok + total_unknown + total_warning + total_critical + total_pending; + total_problems = total_unknown + total_warning + total_critical; + + + printf("
    Service Status Totals
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + + /* total services ok */ + printf("\n", (total_ok > 0) ? "OK" : "", total_ok); + + /* total services in warning state */ + printf("\n", (total_warning > 0) ? "WARNING" : "", total_warning); + + /* total services in unknown state */ + printf("\n", (total_unknown > 0) ? "UNKNOWN" : "", total_unknown); + + /* total services in critical state */ + printf("\n", (total_critical > 0) ? "CRITICAL" : "", total_critical); + + /* total services in pending state */ + printf("\n", (total_pending > 0) ? "PENDING" : "", total_pending); + + + printf("\n"); + printf("
    "); + printf("", host_status_types); + printf("Ok"); + printf("", host_status_types); + printf("Warning"); + printf("", host_status_types); + printf("Unknown"); + printf("", host_status_types); + printf("Critical"); + printf("", host_status_types); + printf("Pending
    %d%d%d%d%d
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + + printf("\n"); + + /* total service problems */ + printf("\n", (total_problems > 0) ? "PROBLEMS" : "", total_problems); + + /* total services */ + printf("\n", total_services); + + printf("\n"); + printf("
    "); + printf("", host_status_types); + printf("All Problems"); + printf("", host_status_types); + printf("All Types
    %d%d
    \n"); + + printf("
    \n"); + + printf("
    \n"); + + return; + } + + +/* display a table with host status totals... */ +void show_host_status_totals(void) { + int total_up = 0; + int total_down = 0; + int total_unreachable = 0; + int total_pending = 0; + int total_hosts = 0; + int total_problems = 0; + hoststatus *temp_hoststatus; + host *temp_host; + int count_host; + + + /* check the status of all hosts... */ + for(temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) { + + /* find the host... */ + temp_host = find_host(temp_hoststatus->host_name); + + /* make sure user has rights to view this host */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + count_host = 0; + + if(display_type == DISPLAY_HOSTS && (show_all_hosts == TRUE || !strcmp(host_name, temp_hoststatus->host_name))) + count_host = 1; + else if(display_type == DISPLAY_SERVICEGROUPS) { + if(show_all_servicegroups == TRUE) { + count_host = 1; + } + else if(is_host_member_of_servicegroup(find_servicegroup(servicegroup_name), temp_host) == TRUE) { + count_host = 1; + } + } + else if(display_type == DISPLAY_HOSTGROUPS && (show_all_hostgroups == TRUE || (is_host_member_of_hostgroup(find_hostgroup(hostgroup_name), temp_host) == TRUE))) + count_host = 1; + + if(count_host) { + + if(temp_hoststatus->status == HOST_UP) + total_up++; + else if(temp_hoststatus->status == HOST_DOWN) { + total_down++; + if(temp_hoststatus->problem_has_been_acknowledged == FALSE && temp_hoststatus->notifications_enabled == TRUE && temp_hoststatus->checks_enabled == TRUE && temp_hoststatus->scheduled_downtime_depth == 0) + problem_hosts_down++; + } + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + total_unreachable++; + if(temp_hoststatus->problem_has_been_acknowledged == FALSE && temp_hoststatus->notifications_enabled == TRUE && temp_hoststatus->checks_enabled == TRUE && temp_hoststatus->scheduled_downtime_depth == 0) + problem_hosts_unreachable++; + } + + else if(temp_hoststatus->status == HOST_PENDING) + total_pending++; + else + total_up++; + } + } + + total_hosts = total_up + total_down + total_unreachable + total_pending; + total_problems = total_down + total_unreachable; + + printf("
    Host Status Totals
    \n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + + printf("\n"); + + /* total hosts up */ + printf("\n", (total_up > 0) ? "UP" : "", total_up); + + /* total hosts down */ + printf("\n", (total_down > 0) ? "DOWN" : "", total_down); + + /* total hosts unreachable */ + printf("\n", (total_unreachable > 0) ? "UNREACHABLE" : "", total_unreachable); + + /* total hosts pending */ + printf("\n", (total_pending > 0) ? "PENDING" : "", total_pending); + + printf("\n"); + printf("
    "); + printf("", HOST_UP); + printf("Up"); + printf("", HOST_DOWN); + printf("Down"); + printf("", HOST_UNREACHABLE); + printf("Unreachable"); + printf("", HOST_PENDING); + printf("Pending
    %d%d%d%d
    \n"); + + printf("
    \n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + /* total hosts with problems */ + printf("\n", (total_problems > 0) ? "PROBLEMS" : "", total_problems); + + /* total hosts */ + printf("\n", total_hosts); + + printf("\n"); + printf("
    "); + printf("", HOST_DOWN | HOST_UNREACHABLE); + printf("All Problems"); + printf(""); + printf("All Types
    %d%d
    \n"); + + printf("
    \n"); + + printf("\n"); + + return; + } + + + +/* display a detailed listing of the status of all services... */ +void show_service_detail(void) { + regex_t preg, preg_hostname; + time_t t; + char date_time[MAX_DATETIME_LENGTH]; + char state_duration[48]; + char status[MAX_INPUT_BUFFER]; + char temp_buffer[MAX_INPUT_BUFFER]; + char temp_url[MAX_INPUT_BUFFER]; + char *processed_string = NULL; + char *status_class = ""; + char *status_bg_class = ""; + char *host_status_bg_class = ""; + char *last_host = ""; + int new_host = FALSE; + servicestatus *temp_status = NULL; + hostgroup *temp_hostgroup = NULL; + servicegroup *temp_servicegroup = NULL; + hoststatus *temp_hoststatus = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + int odd = 0; + int total_comments = 0; + int user_has_seen_something = FALSE; + servicesort *temp_servicesort = NULL; + int use_sort = FALSE; + int result = OK; + int first_entry = TRUE; + int days; + int hours; + int minutes; + int seconds; + int duration_error = FALSE; + int total_entries = 0; + int show_service = FALSE; + int visible_entries = 0; + + + /* sort the service list if necessary */ + if(sort_type != SORT_NONE) { + result = sort_services(sort_type, sort_option); + if(result == ERROR) + use_sort = FALSE; + else + use_sort = TRUE; + } + else + use_sort = FALSE; + + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + if(display_header == TRUE) + show_filters(); + + printf("\n"); + + printf("
    Service Status Details For "); + if(display_type == DISPLAY_HOSTS) { + if(show_all_hosts == TRUE) + printf("All Hosts"); + else + printf("Host '%s'", host_name); + } + else if(display_type == DISPLAY_SERVICEGROUPS) { + if(show_all_servicegroups == TRUE) + printf("All Service Groups"); + else + printf("Service Group '%s'", url_encode(servicegroup_name)); + } + else { + if(show_all_hostgroups == TRUE) + printf("All Host Groups"); + else + printf("Host Group '%s'", hostgroup_name); + } + printf("
    \n"); + + if(use_sort == TRUE) { + printf("
    Entries sorted by "); + if(sort_option == SORT_HOSTNAME) + printf("host name"); + else if(sort_option == SORT_SERVICENAME) + printf("service name"); + else if(sort_option == SORT_SERVICESTATUS) + printf("service status"); + else if(sort_option == SORT_LASTCHECKTIME) + printf("last check time"); + else if(sort_option == SORT_CURRENTATTEMPT) + printf("attempt number"); + else if(sort_option == SORT_STATEDURATION) + printf("state duration"); + printf(" (%s)\n", (sort_type == SORT_ASCENDING) ? "ascending" : "descending"); + printf("
    \n"); + } + + if(service_filter != NULL) + printf("
    Filtered By Services Matching \'%s\'
    ", service_filter); + + printf("
    "); + + printf("
    \n"); + + + + + /* handle navigation GET variables */ + snprintf(temp_url, sizeof(temp_url) - 1, "%s?", STATUS_CGI); + temp_url[sizeof(temp_url) - 1] = '\x0'; + if(display_type == DISPLAY_HOSTS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%shost=%s", (navbar_search == TRUE) ? "&navbarsearch=1&" : "", (host_name == NULL) ? "all" : url_encode(host_name)); + else if(display_type == DISPLAY_SERVICEGROUPS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "servicegroup=%s&style=detail", url_encode(servicegroup_name)); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "hostgroup=%s&style=detail", url_encode(hostgroup_name)); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + if(service_status_types != all_service_status_types) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&servicestatustypes=%d", service_status_types); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + if(host_status_types != all_host_status_types) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&hoststatustypes=%d", host_status_types); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + if(service_properties != 0) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&serviceprops=%lu", service_properties); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + if(host_properties != 0) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&hostprops=%lu", host_properties); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + /* + if(temp_result_limit) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&limit=%i", temp_result_limit); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + */ + + if(sort_type != SORT_NONE) { + snprintf(temp_buffer, sizeof(temp_buffer), "&sorttype=%i&sortoption=%i", sort_type, sort_option); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + + /* GET input can override cgi.cfg */ + if(limit_results == TRUE) + result_limit = temp_result_limit ? temp_result_limit : result_limit; + else + result_limit = 0; + /* select box to set result limit */ + if(result_limit) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&limit=%i", temp_result_limit); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + create_page_limiter(result_limit, temp_url); + + /* the main list of services */ + printf("\n"); + printf("\n"); + + printf("", temp_url, SORT_ASCENDING, SORT_HOSTNAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_HOSTNAME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_SERVICENAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_SERVICENAME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_SERVICESTATUS, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_SERVICESTATUS, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_LASTCHECKTIME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_LASTCHECKTIME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_STATEDURATION, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_STATEDURATION, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_CURRENTATTEMPT, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_CURRENTATTEMPT, url_images_path, DOWN_ARROW_ICON); + + printf("\n"); + printf("\n"); + + + if(service_filter != NULL) + regcomp(&preg, service_filter, 0); + if(host_filter != NULL) + regcomp(&preg_hostname, host_filter, REG_ICASE); + + temp_hostgroup = find_hostgroup(hostgroup_name); + temp_servicegroup = find_servicegroup(servicegroup_name); + + /* check all services... */ + while(1) { + + /* get the next service to display */ + if(use_sort == TRUE) { + if(first_entry == TRUE) + temp_servicesort = servicesort_list; + else + temp_servicesort = temp_servicesort->next; + if(temp_servicesort == NULL) + break; + temp_status = temp_servicesort->svcstatus; + } + else { + if(first_entry == TRUE) + temp_status = servicestatus_list; + else + temp_status = temp_status->next; + } + + if(temp_status == NULL) + break; + + first_entry = FALSE; + + /* find the service */ + temp_service = find_service(temp_status->host_name, temp_status->description); + + /* if we couldn't find the service, go to the next service */ + if(temp_service == NULL) + continue; + + /* find the host */ + temp_host = find_host(temp_service->host_name); + + /* make sure user has rights to see this... */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + user_has_seen_something = TRUE; + + /* get the host status information */ + temp_hoststatus = find_hoststatus(temp_service->host_name); + + /* see if we should display services for hosts with tis type of status */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* see if we should display this type of service status */ + if(!(service_status_types & temp_status->status)) + continue; + + /* check host properties filter */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + /* check service properties filter */ + if(passes_service_properties_filter(temp_status) == FALSE) + continue; + + /* servicefilter cgi var */ + if(service_filter != NULL) + if(regexec(&preg, temp_status->description, 0, NULL, 0)) + continue; + + show_service = FALSE; + + if(display_type == DISPLAY_HOSTS) { + if(show_all_hosts == TRUE) + show_service = TRUE; + else if(host_filter != NULL && 0 == regexec(&preg_hostname, temp_status->host_name, 0, NULL, 0)) + show_service = TRUE; + else if(!strcmp(host_name, temp_status->host_name)) + show_service = TRUE; + } + + else if(display_type == DISPLAY_HOSTGROUPS) { + if(show_all_hostgroups == TRUE) + show_service = TRUE; + else if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == TRUE) + show_service = TRUE; + } + + else if(display_type == DISPLAY_SERVICEGROUPS) { + if(show_all_servicegroups == TRUE) + show_service = TRUE; + else if(is_service_member_of_servicegroup(temp_servicegroup, temp_service) == TRUE) + show_service = TRUE; + } + + /* final checks for display visibility, add to total results. Used for page numbers */ + if(result_limit == 0) + limit_results = FALSE; + + if((limit_results == TRUE && show_service == TRUE) && ((total_entries < page_start) || (total_entries >= (page_start + result_limit)))) { + total_entries++; + show_service = FALSE; + } + + /* a visible entry */ + if(show_service == TRUE) { + if(strcmp(last_host, temp_status->host_name) || visible_entries == 0) + new_host = TRUE; + else + new_host = FALSE; + + if(new_host == TRUE) { + if(strcmp(last_host, "")) { + printf("\n"); + printf("\n"); + } + } + + if(odd) + odd = 0; + else + odd = 1; + + /* keep track of total number of services we're displaying */ + visible_entries++; + total_entries++; + + /* get the last service check time */ + t = temp_status->last_check; + get_time_string(&t, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + if((unsigned long)temp_status->last_check == 0L) + strcpy(date_time, "N/A"); + + if(temp_status->status == SERVICE_PENDING) { + strncpy(status, "PENDING", sizeof(status)); + status_class = "PENDING"; + status_bg_class = (odd) ? "Even" : "Odd"; + } + else if(temp_status->status == SERVICE_OK) { + strncpy(status, "OK", sizeof(status)); + status_class = "OK"; + status_bg_class = (odd) ? "Even" : "Odd"; + } + else if(temp_status->status == SERVICE_WARNING) { + strncpy(status, "WARNING", sizeof(status)); + status_class = "WARNING"; + if(temp_status->problem_has_been_acknowledged == TRUE) + status_bg_class = "BGWARNINGACK"; + else if(temp_status->scheduled_downtime_depth > 0) + status_bg_class = "BGWARNINGSCHED"; + else + status_bg_class = "BGWARNING"; + } + else if(temp_status->status == SERVICE_UNKNOWN) { + strncpy(status, "UNKNOWN", sizeof(status)); + status_class = "UNKNOWN"; + if(temp_status->problem_has_been_acknowledged == TRUE) + status_bg_class = "BGUNKNOWNACK"; + else if(temp_status->scheduled_downtime_depth > 0) + status_bg_class = "BGUNKNOWNSCHED"; + else + status_bg_class = "BGUNKNOWN"; + } + else if(temp_status->status == SERVICE_CRITICAL) { + strncpy(status, "CRITICAL", sizeof(status)); + status_class = "CRITICAL"; + if(temp_status->problem_has_been_acknowledged == TRUE) + status_bg_class = "BGCRITICALACK"; + else if(temp_status->scheduled_downtime_depth > 0) + status_bg_class = "BGCRITICALSCHED"; + else + status_bg_class = "BGCRITICAL"; + } + status[sizeof(status) - 1] = '\x0'; + + + printf("\n"); + + /* host name column */ + if(new_host == TRUE) { + + /* grab macros */ + grab_host_macros_r(mac, temp_host); + + if(temp_hoststatus->status == HOST_DOWN) { + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) + host_status_bg_class = "HOSTDOWNACK"; + else if(temp_hoststatus->scheduled_downtime_depth > 0) + host_status_bg_class = "HOSTDOWNSCHED"; + else + host_status_bg_class = "HOSTDOWN"; + } + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) + host_status_bg_class = "HOSTUNREACHABLEACK"; + else if(temp_hoststatus->scheduled_downtime_depth > 0) + host_status_bg_class = "HOSTUNREACHABLESCHED"; + else + host_status_bg_class = "HOSTUNREACHABLE"; + } + else + host_status_bg_class = (odd) ? "Even" : "Odd"; + + printf("\n"); + + /* grab macros */ + grab_service_macros_r(mac, temp_service); + + /* service name column */ + printf("\n"); + + /* state duration calculation... */ + t = 0; + duration_error = FALSE; + if(temp_status->last_state_change == (time_t)0) { + if(program_start > current_time) + duration_error = TRUE; + else + t = current_time - program_start; + } + else { + if(temp_status->last_state_change > current_time) + duration_error = TRUE; + else + t = current_time - temp_status->last_state_change; + } + get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds); + if(duration_error == TRUE) + snprintf(state_duration, sizeof(state_duration) - 1, "???"); + else + snprintf(state_duration, sizeof(state_duration) - 1, "%2dd %2dh %2dm %2ds%s", days, hours, minutes, seconds, (temp_status->last_state_change == (time_t)0) ? "+" : ""); + state_duration[sizeof(state_duration) - 1] = '\x0'; + + /* the rest of the columns... */ + printf("\n", status_class, status); + printf("\n", status_bg_class, date_time); + printf("\n", status_bg_class, state_duration); + printf("\n", status_bg_class, temp_status->current_attempt, temp_status->max_attempts); + printf("\n"); + + printf("\n"); + + /* mod to account for paging */ + if(visible_entries != 0) + last_host = temp_status->host_name; + } + + } + + printf("
    Host Sort by host name (ascending)Sort by host name (descending)Service Sort by service name (ascending)Sort by service name (descending)Status Sort by service status (ascending)Sort by service status (descending)Last Check Sort by last check time (ascending)Sort by last check time (descending)Duration Sort by state duration (ascending)Sort by state duration time (descending)Attempt Sort by current attempt (ascending)Sort by current attempt (descending)Status Information
    ", host_status_bg_class); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n", host_status_bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), temp_host->address, temp_status->host_name); + printf("\n"); + printf("
    %s
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + total_comments = number_of_host_comments(temp_host->name); + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, ACKNOWLEDGEMENT_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + /* only show comments if this is a non-read-only user */ + if(is_authorized_for_read_only(¤t_authdata) == FALSE) { + if(total_comments > 0) + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, COMMENT_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, total_comments, (total_comments == 1) ? "" : "s", total_comments, (total_comments == 1) ? "" : "s"); + } + if(temp_hoststatus->notifications_enabled == FALSE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, NOTIFICATIONS_DISABLED_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_hoststatus->checks_enabled == FALSE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, DISABLED_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_hoststatus->is_flapping == TRUE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, FLAPPING_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_hoststatus->scheduled_downtime_depth > 0) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, SCHEDULED_DOWNTIME_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_host->notes_url != NULL) { + printf("\n"); + } + if(temp_host->action_url != NULL) { + printf("\n"); + } + if(temp_host->icon_image != NULL) { + printf("\n"); + } + printf("\n"); + printf("
    This host problem has been acknowledgedThis host has %d comment%s associated with itNotifications for this host have been disabledChecks of this host have been disabledThis host is flapping between statesThis host is currently in a period of scheduled downtime"); + printf("", (notes_url_target == NULL) ? "_blank" : notes_url_target); + printf("%s", url_images_path, NOTES_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extra Host Notes", "View Extra Host Notes"); + printf(""); + printf(""); + printf("", (action_url_target == NULL) ? "_blank" : action_url_target); + printf("%s", url_images_path, ACTION_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Perform Extra Host Actions", "Perform Extra Host Actions"); + printf(""); + printf(""); + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name)); + printf("%s", STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); + printf(""); + printf("
    \n"); + printf("
    \n"); + } + else + printf("
    "); + printf("", status_bg_class); + printf(""); + printf(""); + printf("\n"); + printf("\n"); + printf(""); + printf("
    "); + printf("\n"); + printf("\n"); + printf("", temp_status->description); + printf("\n"); + printf("
    ", url_encode(temp_status->description)); + printf("%s
    \n"); + printf("
    \n", status_bg_class); + printf("\n"); + printf("\n"); + total_comments = number_of_service_comments(temp_service->host_name, temp_service->description); + /* only show comments if this is a non-read-only user */ + if(is_authorized_for_read_only(¤t_authdata) == FALSE) { + if(total_comments > 0) { + printf("", url_encode(temp_status->description), url_images_path, COMMENT_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, total_comments, (total_comments == 1) ? "" : "s", total_comments, (total_comments == 1) ? "" : "s"); + } + } + if(temp_status->problem_has_been_acknowledged == TRUE) { + printf("", url_encode(temp_status->description), url_images_path, ACKNOWLEDGEMENT_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->checks_enabled == FALSE && temp_status->accept_passive_service_checks == FALSE) { + printf("", url_encode(temp_status->description), url_images_path, DISABLED_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + else if(temp_status->checks_enabled == FALSE) { + printf("", url_encode(temp_status->description), url_images_path, PASSIVE_ONLY_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->notifications_enabled == FALSE) { + printf("", url_encode(temp_status->description), url_images_path, NOTIFICATIONS_DISABLED_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->is_flapping == TRUE) { + printf("", url_encode(temp_status->description), url_images_path, FLAPPING_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->scheduled_downtime_depth > 0) { + printf("", url_encode(temp_status->description), url_images_path, SCHEDULED_DOWNTIME_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_service->notes_url != NULL) { + printf("\n"); + } + if(temp_service->action_url != NULL) { + printf("\n"); + } + if(temp_service->icon_image != NULL) { + printf("\n"); + } + if(enable_splunk_integration == TRUE) { + printf("\n"); + } + printf("\n"); + printf("
    This service has %d comment%s associated with itThis service problem has been acknowledgedActive and passive checks have been disabled for this serviceActive checks of the service have been disabled - only passive checks are being acceptedNotifications for this service have been disabledThis service is flapping between statesThis service is currently in a period of scheduled downtime"); + printf("", (notes_url_target == NULL) ? "_blank" : notes_url_target); + printf("%s", url_images_path, NOTES_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extra Service Notes", "View Extra Service Notes"); + printf(""); + printf(""); + printf("", (action_url_target == NULL) ? "_blank" : action_url_target); + printf("%s", url_images_path, ACTION_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Perform Extra Service Actions", "Perform Extra Service Actions"); + printf(""); + printf(""); + printf("", url_encode(temp_service->description)); + printf("%s", STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, (temp_service->icon_image_alt == NULL) ? "" : temp_service->icon_image_alt, (temp_service->icon_image_alt == NULL) ? "" : temp_service->icon_image_alt); + printf(""); + printf(""); + display_splunk_service_url(temp_service); + printf("
    \n"); + printf("
    "); + printf("
    %s%s%s%d/%d", status_bg_class); + printf("%s ", (temp_status->plugin_output == NULL) ? "" : html_encode(temp_status->plugin_output, TRUE)); + /* + if(enable_splunk_integration==TRUE) + display_splunk_service_url(temp_service); + */ + printf("
    \n"); + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE) { + + if(servicestatus_list != NULL) { + printf("

    It appears as though you do not have permission to view information for any of the services you requested...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + } + else { + printf("

    There doesn't appear to be any service status information in the status log...

    \n"); + printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.

    \n"); + } + } + else { + /* do page numbers if applicable */ + create_pagenumbers(total_entries, visible_entries, temp_url, TRUE); + } + + return; + } + + + + +/* display a detailed listing of the status of all hosts... */ +void show_host_detail(void) { + time_t t; + char date_time[MAX_DATETIME_LENGTH]; + char state_duration[48]; + char status[MAX_INPUT_BUFFER]; + char temp_buffer[MAX_INPUT_BUFFER]; + char temp_url[MAX_INPUT_BUFFER]; + char *processed_string = NULL; + char *status_class = ""; + char *status_bg_class = ""; + hoststatus *temp_status = NULL; + hostgroup *temp_hostgroup = NULL; + host *temp_host = NULL; + hostsort *temp_hostsort = NULL; + int odd = 0; + int total_comments = 0; + int user_has_seen_something = FALSE; + int use_sort = FALSE; + int result = OK; + int first_entry = TRUE; + int days; + int hours; + int minutes; + int seconds; + int duration_error = FALSE; + int total_entries = 0; + int visible_entries = 0; +// int show_host = FALSE; + + + /* sort the host list if necessary */ + if(sort_type != SORT_NONE) { + result = sort_hosts(sort_type, sort_option); + if(result == ERROR) + use_sort = FALSE; + else + use_sort = TRUE; + } + else + use_sort = FALSE; + + +// printf("

    \n"); + + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + if(display_header == TRUE) + show_filters(); + + printf("\n"); + + printf("
    Host Status Details For "); + if(show_all_hostgroups == TRUE) + printf("All Host Groups"); + else + printf("Host Group '%s'", hostgroup_name); + printf("
    \n"); + + if(use_sort == TRUE) { + printf("
    Entries sorted by "); + if(sort_option == SORT_HOSTNAME) + printf("host name"); + else if(sort_option == SORT_HOSTSTATUS) + printf("host status"); + else if(sort_option == SORT_HOSTURGENCY) + printf("host urgency"); + else if(sort_option == SORT_LASTCHECKTIME) + printf("last check time"); + else if(sort_option == SORT_CURRENTATTEMPT) + printf("attempt number"); + else if(sort_option == SORT_STATEDURATION) + printf("state duration"); + printf(" (%s)\n", (sort_type == SORT_ASCENDING) ? "ascending" : "descending"); + printf("
    \n"); + } + + printf("
    "); + + printf("
    \n"); + + + + + + snprintf(temp_url, sizeof(temp_url) - 1, "%s?", STATUS_CGI); + temp_url[sizeof(temp_url) - 1] = '\x0'; + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "hostgroup=%s&style=hostdetail", url_encode(hostgroup_name)); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + if(service_status_types != all_service_status_types) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&servicestatustypes=%d", service_status_types); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + if(host_status_types != all_host_status_types) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&hoststatustypes=%d", host_status_types); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + if(service_properties != 0) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&serviceprops=%lu", service_properties); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + if(host_properties != 0) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&hostprops=%lu", host_properties); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + /* + if(temp_result_limit) { + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "&limit=%i", temp_result_limit); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + strncat(temp_url, temp_buffer, sizeof(temp_url) - strlen(temp_url) - 1); + temp_url[sizeof(temp_url) - 1] = '\x0'; + } + */ + + /* GET input can override cgi.cfg */ + if(limit_results == TRUE) + result_limit = temp_result_limit ? temp_result_limit : result_limit; + else + result_limit = 0; + /* select box to set result limit */ + create_page_limiter(result_limit, temp_url); + + + /* the main list of hosts */ + printf("

    \n"); + printf("\n"); + printf("\n"); + + printf("", temp_url, SORT_ASCENDING, SORT_HOSTNAME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_HOSTNAME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_HOSTSTATUS, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_HOSTSTATUS, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_LASTCHECKTIME, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_LASTCHECKTIME, url_images_path, DOWN_ARROW_ICON); + + printf("", temp_url, SORT_ASCENDING, SORT_STATEDURATION, url_images_path, UP_ARROW_ICON, temp_url, SORT_DESCENDING, SORT_STATEDURATION, url_images_path, DOWN_ARROW_ICON); + + printf("\n"); + printf("\n"); + + + /* check all hosts... */ + while(1) { + + /* get the next service to display */ + if(use_sort == TRUE) { + if(first_entry == TRUE) + temp_hostsort = hostsort_list; + else + temp_hostsort = temp_hostsort->next; + if(temp_hostsort == NULL) + break; + temp_status = temp_hostsort->hststatus; + } + else { + if(first_entry == TRUE) + temp_status = hoststatus_list; + else + temp_status = temp_status->next; + } + + if(temp_status == NULL) + break; + + first_entry = FALSE; + + /* find the host */ + temp_host = find_host(temp_status->host_name); + + /* if we couldn't find the host, go to the next status entry */ + if(temp_host == NULL) + continue; + + /* make sure user has rights to see this... */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + user_has_seen_something = TRUE; + + /* see if we should display services for hosts with this type of status */ + if(!(host_status_types & temp_status->status)) + continue; + + /* check host properties filter */ + if(passes_host_properties_filter(temp_status) == FALSE) + continue; + + + /* see if this host is a member of the hostgroup */ + if(show_all_hostgroups == FALSE) { + temp_hostgroup = find_hostgroup(hostgroup_name); + if(temp_hostgroup == NULL) + continue; + if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == FALSE) + continue; + } + + + + total_entries++; + + /* final checks for display visibility, add to total results. Used for page numbers */ + if(result_limit == 0) + limit_results = FALSE; + + if((limit_results == TRUE) && ((total_entries < page_start) || (total_entries >= (page_start + result_limit)))) { + continue; + } + + visible_entries++; + + + /* grab macros */ + grab_host_macros_r(mac, temp_host); + + + if(display_type == DISPLAY_HOSTGROUPS) { + + if(odd) + odd = 0; + else + odd = 1; + + + /* get the last host check time */ + t = temp_status->last_check; + get_time_string(&t, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + if((unsigned long)temp_status->last_check == 0L) + strcpy(date_time, "N/A"); + + if(temp_status->status == HOST_PENDING) { + strncpy(status, "PENDING", sizeof(status)); + status_class = "PENDING"; + status_bg_class = (odd) ? "Even" : "Odd"; + } + else if(temp_status->status == HOST_UP) { + strncpy(status, "UP", sizeof(status)); + status_class = "HOSTUP"; + status_bg_class = (odd) ? "Even" : "Odd"; + } + else if(temp_status->status == HOST_DOWN) { + strncpy(status, "DOWN", sizeof(status)); + status_class = "HOSTDOWN"; + if(temp_status->problem_has_been_acknowledged == TRUE) + status_bg_class = "BGDOWNACK"; + else if(temp_status->scheduled_downtime_depth > 0) + status_bg_class = "BGDOWNSCHED"; + else + status_bg_class = "BGDOWN"; + } + else if(temp_status->status == HOST_UNREACHABLE) { + strncpy(status, "UNREACHABLE", sizeof(status)); + status_class = "HOSTUNREACHABLE"; + if(temp_status->problem_has_been_acknowledged == TRUE) + status_bg_class = "BGUNREACHABLEACK"; + else if(temp_status->scheduled_downtime_depth > 0) + status_bg_class = "BGUNREACHABLESCHED"; + else + status_bg_class = "BGUNREACHABLE"; + } + status[sizeof(status) - 1] = '\x0'; + + + printf("\n"); + + + /**** host name column ****/ + + printf("\n"); + + + /* state duration calculation... */ + t = 0; + duration_error = FALSE; + if(temp_status->last_state_change == (time_t)0) { + if(program_start > current_time) + duration_error = TRUE; + else + t = current_time - program_start; + } + else { + if(temp_status->last_state_change > current_time) + duration_error = TRUE; + else + t = current_time - temp_status->last_state_change; + } + get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds); + if(duration_error == TRUE) + snprintf(state_duration, sizeof(state_duration) - 1, "???"); + else + snprintf(state_duration, sizeof(state_duration) - 1, "%2dd %2dh %2dm %2ds%s", days, hours, minutes, seconds, (temp_status->last_state_change == (time_t)0) ? "+" : ""); + state_duration[sizeof(state_duration) - 1] = '\x0'; + + /* the rest of the columns... */ + printf("\n", status_class, status); + printf("\n", status_bg_class, date_time); + printf("\n", status_bg_class, state_duration); + printf("\n"); + + printf("\n"); + } + + } + + printf("
    Host Sort by host name (ascending)Sort by host name (descending)Status Sort by host status (ascending)Sort by host status (descending)Last Check Sort by last check time (ascending)Sort by last check time (descending)Duration Sort by state duration (ascending)Sort by state duration time (descending)Status Information
    ", status_class); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n", status_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), temp_host->address, temp_status->host_name); + printf("\n"); + printf("
    %s 
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + total_comments = number_of_host_comments(temp_host->name); + if(temp_status->problem_has_been_acknowledged == TRUE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, ACKNOWLEDGEMENT_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(total_comments > 0) + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, COMMENT_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, total_comments, (total_comments == 1) ? "" : "s", total_comments, (total_comments == 1) ? "" : "s"); + if(temp_status->notifications_enabled == FALSE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, NOTIFICATIONS_DISABLED_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->checks_enabled == FALSE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, DISABLED_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->is_flapping == TRUE) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, FLAPPING_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_status->scheduled_downtime_depth > 0) { + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name), url_images_path, SCHEDULED_DOWNTIME_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT); + } + if(temp_host->notes_url != NULL) { + printf("\n"); + } + if(temp_host->action_url != NULL) { + printf("\n"); + } + if(temp_host->icon_image != NULL) { + printf("\n"); + } + if(enable_splunk_integration == TRUE) { + printf("\n"); + } + printf("\n"); + printf("\n"); + printf("
    This host problem has been acknowledgedThis host has %d comment%s associated with itNotifications for this host have been disabledChecks of this host have been disabledThis host is flapping between statesThis host is currently in a period of scheduled downtime"); + printf("", (notes_url_target == NULL) ? "_blank" : notes_url_target); + printf("%s", url_images_path, NOTES_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extra Host Notes", "View Extra Host Notes"); + printf(""); + printf(""); + printf("", (action_url_target == NULL) ? "_blank" : action_url_target); + printf("%s", url_images_path, ACTION_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Perform Extra Host Actions", "Perform Extra Host Actions"); + printf(""); + printf(""); + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_status->host_name)); + printf("%s", STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); + printf(""); + printf(""); + display_splunk_host_url(temp_host); + printf(""); + printf("View Service Details For This Host", STATUS_CGI, url_encode(temp_status->host_name), url_images_path, STATUS_DETAIL_ICON); + printf("
    \n"); + printf("
    \n"); + + printf("
    %s%s%s", status_bg_class); + printf("%s ", (temp_status->plugin_output == NULL) ? "" : html_encode(temp_status->plugin_output, TRUE)); + /* + if(enable_splunk_integration==TRUE) + display_splunk_host_url(temp_host); + */ + printf("
    \n"); + printf("
    \n"); + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE) { + + if(hoststatus_list != NULL) { + printf("

    It appears as though you do not have permission to view information for any of the hosts you requested...

    \n"); + printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.

    \n"); + } + else { + printf("

    There doesn't appear to be any host status information in the status log...

    \n"); + printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.

    \n"); + } + } + + else { + /* do page numbers if applicable */ + create_pagenumbers(total_entries, visible_entries, temp_url, FALSE); + } + return; + } + + + + +/* show an overview of servicegroup(s)... */ +void show_servicegroup_overviews(void) { + servicegroup *temp_servicegroup = NULL; + int current_column; + int user_has_seen_something = FALSE; + int servicegroup_error = FALSE; + + + //printf("

    \n"); + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + show_filters(); + + printf("\n"); + + printf("
    Service Overview For "); + if(show_all_servicegroups == TRUE) + printf("All Service Groups"); + else + printf("Service Group '%s'", servicegroup_name); + printf("
    \n"); + + printf("
    "); + + printf("
    \n"); + + //printf("

    \n"); + + + /* display status overviews for all servicegroups */ + if(show_all_servicegroups == TRUE) { + + + printf("
    \n"); + printf("\n"); + + current_column = 1; + + /* loop through all servicegroups... */ + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + /* make sure the user is authorized to view at least one host in this servicegroup */ + if(is_authorized_for_servicegroup(temp_servicegroup, ¤t_authdata) == FALSE) + continue; + + if(current_column == 1) + printf("\n"); + printf("\n"); + if(current_column == overview_columns) + printf("\n"); + + if(current_column < overview_columns) + current_column++; + else + current_column = 1; + } + + if(current_column != 1) { + + for(; current_column <= overview_columns; current_column++) + printf("\n"); + printf("\n"); + } + + printf("
    \n"); + + show_servicegroup_overview(temp_servicegroup); + + user_has_seen_something = TRUE; + + printf("
    \n"); + printf("
    \n"); + } + + /* else display overview for just a specific servicegroup */ + else { + + temp_servicegroup = find_servicegroup(servicegroup_name); + if(temp_servicegroup != NULL) { + + //printf("

    \n"); + printf("

    \n"); + printf("
    \n"); + + if(is_authorized_for_servicegroup(temp_servicegroup, ¤t_authdata) == TRUE) { + + show_servicegroup_overview(temp_servicegroup); + + user_has_seen_something = TRUE; + } + + printf("
    \n"); + printf("
    \n"); + //printf("

    \n"); + } + else { + printf("
    Sorry, but service group '%s' doesn't seem to exist...
    ", servicegroup_name); + servicegroup_error = TRUE; + } + } + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE && servicegroup_error == FALSE) { + + //printf("

    \n"); + printf("

    \n"); + + if(servicegroup_list != NULL) { + printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.
    \n"); + } + else { + printf("
    There are no service groups defined.
    \n"); + } + + printf("
    \n"); + //printf("

    \n"); + } + + return; + } + + + +/* shows an overview of a specific servicegroup... */ +void show_servicegroup_overview(servicegroup *temp_servicegroup) { + servicesmember *temp_member; + host *temp_host; + host *last_host; + hoststatus *temp_hoststatus = NULL; + int odd = 0; + + + printf("
    \n"); + printf("%s", STATUS_CGI, url_encode(temp_servicegroup->group_name), temp_servicegroup->alias); + printf(" (%s)", EXTINFO_CGI, DISPLAY_SERVICEGROUP_INFO, url_encode(temp_servicegroup->group_name), temp_servicegroup->group_name); + printf("
    \n"); + + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + /* find all hosts that have services that are members of the servicegroup */ + last_host = NULL; + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the host */ + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + /* skip this if it isn't a new host... */ + if(temp_host == last_host) + continue; + + /* find the host status */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + /* make sure we only display hosts of the specified status levels */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* make sure we only display hosts that have the desired properties */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + if(odd) + odd = 0; + else + odd = 1; + + show_servicegroup_hostgroup_member_overview(temp_hoststatus, odd, temp_servicegroup); + + last_host = temp_host; + } + + printf("
    HostStatusServicesActions
    \n"); + printf("
    \n"); + + return; + } + + + +/* show a summary of servicegroup(s)... */ +void show_servicegroup_summaries(void) { + servicegroup *temp_servicegroup = NULL; + int user_has_seen_something = FALSE; + int servicegroup_error = FALSE; + int odd = 0; + + + printf("

    \n"); + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + show_filters(); + + printf("\n"); + + printf("
    Status Summary For "); + if(show_all_servicegroups == TRUE) + printf("All Service Groups"); + else + printf("Service Group '%s'", servicegroup_name); + printf("
    \n"); + + printf("
    "); + + printf("
    \n"); + + printf("

    \n"); + + + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + /* display status summary for all servicegroups */ + if(show_all_servicegroups == TRUE) { + + /* loop through all servicegroups... */ + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + /* make sure the user is authorized to view at least one host in this servicegroup */ + if(is_authorized_for_servicegroup(temp_servicegroup, ¤t_authdata) == FALSE) + continue; + + if(odd == 0) + odd = 1; + else + odd = 0; + + /* show summary for this servicegroup */ + show_servicegroup_summary(temp_servicegroup, odd); + + user_has_seen_something = TRUE; + } + + } + + /* else just show summary for a specific servicegroup */ + else { + temp_servicegroup = find_servicegroup(servicegroup_name); + if(temp_servicegroup == NULL) + servicegroup_error = TRUE; + else { + show_servicegroup_summary(temp_servicegroup, 1); + user_has_seen_something = TRUE; + } + } + + printf("
    Service GroupHost Status SummaryService Status Summary
    \n"); + printf("
    \n"); + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE && servicegroup_error == FALSE) { + + printf("

    \n"); + + if(servicegroup_list != NULL) { + printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.
    \n"); + } + else { + printf("
    There are no service groups defined.
    \n"); + } + + printf("

    \n"); + } + + /* we couldn't find the servicegroup */ + else if(servicegroup_error == TRUE) { + printf("

    \n"); + printf("
    Sorry, but servicegroup '%s' doesn't seem to exist...
    \n", servicegroup_name); + printf("

    \n"); + } + + return; + } + + + +/* displays status summary information for a specific servicegroup */ +void show_servicegroup_summary(servicegroup *temp_servicegroup, int odd) { + char *status_bg_class = ""; + + if(odd == 1) + status_bg_class = "Even"; + else + status_bg_class = "Odd"; + + printf("\n", status_bg_class, status_bg_class); + printf("%s ", STATUS_CGI, url_encode(temp_servicegroup->group_name), temp_servicegroup->alias); + printf("(%s)", EXTINFO_CGI, DISPLAY_SERVICEGROUP_INFO, url_encode(temp_servicegroup->group_name), temp_servicegroup->group_name); + printf(""); + + printf("", status_bg_class); + show_servicegroup_host_totals_summary(temp_servicegroup); + printf(""); + + printf("", status_bg_class); + show_servicegroup_service_totals_summary(temp_servicegroup); + printf(""); + + printf("\n"); + + return; + } + + + +/* shows host total summary information for a specific servicegroup */ +void show_servicegroup_host_totals_summary(servicegroup *temp_servicegroup) { + servicesmember *temp_member; + int hosts_up = 0; + int hosts_down = 0; + int hosts_unreachable = 0; + int hosts_pending = 0; + int hosts_down_scheduled = 0; + int hosts_down_acknowledged = 0; + int hosts_down_disabled = 0; + int hosts_down_unacknowledged = 0; + int hosts_unreachable_scheduled = 0; + int hosts_unreachable_acknowledged = 0; + int hosts_unreachable_disabled = 0; + int hosts_unreachable_unacknowledged = 0; + hoststatus *temp_hoststatus = NULL; + host *temp_host = NULL; + host *last_host = NULL; + int problem = FALSE; + + /* find all the hosts that belong to the servicegroup */ + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the host... */ + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + /* skip this if it isn't a new host... */ + if(temp_host == last_host) + continue; + + /* find the host status */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + /* make sure we only display hosts of the specified status levels */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* make sure we only display hosts that have the desired properties */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + problem = TRUE; + + if(temp_hoststatus->status == HOST_UP) + hosts_up++; + + else if(temp_hoststatus->status == HOST_DOWN) { + if(temp_hoststatus->scheduled_downtime_depth > 0) { + hosts_down_scheduled++; + problem = FALSE; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + hosts_down_acknowledged++; + problem = FALSE; + } + if(temp_hoststatus->checks_enabled == FALSE) { + hosts_down_disabled++; + problem = FALSE; + } + if(problem == TRUE) + hosts_down_unacknowledged++; + hosts_down++; + } + + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + if(temp_hoststatus->scheduled_downtime_depth > 0) { + hosts_unreachable_scheduled++; + problem = FALSE; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + hosts_unreachable_acknowledged++; + problem = FALSE; + } + if(temp_hoststatus->checks_enabled == FALSE) { + hosts_unreachable_disabled++; + problem = FALSE; + } + if(problem == TRUE) + hosts_unreachable_unacknowledged++; + hosts_unreachable++; + } + + else + hosts_pending++; + + last_host = temp_host; + } + + printf("\n"); + + if(hosts_up > 0) { + printf(""); + printf("", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_UP, host_properties, hosts_up); + printf("\n"); + } + + if(hosts_down > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(hosts_unreachable > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(hosts_pending > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_PENDING, host_properties, hosts_pending); + + printf("
    %d UP
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_DOWN, host_properties, hosts_down); + + printf("\n"); + + printf("\n"); + printf("
    %d DOWN :\n"); + + if(hosts_down_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_DOWN, HOST_NO_SCHEDULED_DOWNTIME | HOST_STATE_UNACKNOWLEDGED | HOST_CHECKS_ENABLED, hosts_down_unacknowledged); + + if(hosts_down_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_DOWN, HOST_SCHEDULED_DOWNTIME, hosts_down_scheduled); + + if(hosts_down_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_DOWN, HOST_STATE_ACKNOWLEDGED, hosts_down_acknowledged); + + if(hosts_down_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_DOWN, HOST_CHECKS_DISABLED, hosts_down_disabled); + + printf("
    %d Unhandled
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_UNREACHABLE, host_properties, hosts_unreachable); + + printf("\n"); + + printf("\n"); + printf("
    %d UNREACHABLE :\n"); + + if(hosts_unreachable_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_UNREACHABLE, HOST_NO_SCHEDULED_DOWNTIME | HOST_STATE_UNACKNOWLEDGED | HOST_CHECKS_ENABLED, hosts_unreachable_unacknowledged); + + if(hosts_unreachable_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_UNREACHABLE, HOST_SCHEDULED_DOWNTIME, hosts_unreachable_scheduled); + + if(hosts_unreachable_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_UNREACHABLE, HOST_STATE_ACKNOWLEDGED, hosts_unreachable_acknowledged); + + if(hosts_unreachable_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), HOST_UNREACHABLE, HOST_CHECKS_DISABLED, hosts_unreachable_disabled); + + printf("
    %d Unhandled
    %d Scheduled
    %d Acknowledged
    %d Disabled
    %d PENDING
    \n"); + + if((hosts_up + hosts_down + hosts_unreachable + hosts_pending) == 0) + printf("No matching hosts"); + + return; + return; + } + + + +/* shows service total summary information for a specific servicegroup */ +void show_servicegroup_service_totals_summary(servicegroup *temp_servicegroup) { + int services_ok = 0; + int services_warning = 0; + int services_unknown = 0; + int services_critical = 0; + int services_pending = 0; + int services_warning_host_problem = 0; + int services_warning_scheduled = 0; + int services_warning_acknowledged = 0; + int services_warning_disabled = 0; + int services_warning_unacknowledged = 0; + int services_unknown_host_problem = 0; + int services_unknown_scheduled = 0; + int services_unknown_acknowledged = 0; + int services_unknown_disabled = 0; + int services_unknown_unacknowledged = 0; + int services_critical_host_problem = 0; + int services_critical_scheduled = 0; + int services_critical_acknowledged = 0; + int services_critical_disabled = 0; + int services_critical_unacknowledged = 0; + servicesmember *temp_member = NULL; + servicestatus *temp_servicestatus = NULL; + hoststatus *temp_hoststatus = NULL; + service *temp_service = NULL; + service *last_service = NULL; + int problem = FALSE; + + + /* find all the services that belong to the servicegroup */ + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the service */ + temp_service = find_service(temp_member->host_name, temp_member->service_description); + if(temp_service == NULL) + continue; + + /* skip this if it isn't a new service... */ + if(temp_service == last_service) + continue; + + /* find the service status */ + temp_servicestatus = find_servicestatus(temp_service->host_name, temp_service->description); + if(temp_servicestatus == NULL) + continue; + + /* find the status of the associated host */ + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus == NULL) + continue; + + /* make sure we only display hosts of the specified status levels */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* make sure we only display hosts that have the desired properties */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + /* make sure we only display services of the specified status levels */ + if(!(service_status_types & temp_servicestatus->status)) + continue; + + /* make sure we only display services that have the desired properties */ + if(passes_service_properties_filter(temp_servicestatus) == FALSE) + continue; + + problem = TRUE; + + if(temp_servicestatus->status == SERVICE_OK) + services_ok++; + + else if(temp_servicestatus->status == SERVICE_WARNING) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_warning_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_warning_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_warning_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_warning_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_warning_unacknowledged++; + services_warning++; + } + + else if(temp_servicestatus->status == SERVICE_UNKNOWN) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_unknown_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_unknown_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_unknown_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_unknown_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_unknown_unacknowledged++; + services_unknown++; + } + + else if(temp_servicestatus->status == SERVICE_CRITICAL) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_critical_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_critical_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_critical_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_critical_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_critical_unacknowledged++; + services_critical++; + } + + else if(temp_servicestatus->status == SERVICE_PENDING) + services_pending++; + + last_service = temp_service; + } + + + printf("\n"); + + if(services_ok > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_OK, host_status_types, service_properties, host_properties, services_ok); + + if(services_warning > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(services_unknown > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(services_critical > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(services_pending > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_PENDING, host_status_types, service_properties, host_properties, services_pending); + + printf("
    %d OK
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_WARNING, host_status_types, service_properties, host_properties, services_warning); + + printf("\n"); + + printf("\n"); + printf("
    %d WARNING :\n"); + + if(services_warning_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_WARNING, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_warning_unacknowledged); + + if(services_warning_host_problem > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_WARNING, HOST_DOWN | HOST_UNREACHABLE, services_warning_host_problem); + + if(services_warning_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_WARNING, SERVICE_SCHEDULED_DOWNTIME, services_warning_scheduled); + + if(services_warning_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_WARNING, SERVICE_STATE_ACKNOWLEDGED, services_warning_acknowledged); + + if(services_warning_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_WARNING, SERVICE_CHECKS_DISABLED, services_warning_disabled); + + printf("
    %d Unhandled
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_UNKNOWN, host_status_types, service_properties, host_properties, services_unknown); + + printf("\n"); + + printf("\n"); + printf("
    %d UNKNOWN :\n"); + + if(services_unknown_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_UNKNOWN, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_unknown_unacknowledged); + + if(services_unknown_host_problem > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_UNKNOWN, HOST_DOWN | HOST_UNREACHABLE, services_unknown_host_problem); + + if(services_unknown_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_UNKNOWN, SERVICE_SCHEDULED_DOWNTIME, services_unknown_scheduled); + + if(services_unknown_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_UNKNOWN, SERVICE_STATE_ACKNOWLEDGED, services_unknown_acknowledged); + + if(services_unknown_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_UNKNOWN, SERVICE_CHECKS_DISABLED, services_unknown_disabled); + + printf("
    %d Unhandled
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_CRITICAL, host_status_types, service_properties, host_properties, services_critical); + + printf("\n"); + + printf("\n"); + printf("
    %d CRITICAL :\n"); + + if(services_critical_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_CRITICAL, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_critical_unacknowledged); + + if(services_critical_host_problem > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_CRITICAL, HOST_DOWN | HOST_UNREACHABLE, services_critical_host_problem); + + if(services_critical_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_CRITICAL, SERVICE_SCHEDULED_DOWNTIME, services_critical_scheduled); + + if(services_critical_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_CRITICAL, SERVICE_STATE_ACKNOWLEDGED, services_critical_acknowledged); + + if(services_critical_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_servicegroup->group_name), SERVICE_CRITICAL, SERVICE_CHECKS_DISABLED, services_critical_disabled); + + printf("
    %d Unhandled
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    %d PENDING
    \n"); + + if((services_ok + services_warning + services_unknown + services_critical + services_pending) == 0) + printf("No matching services"); + + return; + } + + + +/* show a grid layout of servicegroup(s)... */ +void show_servicegroup_grids(void) { + servicegroup *temp_servicegroup = NULL; + int user_has_seen_something = FALSE; + int servicegroup_error = FALSE; + int odd = 0; + + + printf("

    \n"); + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + show_filters(); + + printf("\n"); + + printf("
    Status Grid For "); + if(show_all_servicegroups == TRUE) + printf("All Service Groups"); + else + printf("Service Group '%s'", servicegroup_name); + printf("
    \n"); + + printf("
    "); + + printf("
    \n"); + + printf("

    \n"); + + + /* display status grids for all servicegroups */ + if(show_all_servicegroups == TRUE) { + + /* loop through all servicegroups... */ + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + /* make sure the user is authorized to view at least one host in this servicegroup */ + if(is_authorized_for_servicegroup(temp_servicegroup, ¤t_authdata) == FALSE) + continue; + + if(odd == 0) + odd = 1; + else + odd = 0; + + /* show grid for this servicegroup */ + show_servicegroup_grid(temp_servicegroup); + + user_has_seen_something = TRUE; + } + + } + + /* else just show grid for a specific servicegroup */ + else { + temp_servicegroup = find_servicegroup(servicegroup_name); + if(temp_servicegroup == NULL) + servicegroup_error = TRUE; + else { + show_servicegroup_grid(temp_servicegroup); + user_has_seen_something = TRUE; + } + } + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE && servicegroup_error == FALSE) { + + printf("

    \n"); + + if(servicegroup_list != NULL) { + printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.
    \n"); + } + else { + printf("
    There are no service groups defined.
    \n"); + } + + printf("

    \n"); + } + + /* we couldn't find the servicegroup */ + else if(servicegroup_error == TRUE) { + printf("

    \n"); + printf("
    Sorry, but servicegroup '%s' doesn't seem to exist...
    \n", servicegroup_name); + printf("

    \n"); + } + + return; + } + + +/* displays status grid for a specific servicegroup */ +void show_servicegroup_grid(servicegroup *temp_servicegroup) { + char *status_bg_class = ""; + char *host_status_class = ""; + char *service_status_class = ""; + char *processed_string = NULL; + servicesmember *temp_member; + servicesmember *temp_member2; + host *temp_host; + host *last_host; + hoststatus *temp_hoststatus; + servicestatus *temp_servicestatus; + int odd = 0; + int current_item; + + + printf("

    \n"); + printf("

    \n"); + + printf("
    %s", STATUS_CGI, url_encode(temp_servicegroup->group_name), temp_servicegroup->alias); + printf(" (%s)
    ", EXTINFO_CGI, DISPLAY_SERVICEGROUP_INFO, url_encode(temp_servicegroup->group_name), temp_servicegroup->group_name); + + printf("\n"); + printf("\n"); + + /* find all hosts that have services that are members of the servicegroup */ + last_host = NULL; + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the host */ + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + /* get the status of the host */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + /* skip this if it isn't a new host... */ + if(temp_host == last_host) + continue; + + if(odd == 1) { + status_bg_class = "Even"; + odd = 0; + } + else { + status_bg_class = "Odd"; + odd = 1; + } + + printf("\n", status_bg_class); + + if(temp_hoststatus->status == HOST_DOWN) + host_status_class = "HOStdOWN"; + else if(temp_hoststatus->status == HOST_UNREACHABLE) + host_status_class = "HOSTUNREACHABLE"; + else + host_status_class = status_bg_class; + + printf("\n"); + + printf("\n"); + printf("\n"); + + last_host = temp_host; + } + + printf("
    HostServicesActions
    ", host_status_class); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    ", host_status_class); + printf("%s\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name), temp_host->name); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + if(temp_host->icon_image != NULL) { + printf("\n"); + printf("
    "); + printf("\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name)); + printf("%s", STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); + printf(""); + printf("\n"); + } + + printf("
    \n"); + printf("
    \n"); + + printf("
    ", host_status_class); + + /* display all services on the host that are part of the hostgroup */ + current_item = 1; + for(temp_member2 = temp_member; temp_member2 != NULL; temp_member2 = temp_member2->next) { + + /* bail out if we've reached the end of the services that are associated with this servicegroup */ + if(strcmp(temp_member2->host_name, temp_host->name)) + break; + + if(current_item > max_grid_width && max_grid_width > 0) { + printf("
    \n"); + current_item = 1; + } + + /* get the status of the service */ + temp_servicestatus = find_servicestatus(temp_member2->host_name, temp_member2->service_description); + if(temp_servicestatus == NULL) + service_status_class = "NULL"; + else if(temp_servicestatus->status == SERVICE_OK) + service_status_class = "OK"; + else if(temp_servicestatus->status == SERVICE_WARNING) + service_status_class = "WARNING"; + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + service_status_class = "UNKNOWN"; + else if(temp_servicestatus->status == SERVICE_CRITICAL) + service_status_class = "CRITICAL"; + else + service_status_class = "PENDING"; + + printf("%s ", url_encode(temp_servicestatus->description), service_status_class, temp_servicestatus->description); + + current_item++; + } + + /* actions */ + printf("
    ", host_status_class); + + /* grab macros */ + grab_host_macros_r(mac, temp_host); + + printf("\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name)); + printf("%s", url_images_path, DETAIL_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extended Information For This Host", "View Extended Information For This Host"); + printf(""); + + if(temp_host->notes_url != NULL) { + printf("", (notes_url_target == NULL) ? "_blank" : notes_url_target); + printf("%s", url_images_path, NOTES_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extra Host Notes", "View Extra Host Notes"); + printf(""); + } + if(temp_host->action_url != NULL) { + printf("", (action_url_target == NULL) ? "blank" : action_url_target); + printf("%s", url_images_path, ACTION_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Perform Extra Host Actions", "Perform Extra Host Actions"); + printf(""); + } + + printf("View Service Details For This Host\n", STATUS_CGI, url_encode(temp_host->name), url_images_path, STATUS_DETAIL_ICON); + +#ifdef USE_STATUSMAP + printf("%s", STATUSMAP_CGI, url_encode(temp_host->name), url_images_path, STATUSMAP_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Locate Host On Map", "Locate Host On Map"); +#endif + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + +/* show an overview of hostgroup(s)... */ +void show_hostgroup_overviews(void) { + hostgroup *temp_hostgroup = NULL; + int current_column; + int user_has_seen_something = FALSE; + int hostgroup_error = FALSE; + + + printf("

    \n"); + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + show_filters(); + + printf("\n"); + + printf("
    Service Overview For "); + if(show_all_hostgroups == TRUE) + printf("All Host Groups"); + else + printf("Host Group '%s'", hostgroup_name); + printf("
    \n"); + + printf("
    "); + + printf("
    \n"); + + printf("

    \n"); + + + /* display status overviews for all hostgroups */ + if(show_all_hostgroups == TRUE) { + + + printf("
    \n"); + printf("\n"); + + current_column = 1; + + /* loop through all hostgroups... */ + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + /* make sure the user is authorized to view this hostgroup */ + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == FALSE) + continue; + + if(current_column == 1) + printf("\n"); + printf("\n"); + if(current_column == overview_columns) + printf("\n"); + + if(current_column < overview_columns) + current_column++; + else + current_column = 1; + } + + if(current_column != 1) { + + for(; current_column <= overview_columns; current_column++) + printf("\n"); + printf("\n"); + } + + printf("
    \n"); + + show_hostgroup_overview(temp_hostgroup); + + user_has_seen_something = TRUE; + + printf("
    \n"); + printf("
    \n"); + } + + /* else display overview for just a specific hostgroup */ + else { + + temp_hostgroup = find_hostgroup(hostgroup_name); + if(temp_hostgroup != NULL) { + + printf("

    \n"); + printf("

    \n"); + printf("
    \n"); + + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == TRUE) { + + show_hostgroup_overview(temp_hostgroup); + + user_has_seen_something = TRUE; + } + + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + } + else { + printf("
    Sorry, but host group '%s' doesn't seem to exist...
    ", hostgroup_name); + hostgroup_error = TRUE; + } + } + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE && hostgroup_error == FALSE) { + + printf("

    \n"); + printf("

    \n"); + + if(hoststatus_list != NULL) { + printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.
    \n"); + } + else { + printf("
    There doesn't appear to be any host status information in the status log...

    \n"); + printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.
    \n"); + } + + printf("
    \n"); + printf("

    \n"); + } + + return; + } + + + +/* shows an overview of a specific hostgroup... */ +void show_hostgroup_overview(hostgroup *hstgrp) { + hostsmember *temp_member = NULL; + host *temp_host = NULL; + hoststatus *temp_hoststatus = NULL; + int odd = 0; + + /* make sure the user is authorized to view this hostgroup */ + if(is_authorized_for_hostgroup(hstgrp, ¤t_authdata) == FALSE) + return; + + printf("
    \n"); + printf("%s", STATUS_CGI, url_encode(hstgrp->group_name), hstgrp->alias); + printf(" (%s)", EXTINFO_CGI, DISPLAY_HOSTGROUP_INFO, url_encode(hstgrp->group_name), hstgrp->group_name); + printf("
    \n"); + + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + /* find all the hosts that belong to the hostgroup */ + for(temp_member = hstgrp->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the host... */ + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + /* find the host status */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + /* make sure we only display hosts of the specified status levels */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* make sure we only display hosts that have the desired properties */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + if(odd) + odd = 0; + else + odd = 1; + + show_servicegroup_hostgroup_member_overview(temp_hoststatus, odd, NULL); + } + + printf("
    HostStatusServicesActions
    \n"); + printf("
    \n"); + + return; + } + + + +/* shows a host status overview... */ +void show_servicegroup_hostgroup_member_overview(hoststatus *hststatus, int odd, void *data) { + char status[MAX_INPUT_BUFFER]; + char *status_bg_class = ""; + char *status_class = ""; + host *temp_host = NULL; + char *processed_string = NULL; + + temp_host = find_host(hststatus->host_name); + + /* grab macros */ + grab_host_macros_r(mac, temp_host); + + if(hststatus->status == HOST_PENDING) { + strncpy(status, "PENDING", sizeof(status)); + status_class = "HOSTPENDING"; + status_bg_class = (odd) ? "Even" : "Odd"; + } + else if(hststatus->status == HOST_UP) { + strncpy(status, "UP", sizeof(status)); + status_class = "HOSTUP"; + status_bg_class = (odd) ? "Even" : "Odd"; + } + else if(hststatus->status == HOST_DOWN) { + strncpy(status, "DOWN", sizeof(status)); + status_class = "HOStdOWN"; + status_bg_class = "HOStdOWN"; + } + else if(hststatus->status == HOST_UNREACHABLE) { + strncpy(status, "UNREACHABLE", sizeof(status)); + status_class = "HOSTUNREACHABLE"; + status_bg_class = "HOSTUNREACHABLE"; + } + + status[sizeof(status) - 1] = '\x0'; + + printf("\n", status_bg_class); + + printf("\n", status_bg_class); + + printf("\n"); + printf("\n", status_bg_class); + printf("\n", status_bg_class, STATUS_CGI, url_encode(hststatus->host_name), temp_host->address, hststatus->host_name); + + if(temp_host->icon_image != NULL) { + printf("\n", status_bg_class); + printf("\n"); + } + printf("\n"); + printf("
    %s", status_bg_class); + printf("", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(hststatus->host_name)); + printf("%s", STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); + printf(""); + printf("
    \n"); + printf("\n"); + + printf("%s\n", status_class, status); + + printf("\n", status_bg_class); + show_servicegroup_hostgroup_member_service_status_totals(hststatus->host_name, data); + printf("\n"); + + printf("", status_bg_class); + printf("View Extended Information For This Host\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(hststatus->host_name), url_images_path, DETAIL_ICON); + if(temp_host->notes_url != NULL) { + printf("", (notes_url_target == NULL) ? "_blank" : notes_url_target); + printf("%s", url_images_path, NOTES_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extra Host Notes", "View Extra Host Notes"); + printf(""); + } + if(temp_host->action_url != NULL) { + printf("", (action_url_target == NULL) ? "_blank" : action_url_target); + printf("%s", url_images_path, ACTION_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Perform Extra Host Actions", "Perform Extra Host Actions"); + printf(""); + } + printf("View Service Details For This Host\n", STATUS_CGI, url_encode(hststatus->host_name), url_images_path, STATUS_DETAIL_ICON); +#ifdef USE_STATUSMAP + printf("%s", STATUSMAP_CGI, url_encode(hststatus->host_name), url_images_path, STATUSMAP_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Locate Host On Map", "Locate Host On Map"); +#endif + printf(""); + + printf("\n"); + + return; + } + + + +void show_servicegroup_hostgroup_member_service_status_totals(char *host_name, void *data) { + int total_ok = 0; + int total_warning = 0; + int total_unknown = 0; + int total_critical = 0; + int total_pending = 0; + servicestatus *temp_servicestatus; + service *temp_service; + servicegroup *temp_servicegroup = NULL; + char temp_buffer[MAX_INPUT_BUFFER]; + + + if(display_type == DISPLAY_SERVICEGROUPS) + temp_servicegroup = (servicegroup *)data; + + /* check all services... */ + for(temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) { + + if(!strcmp(host_name, temp_servicestatus->host_name)) { + + /* make sure the user is authorized to see this service... */ + temp_service = find_service(temp_servicestatus->host_name, temp_servicestatus->description); + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + if(display_type == DISPLAY_SERVICEGROUPS) { + + /* is this service a member of the servicegroup? */ + if(is_service_member_of_servicegroup(temp_servicegroup, temp_service) == FALSE) + continue; + } + + /* make sure we only display services of the specified status levels */ + if(!(service_status_types & temp_servicestatus->status)) + continue; + + /* make sure we only display services that have the desired properties */ + if(passes_service_properties_filter(temp_servicestatus) == FALSE) + continue; + + if(temp_servicestatus->status == SERVICE_CRITICAL) + total_critical++; + else if(temp_servicestatus->status == SERVICE_WARNING) + total_warning++; + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + total_unknown++; + else if(temp_servicestatus->status == SERVICE_OK) + total_ok++; + else if(temp_servicestatus->status == SERVICE_PENDING) + total_pending++; + else + total_ok++; + } + } + + + printf("\n"); + + if(display_type == DISPLAY_SERVICEGROUPS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "servicegroup=%s&style=detail", url_encode(temp_servicegroup->group_name)); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "host=%s", url_encode(host_name)); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + + if(total_ok > 0) + printf("\n", STATUS_CGI, temp_buffer, SERVICE_OK, host_status_types, service_properties, host_properties, total_ok); + if(total_warning > 0) + printf("\n", STATUS_CGI, temp_buffer, SERVICE_WARNING, host_status_types, service_properties, host_properties, total_warning); + if(total_unknown > 0) + printf("\n", STATUS_CGI, temp_buffer, SERVICE_UNKNOWN, host_status_types, service_properties, host_properties, total_unknown); + if(total_critical > 0) + printf("\n", STATUS_CGI, temp_buffer, SERVICE_CRITICAL, host_status_types, service_properties, host_properties, total_critical); + if(total_pending > 0) + printf("\n", STATUS_CGI, temp_buffer, SERVICE_PENDING, host_status_types, service_properties, host_properties, total_pending); + + printf("
    %d OK
    %d WARNING
    %d UNKNOWN
    %d CRITICAL
    %d PENDING
    \n"); + + if((total_ok + total_warning + total_unknown + total_critical + total_pending) == 0) + printf("No matching services"); + + return; + } + + + +/* show a summary of hostgroup(s)... */ +void show_hostgroup_summaries(void) { + hostgroup *temp_hostgroup = NULL; + int user_has_seen_something = FALSE; + int hostgroup_error = FALSE; + int odd = 0; + + + printf("

    \n"); + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + show_filters(); + + printf("\n"); + + printf("
    Status Summary For "); + if(show_all_hostgroups == TRUE) + printf("All Host Groups"); + else + printf("Host Group '%s'", hostgroup_name); + printf("
    \n"); + + printf("
    "); + + printf("
    \n"); + + printf("

    \n"); + + + printf("
    \n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + /* display status summary for all hostgroups */ + if(show_all_hostgroups == TRUE) { + + /* loop through all hostgroups... */ + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + /* make sure the user is authorized to view this hostgroup */ + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == FALSE) + continue; + + if(odd == 0) + odd = 1; + else + odd = 0; + + /* show summary for this hostgroup */ + show_hostgroup_summary(temp_hostgroup, odd); + + user_has_seen_something = TRUE; + } + + } + + /* else just show summary for a specific hostgroup */ + else { + temp_hostgroup = find_hostgroup(hostgroup_name); + if(temp_hostgroup == NULL) + hostgroup_error = TRUE; + else { + show_hostgroup_summary(temp_hostgroup, 1); + user_has_seen_something = TRUE; + } + } + + printf("
    Host GroupHost Status SummaryService Status Summary
    \n"); + printf("
    \n"); + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE && hostgroup_error == FALSE) { + + printf("

    \n"); + + if(hoststatus_list != NULL) { + printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.
    \n"); + } + else { + printf("
    There doesn't appear to be any host status information in the status log...

    \n"); + printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.
    \n"); + } + + printf("

    \n"); + } + + /* we couldn't find the hostgroup */ + else if(hostgroup_error == TRUE) { + printf("

    \n"); + printf("
    Sorry, but hostgroup '%s' doesn't seem to exist...
    \n", hostgroup_name); + printf("

    \n"); + } + + return; + } + + + +/* displays status summary information for a specific hostgroup */ +void show_hostgroup_summary(hostgroup *temp_hostgroup, int odd) { + char *status_bg_class = ""; + + if(odd == 1) + status_bg_class = "Even"; + else + status_bg_class = "Odd"; + + printf("\n", status_bg_class, status_bg_class); + printf("%s ", STATUS_CGI, url_encode(temp_hostgroup->group_name), temp_hostgroup->alias); + printf("(%s)", EXTINFO_CGI, DISPLAY_HOSTGROUP_INFO, url_encode(temp_hostgroup->group_name), temp_hostgroup->group_name); + printf(""); + + printf("", status_bg_class); + show_hostgroup_host_totals_summary(temp_hostgroup); + printf(""); + + printf("", status_bg_class); + show_hostgroup_service_totals_summary(temp_hostgroup); + printf(""); + + printf("\n"); + + return; + } + + + +/* shows host total summary information for a specific hostgroup */ +void show_hostgroup_host_totals_summary(hostgroup *temp_hostgroup) { + hostsmember *temp_member; + int hosts_up = 0; + int hosts_down = 0; + int hosts_unreachable = 0; + int hosts_pending = 0; + int hosts_down_scheduled = 0; + int hosts_down_acknowledged = 0; + int hosts_down_disabled = 0; + int hosts_down_unacknowledged = 0; + int hosts_unreachable_scheduled = 0; + int hosts_unreachable_acknowledged = 0; + int hosts_unreachable_disabled = 0; + int hosts_unreachable_unacknowledged = 0; + hoststatus *temp_hoststatus; + host *temp_host; + int problem = FALSE; + + /* find all the hosts that belong to the hostgroup */ + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the host... */ + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + /* find the host status */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + /* make sure we only display hosts of the specified status levels */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* make sure we only display hosts that have the desired properties */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + problem = TRUE; + + if(temp_hoststatus->status == HOST_UP) + hosts_up++; + + else if(temp_hoststatus->status == HOST_DOWN) { + if(temp_hoststatus->scheduled_downtime_depth > 0) { + hosts_down_scheduled++; + problem = FALSE; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + hosts_down_acknowledged++; + problem = FALSE; + } + if(temp_hoststatus->checks_enabled == FALSE) { + hosts_down_disabled++; + problem = FALSE; + } + if(problem == TRUE) + hosts_down_unacknowledged++; + hosts_down++; + } + + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + if(temp_hoststatus->scheduled_downtime_depth > 0) { + hosts_unreachable_scheduled++; + problem = FALSE; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + hosts_unreachable_acknowledged++; + problem = FALSE; + } + if(temp_hoststatus->checks_enabled == FALSE) { + hosts_unreachable_disabled++; + problem = FALSE; + } + if(problem == TRUE) + hosts_unreachable_unacknowledged++; + hosts_unreachable++; + } + + else + hosts_pending++; + } + + printf("\n"); + + if(hosts_up > 0) { + printf(""); + printf("", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_UP, host_properties, hosts_up); + printf("\n"); + } + + if(hosts_down > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(hosts_unreachable > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(hosts_pending > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_PENDING, host_properties, hosts_pending); + + printf("
    %d UP
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_DOWN, host_properties, hosts_down); + + printf("\n"); + + printf("\n"); + printf("
    %d DOWN :\n"); + + if(hosts_down_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_DOWN, HOST_NO_SCHEDULED_DOWNTIME | HOST_STATE_UNACKNOWLEDGED | HOST_CHECKS_ENABLED, hosts_down_unacknowledged); + + if(hosts_down_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_DOWN, HOST_SCHEDULED_DOWNTIME, hosts_down_scheduled); + + if(hosts_down_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_DOWN, HOST_STATE_ACKNOWLEDGED, hosts_down_acknowledged); + + if(hosts_down_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_DOWN, HOST_CHECKS_DISABLED, hosts_down_disabled); + + printf("
    %d Unhandled
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_UNREACHABLE, host_properties, hosts_unreachable); + + printf("\n"); + + printf("\n"); + printf("
    %d UNREACHABLE :\n"); + + if(hosts_unreachable_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_UNREACHABLE, HOST_NO_SCHEDULED_DOWNTIME | HOST_STATE_UNACKNOWLEDGED | HOST_CHECKS_ENABLED, hosts_unreachable_unacknowledged); + + if(hosts_unreachable_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_UNREACHABLE, HOST_SCHEDULED_DOWNTIME, hosts_unreachable_scheduled); + + if(hosts_unreachable_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_UNREACHABLE, HOST_STATE_ACKNOWLEDGED, hosts_unreachable_acknowledged); + + if(hosts_unreachable_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), HOST_UNREACHABLE, HOST_CHECKS_DISABLED, hosts_unreachable_disabled); + + printf("
    %d Unhandled
    %d Scheduled
    %d Acknowledged
    %d Disabled
    %d PENDING
    \n"); + + if((hosts_up + hosts_down + hosts_unreachable + hosts_pending) == 0) + printf("No matching hosts"); + + return; + } + + + +/* shows service total summary information for a specific hostgroup */ +void show_hostgroup_service_totals_summary(hostgroup *temp_hostgroup) { + int services_ok = 0; + int services_warning = 0; + int services_unknown = 0; + int services_critical = 0; + int services_pending = 0; + int services_warning_host_problem = 0; + int services_warning_scheduled = 0; + int services_warning_acknowledged = 0; + int services_warning_disabled = 0; + int services_warning_unacknowledged = 0; + int services_unknown_host_problem = 0; + int services_unknown_scheduled = 0; + int services_unknown_acknowledged = 0; + int services_unknown_disabled = 0; + int services_unknown_unacknowledged = 0; + int services_critical_host_problem = 0; + int services_critical_scheduled = 0; + int services_critical_acknowledged = 0; + int services_critical_disabled = 0; + int services_critical_unacknowledged = 0; + servicestatus *temp_servicestatus = NULL; + hoststatus *temp_hoststatus = NULL; + host *temp_host = NULL; + int problem = FALSE; + + + /* check all services... */ + for(temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) { + + /* find the host this service is associated with */ + temp_host = find_host(temp_servicestatus->host_name); + if(temp_host == NULL) + continue; + + /* see if this service is associated with a host in the specified hostgroup */ + if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == FALSE) + continue; + + /* find the status of the associated host */ + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus == NULL) + continue; + + /* find the status of the associated host */ + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus == NULL) + continue; + + /* make sure we only display hosts of the specified status levels */ + if(!(host_status_types & temp_hoststatus->status)) + continue; + + /* make sure we only display hosts that have the desired properties */ + if(passes_host_properties_filter(temp_hoststatus) == FALSE) + continue; + + /* make sure we only display services of the specified status levels */ + if(!(service_status_types & temp_servicestatus->status)) + continue; + + /* make sure we only display services that have the desired properties */ + if(passes_service_properties_filter(temp_servicestatus) == FALSE) + continue; + + problem = TRUE; + + if(temp_servicestatus->status == SERVICE_OK) + services_ok++; + + else if(temp_servicestatus->status == SERVICE_WARNING) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_warning_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_warning_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_warning_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_warning_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_warning_unacknowledged++; + services_warning++; + } + + else if(temp_servicestatus->status == SERVICE_UNKNOWN) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_unknown_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_unknown_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_unknown_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_unknown_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_unknown_unacknowledged++; + services_unknown++; + } + + else if(temp_servicestatus->status == SERVICE_CRITICAL) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_critical_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_critical_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_critical_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_critical_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_critical_unacknowledged++; + services_critical++; + } + + else if(temp_servicestatus->status == SERVICE_PENDING) + services_pending++; + } + + + printf("\n"); + + if(services_ok > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_OK, host_status_types, service_properties, host_properties, services_ok); + + if(services_warning > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(services_unknown > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(services_critical > 0) { + printf("\n"); + printf("\n"); + printf("\n"); + } + + if(services_pending > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_PENDING, host_status_types, service_properties, host_properties, services_pending); + + printf("
    %d OK
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_WARNING, host_status_types, service_properties, host_properties, services_warning); + + printf("\n"); + + printf("\n"); + printf("
    %d WARNING :\n"); + + if(services_warning_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_WARNING, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_warning_unacknowledged); + + if(services_warning_host_problem > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_WARNING, HOST_DOWN | HOST_UNREACHABLE, services_warning_host_problem); + + if(services_warning_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_WARNING, SERVICE_SCHEDULED_DOWNTIME, services_warning_scheduled); + + if(services_warning_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_WARNING, SERVICE_STATE_ACKNOWLEDGED, services_warning_acknowledged); + + if(services_warning_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_WARNING, SERVICE_CHECKS_DISABLED, services_warning_disabled); + + printf("
    %d Unhandled
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_UNKNOWN, host_status_types, service_properties, host_properties, services_unknown); + + printf("\n"); + + printf("\n"); + printf("
    %d UNKNOWN :\n"); + + if(services_unknown_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_UNKNOWN, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_unknown_unacknowledged); + + if(services_unknown_host_problem > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_UNKNOWN, HOST_DOWN | HOST_UNREACHABLE, services_unknown_host_problem); + + if(services_unknown_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_UNKNOWN, SERVICE_SCHEDULED_DOWNTIME, services_unknown_scheduled); + + if(services_unknown_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_UNKNOWN, SERVICE_STATE_ACKNOWLEDGED, services_unknown_acknowledged); + + if(services_unknown_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_UNKNOWN, SERVICE_CHECKS_DISABLED, services_unknown_disabled); + + printf("
    %d Unhandled
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("\n"); + + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_CRITICAL, host_status_types, service_properties, host_properties, services_critical); + + printf("\n"); + + printf("\n"); + printf("
    %d CRITICAL :\n"); + + if(services_critical_unacknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_CRITICAL, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_critical_unacknowledged); + + if(services_critical_host_problem > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_CRITICAL, HOST_DOWN | HOST_UNREACHABLE, services_critical_host_problem); + + if(services_critical_scheduled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_CRITICAL, SERVICE_SCHEDULED_DOWNTIME, services_critical_scheduled); + + if(services_critical_acknowledged > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_CRITICAL, SERVICE_STATE_ACKNOWLEDGED, services_critical_acknowledged); + + if(services_critical_disabled > 0) + printf("\n", STATUS_CGI, url_encode(temp_hostgroup->group_name), SERVICE_CRITICAL, SERVICE_CHECKS_DISABLED, services_critical_disabled); + + printf("
    %d Unhandled
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    %d PENDING
    \n"); + + if((services_ok + services_warning + services_unknown + services_critical + services_pending) == 0) + printf("No matching services"); + + return; + } + + + +/* show a grid layout of hostgroup(s)... */ +void show_hostgroup_grids(void) { + hostgroup *temp_hostgroup = NULL; + int user_has_seen_something = FALSE; + int hostgroup_error = FALSE; + int odd = 0; + + + printf("

    \n"); + + printf("\n"); + printf("\n"); + + printf(""); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
    \n"); + + show_filters(); + + printf("\n"); + + printf("
    Status Grid For "); + if(show_all_hostgroups == TRUE) + printf("All Host Groups"); + else + printf("Host Group '%s'", hostgroup_name); + printf("
    \n"); + + printf("
    "); + + printf("
    \n"); + + printf("

    \n"); + + + /* display status grids for all hostgroups */ + if(show_all_hostgroups == TRUE) { + + /* loop through all hostgroups... */ + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + /* make sure the user is authorized to view this hostgroup */ + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == FALSE) + continue; + + if(odd == 0) + odd = 1; + else + odd = 0; + + /* show grid for this hostgroup */ + show_hostgroup_grid(temp_hostgroup); + + user_has_seen_something = TRUE; + } + + } + + /* else just show grid for a specific hostgroup */ + else { + temp_hostgroup = find_hostgroup(hostgroup_name); + if(temp_hostgroup == NULL) + hostgroup_error = TRUE; + else { + show_hostgroup_grid(temp_hostgroup); + user_has_seen_something = TRUE; + } + } + + /* if user couldn't see anything, print out some helpful info... */ + if(user_has_seen_something == FALSE && hostgroup_error == FALSE) { + + printf("

    \n"); + + if(hoststatus_list != NULL) { + printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); + printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); + printf("and check the authorization options in your CGI configuration file.
    \n"); + } + else { + printf("
    There doesn't appear to be any host status information in the status log...

    \n"); + printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.
    \n"); + } + + printf("

    \n"); + } + + /* we couldn't find the hostgroup */ + else if(hostgroup_error == TRUE) { + printf("

    \n"); + printf("
    Sorry, but hostgroup '%s' doesn't seem to exist...
    \n", hostgroup_name); + printf("

    \n"); + } + + return; + } + + +/* displays status grid for a specific hostgroup */ +void show_hostgroup_grid(hostgroup *temp_hostgroup) { + hostsmember *temp_member; + char *status_bg_class = ""; + char *host_status_class = ""; + char *service_status_class = ""; + host *temp_host; + service *temp_service; + hoststatus *temp_hoststatus; + servicestatus *temp_servicestatus; + char *processed_string = NULL; + int odd = 0; + int current_item; + + + printf("

    \n"); + printf("

    \n"); + + printf("
    %s", STATUS_CGI, url_encode(temp_hostgroup->group_name), temp_hostgroup->alias); + printf(" (%s)
    ", EXTINFO_CGI, DISPLAY_HOSTGROUP_INFO, url_encode(temp_hostgroup->group_name), temp_hostgroup->group_name); + + printf("\n"); + printf("\n"); + + /* find all the hosts that belong to the hostgroup */ + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + + /* find the host... */ + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + /* grab macros */ + grab_host_macros_r(mac, temp_host); + + /* find the host status */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + if(odd == 1) { + status_bg_class = "Even"; + odd = 0; + } + else { + status_bg_class = "Odd"; + odd = 1; + } + + printf("\n", status_bg_class); + + /* get the status of the host */ + if(temp_hoststatus->status == HOST_DOWN) + host_status_class = "HOStdOWN"; + else if(temp_hoststatus->status == HOST_UNREACHABLE) + host_status_class = "HOSTUNREACHABLE"; + else + host_status_class = status_bg_class; + + printf("\n"); + + printf("\n"); + + /* actions */ + printf("\n"); + + printf("\n"); + } + + printf("
    HostServicesActions
    ", host_status_class); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    ", host_status_class); + printf("%s\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name), temp_host->name); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + if(temp_host->icon_image != NULL) { + printf("\n"); + printf("
    "); + printf("\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name)); + printf("%s", STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt, (temp_host->icon_image_alt == NULL) ? "" : temp_host->icon_image_alt); + printf(""); + printf("\n"); + } + printf("\n"); + + printf("
    \n"); + printf("
    \n"); + + printf("
    ", host_status_class); + + /* display all services on the host */ + current_item = 1; + for(temp_service = service_list; temp_service; temp_service = temp_service->next) { + + /* skip this service if it's not associate with the host */ + if(strcmp(temp_service->host_name, temp_host->name)) + continue; + + if(current_item > max_grid_width && max_grid_width > 0) { + printf("
    \n"); + current_item = 1; + } + + /* grab macros */ + grab_service_macros_r(mac, temp_service); + + /* get the status of the service */ + temp_servicestatus = find_servicestatus(temp_service->host_name, temp_service->description); + if(temp_servicestatus == NULL) + service_status_class = "NULL"; + else if(temp_servicestatus->status == SERVICE_OK) + service_status_class = "OK"; + else if(temp_servicestatus->status == SERVICE_WARNING) + service_status_class = "WARNING"; + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + service_status_class = "UNKNOWN"; + else if(temp_servicestatus->status == SERVICE_CRITICAL) + service_status_class = "CRITICAL"; + else + service_status_class = "PENDING"; + + printf("%s ", url_encode(temp_servicestatus->description), service_status_class, temp_servicestatus->description); + + current_item++; + } + + printf("
    ", host_status_class); + + printf("\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_host->name)); + printf("%s", url_images_path, DETAIL_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extended Information For This Host", "View Extended Information For This Host"); + printf(""); + + if(temp_host->notes_url != NULL) { + printf("", (notes_url_target == NULL) ? "_blank" : notes_url_target); + printf("%s", url_images_path, NOTES_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "View Extra Host Notes", "View Extra Host Notes"); + printf(""); + } + if(temp_host->action_url != NULL) { + printf("", (action_url_target == NULL) ? "_blank" : action_url_target); + printf("%s", url_images_path, ACTION_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Perform Extra Host Actions", "Perform Extra Host Actions"); + printf(""); + } + + printf("View Service Details For This Host\n", STATUS_CGI, url_encode(temp_host->name), url_images_path, STATUS_DETAIL_ICON); +#ifdef USE_STATUSMAP + printf("%s", STATUSMAP_CGI, url_encode(temp_host->name), url_images_path, STATUSMAP_ICON, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, "Locate Host On Map", "Locate Host On Map"); +#endif + printf("
    \n"); + printf("
    \n"); + printf("

    \n"); + + return; + } + + + + +/******************************************************************/ +/********** SERVICE SORTING & FILTERING FUNCTIONS ***************/ +/******************************************************************/ + + +/* sorts the service list */ +int sort_services(int s_type, int s_option) { + servicesort *new_servicesort; + servicesort *last_servicesort; + servicesort *temp_servicesort; + servicestatus *temp_svcstatus; + + if(s_type == SORT_NONE) + return ERROR; + + if(servicestatus_list == NULL) + return ERROR; + + /* sort all services status entries */ + for(temp_svcstatus = servicestatus_list; temp_svcstatus != NULL; temp_svcstatus = temp_svcstatus->next) { + + /* allocate memory for a new sort structure */ + new_servicesort = (servicesort *)malloc(sizeof(servicesort)); + if(new_servicesort == NULL) + return ERROR; + + new_servicesort->svcstatus = temp_svcstatus; + + last_servicesort = servicesort_list; + for(temp_servicesort = servicesort_list; temp_servicesort != NULL; temp_servicesort = temp_servicesort->next) { + + if(compare_servicesort_entries(s_type, s_option, new_servicesort, temp_servicesort) == TRUE) { + new_servicesort->next = temp_servicesort; + if(temp_servicesort == servicesort_list) + servicesort_list = new_servicesort; + else + last_servicesort->next = new_servicesort; + break; + } + else + last_servicesort = temp_servicesort; + } + + if(servicesort_list == NULL) { + new_servicesort->next = NULL; + servicesort_list = new_servicesort; + } + else if(temp_servicesort == NULL) { + new_servicesort->next = NULL; + last_servicesort->next = new_servicesort; + } + } + + return OK; + } + + +int compare_servicesort_entries(int s_type, int s_option, servicesort *new_servicesort, servicesort *temp_servicesort) { + servicestatus *new_svcstatus; + servicestatus *temp_svcstatus; + time_t nt; + time_t tt; + + new_svcstatus = new_servicesort->svcstatus; + temp_svcstatus = temp_servicesort->svcstatus; + + if(s_type == SORT_ASCENDING) { + + if(s_option == SORT_LASTCHECKTIME) { + if(new_svcstatus->last_check < temp_svcstatus->last_check) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_CURRENTATTEMPT) { + if(new_svcstatus->current_attempt < temp_svcstatus->current_attempt) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICESTATUS) { + if(new_svcstatus->status <= temp_svcstatus->status) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTNAME) { + if(strcasecmp(new_svcstatus->host_name, temp_svcstatus->host_name) < 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICENAME) { + if(strcasecmp(new_svcstatus->description, temp_svcstatus->description) < 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_STATEDURATION) { + if(new_svcstatus->last_state_change == (time_t)0) + nt = (program_start > current_time) ? 0 : (current_time - program_start); + else + nt = (new_svcstatus->last_state_change > current_time) ? 0 : (current_time - new_svcstatus->last_state_change); + if(temp_svcstatus->last_state_change == (time_t)0) + tt = (program_start > current_time) ? 0 : (current_time - program_start); + else + tt = (temp_svcstatus->last_state_change > current_time) ? 0 : (current_time - temp_svcstatus->last_state_change); + if(nt < tt) + return TRUE; + else + return FALSE; + } + } + else { + if(s_option == SORT_LASTCHECKTIME) { + if(new_svcstatus->last_check > temp_svcstatus->last_check) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_CURRENTATTEMPT) { + if(new_svcstatus->current_attempt > temp_svcstatus->current_attempt) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICESTATUS) { + if(new_svcstatus->status > temp_svcstatus->status) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTNAME) { + if(strcasecmp(new_svcstatus->host_name, temp_svcstatus->host_name) > 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_SERVICENAME) { + if(strcasecmp(new_svcstatus->description, temp_svcstatus->description) > 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_STATEDURATION) { + if(new_svcstatus->last_state_change == (time_t)0) + nt = (program_start > current_time) ? 0 : (current_time - program_start); + else + nt = (new_svcstatus->last_state_change > current_time) ? 0 : (current_time - new_svcstatus->last_state_change); + if(temp_svcstatus->last_state_change == (time_t)0) + tt = (program_start > current_time) ? 0 : (current_time - program_start); + else + tt = (temp_svcstatus->last_state_change > current_time) ? 0 : (current_time - temp_svcstatus->last_state_change); + if(nt > tt) + return TRUE; + else + return FALSE; + } + } + + return TRUE; + } + + + +/* sorts the host list */ +int sort_hosts(int s_type, int s_option) { + hostsort *new_hostsort; + hostsort *last_hostsort; + hostsort *temp_hostsort; + hoststatus *temp_hststatus; + + if(s_type == SORT_NONE) + return ERROR; + + if(hoststatus_list == NULL) + return ERROR; + + /* sort all hosts status entries */ + for(temp_hststatus = hoststatus_list; temp_hststatus != NULL; temp_hststatus = temp_hststatus->next) { + + /* allocate memory for a new sort structure */ + new_hostsort = (hostsort *)malloc(sizeof(hostsort)); + if(new_hostsort == NULL) + return ERROR; + + new_hostsort->hststatus = temp_hststatus; + + last_hostsort = hostsort_list; + for(temp_hostsort = hostsort_list; temp_hostsort != NULL; temp_hostsort = temp_hostsort->next) { + + if(compare_hostsort_entries(s_type, s_option, new_hostsort, temp_hostsort) == TRUE) { + new_hostsort->next = temp_hostsort; + if(temp_hostsort == hostsort_list) + hostsort_list = new_hostsort; + else + last_hostsort->next = new_hostsort; + break; + } + else + last_hostsort = temp_hostsort; + } + + if(hostsort_list == NULL) { + new_hostsort->next = NULL; + hostsort_list = new_hostsort; + } + else if(temp_hostsort == NULL) { + new_hostsort->next = NULL; + last_hostsort->next = new_hostsort; + } + } + + return OK; + } + + +int compare_hostsort_entries(int s_type, int s_option, hostsort *new_hostsort, hostsort *temp_hostsort) { + hoststatus *new_hststatus; + hoststatus *temp_hststatus; + time_t nt; + time_t tt; + + new_hststatus = new_hostsort->hststatus; + temp_hststatus = temp_hostsort->hststatus; + + if(s_type == SORT_ASCENDING) { + + if(s_option == SORT_LASTCHECKTIME) { + if(new_hststatus->last_check < temp_hststatus->last_check) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTSTATUS) { + if(new_hststatus->status <= temp_hststatus->status) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTURGENCY) { + if(HOST_URGENCY(new_hststatus->status) <= HOST_URGENCY(temp_hststatus->status)) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTNAME) { + if(strcasecmp(new_hststatus->host_name, temp_hststatus->host_name) < 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_STATEDURATION) { + if(new_hststatus->last_state_change == (time_t)0) + nt = (program_start > current_time) ? 0 : (current_time - program_start); + else + nt = (new_hststatus->last_state_change > current_time) ? 0 : (current_time - new_hststatus->last_state_change); + if(temp_hststatus->last_state_change == (time_t)0) + tt = (program_start > current_time) ? 0 : (current_time - program_start); + else + tt = (temp_hststatus->last_state_change > current_time) ? 0 : (current_time - temp_hststatus->last_state_change); + if(nt < tt) + return TRUE; + else + return FALSE; + } + } + else { + if(s_option == SORT_LASTCHECKTIME) { + if(new_hststatus->last_check > temp_hststatus->last_check) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTSTATUS) { + if(new_hststatus->status > temp_hststatus->status) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTURGENCY) { + if(HOST_URGENCY(new_hststatus->status) > HOST_URGENCY(temp_hststatus->status)) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_HOSTNAME) { + if(strcasecmp(new_hststatus->host_name, temp_hststatus->host_name) > 0) + return TRUE; + else + return FALSE; + } + else if(s_option == SORT_STATEDURATION) { + if(new_hststatus->last_state_change == (time_t)0) + nt = (program_start > current_time) ? 0 : (current_time - program_start); + else + nt = (new_hststatus->last_state_change > current_time) ? 0 : (current_time - new_hststatus->last_state_change); + if(temp_hststatus->last_state_change == (time_t)0) + tt = (program_start > current_time) ? 0 : (current_time - program_start); + else + tt = (temp_hststatus->last_state_change > current_time) ? 0 : (current_time - temp_hststatus->last_state_change); + if(nt > tt) + return TRUE; + else + return FALSE; + } + } + + return TRUE; + } + + + +/* free all memory allocated to the servicesort structures */ +void free_servicesort_list(void) { + servicesort *this_servicesort; + servicesort *next_servicesort; + + /* free memory for the servicesort list */ + for(this_servicesort = servicesort_list; this_servicesort != NULL; this_servicesort = next_servicesort) { + next_servicesort = this_servicesort->next; + free(this_servicesort); + } + + return; + } + + +/* free all memory allocated to the hostsort structures */ +void free_hostsort_list(void) { + hostsort *this_hostsort; + hostsort *next_hostsort; + + /* free memory for the hostsort list */ + for(this_hostsort = hostsort_list; this_hostsort != NULL; this_hostsort = next_hostsort) { + next_hostsort = this_hostsort->next; + free(this_hostsort); + } + + return; + } + + + +/* check host properties filter */ +int passes_host_properties_filter(hoststatus *temp_hoststatus) { + + if((host_properties & HOST_SCHEDULED_DOWNTIME) && temp_hoststatus->scheduled_downtime_depth <= 0) + return FALSE; + + if((host_properties & HOST_NO_SCHEDULED_DOWNTIME) && temp_hoststatus->scheduled_downtime_depth > 0) + return FALSE; + + if((host_properties & HOST_STATE_ACKNOWLEDGED) && temp_hoststatus->problem_has_been_acknowledged == FALSE) + return FALSE; + + if((host_properties & HOST_STATE_UNACKNOWLEDGED) && temp_hoststatus->problem_has_been_acknowledged == TRUE) + return FALSE; + + if((host_properties & HOST_CHECKS_DISABLED) && temp_hoststatus->checks_enabled == TRUE) + return FALSE; + + if((host_properties & HOST_CHECKS_ENABLED) && temp_hoststatus->checks_enabled == FALSE) + return FALSE; + + if((host_properties & HOST_EVENT_HANDLER_DISABLED) && temp_hoststatus->event_handler_enabled == TRUE) + return FALSE; + + if((host_properties & HOST_EVENT_HANDLER_ENABLED) && temp_hoststatus->event_handler_enabled == FALSE) + return FALSE; + + if((host_properties & HOST_FLAP_DETECTION_DISABLED) && temp_hoststatus->flap_detection_enabled == TRUE) + return FALSE; + + if((host_properties & HOST_FLAP_DETECTION_ENABLED) && temp_hoststatus->flap_detection_enabled == FALSE) + return FALSE; + + if((host_properties & HOST_IS_FLAPPING) && temp_hoststatus->is_flapping == FALSE) + return FALSE; + + if((host_properties & HOST_IS_NOT_FLAPPING) && temp_hoststatus->is_flapping == TRUE) + return FALSE; + + if((host_properties & HOST_NOTIFICATIONS_DISABLED) && temp_hoststatus->notifications_enabled == TRUE) + return FALSE; + + if((host_properties & HOST_NOTIFICATIONS_ENABLED) && temp_hoststatus->notifications_enabled == FALSE) + return FALSE; + + if((host_properties & HOST_PASSIVE_CHECKS_DISABLED) && temp_hoststatus->accept_passive_host_checks == TRUE) + return FALSE; + + if((host_properties & HOST_PASSIVE_CHECKS_ENABLED) && temp_hoststatus->accept_passive_host_checks == FALSE) + return FALSE; + + if((host_properties & HOST_PASSIVE_CHECK) && temp_hoststatus->check_type == HOST_CHECK_ACTIVE) + return FALSE; + + if((host_properties & HOST_ACTIVE_CHECK) && temp_hoststatus->check_type == HOST_CHECK_PASSIVE) + return FALSE; + + if((host_properties & HOST_HARD_STATE) && temp_hoststatus->state_type == SOFT_STATE) + return FALSE; + + if((host_properties & HOST_SOFT_STATE) && temp_hoststatus->state_type == HARD_STATE) + return FALSE; + + return TRUE; + } + + + +/* check service properties filter */ +int passes_service_properties_filter(servicestatus *temp_servicestatus) { + + if((service_properties & SERVICE_SCHEDULED_DOWNTIME) && temp_servicestatus->scheduled_downtime_depth <= 0) + return FALSE; + + if((service_properties & SERVICE_NO_SCHEDULED_DOWNTIME) && temp_servicestatus->scheduled_downtime_depth > 0) + return FALSE; + + if((service_properties & SERVICE_STATE_ACKNOWLEDGED) && temp_servicestatus->problem_has_been_acknowledged == FALSE) + return FALSE; + + if((service_properties & SERVICE_STATE_UNACKNOWLEDGED) && temp_servicestatus->problem_has_been_acknowledged == TRUE) + return FALSE; + + if((service_properties & SERVICE_CHECKS_DISABLED) && temp_servicestatus->checks_enabled == TRUE) + return FALSE; + + if((service_properties & SERVICE_CHECKS_ENABLED) && temp_servicestatus->checks_enabled == FALSE) + return FALSE; + + if((service_properties & SERVICE_EVENT_HANDLER_DISABLED) && temp_servicestatus->event_handler_enabled == TRUE) + return FALSE; + + if((service_properties & SERVICE_EVENT_HANDLER_ENABLED) && temp_servicestatus->event_handler_enabled == FALSE) + return FALSE; + + if((service_properties & SERVICE_FLAP_DETECTION_DISABLED) && temp_servicestatus->flap_detection_enabled == TRUE) + return FALSE; + + if((service_properties & SERVICE_FLAP_DETECTION_ENABLED) && temp_servicestatus->flap_detection_enabled == FALSE) + return FALSE; + + if((service_properties & SERVICE_IS_FLAPPING) && temp_servicestatus->is_flapping == FALSE) + return FALSE; + + if((service_properties & SERVICE_IS_NOT_FLAPPING) && temp_servicestatus->is_flapping == TRUE) + return FALSE; + + if((service_properties & SERVICE_NOTIFICATIONS_DISABLED) && temp_servicestatus->notifications_enabled == TRUE) + return FALSE; + + if((service_properties & SERVICE_NOTIFICATIONS_ENABLED) && temp_servicestatus->notifications_enabled == FALSE) + return FALSE; + + if((service_properties & SERVICE_PASSIVE_CHECKS_DISABLED) && temp_servicestatus->accept_passive_service_checks == TRUE) + return FALSE; + + if((service_properties & SERVICE_PASSIVE_CHECKS_ENABLED) && temp_servicestatus->accept_passive_service_checks == FALSE) + return FALSE; + + if((service_properties & SERVICE_PASSIVE_CHECK) && temp_servicestatus->check_type == SERVICE_CHECK_ACTIVE) + return FALSE; + + if((service_properties & SERVICE_ACTIVE_CHECK) && temp_servicestatus->check_type == SERVICE_CHECK_PASSIVE) + return FALSE; + + if((service_properties & SERVICE_HARD_STATE) && temp_servicestatus->state_type == SOFT_STATE) + return FALSE; + + if((service_properties & SERVICE_SOFT_STATE) && temp_servicestatus->state_type == HARD_STATE) + return FALSE; + + return TRUE; + } + + + +/* shows service and host filters in use */ +void show_filters(void) { + int found = 0; + + /* show filters box if necessary */ + if(host_properties != 0L || service_properties != 0L || host_status_types != all_host_status_types || service_status_types != all_service_status_types) { + + printf("\n"); + printf(""); + printf("
    \n"); + printf("\n"); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("\n"); + + + printf(""); + printf(""); + printf(""); + printf(""); + printf("
    Display Filters:
    Host Status Types:"); + if(host_status_types == all_host_status_types) + printf("All"); + else if(host_status_types == all_host_problems) + printf("All problems"); + else { + found = 0; + if(host_status_types & HOST_PENDING) { + printf(" Pending"); + found = 1; + } + if(host_status_types & HOST_UP) { + printf("%s Up", (found == 1) ? " |" : ""); + found = 1; + } + if(host_status_types & HOST_DOWN) { + printf("%s Down", (found == 1) ? " |" : ""); + found = 1; + } + if(host_status_types & HOST_UNREACHABLE) + printf("%s Unreachable", (found == 1) ? " |" : ""); + } + printf("
    Host Properties:"); + if(host_properties == 0) + printf("Any"); + else { + found = 0; + if(host_properties & HOST_SCHEDULED_DOWNTIME) { + printf(" In Scheduled Downtime"); + found = 1; + } + if(host_properties & HOST_NO_SCHEDULED_DOWNTIME) { + printf("%s Not In Scheduled Downtime", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_STATE_ACKNOWLEDGED) { + printf("%s Has Been Acknowledged", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_STATE_UNACKNOWLEDGED) { + printf("%s Has Not Been Acknowledged", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_CHECKS_DISABLED) { + printf("%s Checks Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_CHECKS_ENABLED) { + printf("%s Checks Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_EVENT_HANDLER_DISABLED) { + printf("%s Event Handler Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_EVENT_HANDLER_ENABLED) { + printf("%s Event Handler Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_FLAP_DETECTION_DISABLED) { + printf("%s Flap Detection Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_FLAP_DETECTION_ENABLED) { + printf("%s Flap Detection Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_IS_FLAPPING) { + printf("%s Is Flapping", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_IS_NOT_FLAPPING) { + printf("%s Is Not Flapping", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_NOTIFICATIONS_DISABLED) { + printf("%s Notifications Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_NOTIFICATIONS_ENABLED) { + printf("%s Notifications Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_PASSIVE_CHECKS_DISABLED) { + printf("%s Passive Checks Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_PASSIVE_CHECKS_ENABLED) { + printf("%s Passive Checks Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_PASSIVE_CHECK) { + printf("%s Passive Checks", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_ACTIVE_CHECK) { + printf("%s Active Checks", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_HARD_STATE) { + printf("%s In Hard State", (found == 1) ? " &" : ""); + found = 1; + } + if(host_properties & HOST_SOFT_STATE) { + printf("%s In Soft State", (found == 1) ? " &" : ""); + found = 1; + } + } + printf("
    Service Status Types:"); + if(service_status_types == all_service_status_types) + printf("All"); + else if(service_status_types == all_service_problems) + printf("All Problems"); + else { + found = 0; + if(service_status_types & SERVICE_PENDING) { + printf(" Pending"); + found = 1; + } + if(service_status_types & SERVICE_OK) { + printf("%s Ok", (found == 1) ? " |" : ""); + found = 1; + } + if(service_status_types & SERVICE_UNKNOWN) { + printf("%s Unknown", (found == 1) ? " |" : ""); + found = 1; + } + if(service_status_types & SERVICE_WARNING) { + printf("%s Warning", (found == 1) ? " |" : ""); + found = 1; + } + if(service_status_types & SERVICE_CRITICAL) { + printf("%s Critical", (found == 1) ? " |" : ""); + found = 1; + } + } + printf("
    Service Properties:"); + if(service_properties == 0) + printf("Any"); + else { + found = 0; + if(service_properties & SERVICE_SCHEDULED_DOWNTIME) { + printf(" In Scheduled Downtime"); + found = 1; + } + if(service_properties & SERVICE_NO_SCHEDULED_DOWNTIME) { + printf("%s Not In Scheduled Downtime", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_STATE_ACKNOWLEDGED) { + printf("%s Has Been Acknowledged", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_STATE_UNACKNOWLEDGED) { + printf("%s Has Not Been Acknowledged", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_CHECKS_DISABLED) { + printf("%s Active Checks Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_CHECKS_ENABLED) { + printf("%s Active Checks Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_EVENT_HANDLER_DISABLED) { + printf("%s Event Handler Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_EVENT_HANDLER_ENABLED) { + printf("%s Event Handler Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_FLAP_DETECTION_DISABLED) { + printf("%s Flap Detection Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_FLAP_DETECTION_ENABLED) { + printf("%s Flap Detection Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_IS_FLAPPING) { + printf("%s Is Flapping", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_IS_NOT_FLAPPING) { + printf("%s Is Not Flapping", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_NOTIFICATIONS_DISABLED) { + printf("%s Notifications Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_NOTIFICATIONS_ENABLED) { + printf("%s Notifications Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_PASSIVE_CHECKS_DISABLED) { + printf("%s Passive Checks Disabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_PASSIVE_CHECKS_ENABLED) { + printf("%s Passive Checks Enabled", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_PASSIVE_CHECK) { + printf("%s Passive Checks", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_ACTIVE_CHECK) { + printf("%s Active Checks", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_HARD_STATE) { + printf("%s In Hard State", (found == 1) ? " &" : ""); + found = 1; + } + if(service_properties & SERVICE_SOFT_STATE) { + printf("%s In Soft State", (found == 1) ? " &" : ""); + found = 1; + } + } + printf("
    \n"); + + printf("
    \n"); + } + + return; + } + +void create_pagenumbers(int total_entries, int visible_entries, char *temp_url, int type_service) { + + int pages = 1; + int leftovers = 0; + int tmp_start; + int i; + int next_page; + int previous_page; + + /* do page numbers if applicable */ + if(result_limit > 0 && total_entries > result_limit) { + pages = (total_entries / result_limit); + leftovers = (total_entries % result_limit); + previous_page = (page_start - result_limit) > 0 ? (page_start - result_limit) : 0; + next_page = (page_start + result_limit) > total_entries ? page_start : (page_start + result_limit); + printf("
    \n"); + printf("
    \n"); + printf("<<\n", temp_url, result_limit, url_images_path, FIRST_PAGE_ICON); + printf("<\n", temp_url, previous_page, result_limit, url_images_path, PREVIOUS_PAGE_ICON); + + for(i = 0; i < (pages + 1); i++) { + tmp_start = (i * result_limit); + if(tmp_start == page_start) + printf("
    %i
    \n", (i + 1)); + else + printf(" %i \n", temp_url, tmp_start, result_limit, (i + 1), (i + 1)); + } + + printf(">\n", temp_url, (page_start + result_limit), result_limit, url_images_path, NEXT_PAGE_ICON); + printf(">>\n", temp_url, ((pages)*result_limit), result_limit, url_images_path, LAST_PAGE_ICON); + printf("
    \n"); + if(type_service == TRUE) + printf("
    Results %i - %i of %d Matching Services
    \n
    \n", page_start, ((page_start + result_limit) > total_entries ? total_entries : (page_start + result_limit)), total_entries); + else + printf("
    Results %i - %i of %d Matching Hosts
    \n\n", page_start, ((page_start + result_limit) > total_entries ? total_entries : (page_start + result_limit)), total_entries); + + printf(" \n\n"); + } + else { + if(type_service == TRUE) + printf("
    Results %i - %i of %d Matching Services
    \n\n", 1, total_entries, total_entries); + else + printf("
    Results %i - %i of %d Matching Hosts
    \n\n", 1, total_entries, total_entries); + + } + + /* show total results displayed */ + //printf("
    Results %i - %i of %d Matching Services
    \n\n",page_start,((page_start+result_limit) > total_entries ? total_entries :(page_start+result_limit) ),total_entries ); + + } + +void create_page_limiter(int result_limit, char *temp_url) { + + /* Result Limit Select Box */ + printf("
    \n
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n
    \n"); + //page numbers + + } diff --git a/cgi/statusmap.c b/cgi/statusmap.c new file mode 100644 index 0000000..72f1cf3 --- /dev/null +++ b/cgi/statusmap.c @@ -0,0 +1,2859 @@ +/***************************************************************************** + * + * STATUSMAP.C - Nagios Network Status Map CGI + * + * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 05-19-2008 + * + * Description: + * + * This CGI will create a map of all hosts that are being monitored on your + * network. + * + * 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/macros.h" +#include "../include/statusdata.h" +#include "../include/cgiutils.h" +#include "../include/getcgi.h" +#include "../include/cgiauth.h" + +#include /* Boutell's GD library function */ +#include /* GD library small font definition */ + +static nagios_macros *mac; + +extern int refresh_rate; + +/*#define DEBUG*/ + +#define UNKNOWN_GD2_ICON "unknown.gd2" +#define UNKNOWN_ICON_IMAGE "unknown.gif" +#define NAGIOS_GD2_ICON "nagios.gd2" + +extern char main_config_file[MAX_FILENAME_LENGTH]; +extern char url_html_path[MAX_FILENAME_LENGTH]; +extern char physical_images_path[MAX_FILENAME_LENGTH]; +extern char url_images_path[MAX_FILENAME_LENGTH]; +extern char url_logo_images_path[MAX_FILENAME_LENGTH]; +extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; + +extern host *host_list; +extern hostgroup *hostgroup_list; +extern service *service_list; +extern hoststatus *hoststatus_list; +extern servicestatus *servicestatus_list; + +extern char *statusmap_background_image; + +extern int default_statusmap_layout_method; + +#define DEFAULT_NODE_WIDTH 40 +#define DEFAULT_NODE_HEIGHT 65 + +#define DEFAULT_NODE_VSPACING 15 +#define DEFAULT_NODE_HSPACING 45 + +#define DEFAULT_PROXIMITY_WIDTH 1000 +#define DEFAULT_PROXIMITY_HEIGHT 800 + +#define MINIMUM_PROXIMITY_WIDTH 250 +#define MINIMUM_PROXIMITY_HEIGHT 200 + +#define COORDS_WARNING_WIDTH 650 +#define COORDS_WARNING_HEIGHT 60 + +#define CIRCULAR_DRAWING_RADIUS 100 + +#define CREATE_HTML 0 +#define CREATE_IMAGE 1 + +#define LAYOUT_USER_SUPPLIED 0 +#define LAYOUT_SUBLAYERS 1 +#define LAYOUT_COLLAPSED_TREE 2 +#define LAYOUT_BALANCED_TREE 3 +#define LAYOUT_CIRCULAR 4 +#define LAYOUT_CIRCULAR_MARKUP 5 +#define LAYOUT_CIRCULAR_BALLOON 6 + + +typedef struct layer_struct { + char *layer_name; + struct layer_struct *next; + } layer; + + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + +void display_page_header(void); +void display_map(void); +void calculate_host_coords(void); +void calculate_total_image_bounds(void); +void calculate_canvas_bounds(void); +void calculate_canvas_bounds_from_host(char *); +void calculate_scaling_factor(void); +void find_eligible_hosts(void); +void load_background_image(void); +void draw_background_image(void); +void draw_background_extras(void); +void draw_host_links(void); +void draw_hosts(void); +void draw_host_text(char *, int, int); +void draw_text(char *, int, int, int); +void write_popup_code(void); +void write_host_popup_text(host *); + +int initialize_graphics(void); +gdImagePtr load_image_from_file(char *); +void write_graphics(void); +void cleanup_graphics(void); +void draw_line(int, int, int, int, int); +void draw_dotted_line(int, int, int, int, int); +void draw_dashed_line(int, int, int, int, int); + +int is_host_in_layer_list(host *); +int add_layer(char *); +void free_layer_list(void); +void print_layer_url(int); + +int number_of_host_layer_members(host *, int); +int max_child_host_layer_members(host *); +int host_child_depth_separation(host *, host *); +int max_child_host_drawing_width(host *); +int number_of_host_services(host *); + +void calculate_balanced_tree_coords(host *, int, int); +void calculate_circular_coords(void); +void calculate_circular_layer_coords(host *, double, double, int, int); + +void draw_circular_markup(void); +void draw_circular_layer_markup(host *, double, double, int, int); + + +char physical_logo_images_path[MAX_FILENAME_LENGTH]; + +authdata current_authdata; + +int create_type = CREATE_HTML; + +gdImagePtr unknown_logo_image = NULL; +gdImagePtr logo_image = NULL; +gdImagePtr map_image = NULL; +gdImagePtr background_image = NULL; +int color_white = 0; +int color_black = 0; +int color_red = 0; +int color_lightred = 0; +int color_green = 0; +int color_lightgreen = 0; +int color_blue = 0; +int color_yellow = 0; +int color_orange = 0; +int color_grey = 0; +int color_lightgrey = 0; +int color_transparency_index = 0; +extern int color_transparency_index_r; +extern int color_transparency_index_g; +extern int color_transparency_index_b; + +int show_all_hosts = TRUE; +char *host_name = "all"; + +int embedded = FALSE; +int display_header = TRUE; +int display_popups = TRUE; +int use_links = TRUE; +int use_text = TRUE; +int use_highlights = TRUE; +int user_supplied_canvas = FALSE; +int user_supplied_scaling = FALSE; + +int layout_method = LAYOUT_USER_SUPPLIED; + +int proximity_width = DEFAULT_PROXIMITY_WIDTH; +int proximity_height = DEFAULT_PROXIMITY_HEIGHT; + +int coordinates_were_specified = FALSE; /* were any coordinates specified in extended host information entries? */ + +int scaled_image_width = 0; /* size of the image actually displayed on the screen (after scaling) */ +int scaled_image_height = 0; +int canvas_width = 0; /* actual size of the image (or portion thereof) that we are drawing */ +int canvas_height = 0; +int total_image_width = 0; /* actual size of the image that would be created if we drew all hosts */ +int total_image_height = 0; +int max_image_width = 0; /* max image size the user wants (scaled) */ +int max_image_height = 0; +double scaling_factor = 1.0; /* scaling factor to use */ +double user_scaling_factor = 1.0; /* user-supplied scaling factor */ +int background_image_width = 0; +int background_image_height = 0; + +int canvas_x = 0; /* upper left coords of drawing canvas */ +int canvas_y = 0; + +int bottom_margin = 0; + +int draw_child_links = FALSE; +int draw_parent_links = FALSE; + +int draw_nagios_icon = FALSE; /* should we drawn the Nagios process icon? */ +int nagios_icon_x = 0; /* coords of Nagios icon */ +int nagios_icon_y = 0; + +extern hoststatus *hoststatus_list; + +extern time_t program_start; + +layer *layer_list = NULL; +int exclude_layers = TRUE; +int all_layers = FALSE; + + + + + +int main(int argc, char **argv) { + int result; + + mac = get_global_macros(); + + /* 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); + if(create_type == CREATE_HTML) + cgi_config_file_error(get_cgi_config_location()); + document_footer(); + return ERROR; + } + + /* defaults from CGI config file */ + layout_method = default_statusmap_layout_method; + + /* get the arguments passed in the URL */ + process_cgivars(); + + /* read the main configuration file */ + result = read_main_config_file(main_config_file); + if(result == ERROR) { + document_header(FALSE); + if(create_type == CREATE_HTML) + 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); + if(create_type == CREATE_HTML) + 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); + if(create_type == CREATE_HTML) + status_data_error(); + document_footer(); + free_memory(); + return ERROR; + } + + /* initialize macros */ + init_macros(); + + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + /* display the network map... */ + display_map(); + + document_footer(); + + /* free all allocated memory */ + free_memory(); + free_layer_list(); + + return OK; + } + + + +void document_header(int use_stylesheet) { + char date_time[MAX_DATETIME_LENGTH]; + time_t current_time; + time_t expire_time; + + if(create_type == CREATE_HTML) { + 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, sizeof(date_time), HTTP_DATE_TIME); + printf("Last-Modified: %s\r\n", date_time); + + expire_time = 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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Network Map\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, STATUSMAP_CSS); + } + + /* write JavaScript code for popup window */ + write_popup_code(); + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(STATUSMAP_CGI, SSI_HEADER); + + printf("
    \n"); + } + + else { + printf("Cache-Control: no-store\n"); + printf("Pragma: no-cache\n"); + + time(¤t_time); + get_time_string(¤t_time, date_time, sizeof(date_time), HTTP_DATE_TIME); + printf("Last-Modified: %s\n", date_time); + + expire_time = (time_t)0L; + get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME); + printf("Expires: %s\n", date_time); + + printf("Content-Type: image/png\n\n"); + } + + return; + } + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + if(create_type == CREATE_HTML) { + + /* include user SSI footer */ + include_ssi_files(STATUSMAP_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((host_name = (char *)strdup(variables[x])) == NULL) + host_name = "all"; + else + strip_html_brackets(host_name); + + if(!strcmp(host_name, "all")) + show_all_hosts = TRUE; + else + show_all_hosts = FALSE; + } + + /* we found the image creation option */ + else if(!strcmp(variables[x], "createimage")) { + create_type = CREATE_IMAGE; + } + + /* 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 canvas origin */ + else if(!strcmp(variables[x], "canvas_x")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + canvas_x = atoi(variables[x]); + user_supplied_canvas = TRUE; + } + else if(!strcmp(variables[x], "canvas_y")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + canvas_y = atoi(variables[x]); + user_supplied_canvas = TRUE; + } + + /* we found the canvas size */ + else if(!strcmp(variables[x], "canvas_width")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + canvas_width = atoi(variables[x]); + user_supplied_canvas = TRUE; + } + else if(!strcmp(variables[x], "canvas_height")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + canvas_height = atoi(variables[x]); + user_supplied_canvas = TRUE; + } + else if(!strcmp(variables[x], "proximity_width")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + proximity_width = atoi(variables[x]); + if(proximity_width < 0) + proximity_width = DEFAULT_PROXIMITY_WIDTH; + } + else if(!strcmp(variables[x], "proximity_height")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + proximity_height = atoi(variables[x]); + if(proximity_height < 0) + proximity_height = DEFAULT_PROXIMITY_HEIGHT; + } + + /* we found the scaling factor */ + else if(!strcmp(variables[x], "scaling_factor")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + user_scaling_factor = strtod(variables[x], NULL); + if(user_scaling_factor > 0.0) + user_supplied_scaling = TRUE; + } + + /* we found the max image size */ + else if(!strcmp(variables[x], "max_width")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + max_image_width = atoi(variables[x]); + } + else if(!strcmp(variables[x], "max_height")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + max_image_height = atoi(variables[x]); + } + + /* we found the layout method option */ + else if(!strcmp(variables[x], "layout")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + layout_method = atoi(variables[x]); + } + + /* we found the no links argument*/ + else if(!strcmp(variables[x], "nolinks")) + use_links = FALSE; + + /* we found the no text argument*/ + else if(!strcmp(variables[x], "notext")) + use_text = FALSE; + + /* we found the no highlights argument*/ + else if(!strcmp(variables[x], "nohighlights")) + use_highlights = FALSE; + + /* we found the no popups argument*/ + else if(!strcmp(variables[x], "nopopups")) + display_popups = FALSE; + + /* we found the layer inclusion/exclusion argument */ + else if(!strcmp(variables[x], "layermode")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "include")) + exclude_layers = FALSE; + else + exclude_layers = TRUE; + } + + /* we found the layer argument */ + else if(!strcmp(variables[x], "layer")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + strip_html_brackets(variables[x]); + add_layer(variables[x]); + } + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* top of page */ +void display_page_header(void) { + char temp_buffer[MAX_INPUT_BUFFER]; + int zoom; + int zoom_width, zoom_height; + int zoom_width_granularity = 0; + int zoom_height_granularity = 0; + int current_zoom_granularity = 0; + hostgroup *temp_hostgroup; + layer *temp_layer; + int found = 0; + + + if(create_type != CREATE_HTML) + return; + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + + + /* center column of top row */ + printf("\n"); + + + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + + if(show_all_hosts == TRUE) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Network Map For All Hosts"); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Network Map For Host %s", host_name); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + display_info_table(temp_buffer, TRUE, ¤t_authdata); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + /* print image size and scaling info */ +#ifdef DEBUG + printf("

    \n"); + printf("[ Raw Image Size: %d x %d pixels | Scaling Factor: %1.2lf | Scaled Image Size: %d x %d pixels ]", canvas_width, canvas_height, scaling_factor, (int)(canvas_width * scaling_factor), (int)(canvas_height * scaling_factor)); + printf("

    \n"); + + printf("

    \n"); + printf("[ Canvas_x: %d | Canvas_y: %d | Canvas_width: %d | Canvas_height: %d ]", canvas_x, canvas_y, canvas_width, canvas_height); + printf("

    \n"); +#endif + + /* zoom links */ + if(user_supplied_canvas == FALSE && strcmp(host_name, "all") && display_header == TRUE) { + + printf("

    \n"); + + zoom_width_granularity = ((total_image_width - MINIMUM_PROXIMITY_WIDTH) / 11); + if(zoom_width_granularity == 0) + zoom_width_granularity = 1; + zoom_height_granularity = ((total_image_height - MINIMUM_PROXIMITY_HEIGHT) / 11); + + if(proximity_width <= 0) + current_zoom_granularity = 0; + else + current_zoom_granularity = (total_image_width - proximity_width) / zoom_width_granularity; + if(current_zoom_granularity > 10) + current_zoom_granularity = 10; + + printf("\n"); + printf("\n"); + printf("\n"); + + for(zoom = 0; zoom <= 10; zoom++) { + + zoom_width = total_image_width - (zoom * zoom_width_granularity); + zoom_height = total_image_height - (zoom * zoom_height_granularity); + + printf("\n", url_images_path, (current_zoom_granularity == zoom) ? ZOOM2_ICON : ZOOM1_ICON, zoom, zoom); + } + + printf("\n"); + printf("\n"); + printf("
    Zoom Out  "); + printf("%d  Zoom In
    \n"); + + printf("

    \n"); + } + + printf("
    \n"); + + printf("
    \n", STATUSMAP_CGI); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n", escape_string(host_name)); + printf("\n", layout_method); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + /* + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + */ + + printf("\n", max_image_width); + printf("\n", max_image_height); + printf("\n", proximity_width); + printf("\n", proximity_height); + + printf("\n"); + + printf("\n"); + + /* display context-sensitive help */ + printf("\n"); + + printf("
    \n"); + printf("Layout Method:
    \n"); + printf("\n"); + printf("
    \n"); + printf("Scaling factor:
    \n"); + printf("\n", (user_supplied_scaling == TRUE) ? user_scaling_factor : 0.0); + printf("
    \n"); + printf("Max image width:
    \n"); + printf("\n",max_image_width); + printf("
    \n"); + printf("Max image height:
    \n"); + printf("\n",max_image_height); + printf("
    \n"); + printf("Proximity width:
    \n"); + printf("\n",proximity_width); + printf("
    \n"); + printf("Proximity height:
    \n"); + printf("\n",proximity_height); + printf("
    Drawing Layers:
    \n"); + printf("\n"); + printf("
    Layer mode:
    "); + printf("Include
    \n", (exclude_layers == FALSE) ? "CHECKED" : ""); + printf("Exclude\n", (exclude_layers == TRUE) ? "CHECKED" : ""); + printf("
    \n"); + printf("Suppress popups:
    \n"); + printf("\n", (display_popups == FALSE) ? "CHECKED" : ""); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + display_context_help(CONTEXTHELP_MAP); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + printf("
    \n"); + } + + + return; + } + + + +/* top-level map generation... */ +void display_map(void) { + + load_background_image(); + calculate_host_coords(); + calculate_total_image_bounds(); + calculate_canvas_bounds(); + calculate_scaling_factor(); + find_eligible_hosts(); + + /* display page header */ + display_page_header(); + + initialize_graphics(); + draw_background_image(); + draw_background_extras(); + draw_host_links(); + + if(create_type == CREATE_HTML) + printf("\n"); + + draw_hosts(); + + if(create_type == CREATE_HTML) + printf("\n"); + + write_graphics(); + cleanup_graphics(); + + + /* write the URL location for the image we just generated - the web browser will come and get it... */ + if(create_type == CREATE_HTML) { + printf("

    \n"); + printf("\n", (int)(canvas_width * scaling_factor), (int)(canvas_height * scaling_factor)); + printf("

    \n"); + } + + return; + } + + + +/******************************************************************/ +/********************* CALCULATION FUNCTIONS **********************/ +/******************************************************************/ + +/* calculates host drawing coordinates */ +void calculate_host_coords(void) { + host *this_host; + host *temp_host; + int child_hosts = 0; + int parent_hosts = 0; + int max_layer_width = 1; + int current_child_host = 0; + int current_parent_host = 0; + int center_x = 0; + int offset_x = DEFAULT_NODE_WIDTH / 2; + int offset_y = DEFAULT_NODE_WIDTH / 2; + int current_layer = 0; + int layer_members = 0; + int current_layer_member = 0; + int max_drawing_width = 0; + + + /******************************/ + /***** MANUAL LAYOUT MODE *****/ + /******************************/ + + /* user-supplied coords */ + if(layout_method == LAYOUT_USER_SUPPLIED) { + + /* see which hosts we should draw and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(temp_host->have_2d_coords == TRUE) + temp_host->should_be_drawn = TRUE; + else + temp_host->should_be_drawn = FALSE; + } + + return; + } + + + /*****************************/ + /***** AUTO-LAYOUT MODES *****/ + /*****************************/ + + /***** DEPTH LAYER MODE *****/ + if(layout_method == LAYOUT_SUBLAYERS) { + + /* find the "main" host we're displaying */ + if(show_all_hosts == TRUE) + this_host = NULL; + else + this_host = find_host(host_name); + + /* find total number of immediate parents/children for this host */ + child_hosts = number_of_immediate_child_hosts(this_host); + parent_hosts = number_of_immediate_parent_hosts(this_host); + + if(child_hosts == 0 && parent_hosts == 0) + max_layer_width = 1; + else + max_layer_width = (child_hosts > parent_hosts) ? child_hosts : parent_hosts; + + /* calculate center x coord */ + center_x = (((DEFAULT_NODE_WIDTH * max_layer_width) + (DEFAULT_NODE_HSPACING * (max_layer_width - 1))) / 2) + offset_x; + + /* coords for Nagios icon if necessary */ + if(this_host == NULL || this_host->parent_hosts == NULL) { + nagios_icon_x = center_x; + nagios_icon_y = offset_y; + draw_nagios_icon = TRUE; + } + + /* do we need to draw a link to parent(s)? */ + if(this_host != NULL && is_host_immediate_child_of_host(NULL, this_host) == FALSE) { + draw_parent_links = TRUE; + offset_y += DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + } + + /* see which hosts we should draw and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* this is an immediate parent of the "main" host we're drawing */ + if(is_host_immediate_parent_of_host(this_host, temp_host) == TRUE) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x - (((parent_hosts * DEFAULT_NODE_WIDTH) + ((parent_hosts - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_parent_host * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + temp_host->y_2d = offset_y; + current_parent_host++; + } + + /* this is the "main" host we're drawing */ + else if(this_host == temp_host) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x; + temp_host->y_2d = DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y; + } + + /* this is an immediate child of the "main" host we're drawing */ + else if(is_host_immediate_child_of_host(this_host, temp_host) == TRUE) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x - (((child_hosts * DEFAULT_NODE_WIDTH) + ((child_hosts - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_child_host * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + if(this_host == NULL) + temp_host->y_2d = (DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING) + offset_y; + else + temp_host->y_2d = ((DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING) * 2) + offset_y; + current_child_host++; + if(number_of_immediate_child_hosts(temp_host) > 0) { + bottom_margin = DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + draw_child_links = TRUE; + } + } + + /* else do not draw this host */ + else { + temp_host->should_be_drawn = FALSE; + temp_host->have_2d_coords = FALSE; + } + } + } + + + + /***** COLLAPSED TREE MODE *****/ + else if(layout_method == LAYOUT_COLLAPSED_TREE) { + + /* find the "main" host we're displaying - DO NOT USE THIS (THIS IS THE OLD METHOD) */ + /* + if(show_all_hosts==TRUE) + this_host=NULL; + else + this_host=find_host(host_name); + */ + + /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ + this_host = NULL; + + /* find total number of immediate parents for this host */ + parent_hosts = number_of_immediate_parent_hosts(this_host); + + /* find the max layer width we have... */ + max_layer_width = max_child_host_layer_members(this_host); + if(parent_hosts > max_layer_width) + max_layer_width = parent_hosts; + + /* calculate center x coord */ + center_x = (((DEFAULT_NODE_WIDTH * max_layer_width) + (DEFAULT_NODE_HSPACING * (max_layer_width - 1))) / 2) + offset_x; + + /* coords for Nagios icon if necessary */ + if(this_host == NULL || this_host->parent_hosts == NULL) { + nagios_icon_x = center_x; + nagios_icon_y = offset_y; + draw_nagios_icon = TRUE; + } + + /* do we need to draw a link to parent(s)? */ + if(this_host != NULL && is_host_immediate_child_of_host(NULL, this_host) == FALSE) { + draw_parent_links = TRUE; + offset_y += DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + } + + /* see which hosts we should draw and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* this is an immediate parent of the "main" host we're drawing */ + if(is_host_immediate_parent_of_host(this_host, temp_host) == TRUE) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x - (((parent_hosts * DEFAULT_NODE_WIDTH) + ((parent_hosts - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_parent_host * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + temp_host->y_2d = offset_y; + current_parent_host++; + } + + /* this is the "main" host we're drawing */ + else if(this_host == temp_host) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x; + temp_host->y_2d = DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y; + } + + /* else do not draw this host (we might if its a child - see below, but assume no for now) */ + else { + temp_host->should_be_drawn = FALSE; + temp_host->have_2d_coords = FALSE; + } + } + + + /* TODO: REORDER CHILD LAYER MEMBERS SO THAT WE MINIMIZE LINK CROSSOVERS FROM PARENT HOSTS */ + + /* draw hosts in child "layers" */ + for(current_layer = 1;; current_layer++) { + + /* how many members in this layer? */ + layer_members = number_of_host_layer_members(this_host, current_layer); + + if(layer_members == 0) + break; + + current_layer_member = 0; + + /* see which hosts are members of this layer and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* is this host a member of the current child layer? */ + if(host_child_depth_separation(this_host, temp_host) == current_layer) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x - (((layer_members * DEFAULT_NODE_WIDTH) + ((layer_members - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_layer_member * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + if(this_host == NULL) + temp_host->y_2d = ((DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING) * current_layer) + offset_y; + else + temp_host->y_2d = ((DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING) * (current_layer + 1)) + offset_y; + current_layer_member++; + } + } + } + + } + + + /***** "BALANCED" TREE MODE *****/ + else if(layout_method == LAYOUT_BALANCED_TREE) { + + /* find the "main" host we're displaying - DO NOT USE THIS (THIS IS THE OLD METHOD) */ + /* + if(show_all_hosts==TRUE) + this_host=NULL; + else + this_host=find_host(host_name); + */ + + /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ + this_host = NULL; + + /* find total number of immediate parents for this host */ + parent_hosts = number_of_immediate_parent_hosts(this_host); + + /* find the max drawing width we have... */ + max_drawing_width = max_child_host_drawing_width(this_host); + if(parent_hosts > max_drawing_width) + max_drawing_width = parent_hosts; + + /* calculate center x coord */ + center_x = (((DEFAULT_NODE_WIDTH * max_drawing_width) + (DEFAULT_NODE_HSPACING * (max_drawing_width - 1))) / 2) + offset_x; + + /* coords for Nagios icon if necessary */ + if(this_host == NULL || this_host->parent_hosts == NULL) { + nagios_icon_x = center_x; + nagios_icon_y = offset_y; + draw_nagios_icon = TRUE; + } + + /* do we need to draw a link to parent(s)? */ + if(this_host != NULL && is_host_immediate_child_of_host(NULL, this_host) == FALSE) { + draw_parent_links = TRUE; + offset_y += DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + } + + /* see which hosts we should draw and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* this is an immediate parent of the "main" host we're drawing */ + if(is_host_immediate_parent_of_host(this_host, temp_host) == TRUE) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x - (((parent_hosts * DEFAULT_NODE_WIDTH) + ((parent_hosts - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_parent_host * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + temp_host->y_2d = offset_y; + current_parent_host++; + } + + /* this is the "main" host we're drawing */ + else if(this_host == temp_host) { + temp_host->should_be_drawn = TRUE; + temp_host->have_2d_coords = TRUE; + temp_host->x_2d = center_x; + temp_host->y_2d = DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y; + } + + /* else do not draw this host (we might if its a child - see below, but assume no for now) */ + else { + temp_host->should_be_drawn = FALSE; + temp_host->have_2d_coords = FALSE; + } + } + + /* draw all children hosts */ + calculate_balanced_tree_coords(this_host, center_x, DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y); + + } + + + /***** CIRCULAR LAYOUT MODE *****/ + else if(layout_method == LAYOUT_CIRCULAR || layout_method == LAYOUT_CIRCULAR_MARKUP || layout_method == LAYOUT_CIRCULAR_BALLOON) { + + /* draw process icon */ + nagios_icon_x = 0; + nagios_icon_y = 0; + draw_nagios_icon = TRUE; + + /* calculate coordinates for all hosts */ + calculate_circular_coords(); + } + + return; + } + + + +/* calculates max possible image dimensions */ +void calculate_total_image_bounds(void) { + host *temp_host; + + total_image_width = 0; + total_image_height = 0; + + /* check all extended host information entries... */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* only check entries that have 2-D coords specified */ + if(temp_host->have_2d_coords == FALSE) + continue; + + /* skip hosts we shouldn't be drawing */ + if(temp_host->should_be_drawn == FALSE) + continue; + + if(temp_host->x_2d > total_image_width) + total_image_width = temp_host->x_2d; + if(temp_host->y_2d > total_image_height) + total_image_height = temp_host->y_2d; + + coordinates_were_specified = TRUE; + } + + /* add some space for icon size and overlapping text... */ + if(coordinates_were_specified == TRUE) { + + total_image_width += (DEFAULT_NODE_WIDTH * 2); + total_image_height += DEFAULT_NODE_HEIGHT; + + /* add space for bottom margin if necessary */ + total_image_height += bottom_margin; + } + + /* image size should be at least as large as dimensions of background image */ + if(total_image_width < background_image_width) + total_image_width = background_image_width; + if(total_image_height < background_image_height) + total_image_height = background_image_height; + + /* we didn't find any hosts that had user-supplied coordinates, so we're going to display a warning */ + if(coordinates_were_specified == FALSE) { + coordinates_were_specified = FALSE; + total_image_width = COORDS_WARNING_WIDTH; + total_image_height = COORDS_WARNING_HEIGHT; + } + + return; + } + + +/* calculates canvas coordinates/dimensions */ +void calculate_canvas_bounds(void) { + + if(user_supplied_canvas == FALSE && strcmp(host_name, "all")) + calculate_canvas_bounds_from_host(host_name); + + /* calculate canvas origin (based on total image bounds) */ + if(canvas_x <= 0 || canvas_width > total_image_width) + canvas_x = 0; + if(canvas_y <= 0 || canvas_height > total_image_height) + canvas_y = 0; + + /* calculate canvas dimensions */ + if(canvas_height <= 0) + canvas_height = (total_image_height - canvas_y); + if(canvas_width <= 0) + canvas_width = (total_image_width - canvas_x); + + if(canvas_x + canvas_width > total_image_width) + canvas_width = total_image_width - canvas_x; + if(canvas_y + canvas_height > total_image_height) + canvas_height = total_image_height - canvas_y; + + return; + } + + +/* calculates canvas coordinates/dimensions around a particular host */ +void calculate_canvas_bounds_from_host(char *host_name) { + host *temp_host; + int zoom_width; + int zoom_height; + + /* find the extended host info */ + temp_host = find_host(host_name); + if(temp_host == NULL) + return; + + /* make sure we have 2-D coords */ + if(temp_host->have_2d_coords == FALSE) + return; + + if(max_image_width > 0 && proximity_width > max_image_width) + zoom_width = max_image_width; + else + zoom_width = proximity_width; + if(max_image_height > 0 && proximity_height > max_image_height) + zoom_height = max_image_height; + else + zoom_height = proximity_height; + + canvas_width = zoom_width; + if(canvas_width >= total_image_width) + canvas_x = 0; + else + canvas_x = (temp_host->x_2d - (zoom_width / 2)); + + canvas_height = zoom_height; + if(canvas_height >= total_image_height) + canvas_y = 0; + else + canvas_y = (temp_host->y_2d - (zoom_height / 2)); + + + return; + } + + +/* calculates scaling factor used in image generation */ +void calculate_scaling_factor(void) { + double x_scaling = 1.0; + double y_scaling = 1.0; + + /* calculate horizontal scaling factor */ + if(max_image_width <= 0 || canvas_width <= max_image_width) + x_scaling = 1.0; + else + x_scaling = (double)((double)max_image_width / (double)canvas_width); + + /* calculate vertical scaling factor */ + if(max_image_height <= 0 || canvas_height <= max_image_height) + y_scaling = 1.0; + else + y_scaling = (double)((double)max_image_height / (double)canvas_height); + + /* calculate general scaling factor to use */ + if(x_scaling < y_scaling) + scaling_factor = x_scaling; + else + scaling_factor = y_scaling; + + /*** USER-SUPPLIED SCALING FACTOR ***/ + if(user_supplied_scaling == TRUE) + scaling_factor = user_scaling_factor; + + return; + } + + +/* finds hosts that can be drawn in the canvas area */ +void find_eligible_hosts(void) { + int total_eligible_hosts = 0; + host *temp_host; + + /* check all extended host information entries... */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* only include hosts that have 2-D coords supplied */ + if(temp_host->have_2d_coords == FALSE) + temp_host->should_be_drawn = FALSE; + + /* make sure coords are all positive */ + else if(temp_host->x_2d < 0 || temp_host->y_2d < 0) + temp_host->should_be_drawn = FALSE; + + /* make sure x coordinates fall within canvas bounds */ + else if(temp_host->x_2d < (canvas_x - DEFAULT_NODE_WIDTH) || temp_host->x_2d > (canvas_x + canvas_width)) + temp_host->should_be_drawn = FALSE; + + /* make sure y coordinates fall within canvas bounds */ + else if(temp_host->y_2d < (canvas_y - DEFAULT_NODE_HEIGHT) || temp_host->y_2d > (canvas_y + canvas_height)) + temp_host->should_be_drawn = FALSE; + + /* see if the user is authorized to view the host */ + else if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + temp_host->should_be_drawn = FALSE; + + /* all checks passed, so we can draw the host! */ + else { + temp_host->should_be_drawn = TRUE; + total_eligible_hosts++; + } + } + + return; + } + + + +/******************************************************************/ +/*********************** DRAWING FUNCTIONS ************************/ +/******************************************************************/ + + +/* loads background image from file */ +void load_background_image(void) { + char temp_buffer[MAX_INPUT_BUFFER]; + + /* bail out if we shouldn't be drawing a background image */ + if(layout_method != LAYOUT_USER_SUPPLIED || statusmap_background_image == NULL) + return; + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s%s", physical_images_path, statusmap_background_image); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + + /* read the background image into memory */ + background_image = load_image_from_file(temp_buffer); + + /* grab background image dimensions for calculating total image width later */ + if(background_image != NULL) { + background_image_width = background_image->sx; + background_image_height = background_image->sy; + } + + /* if we are just creating the html, we don't need the image anymore */ + if(create_type == CREATE_HTML && background_image != NULL) + gdImageDestroy(background_image); + + return; + } + + +/* draws background image on drawing canvas */ +void draw_background_image(void) { + + /* bail out if we shouldn't be drawing a background image */ + if(create_type == CREATE_HTML || layout_method != LAYOUT_USER_SUPPLIED || statusmap_background_image == NULL) + return; + + /* bail out if we don't have an image */ + if(background_image == NULL) + return; + + /* copy the background image to the canvas */ + gdImageCopy(map_image, background_image, 0, 0, canvas_x, canvas_y, canvas_width, canvas_height); + + /* free memory for background image, as we don't need it anymore */ + gdImageDestroy(background_image); + + return; + } + + + +/* draws background "extras" */ +void draw_background_extras(void) { + + /* bail out if we shouldn't be here */ + if(create_type == CREATE_HTML) + return; + + /* circular layout stuff... */ + if(layout_method == LAYOUT_CIRCULAR_MARKUP) { + + /* draw colored sections... */ + draw_circular_markup(); + } + + return; + } + + +/* draws host links */ +void draw_host_links(void) { + host *this_host; + host *main_host; + host *parent_host; + hostsmember *temp_hostsmember; + int status_color = color_black; + hoststatus *this_hoststatus; + hoststatus *parent_hoststatus; + int child_in_layer_list = FALSE; + int parent_in_layer_list = FALSE; + int dotted_line = FALSE; + int x = 0; + int y = 0; + + if(create_type == CREATE_HTML) + return; + + if(use_links == FALSE) + return; + + /* find the "main" host we're drawing */ + main_host = find_host(host_name); + if(show_all_hosts == TRUE) + main_host = NULL; + + /* check all extended host information entries... */ + for(this_host = host_list; this_host != NULL; this_host = this_host->next) { + + /* only draw link if user is authorized to view this host */ + if(is_authorized_for_host(this_host, ¤t_authdata) == FALSE) + continue; + + /* this is a "root" host, so draw link to Nagios process icon if using auto-layout mode */ + if(this_host->parent_hosts == NULL && layout_method != LAYOUT_USER_SUPPLIED && draw_nagios_icon == TRUE) { + + x = this_host->x_2d + (DEFAULT_NODE_WIDTH / 2) - canvas_x; + y = this_host->y_2d + (DEFAULT_NODE_WIDTH / 2) - canvas_y; + + draw_line(x, y, nagios_icon_x + (DEFAULT_NODE_WIDTH / 2) - canvas_x, nagios_icon_y + (DEFAULT_NODE_WIDTH / 2) - canvas_y, color_black); + } + + /* this is a child of the main host we're drawing in auto-layout mode... */ + if(layout_method != LAYOUT_USER_SUPPLIED && draw_child_links == TRUE && number_of_immediate_child_hosts(this_host) > 0 && is_host_immediate_child_of_host(main_host, this_host) == TRUE) { + /* determine color to use when drawing links to children */ + this_hoststatus = find_hoststatus(this_host->name); + if(this_hoststatus != NULL) { + if(this_hoststatus->status == HOST_DOWN || this_hoststatus->status == HOST_UNREACHABLE) + status_color = color_red; + else + status_color = color_black; + } + else + status_color = color_black; + + x = this_host->x_2d + (DEFAULT_NODE_WIDTH / 2) - canvas_x; + y = (this_host->y_2d + (DEFAULT_NODE_WIDTH) / 2) - canvas_y; + + draw_dashed_line(x, y, x, y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING, status_color); + + /* draw arrow tips */ + draw_line(x, y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING, x - 5, y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING - 5, color_black); + draw_line(x, y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING, x + 5, y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING - 5, color_black); + } + + /* this is a parent of the main host we're drawing in auto-layout mode... */ + if(layout_method != LAYOUT_USER_SUPPLIED && draw_parent_links == TRUE && is_host_immediate_child_of_host(this_host, main_host) == TRUE) { + + x = this_host->x_2d + (DEFAULT_NODE_WIDTH / 2) - canvas_x; + y = this_host->y_2d + (DEFAULT_NODE_WIDTH / 2) - canvas_y; + + draw_dashed_line(x, y, x, y - DEFAULT_NODE_HEIGHT - DEFAULT_NODE_VSPACING, color_black); + + /* draw arrow tips */ + draw_line(x, y - DEFAULT_NODE_HEIGHT - DEFAULT_NODE_VSPACING, x - 5, y - DEFAULT_NODE_HEIGHT - DEFAULT_NODE_VSPACING + 5, color_black); + draw_line(x, y - DEFAULT_NODE_HEIGHT - DEFAULT_NODE_VSPACING, x + 5, y - DEFAULT_NODE_HEIGHT - DEFAULT_NODE_VSPACING + 5, color_black); + } + + /* draw links to all parent hosts */ + for(temp_hostsmember = this_host->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + + /* find the parent host config entry */ + parent_host = find_host(temp_hostsmember->host_name); + if(parent_host == NULL) + continue; + + /* don't draw the link if we don't have the coords */ + if(parent_host->have_2d_coords == FALSE || this_host->have_2d_coords == FALSE) + continue; + + /* only draw link if user is authorized for this parent host */ + if(is_authorized_for_host(parent_host, ¤t_authdata) == FALSE) + continue; + + /* are the hosts in the layer list? */ + child_in_layer_list = is_host_in_layer_list(this_host); + parent_in_layer_list = is_host_in_layer_list(parent_host); + + /* use dotted or solid line? */ + /* either the child or parent should not be drawn, so use a dotted line */ + if((child_in_layer_list == TRUE && parent_in_layer_list == FALSE) || (child_in_layer_list == FALSE && parent_in_layer_list == TRUE)) + dotted_line = TRUE; + /* both hosts should not be drawn, so use a dotted line */ + else if((child_in_layer_list == FALSE && parent_in_layer_list == FALSE && exclude_layers == FALSE) || (child_in_layer_list == TRUE && parent_in_layer_list == TRUE && exclude_layers == TRUE)) + dotted_line = TRUE; + /* both hosts should be drawn, so use a solid line */ + else + dotted_line = FALSE; + + /* determine color to use when drawing links to parent host */ + parent_hoststatus = find_hoststatus(parent_host->name); + if(parent_hoststatus != NULL) { + if(parent_hoststatus->status == HOST_DOWN || parent_hoststatus->status == HOST_UNREACHABLE) + status_color = color_red; + else + status_color = color_black; + } + else + status_color = color_black; + + /* draw the link */ + if(dotted_line == TRUE) + draw_dotted_line((this_host->x_2d + (DEFAULT_NODE_WIDTH / 2)) - canvas_x, (this_host->y_2d + (DEFAULT_NODE_WIDTH) / 2) - canvas_y, (parent_host->x_2d + (DEFAULT_NODE_WIDTH / 2)) - canvas_x, (parent_host->y_2d + (DEFAULT_NODE_WIDTH / 2)) - canvas_y, status_color); + else + draw_line((this_host->x_2d + (DEFAULT_NODE_WIDTH / 2)) - canvas_x, (this_host->y_2d + (DEFAULT_NODE_WIDTH) / 2) - canvas_y, (parent_host->x_2d + (DEFAULT_NODE_WIDTH / 2)) - canvas_x, (parent_host->y_2d + (DEFAULT_NODE_WIDTH / 2)) - canvas_y, status_color); + } + + } + + return; + } + + + +/* draws hosts */ +void draw_hosts(void) { + host *temp_host; + int x1, x2; + int y1, y2; + int has_image = FALSE; + char image_input_file[MAX_INPUT_BUFFER]; + int current_radius = 0; + int status_color = color_black; + hoststatus *temp_hoststatus; + int in_layer_list = FALSE; + int average_host_services; + int host_services; + double host_services_ratio; + int outer_radius; + int inner_radius; + int time_color = 0; + time_t current_time; + int translated_x; + int translated_y; + + + /* user didn't supply any coordinates for hosts, so display a warning */ + if(coordinates_were_specified == FALSE) { + + if(create_type == CREATE_IMAGE) { + draw_text("You have not supplied any host drawing coordinates, so you cannot use this layout method.", (COORDS_WARNING_WIDTH / 2), 30, color_black); + draw_text("Read the FAQs for more information on specifying drawing coordinates or select a different layout method.", (COORDS_WARNING_WIDTH / 2), 45, color_black); + } + + return; + } + + /* draw Nagios process icon if using auto-layout mode */ + if(layout_method != LAYOUT_USER_SUPPLIED && draw_nagios_icon == TRUE) { + + /* get coords of bounding box */ + x1 = nagios_icon_x - canvas_x; + x2 = x1 + DEFAULT_NODE_WIDTH; + y1 = nagios_icon_y - canvas_y; + y2 = y1 + DEFAULT_NODE_HEIGHT; + + /* get the name of the image file to open for the logo */ + snprintf(image_input_file, sizeof(image_input_file) - 1, "%s%s", physical_logo_images_path, NAGIOS_GD2_ICON); + image_input_file[sizeof(image_input_file) - 1] = '\x0'; + + /* read in the image from file... */ + logo_image = load_image_from_file(image_input_file); + + /* copy the logo image to the canvas image... */ + if(logo_image != NULL) { + gdImageCopy(map_image, logo_image, x1, y1, 0, 0, logo_image->sx, logo_image->sy); + gdImageDestroy(logo_image); + } + + /* if we don't have an image, draw a bounding box */ + else { + draw_line(x1, y1, x1, y1 + DEFAULT_NODE_WIDTH, color_black); + draw_line(x1, y1 + DEFAULT_NODE_WIDTH, x2, y1 + DEFAULT_NODE_WIDTH, color_black); + draw_line(x2, y1 + DEFAULT_NODE_WIDTH, x2, y1, color_black); + draw_line(x2, y1, x1, y1, color_black); + } + + if(create_type == CREATE_IMAGE) + draw_text("Nagios Process", x1 + (DEFAULT_NODE_WIDTH / 2), y1 + DEFAULT_NODE_HEIGHT, color_black); + } + + /* calculate average services per host */ + average_host_services = 4; + + /* draw all hosts... */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* skip hosts that should not be drawn */ + if(temp_host->should_be_drawn == FALSE) + continue; + + /* is this host in the layer inclusion/exclusion list? */ + in_layer_list = is_host_in_layer_list(temp_host); + if((in_layer_list == TRUE && exclude_layers == TRUE) || (in_layer_list == FALSE && exclude_layers == FALSE)) + continue; + + /* get coords of host bounding box */ + x1 = temp_host->x_2d - canvas_x; + x2 = x1 + DEFAULT_NODE_WIDTH; + y1 = temp_host->y_2d - canvas_y; + y2 = y1 + DEFAULT_NODE_HEIGHT; + + if(create_type == CREATE_IMAGE) { + + + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus != NULL) { + if(temp_hoststatus->status == HOST_DOWN) + status_color = color_red; + else if(temp_hoststatus->status == HOST_UNREACHABLE) + status_color = color_red; + else if(temp_hoststatus->status == HOST_UP) + status_color = color_green; + else if(temp_hoststatus->status == HOST_PENDING) + status_color = color_grey; + } + else + status_color = color_black; + + + /* use balloons instead of icons... */ + if(layout_method == LAYOUT_CIRCULAR_BALLOON) { + + /* get the number of services associated with the host */ + host_services = number_of_host_services(temp_host); + + if(average_host_services == 0) + host_services_ratio = 0.0; + else + host_services_ratio = (double)((double)host_services / (double)average_host_services); + + /* calculate size of node */ + if(host_services_ratio >= 2.0) + outer_radius = DEFAULT_NODE_WIDTH; + else if(host_services_ratio >= 1.5) + outer_radius = DEFAULT_NODE_WIDTH * 0.8; + else if(host_services_ratio >= 1.0) + outer_radius = DEFAULT_NODE_WIDTH * 0.6; + else if(host_services_ratio >= 0.5) + outer_radius = DEFAULT_NODE_WIDTH * 0.4; + else + outer_radius = DEFAULT_NODE_WIDTH * 0.2; + + /* calculate width of border */ + if(temp_hoststatus == NULL) + inner_radius = outer_radius; + else if((temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE) && temp_hoststatus->problem_has_been_acknowledged == FALSE) + inner_radius = outer_radius - 3; + else + inner_radius = outer_radius; + + /* fill node with color based on how long its been in this state... */ + gdImageArc(map_image, x1 + (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH / 2), outer_radius, outer_radius, 0, 360, color_blue); + + /* determine fill color */ + time(¤t_time); + if(temp_hoststatus == NULL) + time_color = color_white; + else if(current_time - temp_hoststatus->last_state_change <= 900) + time_color = color_orange; + else if(current_time - temp_hoststatus->last_state_change <= 3600) + time_color = color_yellow; + else + time_color = color_white; + + /* fill node with appropriate time color */ + /* the fill function only works with coordinates that are in bounds of the actual image */ + translated_x = x1 + (DEFAULT_NODE_WIDTH / 2); + translated_y = y1 + (DEFAULT_NODE_WIDTH / 2); + if(translated_x > 0 && translated_y > 0 && translated_x < canvas_width && translated_y < canvas_height) + gdImageFillToBorder(map_image, translated_x, translated_y, color_blue, time_color); + + /* border of node should reflect current state */ + for(current_radius = outer_radius; current_radius >= inner_radius; current_radius--) + gdImageArc(map_image, x1 + (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH / 2), current_radius, current_radius, 0, 360, status_color); + + /* draw circles around the selected host (if there is one) */ + if(!strcmp(host_name, temp_host->name) && use_highlights == TRUE) { + for(current_radius = DEFAULT_NODE_WIDTH * 2; current_radius > 0; current_radius -= 10) + gdImageArc(map_image, x1 + (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH / 2), current_radius, current_radius, 0, 360, status_color); + } + } + + + /* normal method is to use icons for hosts... */ + else { + + /* draw a target around root hosts (hosts with no parents) */ + if(temp_host != NULL && use_highlights == TRUE) { + if(temp_host->parent_hosts == NULL) { + gdImageArc(map_image, x1 + (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH / 2), (DEFAULT_NODE_WIDTH * 2), (DEFAULT_NODE_WIDTH * 2), 0, 360, status_color); + draw_line(x1 - (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH / 2), x1 + (DEFAULT_NODE_WIDTH * 3 / 2), y1 + (DEFAULT_NODE_WIDTH / 2), status_color); + draw_line(x1 + (DEFAULT_NODE_WIDTH / 2), y1 - (DEFAULT_NODE_WIDTH / 2), x1 + (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH * 3 / 2), status_color); + } + } + + /* draw circles around the selected host (if there is one) */ + if(!strcmp(host_name, temp_host->name) && use_highlights == TRUE) { + for(current_radius = DEFAULT_NODE_WIDTH * 2; current_radius > 0; current_radius -= 10) + gdImageArc(map_image, x1 + (DEFAULT_NODE_WIDTH / 2), y1 + (DEFAULT_NODE_WIDTH / 2), current_radius, current_radius, 0, 360, status_color); + } + + + if(temp_host->statusmap_image != NULL) + has_image = TRUE; + else + has_image = FALSE; + + /* load the logo associated with this host */ + if(has_image == TRUE) { + + /* get the name of the image file to open for the logo */ + snprintf(image_input_file, sizeof(image_input_file) - 1, "%s%s", physical_logo_images_path, temp_host->statusmap_image); + image_input_file[sizeof(image_input_file) - 1] = '\x0'; + + /* read in the logo image from file... */ + logo_image = load_image_from_file(image_input_file); + + /* copy the logo image to the canvas image... */ + if(logo_image != NULL) { + gdImageCopy(map_image, logo_image, x1, y1, 0, 0, logo_image->sx, logo_image->sy); + gdImageDestroy(logo_image); + } + else + has_image = FALSE; + } + + /* if the host doesn't have an image associated with it (or the user doesn't have rights to see this host), use the unknown image */ + if(has_image == FALSE) { + + if(unknown_logo_image != NULL) + gdImageCopy(map_image, unknown_logo_image, x1, y1, 0, 0, unknown_logo_image->sx, unknown_logo_image->sy); + + else { + + /* last ditch effort - draw a host bounding box */ + draw_line(x1, y1, x1, y1 + DEFAULT_NODE_WIDTH, color_black); + draw_line(x1, y1 + DEFAULT_NODE_WIDTH, x2, y1 + DEFAULT_NODE_WIDTH, color_black); + draw_line(x2, y1 + DEFAULT_NODE_WIDTH, x2, y1, color_black); + draw_line(x2, y1, x1, y1, color_black); + } + } + } + + + /* draw host name, status, etc. */ + draw_host_text(temp_host->name, x1 + (DEFAULT_NODE_WIDTH / 2), y1 + DEFAULT_NODE_HEIGHT); + } + + /* we're creating HTML image map... */ + else { + printf("name)) + printf("href='%s?host=%s' ", STATUS_CGI, url_encode(temp_host->name)); + else { + printf("href='%s?host=%s&layout=%d&max_width=%d&max_height=%d&proximity_width=%d&proximity_height=%d%s%s%s%s%s", STATUSMAP_CGI, url_encode(temp_host->name), layout_method, max_image_width, max_image_height, proximity_width, proximity_height, (display_header == TRUE) ? "" : "&noheader", (use_links == FALSE) ? "&nolinks" : "", (use_text == FALSE) ? "¬ext" : "", (use_highlights == FALSE) ? "&nohighlights" : "", (display_popups == FALSE) ? "&nopopups" : ""); + if(user_supplied_scaling == TRUE) + printf("&scaling_factor=%2.1f", user_scaling_factor); + print_layer_url(TRUE); + printf("' "); + } + + /* popup text */ + if(display_popups == TRUE) { + + printf("onMouseOver='showPopup(\""); + write_host_popup_text(find_host(temp_host->name)); + printf("\",event)' onMouseOut='hidePopup()'"); + } + + printf(">\n"); + } + + } + + return; + } + + +/* draws text */ +void draw_text(char *buffer, int x, int y, int text_color) { + int string_width = 0; + int string_height = 0; + + /* write the string to the generated image... */ + string_height = gdFontSmall->h; + string_width = gdFontSmall->w * strlen(buffer); + if(layout_method != LAYOUT_CIRCULAR_MARKUP) + gdImageFilledRectangle(map_image, x - (string_width / 2) - 2, y - (2 * string_height), x + (string_width / 2) + 2, y - string_height, color_white); + gdImageString(map_image, gdFontSmall, x - (string_width / 2), y - (2 * string_height), (unsigned char *)buffer, text_color); + + return; + } + + +/* draws host text */ +void draw_host_text(char *name, int x, int y) { + hoststatus *temp_hoststatus; + int status_color = color_black; + char temp_buffer[MAX_INPUT_BUFFER]; + + if(use_text == FALSE) + return; + + strncpy(temp_buffer, name, sizeof(temp_buffer) - 1); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + + /* write the host status string to the generated image... */ + draw_text(temp_buffer, x, y, color_black); + + /* find the status entry for this host */ + temp_hoststatus = find_hoststatus(name); + + /* get the status of the host (pending, up, down, or unreachable) */ + if(temp_hoststatus != NULL) { + + /* draw the status string */ + if(temp_hoststatus->status == HOST_DOWN) { + strncpy(temp_buffer, "Down", sizeof(temp_buffer)); + status_color = color_red; + } + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + strncpy(temp_buffer, "Unreachable", sizeof(temp_buffer)); + status_color = color_red; + } + else if(temp_hoststatus->status == HOST_UP) { + strncpy(temp_buffer, "Up", sizeof(temp_buffer)); + status_color = color_green; + } + else if(temp_hoststatus->status == HOST_PENDING) { + strncpy(temp_buffer, "Pending", sizeof(temp_buffer)); + status_color = color_grey; + } + else { + strncpy(temp_buffer, "Unknown", sizeof(temp_buffer)); + status_color = color_orange; + } + + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + + /* write the host status string to the generated image... */ + draw_text(temp_buffer, x, y + gdFontSmall->h, status_color); + } + + return; + } + + +/* writes popup text for a specific host */ +void write_host_popup_text(host *hst) { + hoststatus *temp_status = NULL; + hostsmember *temp_hostsmember = NULL; + char *processed_string = NULL; + int service_totals; + char date_time[48]; + time_t current_time; + time_t t; + char state_duration[48]; + int days; + int hours; + int minutes; + int seconds; + + if(hst == NULL) { + printf("Host data not found"); + return; + } + + /* find the status entry for this host */ + temp_status = find_hoststatus(hst->name); + if(temp_status == NULL) { + printf("Host status information not found"); + return; + } + + /* grab macros */ + grab_host_macros_r(mac, hst); + + /* strip nasty stuff from plugin output */ + sanitize_plugin_output(temp_status->plugin_output); + + printf(""); + + printf(""); + printf("", (hst->icon_image_alt == NULL) ? "" : html_encode(hst->icon_image_alt, TRUE)); + + printf("", escape_string(hst->name)); + printf("", escape_string(hst->alias)); + printf("", html_encode(hst->address, TRUE)); + printf(""); + printf("", (temp_status->plugin_output == NULL) ? "" : temp_status->plugin_output); + + current_time = time(NULL); + if(temp_status->last_state_change == (time_t)0) + t = current_time - program_start; + else + t = current_time - temp_status->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_status->last_state_change == (time_t)0) ? "+" : ""); + state_duration[sizeof(state_duration) - 1] = '\x0'; + printf("", state_duration); + + get_time_string(&temp_status->last_check, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", (temp_status->last_check == (time_t)0) ? "N/A" : date_time); + get_time_string(&temp_status->last_state_change, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", (temp_status->last_state_change == (time_t)0) ? "N/A" : date_time); + + printf(""); + + printf(""); + + printf("
    icon_image == NULL) + printf("%s", UNKNOWN_ICON_IMAGE); + else { + process_macros_r(mac, hst->icon_image, &processed_string, 0); + printf("%s", processed_string); + free(processed_string); + } + printf("\\\" border=0 width=40 height=40>%s
    Name:%s
    Alias:%s
    Address:%s
    State:"); + + /* get the status of the host (pending, up, down, or unreachable) */ + if(temp_status->status == HOST_DOWN) { + printf("Down"); + if(temp_status->problem_has_been_acknowledged == TRUE) + printf(" (Acknowledged)"); + printf(""); + } + + else if(temp_status->status == HOST_UNREACHABLE) { + printf("Unreachable"); + if(temp_status->problem_has_been_acknowledged == TRUE) + printf(" (Acknowledged)"); + printf(""); + } + + else if(temp_status->status == HOST_UP) + printf("Up"); + + else if(temp_status->status == HOST_PENDING) + printf("Pending"); + + printf("
    Status Information:%s
    State Duration:%s
    Last Status Check:%s
    Last State Change:%s
    Parent Host(s):"); + if(hst->parent_hosts == NULL) + printf("None (This is a root host)"); + else { + for(temp_hostsmember = hst->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) + printf("%s%s", (temp_hostsmember == hst->parent_hosts) ? "" : ", ", html_encode(temp_hostsmember->host_name, TRUE)); + } + printf("
    Immediate Child Hosts:"); + printf("%d", number_of_immediate_child_hosts(hst)); + printf("
    "); + + printf("
    Services:
    "); + + service_totals = get_servicestatus_count(hst->name, SERVICE_OK); + if(service_totals > 0) + printf("- %d ok
    ", service_totals); + service_totals = get_servicestatus_count(hst->name, SERVICE_CRITICAL); + if(service_totals > 0) + printf("- %d critical
    ", service_totals); + service_totals = get_servicestatus_count(hst->name, SERVICE_WARNING); + if(service_totals > 0) + printf("- %d warning
    ", service_totals); + service_totals = get_servicestatus_count(hst->name, SERVICE_UNKNOWN); + if(service_totals > 0) + printf("- %d unknown
    ", service_totals); + service_totals = get_servicestatus_count(hst->name, SERVICE_PENDING); + if(service_totals > 0) + printf("- %d pending
    ", service_totals); + + return; + } + + + +/* draws a solid line */ +void draw_line(int x1, int y1, int x2, int y2, int color) { + + if(create_type == CREATE_HTML) + return; + + gdImageLine(map_image, x1, y1, x2, y2, color); + + return; + } + + +/* draws a dotted line */ +void draw_dotted_line(int x1, int y1, int x2, int y2, int color) { + int styleDotted[12]; + + styleDotted[0] = color; + styleDotted[1] = gdTransparent; + styleDotted[2] = gdTransparent; + styleDotted[3] = gdTransparent; + styleDotted[4] = gdTransparent; + styleDotted[5] = gdTransparent; + styleDotted[6] = color; + styleDotted[7] = gdTransparent; + styleDotted[8] = gdTransparent; + styleDotted[9] = gdTransparent; + styleDotted[10] = gdTransparent; + styleDotted[11] = gdTransparent; + + /* sets current style to a dashed line */ + gdImageSetStyle(map_image, styleDotted, 12); + + /* draws a line (dotted) */ + gdImageLine(map_image, x1, y1, x2, y2, gdStyled); + + return; + } + +/* draws a dashed line */ +void draw_dashed_line(int x1, int y1, int x2, int y2, int color) { + int styleDashed[12]; + + styleDashed[0] = color; + styleDashed[1] = color; + styleDashed[2] = color; + styleDashed[3] = color; + styleDashed[4] = gdTransparent; + styleDashed[5] = gdTransparent; + styleDashed[6] = color; + styleDashed[7] = color; + styleDashed[8] = color; + styleDashed[9] = color; + styleDashed[10] = gdTransparent; + styleDashed[11] = gdTransparent; + + /* sets current style to a dashed line */ + gdImageSetStyle(map_image, styleDashed, 12); + + /* draws a line (dashed) */ + gdImageLine(map_image, x1, y1, x2, y2, gdStyled); + + return; + } + + + +/******************************************************************/ +/*********************** GRAPHICS FUNCTIONS ***********************/ +/******************************************************************/ + +/* initialize graphics */ +int initialize_graphics(void) { + char image_input_file[MAX_INPUT_BUFFER]; + + if(create_type == CREATE_HTML) + return ERROR; + + /* allocate buffer for storing image */ +#ifndef HAVE_GDIMAGECREATETRUECOLOR + map_image = gdImageCreate(canvas_width, canvas_height); +#else + map_image = gdImageCreateTrueColor(canvas_width, canvas_height); +#endif + if(map_image == NULL) + return ERROR; + + /* allocate colors used for drawing */ + color_white = gdImageColorAllocate(map_image, 255, 255, 255); + color_black = gdImageColorAllocate(map_image, 0, 0, 0); + color_grey = gdImageColorAllocate(map_image, 128, 128, 128); + color_lightgrey = gdImageColorAllocate(map_image, 210, 210, 210); + color_red = gdImageColorAllocate(map_image, 255, 0, 0); + color_lightred = gdImageColorAllocate(map_image, 215, 175, 175); + color_green = gdImageColorAllocate(map_image, 0, 175, 0); + color_lightgreen = gdImageColorAllocate(map_image, 210, 255, 215); + color_blue = gdImageColorAllocate(map_image, 0, 0, 255); + color_yellow = gdImageColorAllocate(map_image, 255, 255, 0); + color_orange = gdImageColorAllocate(map_image, 255, 100, 25); + color_transparency_index = gdImageColorAllocate(map_image, color_transparency_index_r, color_transparency_index_g, color_transparency_index_b); + + /* set transparency index */ +#ifndef HAVE_GDIMAGECREATETRUECOLOR + gdImageColorTransparent(map_image, color_white); +#else + gdImageColorTransparent(map_image, color_transparency_index); + + /* set background */ + gdImageFill(map_image, 0, 0, color_transparency_index); +#endif + + /* make sure the graphic is interlaced */ + gdImageInterlace(map_image, 1); + + /* get the path where we will be reading logo images from (GD2 format)... */ + snprintf(physical_logo_images_path, sizeof(physical_logo_images_path) - 1, "%slogos/", physical_images_path); + physical_logo_images_path[sizeof(physical_logo_images_path) - 1] = '\x0'; + + /* load the unknown icon to use for hosts that don't have pretty images associated with them... */ + snprintf(image_input_file, sizeof(image_input_file) - 1, "%s%s", physical_logo_images_path, UNKNOWN_GD2_ICON); + image_input_file[sizeof(image_input_file) - 1] = '\x0'; + unknown_logo_image = load_image_from_file(image_input_file); + + return OK; + } + + + +/* loads a graphic image (GD2, JPG or PNG) from file into memory */ +gdImagePtr load_image_from_file(char *filename) { + FILE *fp; + gdImagePtr im = NULL; + char *ext; + + /* make sure we were passed a file name */ + if(filename == NULL) + return NULL; + + /* find the file extension */ + if((ext = rindex(filename, '.')) == NULL) + return NULL; + + /* open the file for reading (binary mode) */ + fp = fopen(filename, "rb"); + if(fp == NULL) + return NULL; + + /* attempt to read files in various formats */ + if(!strcasecmp(ext, ".png")) + im = gdImageCreateFromPng(fp); + else if(!strcasecmp(ext, ".jpg") || !strcasecmp(ext, ".jpeg")) + im = gdImageCreateFromJpeg(fp); + else if(!strcasecmp(ext, ".xbm")) + im = gdImageCreateFromXbm(fp); + else if(!strcasecmp(ext, ".gd2")) + im = gdImageCreateFromGd2(fp); + else if(!strcasecmp(ext, ".gd")) + im = gdImageCreateFromGd(fp); + + /* fall back to GD2 image format */ + else + im = gdImageCreateFromGd2(fp); + + /* close the file */ + fclose(fp); + + return im; + } + + + +/* draw graphics */ +void write_graphics(void) { + FILE *image_output_file = NULL; + + if(create_type == CREATE_HTML) + return; + + /* use STDOUT for writing the image data... */ + image_output_file = stdout; + + /* write the image out in PNG format */ + gdImagePng(map_image, image_output_file); + + /* or we could write the image out in JPG format... */ + /*gdImageJpeg(map_image,image_output_file,99);*/ + + return; + } + + +/* cleanup graphics resources */ +void cleanup_graphics(void) { + + if(create_type == CREATE_HTML) + return; + + /* free memory allocated to image */ + gdImageDestroy(map_image); + + return; + } + + + + +/******************************************************************/ +/************************* MISC FUNCTIONS *************************/ +/******************************************************************/ + + +/* write JavaScript code an layer for popup window */ +void write_popup_code(void) { + char *border_color = "#000000"; + char *background_color = "#ffffcc"; + int border = 1; + int padding = 3; + int x_offset = 3; + int y_offset = 3; + + printf("\n"); + + return; + } + + + +/* adds a layer to the list in memory */ +int add_layer(char *group_name) { + layer *new_layer; + + if(group_name == NULL) + return ERROR; + + /* allocate memory for a new layer */ + new_layer = (layer *)malloc(sizeof(layer)); + if(new_layer == NULL) + return ERROR; + + new_layer->layer_name = (char *)malloc(strlen(group_name) + 1); + if(new_layer->layer_name == NULL) { + free(new_layer); + return ERROR; + } + + strcpy(new_layer->layer_name, group_name); + + /* add new layer to head of layer list */ + new_layer->next = layer_list; + layer_list = new_layer; + + return OK; + } + + + +/* frees memory allocated to the layer list */ +void free_layer_list(void) { + layer *this_layer; + layer *next_layer; + + return; + + for(this_layer = layer_list; layer_list != NULL; this_layer = next_layer) { + next_layer = this_layer->next; + free(this_layer->layer_name); + free(this_layer); + } + + return; + } + + +/* checks to see if a host is in the layer list */ +int is_host_in_layer_list(host *hst) { + hostgroup *temp_hostgroup; + layer *temp_layer; + + if(hst == NULL) + return FALSE; + + /* check each layer... */ + for(temp_layer = layer_list; temp_layer != NULL; temp_layer = temp_layer->next) { + + /* find the hostgroup */ + temp_hostgroup = find_hostgroup(temp_layer->layer_name); + if(temp_hostgroup == NULL) + continue; + + /* is the requested host a member of the hostgroup/layer? */ + if(is_host_member_of_hostgroup(temp_hostgroup, hst) == TRUE) + return TRUE; + } + + return FALSE; + } + + +/* print layer url info */ +void print_layer_url(int get_method) { + layer *temp_layer; + + for(temp_layer = layer_list; temp_layer != NULL; temp_layer = temp_layer->next) { + if(get_method == TRUE) + printf("&layer=%s", escape_string(temp_layer->layer_name)); + else + printf("\n", escape_string(temp_layer->layer_name)); + } + + if(get_method == TRUE) + printf("&layermode=%s", (exclude_layers == TRUE) ? "exclude" : "include"); + else + printf("\n", (exclude_layers == TRUE) ? "exclude" : "include"); + + return; + } + + + + +/******************************************************************/ +/************************ UTILITY FUNCTIONS ***********************/ +/******************************************************************/ + +/* calculates how many "layers" separate parent and child - used by collapsed tree layout method */ +int host_child_depth_separation(host *parent, host *child) { + int this_depth = 0; + int min_depth = 0; + int have_min_depth = FALSE; + host *temp_host; + + if(child == NULL) + return -1; + + if(parent == child) + return 0; + + if(is_host_immediate_child_of_host(parent, child) == TRUE) + return 1; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + this_depth = host_child_depth_separation(temp_host, child); + + if(this_depth >= 0 && (have_min_depth == FALSE || (have_min_depth == TRUE && (this_depth < min_depth)))) { + have_min_depth = TRUE; + min_depth = this_depth; + } + } + } + + if(have_min_depth == FALSE) + return -1; + else + return min_depth + 1; + } + + + +/* calculates how many hosts reside on a specific "layer" - used by collapsed tree layout method */ +int number_of_host_layer_members(host *parent, int layer) { + int current_layer; + int layer_members = 0; + host *temp_host; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + current_layer = host_child_depth_separation(parent, temp_host); + + if(current_layer == layer) + layer_members++; + } + + return layer_members; + } + + + +/* calculate max number of members on all "layers" beneath and including parent host - used by collapsed tree layout method */ +int max_child_host_layer_members(host *parent) { + int current_layer; + int max_members = 1; + int current_members = 0; + + for(current_layer = 1;; current_layer++) { + + current_members = number_of_host_layer_members(parent, current_layer); + + if(current_members <= 0) + break; + + if(current_members > max_members) + max_members = current_members; + } + + return max_members; + } + + + +/* calculate max drawing width for host and children - used by balanced tree layout method */ +int max_child_host_drawing_width(host *parent) { + host *temp_host; + int child_width = 0; + + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) + child_width += max_child_host_drawing_width(temp_host); + } + + /* no children, so set width to 1 for this host */ + if(child_width == 0) + return 1; + + else + return child_width; + } + + + +/* calculates number of services associated with a particular service */ +int number_of_host_services(host *hst) { + service *temp_service; + int total_services = 0; + + if(hst == NULL) + return 0; + + /* check all the 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; + } + + + +/******************************************************************/ +/***************** COORDINATE CALCULATION FUNCTIONS ***************/ +/******************************************************************/ + +/* calculates coords of a host's children - used by balanced tree layout method */ +void calculate_balanced_tree_coords(host *parent, int x, int y) { + int parent_drawing_width; + int start_drawing_x; + int current_drawing_x; + int this_drawing_width; + host *temp_host; + + /* calculate total drawing width of parent host */ + parent_drawing_width = max_child_host_drawing_width(parent); + + /* calculate starting x coord */ + start_drawing_x = x - (((DEFAULT_NODE_WIDTH * parent_drawing_width) + (DEFAULT_NODE_HSPACING * (parent_drawing_width - 1))) / 2); + current_drawing_x = start_drawing_x; + + + /* calculate coords for children */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + /* get drawing width of child host */ + this_drawing_width = max_child_host_drawing_width(temp_host); + + temp_host->x_2d = current_drawing_x + (((DEFAULT_NODE_WIDTH * this_drawing_width) + (DEFAULT_NODE_HSPACING * (this_drawing_width - 1))) / 2); + temp_host->y_2d = y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + temp_host->have_2d_coords = TRUE; + temp_host->should_be_drawn = TRUE; + + current_drawing_x += (this_drawing_width * DEFAULT_NODE_WIDTH) + ((this_drawing_width - 1) * DEFAULT_NODE_HSPACING) + DEFAULT_NODE_HSPACING; + + /* recurse into child host ... */ + calculate_balanced_tree_coords(temp_host, temp_host->x_2d, temp_host->y_2d); + } + + } + + return; + } + + +/* calculate coords of all hosts in circular layout method */ +void calculate_circular_coords(void) { + int min_x = 0; + int min_y = 0; + int have_min_x = FALSE; + int have_min_y = FALSE; + host *temp_host; + + /* calculate all host coords, starting with first layer */ + calculate_circular_layer_coords(NULL, 0.0, 360.0, 1, CIRCULAR_DRAWING_RADIUS); + + /* adjust all calculated coords so none are negative in x or y axis... */ + + /* calculate min x, y coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(have_min_x == FALSE || temp_host->x_2d < min_x) { + have_min_x = TRUE; + min_x = temp_host->x_2d; + } + if(have_min_y == FALSE || temp_host->y_2d < min_y) { + have_min_y = TRUE; + min_y = temp_host->y_2d; + } + } + + /* offset all drawing coords by the min x,y coords we found */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(min_x < 0) + temp_host->x_2d -= min_x; + if(min_y < 0) + temp_host->y_2d -= min_y; + } + + if(min_x < 0) + nagios_icon_x -= min_x; + if(min_y < 0) + nagios_icon_y -= min_y; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + temp_host->x_2d += (DEFAULT_NODE_WIDTH / 2); + temp_host->y_2d += (DEFAULT_NODE_HEIGHT / 2); + } + nagios_icon_x += (DEFAULT_NODE_WIDTH / 2); + nagios_icon_y += (DEFAULT_NODE_HEIGHT / 2); + + return; + } + + +/* calculates coords of all hosts in a particular "layer" in circular layout method */ +void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius) { + int parent_drawing_width = 0; + int this_drawing_width = 0; + int immediate_children = 0; + double current_drawing_angle = 0.0; + double this_drawing_angle = 0.0; + double available_angle = 0.0; + double clipped_available_angle = 0.0; + double average_child_angle = 0.0; + double x_coord = 0.0; + double y_coord = 0.0; + host *temp_host; + + + /* get the total number of immediate children to this host */ + immediate_children = number_of_immediate_child_hosts(parent); + + /* bail out if we're done */ + if(immediate_children == 0) + return; + + /* calculate total drawing "width" of parent host */ + parent_drawing_width = max_child_host_drawing_width(parent); + + /* calculate average angle given to each child host */ + average_child_angle = (double)(useable_angle / (double)immediate_children); + + /* calculate initial drawing angle */ + current_drawing_angle = start_angle; + + + /* calculate coords for children */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + /* get drawing width of child host */ + this_drawing_width = max_child_host_drawing_width(temp_host); + + /* calculate angle this host gets for drawing */ + available_angle = useable_angle * ((double)this_drawing_width / (double)parent_drawing_width); + + /* clip available angle if necessary */ + /* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */ + clipped_available_angle = 360.0 / layer; + if(available_angle < clipped_available_angle) + clipped_available_angle = available_angle; + + /* calculate the exact angle at which we should draw this child */ + this_drawing_angle = current_drawing_angle + (available_angle / 2.0); + + /* compensate for angle overflow */ + while(this_drawing_angle >= 360.0) + this_drawing_angle -= 360.0; + while(this_drawing_angle < 0.0) + this_drawing_angle += 360.0; + + /* calculate drawing coords of this host using good ol' geometry... */ + x_coord = -(sin(-this_drawing_angle * (M_PI / 180.0)) * radius); + y_coord = -(sin((90 + this_drawing_angle) * (M_PI / 180.0)) * radius); + + temp_host->x_2d = (int)x_coord; + temp_host->y_2d = (int)y_coord; + temp_host->have_2d_coords = TRUE; + temp_host->should_be_drawn = TRUE; + + /* recurse into child host ... */ + calculate_circular_layer_coords(temp_host, current_drawing_angle + ((available_angle - clipped_available_angle) / 2), clipped_available_angle, layer + 1, radius + CIRCULAR_DRAWING_RADIUS); + + /* increment current drawing angle */ + current_drawing_angle += available_angle; + } + } + + return; + } + + + +/* draws background "extras" for all hosts in circular markup layout */ +void draw_circular_markup(void) { + + /* calculate all host sections, starting with first layer */ + draw_circular_layer_markup(NULL, 0.0, 360.0, 1, CIRCULAR_DRAWING_RADIUS); + + return; + } + + +/* draws background "extras" for all hosts in a particular "layer" in circular markup layout */ +void draw_circular_layer_markup(host *parent, double start_angle, double useable_angle, int layer, int radius) { + int parent_drawing_width = 0; + int this_drawing_width = 0; + int immediate_children = 0; + double current_drawing_angle = 0.0; + double available_angle = 0.0; + double clipped_available_angle = 0.0; + double average_child_angle = 0.0; + double x_coord[4] = {0.0, 0.0, 0.0, 0.0}; + double y_coord[4] = {0.0, 0.0, 0.0, 0.0}; + hoststatus *temp_hoststatus; + host *temp_host; + int x_offset = 0; + int y_offset = 0; + int center_x = 0; + int center_y = 0; + int bgcolor = 0; + double arc_start_angle = 0.0; + double arc_end_angle = 0.0; + int translated_x = 0; + int translated_y = 0; + + /* get the total number of immediate children to this host */ + immediate_children = number_of_immediate_child_hosts(parent); + + /* bail out if we're done */ + if(immediate_children == 0) + return; + + /* calculate total drawing "width" of parent host */ + parent_drawing_width = max_child_host_drawing_width(parent); + + /* calculate average angle given to each child host */ + average_child_angle = (double)(useable_angle / (double)immediate_children); + + /* calculate initial drawing angle */ + current_drawing_angle = start_angle; + + /* calculate coords for children */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + /* get drawing width of child host */ + this_drawing_width = max_child_host_drawing_width(temp_host); + + /* calculate angle this host gets for drawing */ + available_angle = useable_angle * ((double)this_drawing_width / (double)parent_drawing_width); + + /* clip available angle if necessary */ + /* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */ + clipped_available_angle = 360.0 / layer; + if(available_angle < clipped_available_angle) + clipped_available_angle = available_angle; + + /* calculate drawing coords of "leftmost" divider using good ol' geometry... */ + x_coord[0] = -(sin(-current_drawing_angle * (M_PI / 180.0)) * (radius - (CIRCULAR_DRAWING_RADIUS / 2))); + y_coord[0] = -(sin((90 + current_drawing_angle) * (M_PI / 180.0)) * (radius - (CIRCULAR_DRAWING_RADIUS / 2))); + x_coord[1] = -(sin(-current_drawing_angle * (M_PI / 180.0)) * (radius + (CIRCULAR_DRAWING_RADIUS / 2))); + y_coord[1] = -(sin((90 + current_drawing_angle) * (M_PI / 180.0)) * (radius + (CIRCULAR_DRAWING_RADIUS / 2))); + + /* calculate drawing coords of "rightmost" divider using good ol' geometry... */ + x_coord[2] = -(sin((-(current_drawing_angle + available_angle)) * (M_PI / 180.0)) * (radius - (CIRCULAR_DRAWING_RADIUS / 2))); + y_coord[2] = -(sin((90 + current_drawing_angle + available_angle) * (M_PI / 180.0)) * (radius - (CIRCULAR_DRAWING_RADIUS / 2))); + x_coord[3] = -(sin((-(current_drawing_angle + available_angle)) * (M_PI / 180.0)) * (radius + (CIRCULAR_DRAWING_RADIUS / 2))); + y_coord[3] = -(sin((90 + current_drawing_angle + available_angle) * (M_PI / 180.0)) * (radius + (CIRCULAR_DRAWING_RADIUS / 2))); + + + x_offset = nagios_icon_x + (DEFAULT_NODE_WIDTH / 2) - canvas_x; + y_offset = nagios_icon_y + (DEFAULT_NODE_HEIGHT / 2) - canvas_y; + + /* draw "slice" dividers */ + if(immediate_children > 1 || layer > 1) { + + /* draw "leftmost" divider */ + gdImageLine(map_image, (int)x_coord[0] + x_offset, (int)y_coord[0] + y_offset, (int)x_coord[1] + x_offset, (int)y_coord[1] + y_offset, color_lightgrey); + + /* draw "rightmost" divider */ + gdImageLine(map_image, (int)x_coord[2] + x_offset, (int)y_coord[2] + y_offset, (int)x_coord[3] + x_offset, (int)y_coord[3] + y_offset, color_lightgrey); + } + + /* determine arc drawing angles */ + arc_start_angle = current_drawing_angle - 90.0; + while(arc_start_angle < 0.0) + arc_start_angle += 360.0; + arc_end_angle = arc_start_angle + available_angle; + + /* draw inner arc */ + gdImageArc(map_image, x_offset, y_offset, (radius - (CIRCULAR_DRAWING_RADIUS / 2)) * 2, (radius - (CIRCULAR_DRAWING_RADIUS / 2)) * 2, floor(arc_start_angle), ceil(arc_end_angle), color_lightgrey); + + /* draw outer arc */ + gdImageArc(map_image, x_offset, y_offset, (radius + (CIRCULAR_DRAWING_RADIUS / 2)) * 2, (radius + (CIRCULAR_DRAWING_RADIUS / 2)) * 2, floor(arc_start_angle), ceil(arc_end_angle), color_lightgrey); + + + /* determine center of "slice" and fill with appropriate color */ + center_x = -(sin(-(current_drawing_angle + (available_angle / 2.0)) * (M_PI / 180.0)) * (radius)); + center_y = -(sin((90 + current_drawing_angle + (available_angle / 2.0)) * (M_PI / 180.0)) * (radius)); + translated_x = center_x + x_offset; + translated_y = center_y + y_offset; + + /* determine background color */ + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + bgcolor = color_lightgrey; + else if(temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE) + bgcolor = color_lightred; + else + bgcolor = color_lightgreen; + + /* fill slice with background color */ + /* the fill function only works with coordinates that are in bounds of the actual image */ + if(translated_x > 0 && translated_y > 0 && translated_x < canvas_width && translated_y < canvas_height) + gdImageFillToBorder(map_image, translated_x, translated_y, color_lightgrey, bgcolor); + + /* recurse into child host ... */ + draw_circular_layer_markup(temp_host, current_drawing_angle + ((available_angle - clipped_available_angle) / 2), clipped_available_angle, layer + 1, radius + CIRCULAR_DRAWING_RADIUS); + + /* increment current drawing angle */ + current_drawing_angle += available_angle; + } + } + + return; + } + diff --git a/cgi/statuswml.c b/cgi/statuswml.c new file mode 100644 index 0000000..2d608f0 --- /dev/null +++ b/cgi/statuswml.c @@ -0,0 +1,1515 @@ +/************************************************************************** + * + * STATUSWML.C - Nagios Status CGI for WAP-enabled devices + * + * Copyright (c) 2001-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-15-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *************************************************************************/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/statusdata.h" + +#include "../include/cgiutils.h" +#include "../include/getcgi.h" +#include "../include/cgiauth.h" + +extern time_t program_start; + +extern char main_config_file[MAX_FILENAME_LENGTH]; + +extern host *host_list; +extern hostgroup *hostgroup_list; +extern service *service_list; +extern hoststatus *hoststatus_list; +extern servicestatus *servicestatus_list; + +extern int use_ssl_authentication; +extern int enable_notifications; +extern int execute_service_checks; +extern int nagios_process_state; + +extern char *ping_syntax; + +#define DISPLAY_HOST 0 +#define DISPLAY_SERVICE 1 +#define DISPLAY_HOSTGROUP 2 +#define DISPLAY_INDEX 3 +#define DISPLAY_PING 4 +#define DISPLAY_TRACEROUTE 5 +#define DISPLAY_QUICKSTATS 6 +#define DISPLAY_PROCESS 7 +#define DISPLAY_ALL_PROBLEMS 8 +#define DISPLAY_UNHANDLED_PROBLEMS 9 + +#define DISPLAY_HOSTGROUP_SUMMARY 0 +#define DISPLAY_HOSTGROUP_OVERVIEW 1 + +#define DISPLAY_HOST_SUMMARY 0 +#define DISPLAY_HOST_SERVICES 1 + +void document_header(void); +void document_footer(void); +int process_cgivars(void); +int validate_arguments(void); +int is_valid_hostip(char *hostip); + +int display_type = DISPLAY_INDEX; +int hostgroup_style = DISPLAY_HOSTGROUP_SUMMARY; +int host_style = DISPLAY_HOST_SUMMARY; + +void display_index(void); +void display_host(void); +void display_host_services(void); +void display_service(void); +void display_hostgroup_summary(void); +void display_hostgroup_overview(void); +void display_ping(void); +void display_traceroute(void); +void display_quick_stats(void); +void display_process(void); +void display_problems(void); + +char *host_name = ""; +char *hostgroup_name = ""; +char *service_desc = ""; +char *ping_address = ""; +char *traceroute_address = ""; + +int show_all_hostgroups = TRUE; + + +authdata current_authdata; + + + +int main(void) { + int result = OK; + + /* get the arguments passed in the URL */ + process_cgivars(); + + /* reset internal variables */ + reset_cgi_vars(); + + document_header(); + + /* validate arguments in URL */ + result = validate_arguments(); + if(result == ERROR) { + document_footer(); + return ERROR; + } + + /* read the CGI configuration file */ + result = read_cgi_config_file(get_cgi_config_location()); + if(result == ERROR) { + printf("

    Error: Could not open CGI configuration file '%s' for reading!

    \n", get_cgi_config_location()); + document_footer(); + return ERROR; + } + + /* read the main configuration file */ + result = read_main_config_file(main_config_file); + if(result == ERROR) { + printf("

    Error: Could not open main configuration file '%s' for reading!

    \n", 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) { + printf("

    Error: Could not read some or all object configuration data!

    \n"); + document_footer(); + return ERROR; + } + + /* read all status data */ + result = read_all_status_data(get_cgi_config_location(), READ_ALL_STATUS_DATA); + if(result == ERROR) { + printf("

    Error: Could not read host and service status information!

    \n"); + document_footer(); + free_memory(); + return ERROR; + } + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + /* decide what to display to the user */ + if(display_type == DISPLAY_HOST && host_style == DISPLAY_HOST_SERVICES) + display_host_services(); + else if(display_type == DISPLAY_HOST) + display_host(); + else if(display_type == DISPLAY_SERVICE) + display_service(); + else if(display_type == DISPLAY_HOSTGROUP && hostgroup_style == DISPLAY_HOSTGROUP_OVERVIEW) + display_hostgroup_overview(); + else if(display_type == DISPLAY_HOSTGROUP && hostgroup_style == DISPLAY_HOSTGROUP_SUMMARY) + display_hostgroup_summary(); + else if(display_type == DISPLAY_PING) + display_ping(); + else if(display_type == DISPLAY_TRACEROUTE) + display_traceroute(); + else if(display_type == DISPLAY_QUICKSTATS) + display_quick_stats(); + else if(display_type == DISPLAY_PROCESS) + display_process(); + else if(display_type == DISPLAY_ALL_PROBLEMS || display_type == DISPLAY_UNHANDLED_PROBLEMS) + display_problems(); + else + display_index(); + + document_footer(); + + /* free all allocated memory */ + free_memory(); + + return OK; + } + + +void document_header(void) { + char date_time[MAX_DATETIME_LENGTH]; + time_t expire_time; + time_t current_time; + + time(¤t_time); + + printf("Cache-Control: no-store\r\n"); + printf("Pragma: no-cache\r\n"); + + 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/vnd.wap.wml\r\n\r\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + return; + } + + +void document_footer(void) { + + printf("\n"); + + return; + } + + +int process_cgivars(void) { + char **variables; + int error = FALSE; + int x; + + variables = getcgivars(); + + for(x = 0; variables[x] != NULL; x++) { + + /* we found the hostgroup argument */ + if(!strcmp(variables[x], "hostgroup")) { + display_type = DISPLAY_HOSTGROUP; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((hostgroup_name = (char *)strdup(variables[x])) == NULL) + hostgroup_name = ""; + strip_html_brackets(hostgroup_name); + + if(!strcmp(hostgroup_name, "all")) + show_all_hostgroups = TRUE; + else + show_all_hostgroups = FALSE; + } + + /* we found the host argument */ + else if(!strcmp(variables[x], "host")) { + display_type = DISPLAY_HOST; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((host_name = (char *)strdup(variables[x])) == NULL) + host_name = ""; + strip_html_brackets(host_name); + } + + /* we found the service argument */ + else if(!strcmp(variables[x], "service")) { + display_type = DISPLAY_SERVICE; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((service_desc = (char *)strdup(variables[x])) == NULL) + service_desc = ""; + strip_html_brackets(service_desc); + } + + + /* we found the hostgroup style argument */ + else if(!strcmp(variables[x], "style")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "overview")) + hostgroup_style = DISPLAY_HOSTGROUP_OVERVIEW; + else if(!strcmp(variables[x], "summary")) + hostgroup_style = DISPLAY_HOSTGROUP_SUMMARY; + else if(!strcmp(variables[x], "servicedetail")) + host_style = DISPLAY_HOST_SERVICES; + else if(!strcmp(variables[x], "processinfo")) + display_type = DISPLAY_PROCESS; + else if(!strcmp(variables[x], "aprobs")) + display_type = DISPLAY_ALL_PROBLEMS; + else if(!strcmp(variables[x], "uprobs")) + display_type = DISPLAY_UNHANDLED_PROBLEMS; + else + display_type = DISPLAY_QUICKSTATS; + } + + /* we found the ping argument */ + else if(!strcmp(variables[x], "ping")) { + display_type = DISPLAY_PING; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((ping_address = (char *)strdup(variables[x])) == NULL) + ping_address = ""; + strip_html_brackets(ping_address); + } + + /* we found the traceroute argument */ + else if(!strcmp(variables[x], "traceroute")) { + display_type = DISPLAY_TRACEROUTE; + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((traceroute_address = (char *)strdup(variables[x])) == NULL) + traceroute_address = ""; + strip_html_brackets(traceroute_address); + } + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + +int validate_arguments(void) { + int result = OK; + if((strcmp(ping_address, "")) && !is_valid_hostip(ping_address)) { + printf("

    Invalid host name/ip

    \n"); + result = ERROR; + } + if(strcmp(traceroute_address, "") && !is_valid_hostip(traceroute_address)) { + printf("

    Invalid host name/ip

    \n"); + result = ERROR; + } + return result; + } + +int is_valid_hostip(char *hostip) { + char *valid_domain_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"; + if(strcmp(hostip, "") && strlen(hostip) == strspn(hostip, valid_domain_chars) && hostip[0] != '-' && hostip[strlen(hostip) - 1] != '-') + return TRUE; + return FALSE; + } + +/* main intro screen */ +void display_index(void) { + + + /**** MAIN MENU SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + + printf("Nagios
    WAP Interface
    \n"); + + printf("Quick Stats
    \n", STATUSWML_CGI); + + printf("Status Summary
    \n", STATUSWML_CGI); + + printf("Status Overview
    \n", STATUSWML_CGI); + + printf("All Problems
    \n", STATUSWML_CGI); + + printf("Unhandled Problems
    \n", STATUSWML_CGI); + + printf("Process Info
    \n", STATUSWML_CGI); + + printf("Tools
    \n"); + + printf("About
    \n"); + + printf("

    \n"); + printf("
    \n"); + + + /**** TOOLS SCREEN (CARD 2) ****/ + printf("\n"); + printf("

    \n"); + + printf("Network Tools:
    \n"); + + printf("Ping
    \n", STATUSWML_CGI); + printf("Traceroute
    \n", STATUSWML_CGI); + printf("View Host
    \n"); + printf("View Hostgroup
    \n"); + + printf("

    \n"); + printf("
    \n"); + + + /**** ABOUT SCREEN (CARD 3) ****/ + printf("\n"); + printf("

    \n"); + printf("About
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Nagios %s
    WAP Interface
    \n", PROGRAM_VERSION); + printf("Copyright (C) 2001 Ethan Galstad
    \n"); + printf("egalstad@nagios.org

    \n"); + printf("License: GPL

    \n"); + printf("Based in part on features found in AskAround's Wireless Network Tools
    \n"); + printf("www.askaround.com
    \n"); + printf("

    \n"); + + printf("
    \n"); + + + + /**** VIEW HOST SCREEN (CARD 4) ****/ + printf("\n"); + printf("

    \n"); + printf("View Host
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Host Name:
    \n"); + printf("\n"); + printf("\n"); + printf("\n", STATUSWML_CGI); + printf("\n"); + printf("

    \n"); + + printf("
    \n"); + + + + /**** VIEW HOSTGROUP SCREEN (CARD 5) ****/ + printf("\n"); + printf("

    \n"); + printf("View Hostgroup
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Hostgroup Name:
    \n"); + printf("\n"); + printf("\n"); + printf("\n", STATUSWML_CGI); + printf("\n"); + printf("

    \n"); + + printf("
    \n"); + + + return; + } + + +/* displays process info */ +void display_process(void) { + + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + printf("Process Info

    \n"); + + /* check authorization */ + if(is_authorized_for_system_information(¤t_authdata) == FALSE) { + + printf("Error: Not authorized for process info!\n"); + printf("

    \n"); + printf("
    \n"); + return; + } + + if(nagios_process_state == STATE_OK) + printf("Nagios process is running
    \n"); + else + printf("Nagios process may not be running
    \n"); + + if(enable_notifications == TRUE) + printf("Notifications are enabled
    \n"); + else + printf("Notifications are disabled
    \n"); + + if(execute_service_checks == TRUE) + printf("Check execution is enabled
    \n"); + else + printf("Check execution is disabled
    \n"); + + printf("
    \n"); + printf("Process Commands\n"); + printf("

    \n"); + + printf("\n"); + + + /**** COMMANDS SCREEN (CARD 2) ****/ + printf("\n"); + printf("

    \n"); + printf("Process Commands
    \n"); + + if(enable_notifications == FALSE) + printf("Enable Notifications
    \n", COMMAND_CGI, CMD_ENABLE_NOTIFICATIONS, CMDMODE_COMMIT); + else + printf("Disable Notifications
    \n", COMMAND_CGI, CMD_DISABLE_NOTIFICATIONS, CMDMODE_COMMIT); + + if(execute_service_checks == FALSE) + printf("Enable Check Execution
    \n", COMMAND_CGI, CMD_START_EXECUTING_SVC_CHECKS, CMDMODE_COMMIT); + else + printf("Disable Check Execution
    \n", COMMAND_CGI, CMD_STOP_EXECUTING_SVC_CHECKS, CMDMODE_COMMIT); + + printf("

    \n"); + + printf("
    \n"); + + + return; + } + + + +/* displays quick stats */ +void display_quick_stats(void) { + host *temp_host; + hoststatus *temp_hoststatus; + service *temp_service; + servicestatus *temp_servicestatus; + int hosts_unreachable = 0; + int hosts_down = 0; + int hosts_up = 0; + int hosts_pending = 0; + int services_critical = 0; + int services_unknown = 0; + int services_warning = 0; + int services_ok = 0; + int services_pending = 0; + + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + printf("Quick Stats
    \n"); + printf("

    \n"); + + /* check all hosts */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + if(temp_hoststatus->status == HOST_UNREACHABLE) + hosts_unreachable++; + else if(temp_hoststatus->status == HOST_DOWN) + hosts_down++; + else if(temp_hoststatus->status == HOST_PENDING) + hosts_pending++; + else + hosts_up++; + } + + /* check all services */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + temp_servicestatus = find_servicestatus(temp_service->host_name, temp_service->description); + if(temp_servicestatus == NULL) + continue; + + if(temp_servicestatus->status == SERVICE_CRITICAL) + services_critical++; + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + services_unknown++; + else if(temp_servicestatus->status == SERVICE_WARNING) + services_warning++; + else if(temp_servicestatus->status == SERVICE_PENDING) + services_pending++; + else + services_ok++; + } + + printf("

    \n"); + + printf("Host Totals:
    \n"); + printf("%d UP
    \n", hosts_up); + printf("%d DOWN
    \n", hosts_down); + printf("%d UNREACHABLE
    \n", hosts_unreachable); + printf("%d PENDING
    \n", hosts_pending); + + printf("
    \n"); + + printf("Service Totals:
    \n"); + printf("%d OK
    \n", services_ok); + printf("%d WARNING
    \n", services_warning); + printf("%d UNKNOWN
    \n", services_unknown); + printf("%d CRITICAL
    \n", services_critical); + printf("%d PENDING
    \n", services_pending); + + printf("

    \n"); + + printf("
    \n"); + + return; + } + + + +/* displays hostgroup status overview */ +void display_hostgroup_overview(void) { + hostgroup *temp_hostgroup; + hostsmember *temp_member; + host *temp_host; + hoststatus *temp_hoststatus; + + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + + printf("Status Overview

    \n", STATUSWML_CGI, escape_string(hostgroup_name)); + + /* check all hostgroups */ + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + if(show_all_hostgroups == FALSE && strcmp(temp_hostgroup->group_name, hostgroup_name)) + continue; + + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == FALSE) + continue; + + printf("%s\n", temp_hostgroup->alias); + + printf("\n"); + + /* check all hosts in this hostgroup */ + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == FALSE) + continue; + + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + printf("", STATUSWML_CGI, temp_host->name); + printf("\n", temp_host->name); + } + + printf("
    ", temp_host->name); + if(temp_hoststatus->status == HOST_UP) + printf("UP"); + else if(temp_hoststatus->status == HOST_PENDING) + printf("PND"); + else if(temp_hoststatus->status == HOST_DOWN) + printf("DWN"); + else if(temp_hoststatus->status == HOST_UNREACHABLE) + printf("UNR"); + else + printf("???"); + printf("%s
    \n"); + + printf("
    \n"); + } + + if(show_all_hostgroups == FALSE) + printf("View All Hostgroups\n", STATUSWML_CGI); + + printf("

    \n"); + printf("
    \n"); + + return; + } + + +/* displays hostgroup status summary */ +void display_hostgroup_summary(void) { + hostgroup *temp_hostgroup; + hostsmember *temp_member; + host *temp_host; + hoststatus *temp_hoststatus; + service *temp_service; + servicestatus *temp_servicestatus; + int hosts_unreachable = 0; + int hosts_down = 0; + int hosts_up = 0; + int hosts_pending = 0; + int services_critical = 0; + int services_unknown = 0; + int services_warning = 0; + int services_ok = 0; + int services_pending = 0; + int found = 0; + + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + + printf("Status Summary

    \n", STATUSWML_CGI, escape_string(hostgroup_name)); + + /* check all hostgroups */ + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + if(show_all_hostgroups == FALSE && strcmp(temp_hostgroup->group_name, hostgroup_name)) + continue; + + if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == FALSE) + continue; + + printf("%s\n", temp_hostgroup->group_name, temp_hostgroup->alias, STATUSWML_CGI, temp_hostgroup->group_name); + + printf("\n"); + + hosts_up = 0; + hosts_pending = 0; + hosts_down = 0; + hosts_unreachable = 0; + + services_ok = 0; + services_pending = 0; + services_warning = 0; + services_unknown = 0; + services_critical = 0; + + /* check all hosts in this hostgroup */ + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + + temp_host = find_host(temp_member->host_name); + if(temp_host == NULL) + continue; + + if(is_host_member_of_hostgroup(temp_hostgroup, temp_host) == FALSE) + continue; + + temp_hoststatus = find_hoststatus(temp_host->name); + if(temp_hoststatus == NULL) + continue; + + if(temp_hoststatus->status == HOST_UNREACHABLE) + hosts_unreachable++; + else if(temp_hoststatus->status == HOST_DOWN) + hosts_down++; + else if(temp_hoststatus->status == HOST_PENDING) + hosts_pending++; + else + hosts_up++; + + /* check all services on this host */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + if(strcmp(temp_service->host_name, temp_host->name)) + continue; + + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + temp_servicestatus = find_servicestatus(temp_service->host_name, temp_service->description); + if(temp_servicestatus == NULL) + continue; + + if(temp_servicestatus->status == SERVICE_CRITICAL) + services_critical++; + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + services_unknown++; + else if(temp_servicestatus->status == SERVICE_WARNING) + services_warning++; + else if(temp_servicestatus->status == SERVICE_PENDING) + services_pending++; + else + services_ok++; + } + } + + printf("\n"); + printf("\n"); + + printf("
    Hosts:"); + found = 0; + if(hosts_unreachable > 0) { + printf("%d UNR", hosts_unreachable); + found = 1; + } + if(hosts_down > 0) { + printf("%s%d DWN", (found == 1) ? ", " : "", hosts_down); + found = 1; + } + if(hosts_pending > 0) { + printf("%s%d PND", (found == 1) ? ", " : "", hosts_pending); + found = 1; + } + printf("%s%d UP", (found == 1) ? ", " : "", hosts_up); + printf("
    Services:"); + found = 0; + if(services_critical > 0) { + printf("%d CRI", services_critical); + found = 1; + } + if(services_warning > 0) { + printf("%s%d WRN", (found == 1) ? ", " : "", services_warning); + found = 1; + } + if(services_unknown > 0) { + printf("%s%d UNK", (found == 1) ? ", " : "", services_unknown); + found = 1; + } + if(services_pending > 0) { + printf("%s%d PND", (found == 1) ? ", " : "", services_pending); + found = 1; + } + printf("%s%d OK", (found == 1) ? ", " : "", services_ok); + printf("
    \n"); + + printf("
    \n"); + } + + if(show_all_hostgroups == FALSE) + printf("View All Hostgroups\n", STATUSWML_CGI); + + printf("

    \n"); + + printf("
    \n"); + + return; + } + + + +/* displays host status */ +void display_host(void) { + host *temp_host; + hoststatus *temp_hoststatus; + char last_check[MAX_DATETIME_LENGTH]; + int days; + int hours; + int minutes; + int seconds; + time_t current_time; + time_t t; + char state_duration[48]; + int found; + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + printf("Host '%s'
    \n", host_name); + + /* find the host */ + temp_host = find_host(host_name); + temp_hoststatus = find_hoststatus(host_name); + if(temp_host == NULL || temp_hoststatus == NULL) { + + printf("Error: Could not find host!\n"); + printf("

    \n"); + printf("
    \n"); + return; + } + + /* check authorization */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) { + + printf("Error: Not authorized for host!\n"); + printf("

    \n"); + printf("\n"); + return; + } + + + printf("\n"); + + printf("\n"); + + printf("\n", temp_hoststatus->plugin_output); + + get_time_string(&temp_hoststatus->last_check, last_check, sizeof(last_check) - 1, SHORT_DATE_TIME); + printf("\n", last_check); + + 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) ? "+" : ""); + printf("\n", state_duration); + + printf("\n"); + + printf("
    Status:"); + if(temp_hoststatus->status == HOST_UP) + printf("UP"); + else if(temp_hoststatus->status == HOST_PENDING) + printf("PENDING"); + else if(temp_hoststatus->status == HOST_DOWN) + printf("DOWN"); + else if(temp_hoststatus->status == HOST_UNREACHABLE) + printf("UNREACHABLE"); + else + printf("?"); + printf("
    Info:%s
    Last Check:%s
    Duration:%s
    Properties:"); + found = 0; + if(temp_hoststatus->checks_enabled == FALSE) { + printf("%sChecks disabled", (found == 1) ? ", " : ""); + found = 1; + } + if(temp_hoststatus->notifications_enabled == FALSE) { + printf("%sNotifications disabled", (found == 1) ? ", " : ""); + found = 1; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + printf("%sProblem acknowledged", (found == 1) ? ", " : ""); + found = 1; + } + if(temp_hoststatus->scheduled_downtime_depth > 0) { + printf("%sIn scheduled downtime", (found == 1) ? ", " : ""); + found = 1; + } + if(found == 0) + printf("N/A"); + printf("
    \n"); + printf("
    \n"); + printf("View Services\n", STATUSWML_CGI, escape_string(host_name)); + printf("Host Commands\n"); + printf("

    \n"); + + printf("\n"); + + + /**** COMMANDS SCREEN (CARD 2) ****/ + printf("\n"); + printf("

    \n"); + printf("Host Commands
    \n"); + + printf("Ping Host\n", STATUSWML_CGI, temp_host->address); + printf("Traceroute\n", STATUSWML_CGI, temp_host->address); + + if(temp_hoststatus->status != HOST_UP && temp_hoststatus->status != HOST_PENDING) + printf("Acknowledge Problem\n"); + + if(temp_hoststatus->checks_enabled == FALSE) + printf("Enable Host Checks
    \n", COMMAND_CGI, escape_string(host_name), CMD_ENABLE_HOST_CHECK, CMDMODE_COMMIT); + else + printf("Disable Host Checks
    \n", COMMAND_CGI, escape_string(host_name), CMD_DISABLE_HOST_CHECK, CMDMODE_COMMIT); + + if(temp_hoststatus->notifications_enabled == FALSE) + printf("Enable Host Notifications
    \n", COMMAND_CGI, escape_string(host_name), CMD_ENABLE_HOST_NOTIFICATIONS, CMDMODE_COMMIT); + else + printf("Disable Host Notifications
    \n", COMMAND_CGI, escape_string(host_name), CMD_DISABLE_HOST_NOTIFICATIONS, CMDMODE_COMMIT); + + + printf("Enable All Service Checks
    \n", COMMAND_CGI, escape_string(host_name), CMD_ENABLE_HOST_SVC_CHECKS, CMDMODE_COMMIT); + + printf("Disable All Service Checks
    \n", COMMAND_CGI, escape_string(host_name), CMD_DISABLE_HOST_SVC_CHECKS, CMDMODE_COMMIT); + + printf("Enable All Service Notifications
    \n", COMMAND_CGI, escape_string(host_name), CMD_ENABLE_HOST_SVC_NOTIFICATIONS, CMDMODE_COMMIT); + + printf("Disable All Service Notifications
    \n", COMMAND_CGI, escape_string(host_name), CMD_DISABLE_HOST_SVC_NOTIFICATIONS, CMDMODE_COMMIT); + + printf("

    \n"); + + printf("
    \n"); + + + /**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/ + printf("\n"); + printf("

    \n"); + printf("Acknowledge Problem
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Your Name:
    \n"); + printf("
    \n", ((use_ssl_authentication) ? (getenv("SSL_CLIENT_S_DN_CN")) : (getenv("REMOTE_USER")))); + printf("Comment:
    \n"); + printf("\n"); + + printf("\n"); + printf("\n", COMMAND_CGI, escape_string(host_name), CMD_ACKNOWLEDGE_HOST_PROBLEM, CMDMODE_COMMIT); + printf("\n"); + + printf("

    \n"); + + printf("
    \n"); + + return; + } + + + +/* displays services on a host */ +void display_host_services(void) { + service *temp_service; + servicestatus *temp_servicestatus; + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + printf("Host ", url_encode(host_name)); + printf("'%s' Services
    \n", host_name, STATUSWML_CGI, escape_string(host_name)); + + printf("\n"); + + /* check all services */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + if(strcmp(temp_service->host_name, host_name)) + continue; + + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + temp_servicestatus = find_servicestatus(temp_service->host_name, temp_service->description); + if(temp_servicestatus == NULL) + continue; + + printf("", STATUSWML_CGI, temp_service->host_name, temp_service->description); + printf("\n", temp_service->description); + } + + printf("
    ", temp_service->description); + if(temp_servicestatus->status == SERVICE_OK) + printf("OK"); + else if(temp_servicestatus->status == SERVICE_PENDING) + printf("PND"); + else if(temp_servicestatus->status == SERVICE_WARNING) + printf("WRN"); + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + printf("UNK"); + else if(temp_servicestatus->status == SERVICE_CRITICAL) + printf("CRI"); + else + printf("???"); + + printf("%s
    \n"); + + printf("

    \n"); + + printf("
    \n"); + + return; + } + + + +/* displays service status */ +void display_service(void) { + service *temp_service; + servicestatus *temp_servicestatus; + char last_check[MAX_DATETIME_LENGTH]; + int days; + int hours; + int minutes; + int seconds; + time_t current_time; + time_t t; + char state_duration[48]; + int found; + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + printf("

    \n"); + printf("Service '%s' on host '%s'
    \n", service_desc, host_name); + + /* find the service */ + temp_service = find_service(host_name, service_desc); + temp_servicestatus = find_servicestatus(host_name, service_desc); + if(temp_service == NULL || temp_servicestatus == NULL) { + + printf("Error: Could not find service!\n"); + printf("

    \n"); + printf("
    \n"); + return; + } + + /* check authorization */ + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) { + + printf("Error: Not authorized for service!\n"); + printf("

    \n"); + printf("\n"); + return; + } + + + printf("\n"); + + printf("\n"); + + printf("\n", temp_servicestatus->plugin_output); + + get_time_string(&temp_servicestatus->last_check, last_check, sizeof(last_check) - 1, SHORT_DATE_TIME); + printf("\n", last_check); + + current_time = time(NULL); + if(temp_servicestatus->last_state_change == (time_t)0) + t = current_time - program_start; + else + t = current_time - temp_servicestatus->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_servicestatus->last_state_change == (time_t)0) ? "+" : ""); + printf("\n", state_duration); + + printf("\n"); + + printf("
    Status:"); + if(temp_servicestatus->status == SERVICE_OK) + printf("OK"); + else if(temp_servicestatus->status == SERVICE_PENDING) + printf("PENDING"); + else if(temp_servicestatus->status == SERVICE_WARNING) + printf("WARNING"); + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + printf("UNKNOWN"); + else if(temp_servicestatus->status == SERVICE_CRITICAL) + printf("CRITICAL"); + else + printf("?"); + printf("
    Info:%s
    Last Check:%s
    Duration:%s
    Properties:"); + found = 0; + if(temp_servicestatus->checks_enabled == FALSE) { + printf("%sChecks disabled", (found == 1) ? ", " : ""); + found = 1; + } + if(temp_servicestatus->notifications_enabled == FALSE) { + printf("%sNotifications disabled", (found == 1) ? ", " : ""); + found = 1; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + printf("%sProblem acknowledged", (found == 1) ? ", " : ""); + found = 1; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + printf("%sIn scheduled downtime", (found == 1) ? ", " : ""); + found = 1; + } + if(found == 0) + printf("N/A"); + printf("
    \n"); + printf("
    \n"); + printf("View Host\n", STATUSWML_CGI, escape_string(host_name)); + printf("Svc. Commands\n"); + printf("

    \n"); + + printf("\n"); + + + /**** COMMANDS SCREEN (CARD 2) ****/ + printf("\n"); + printf("

    \n"); + printf("Service Commands
    \n"); + + if(temp_servicestatus->status != SERVICE_OK && temp_servicestatus->status != SERVICE_PENDING) + printf("Acknowledge Problem\n"); + + if(temp_servicestatus->checks_enabled == FALSE) { + printf("Enable Checks", COMMAND_CGI, escape_string(host_name)); + printf("
    \n", escape_string(service_desc), CMD_ENABLE_SVC_CHECK, CMDMODE_COMMIT); + } + else { + printf("Disable Checks", COMMAND_CGI, escape_string(host_name)); + printf("
    \n", escape_string(service_desc), CMD_DISABLE_SVC_CHECK, CMDMODE_COMMIT); + + printf("Schedule Immediate Check", COMMAND_CGI, escape_string(host_name)); + printf("
    \n", escape_string(service_desc), (unsigned long)current_time, CMD_SCHEDULE_SVC_CHECK, CMDMODE_COMMIT); + } + + if(temp_servicestatus->notifications_enabled == FALSE) { + printf("Enable Notifications", COMMAND_CGI, escape_string(host_name)); + printf("
    \n", escape_string(service_desc), CMD_ENABLE_SVC_NOTIFICATIONS, CMDMODE_COMMIT); + } + else { + printf("Disable Notifications", COMMAND_CGI, escape_string(host_name)); + printf("
    \n", escape_string(service_desc), CMD_DISABLE_SVC_NOTIFICATIONS, CMDMODE_COMMIT); + } + + printf("

    \n"); + + printf("
    \n"); + + + /**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/ + printf("\n"); + printf("

    \n"); + printf("Acknowledge Problem
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Your Name:
    \n"); + printf("
    \n", ((use_ssl_authentication) ? (getenv("SSL_CLIENT_S_DN_CN")) : (getenv("REMOTE_USER")))); + printf("Comment:
    \n"); + printf("\n"); + + printf("\n"); + printf("", COMMAND_CGI, escape_string(host_name)); + printf("\n", escape_string(service_desc), CMD_ACKNOWLEDGE_SVC_PROBLEM, CMDMODE_COMMIT); + printf("\n"); + + printf("

    \n"); + + printf("
    \n"); + + return; + } + + +/* displays ping results */ +void display_ping(void) { + char input_buffer[MAX_INPUT_BUFFER]; + char buffer[MAX_INPUT_BUFFER]; + char *temp_ptr; + FILE *fp; + int odd = 0; + int in_macro = FALSE; + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + + if(!strcmp(ping_address, "")) { + + printf("

    \n"); + printf("Ping Host
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Host Name/Address:
    \n"); + printf("\n"); + printf("\n"); + printf("\n", STATUSWML_CGI); + printf("\n"); + printf("

    \n"); + } + + else { + + printf("

    \n"); + printf("Results For Ping Of %s:
    \n", ping_address); + printf("

    \n"); + + printf("

    \n"); + + if(ping_syntax == NULL) + printf("ping_syntax in CGI config file is NULL!\n"); + + else { + + /* process macros in the ping syntax */ + strcpy(buffer, ""); + strncpy(input_buffer, ping_syntax, sizeof(input_buffer) - 1); + input_buffer[strlen(ping_syntax) - 1] = '\x0'; + for(temp_ptr = my_strtok(input_buffer, "$"); temp_ptr != NULL; temp_ptr = my_strtok(NULL, "$")) { + + if(in_macro == FALSE) { + if(strlen(buffer) + strlen(temp_ptr) < sizeof(buffer) - 1) { + strncat(buffer, temp_ptr, sizeof(buffer) - strlen(buffer) - 1); + buffer[sizeof(buffer) - 1] = '\x0'; + } + in_macro = TRUE; + } + else { + + if(strlen(buffer) + strlen(temp_ptr) < sizeof(buffer) - 1) { + + if(!strcmp(temp_ptr, "HOSTADDRESS")) + strncat(buffer, ping_address, sizeof(buffer) - strlen(buffer) - 1); + } + + in_macro = FALSE; + } + } + + /* run the ping command */ + fp = popen(buffer, "r"); + if(fp) { + while(1) { + fgets(buffer, sizeof(buffer) - 1, fp); + if(feof(fp)) + break; + + strip(buffer); + + if(odd) { + odd = 0; + printf("%s
    \n", buffer); + } + else { + odd = 1; + printf("%s
    \n", buffer); + } + } + } + else + printf("Error executing ping!\n"); + + pclose(fp); + } + + printf("

    \n"); + } + + printf("
    \n"); + + return; + } + + +/* displays traceroute results */ +void display_traceroute(void) { + char buffer[MAX_INPUT_BUFFER]; + FILE *fp; + int odd = 0; + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n"); + + if(!strcmp(traceroute_address, "")) { + + printf("

    \n"); + printf("Traceroute
    \n"); + printf("

    \n"); + + printf("

    \n"); + printf("Host Name/Address:
    \n"); + printf("\n"); + printf("\n"); + printf("\n", STATUSWML_CGI); + printf("\n"); + printf("

    \n"); + } + + else { + + printf("

    \n"); + printf("Results For Traceroute To %s:
    \n", traceroute_address); + printf("

    \n"); + + printf("

    \n"); + + snprintf(buffer, sizeof(buffer) - 1, "%s %s", TRACEROUTE_COMMAND, traceroute_address); + buffer[sizeof(buffer) - 1] = '\x0'; + + fp = popen(buffer, "r"); + if(fp) { + while(1) { + fgets(buffer, sizeof(buffer) - 1, fp); + if(feof(fp)) + break; + + strip(buffer); + + if(odd) { + odd = 0; + printf("%s
    \n", buffer); + } + else { + odd = 1; + printf("%s
    \n", buffer); + } + } + } + else + printf("Error executing traceroute!\n"); + + pclose(fp); + + printf("

    \n"); + } + + printf("
    \n"); + + return; + } + + + +/* displays problems */ +void display_problems(void) { + host *temp_host; + service *temp_service; + hoststatus *temp_hoststatus; + int total_host_problems = 0; + servicestatus *temp_servicestatus; + int total_service_problems = 0; + + /**** MAIN SCREEN (CARD 1) ****/ + printf("\n", (display_type == DISPLAY_ALL_PROBLEMS) ? "All" : "Unhandled"); + printf("

    \n"); + printf("%s Problems

    \n", (display_type == DISPLAY_ALL_PROBLEMS) ? "All" : "Unhandled"); + + printf("Host Problems:\n"); + + printf("\n"); + + /* check all hosts */ + for(temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) { + + temp_host = find_host(temp_hoststatus->host_name); + if(temp_host == NULL) + continue; + + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + if(temp_hoststatus->status == HOST_UP || temp_hoststatus->status == HOST_PENDING) + continue; + + if(display_type == DISPLAY_UNHANDLED_PROBLEMS) { + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) + continue; + if(temp_hoststatus->notifications_enabled == FALSE) + continue; + if(temp_hoststatus->scheduled_downtime_depth > 0) + continue; + } + + total_host_problems++; + + printf("", STATUSWML_CGI, temp_host->name); + printf("\n", temp_host->name); + } + + if(total_host_problems == 0) + printf("\n"); + + printf("
    ", temp_host->name); + if(temp_hoststatus->status == HOST_DOWN) + printf("DWN"); + else if(temp_hoststatus->status == HOST_UNREACHABLE) + printf("UNR"); + else + printf("???"); + printf("%s
    No problems
    \n"); + + printf("
    \n"); + + + printf("Svc Problems:\n"); + + printf("\n"); + + /* check all services */ + for(temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) { + + temp_service = find_service(temp_servicestatus->host_name, temp_servicestatus->description); + if(temp_service == NULL) + continue; + + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + if(temp_servicestatus->status == SERVICE_OK || temp_servicestatus->status == SERVICE_PENDING) + continue; + + if(display_type == DISPLAY_UNHANDLED_PROBLEMS) { + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) + continue; + if(temp_servicestatus->notifications_enabled == FALSE) + continue; + if(temp_servicestatus->scheduled_downtime_depth > 0) + continue; + if((temp_hoststatus = find_hoststatus(temp_service->host_name))) { + if(temp_hoststatus->scheduled_downtime_depth > 0) + continue; + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) + continue; + } + } + + total_service_problems++; + + printf("", STATUSWML_CGI, temp_service->host_name, temp_service->description); + printf("\n", temp_service->host_name, temp_service->description); + } + + if(total_service_problems == 0) + printf("\n"); + + printf("
    ", temp_servicestatus->description); + if(temp_servicestatus->status == SERVICE_CRITICAL) + printf("CRI"); + else if(temp_servicestatus->status == SERVICE_WARNING) + printf("WRN"); + else if(temp_servicestatus->status == SERVICE_UNKNOWN) + printf("UNK"); + else + printf("???"); + printf("%s/%s
    No problems
    \n"); + + printf("

    \n"); + + printf("
    \n"); + + return; + } + + + diff --git a/cgi/statuswrl.c b/cgi/statuswrl.c new file mode 100644 index 0000000..6e5ef2b --- /dev/null +++ b/cgi/statuswrl.c @@ -0,0 +1,1301 @@ +/***************************************************************************** + * + * STATUSWRL.C - Nagios 3-D (VRML) Network Status View + * + * Copyright (c) 1999-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 07-16-2007 + * + * Description: + * + * This CGI will dynamically create a 3-D VRML model of all hosts that are + * being monitored on your network. + * + * 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/statusdata.h" + +#include "../include/cgiutils.h" +#include "../include/getcgi.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_logo_images_path[MAX_FILENAME_LENGTH]; + +extern char *statuswrl_include; + +extern host *host_list; +extern service *service_list; + +extern int default_statuswrl_layout_method; + + +#define NAGIOS_VRML_IMAGE "nagiosvrml.png" + +#define DEFAULT_NODE_WIDTH 0.5 +#define DEFAULT_HORIZONTAL_SPACING 1.0 +#define DEFAULT_VERTICAL_SPACING 1.0 + +/* needed for auto-layout modes */ +#define DEFAULT_NODE_HEIGHT 0.5 +#define DEFAULT_NODE_HSPACING 1.0 +#define DEFAULT_NODE_VSPACING 1.0 +#define CIRCULAR_DRAWING_RADIUS 5.0 + +#define LAYOUT_USER_SUPPLIED 0 +#define LAYOUT_COLLAPSED_TREE 2 +#define LAYOUT_BALANCED_TREE 3 +#define LAYOUT_CIRCULAR 4 + + +void calculate_host_coords(void); +void calculate_world_bounds(void); +void display_world(void); +void write_global_vrml_data(void); +void draw_process_icon(void); +void draw_host(host *); +void draw_host_links(void); +void draw_host_link(host *, double, double, double, double, double, double); +void document_header(void); +int process_cgivars(void); + +int number_of_host_layer_members(host *, int); +int max_child_host_layer_members(host *); +int host_child_depth_separation(host *, host *); +int max_child_host_drawing_width(host *); + +void calculate_balanced_tree_coords(host *, int, int); +void calculate_circular_coords(void); +void calculate_circular_layer_coords(host *, double, double, int, int); + + +authdata current_authdata; + +float link_radius = 0.016; + +float floor_width = 0.0; +float floor_depth = 0.0; + +double min_z_coord = 0.0; +double min_x_coord = 0.0; +double min_y_coord = 0.0; +double max_z_coord = 0.0; +double max_x_coord = 0.0; +double max_y_coord = 0.0; + +double max_world_size = 0.0; + +double nagios_icon_x = 0.0; +double nagios_icon_y = 0.0; +int draw_nagios_icon = FALSE; + +double custom_viewpoint_x = 0.0; +double custom_viewpoint_y = 0.0; +double custom_viewpoint_z = 0.0; +int custom_viewpoint = FALSE; + +float vertical_spacing = DEFAULT_VERTICAL_SPACING; +float horizontal_spacing = DEFAULT_HORIZONTAL_SPACING; +float node_width = DEFAULT_NODE_WIDTH; +float node_height = DEFAULT_NODE_WIDTH; /* should be the same as the node width */ + +char *host_name = "all"; +int show_all_hosts = TRUE; + +int use_textures = TRUE; +int use_text = TRUE; +int use_links = TRUE; + +int layout_method = LAYOUT_USER_SUPPLIED; + +int coordinates_were_specified = FALSE; /* were drawing coordinates specified with extended host info entries? */ + + + + + +int main(int argc, char **argv) { + int result; + + /* 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(); + return ERROR; + } + + /* defaults from CGI config file */ + layout_method = default_statuswrl_layout_method; + + /* get the arguments passed in the URL */ + process_cgivars(); + + document_header(); + + /* read the main configuration file */ + result = read_main_config_file(main_config_file); + if(result == ERROR) + return ERROR; + + /* read all object configuration data */ + result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA); + if(result == ERROR) + return ERROR; + + /* read all status data */ + result = read_all_status_data(get_cgi_config_location(), READ_ALL_STATUS_DATA); + if(result == ERROR) { + free_memory(); + return ERROR; + } + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + /* display the 3-D VRML world... */ + display_world(); + + /* free all allocated memory */ + free_memory(); + + return OK; + } + + + +void document_header(void) { + 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 = 0L; + get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME); + printf("Expires: %s\r\n", date_time); + + printf("Content-Type: x-world/x-vrml\r\n\r\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")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((host_name = (char *)strdup(variables[x])) == NULL) + host_name = "all"; + else + strip_html_brackets(host_name); + + if(!strcmp(host_name, "all")) + show_all_hosts = TRUE; + else + show_all_hosts = FALSE; + } + + /* we found the no textures argument*/ + else if(!strcmp(variables[x], "notextures")) + use_textures = FALSE; + + /* we found the no text argument*/ + else if(!strcmp(variables[x], "notext")) + use_text = FALSE; + + /* we found the no links argument*/ + else if(!strcmp(variables[x], "nolinks")) + use_links = FALSE; + + /* we found the layout method option */ + else if(!strcmp(variables[x], "layout")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + layout_method = atoi(variables[x]); + } + + /* we found custom viewpoint coord */ + else if(!strcmp(variables[x], "viewx")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + custom_viewpoint_x = strtod(variables[x], NULL); + custom_viewpoint = TRUE; + } + else if(!strcmp(variables[x], "viewy")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + custom_viewpoint_y = strtod(variables[x], NULL); + custom_viewpoint = TRUE; + } + else if(!strcmp(variables[x], "viewz")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + custom_viewpoint_z = strtod(variables[x], NULL); + custom_viewpoint = TRUE; + } + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* top-level VRML world generation... */ +void display_world(void) { + host *temp_host = NULL; + + /* get the url we will use to grab the logo images... */ + snprintf(url_logo_images_path, sizeof(url_logo_images_path), "%slogos/", url_images_path); + url_logo_images_path[sizeof(url_logo_images_path) - 1] = '\x0'; + + /* calculate host drawing coordinates */ + calculate_host_coords(); + + /* calculate world bounds */ + calculate_world_bounds(); + + /* get the floor dimensions */ + if(max_x_coord > 0) + floor_width = (float)(max_x_coord - min_x_coord) + (node_width * 2); + else + floor_width = (float)(max_x_coord + min_x_coord) + (node_width * 2); + if(max_z_coord > 0) + floor_depth = (float)(max_z_coord - min_z_coord) + (node_height * 2); + else + floor_depth = (float)(max_z_coord + min_z_coord) + (node_height * 2); + + /* write global VRML data */ + write_global_vrml_data(); + + /* no coordinates were specified, so display warning message */ + if(coordinates_were_specified == FALSE) { + + printf("\n"); + printf("Transform{\n"); + printf("translation 0.0 0.0 0.0\n"); + printf("children[\n"); + + printf("Billboard{\n"); + printf("children[\n"); + printf("Shape{\n"); + printf("appearance Appearance {\n"); + printf("material Material {\n"); + printf("diffuseColor 1 0 0\n"); + printf("}\n"); + printf("}\n"); + printf("geometry Text {\n"); + printf("string [ \"Error: You have not supplied any 3-D drawing coordinates.\", \"Read the documentation for more information on supplying\", \"3-D drawing coordinates by defining\", \"extended host information entries in your config files.\" ]\n"); + printf("fontStyle FontStyle {\n"); + printf("family \"TYPEWRITER\"\n"); + printf("size 0.3\n"); + printf("justify \"MIDDLE\"\n"); + printf("}\n"); + printf("}\n"); + printf("}\n"); + printf("]\n"); + printf("}\n"); + + printf("]\n"); + printf("}\n"); + } + + /* coordinates were specified... */ + else { + + /* draw Nagios icon */ + if(layout_method != LAYOUT_USER_SUPPLIED) + draw_process_icon(); + + /* draw all hosts */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) + draw_host(temp_host); + + /* draw host links */ + draw_host_links(); + } + + return; + } + + + + +/******************************************************************/ +/************************ UTILITY FUNCTIONS ***********************/ +/******************************************************************/ + +/* calculates how many "layers" separate parent and child - used by collapsed tree layout method */ +int host_child_depth_separation(host *parent, host *child) { + int this_depth = 0; + int min_depth = 0; + int have_min_depth = FALSE; + host *temp_host; + + if(child == NULL) + return -1; + + if(parent == child) + return 0; + + if(is_host_immediate_child_of_host(parent, child) == TRUE) + return 1; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + this_depth = host_child_depth_separation(temp_host, child); + + if(this_depth >= 0 && (have_min_depth == FALSE || (have_min_depth == TRUE && (this_depth < min_depth)))) { + have_min_depth = TRUE; + min_depth = this_depth; + } + } + } + + if(have_min_depth == FALSE) + return -1; + else + return min_depth + 1; + } + + + +/* calculates how many hosts reside on a specific "layer" - used by collapsed tree layout method */ +int number_of_host_layer_members(host *parent, int layer) { + int current_layer; + int layer_members = 0; + host *temp_host; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + current_layer = host_child_depth_separation(parent, temp_host); + + if(current_layer == layer) + layer_members++; + } + + return layer_members; + } + + + +/* calculate max number of members on all "layers" beneath and including parent host - used by collapsed tree layout method */ +int max_child_host_layer_members(host *parent) { + int current_layer; + int max_members = 1; + int current_members = 0; + + for(current_layer = 1;; current_layer++) { + + current_members = number_of_host_layer_members(parent, current_layer); + + if(current_members <= 0) + break; + + if(current_members > max_members) + max_members = current_members; + } + + return max_members; + } + + + +/* calculate max drawing width for host and children - used by balanced tree layout method */ +int max_child_host_drawing_width(host *parent) { + host *temp_host; + int child_width = 0; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) + child_width += max_child_host_drawing_width(temp_host); + } + + /* no children, so set width to 1 for this host */ + if(child_width == 0) + return 1; + + else + return child_width; + } + + + + +/******************************************************************/ +/********************* CALCULATION FUNCTIONS **********************/ +/******************************************************************/ + +/* calculates host drawing coordinates */ +void calculate_host_coords(void) { + host *this_host; + host *temp_host; + int parent_hosts = 0; + int max_layer_width = 1; + int current_parent_host = 0; + int center_x = 0; + int offset_x = DEFAULT_NODE_WIDTH / 2; + int offset_y = DEFAULT_NODE_WIDTH / 2; + int current_layer = 0; + int layer_members = 0; + int current_layer_member = 0; + int max_drawing_width = 0; + + + /******************************/ + /***** MANUAL LAYOUT MODE *****/ + /******************************/ + + /* user-supplied coords */ + if(layout_method == LAYOUT_USER_SUPPLIED) { + + /* see which hosts we should draw (only those with 3-D coords) */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(temp_host->have_3d_coords == TRUE) + temp_host->should_be_drawn = TRUE; + else + temp_host->should_be_drawn = FALSE; + } + + return; + } + + /*****************************/ + /***** AUTO-LAYOUT MODES *****/ + /*****************************/ + + /* add empty extended host info entries for all hosts that don't have any */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* none was found, so add a blank one */ + /* + if(temp_hostextinfo==NULL) + add_hostextinfo(temp_host->name,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0.0,0.0,0.0,0,0); + */ + + /* default z coord should 0 for auto-layout modes unless overridden later */ + /* + else + */ + temp_host->z_3d = 0.0; + } + + + /***** COLLAPSED TREE MODE *****/ + if(layout_method == LAYOUT_COLLAPSED_TREE) { + + /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ + this_host = NULL; + + /* find total number of immediate parents for this host */ + parent_hosts = number_of_immediate_parent_hosts(this_host); + + /* find the max layer width we have... */ + max_layer_width = max_child_host_layer_members(this_host); + if(parent_hosts > max_layer_width) + max_layer_width = parent_hosts; + + /* calculate center x coord */ + center_x = (((DEFAULT_NODE_WIDTH * max_layer_width) + (DEFAULT_NODE_HSPACING * (max_layer_width - 1))) / 2) + offset_x; + + /* coords for Nagios icon if necessary */ + if(this_host == NULL || this_host->parent_hosts == NULL) { + nagios_icon_x = center_x; + nagios_icon_y = offset_y; + draw_nagios_icon = TRUE; + } + + /* do we need to draw a link to parent(s)? */ + if(this_host != NULL && is_host_immediate_child_of_host(NULL, this_host) == FALSE) + offset_y += DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + + /* see which hosts we should draw and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* this is an immediate parent of the "main" host we're drawing */ + if(is_host_immediate_parent_of_host(this_host, temp_host) == TRUE) { + temp_host->should_be_drawn = TRUE; + temp_host->have_3d_coords = TRUE; + temp_host->x_3d = center_x - (((parent_hosts * DEFAULT_NODE_WIDTH) + ((parent_hosts - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_parent_host * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + temp_host->y_3d = offset_y; + current_parent_host++; + } + + /* this is the "main" host we're drawing */ + else if(this_host == temp_host) { + temp_host->should_be_drawn = TRUE; + temp_host->have_3d_coords = TRUE; + temp_host->x_3d = center_x; + temp_host->y_3d = DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y; + } + + /* else do not draw this host (we might if its a child - see below, but assume no for now) */ + else { + temp_host->should_be_drawn = FALSE; + temp_host->have_3d_coords = FALSE; + } + } + + + /* TODO: REORDER CHILD LAYER MEMBERS SO THAT WE MINIMIZE LINK CROSSOVERS FROM PARENT HOSTS */ + + /* draw hosts in child "layers" */ + for(current_layer = 1;; current_layer++) { + + /* how many members in this layer? */ + layer_members = number_of_host_layer_members(this_host, current_layer); + + if(layer_members == 0) + break; + + current_layer_member = 0; + + /* see which hosts are members of this layer and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* is this host a member of the current child layer? */ + if(host_child_depth_separation(this_host, temp_host) == current_layer) { + temp_host->should_be_drawn = TRUE; + temp_host->have_3d_coords = TRUE; + temp_host->x_3d = center_x - (((layer_members * DEFAULT_NODE_WIDTH) + ((layer_members - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_layer_member * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + if(this_host == NULL) + temp_host->y_3d = ((DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING) * current_layer) + offset_y; + else + temp_host->y_3d = ((DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING) * (current_layer + 1)) + offset_y; + current_layer_member++; + } + } + } + + } + + + /***** "BALANCED" TREE MODE *****/ + else if(layout_method == LAYOUT_BALANCED_TREE) { + + /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ + this_host = NULL; + + /* find total number of immediate parents for this host */ + parent_hosts = number_of_immediate_parent_hosts(this_host); + + /* find the max drawing width we have... */ + max_drawing_width = max_child_host_drawing_width(this_host); + if(parent_hosts > max_drawing_width) + max_drawing_width = parent_hosts; + + /* calculate center x coord */ + center_x = (((DEFAULT_NODE_WIDTH * max_drawing_width) + (DEFAULT_NODE_HSPACING * (max_drawing_width - 1))) / 2) + offset_x; + + /* coords for Nagios icon if necessary */ + if(this_host == NULL || this_host->parent_hosts == NULL) { + nagios_icon_x = center_x; + nagios_icon_y = offset_y; + draw_nagios_icon = TRUE; + } + + /* do we need to draw a link to parent(s)? */ + if(this_host != NULL && is_host_immediate_child_of_host(NULL, this_host) == FALSE) + offset_y += DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + + /* see which hosts we should draw and calculate drawing coords */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* this is an immediate parent of the "main" host we're drawing */ + if(is_host_immediate_parent_of_host(this_host, temp_host) == TRUE) { + temp_host->should_be_drawn = TRUE; + temp_host->have_3d_coords = TRUE; + temp_host->x_3d = center_x - (((parent_hosts * DEFAULT_NODE_WIDTH) + ((parent_hosts - 1) * DEFAULT_NODE_HSPACING)) / 2) + (current_parent_host * (DEFAULT_NODE_WIDTH + DEFAULT_NODE_HSPACING)) + (DEFAULT_NODE_WIDTH / 2); + temp_host->y_3d = offset_y; + current_parent_host++; + } + + /* this is the "main" host we're drawing */ + else if(this_host == temp_host) { + temp_host->should_be_drawn = TRUE; + temp_host->have_3d_coords = TRUE; + temp_host->x_3d = center_x; + temp_host->y_3d = DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y; + } + + /* else do not draw this host (we might if its a child - see below, but assume no for now) */ + else { + temp_host->should_be_drawn = FALSE; + temp_host->have_3d_coords = FALSE; + } + } + + /* draw all children hosts */ + calculate_balanced_tree_coords(this_host, center_x, DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING + offset_y); + + } + + + /***** CIRCULAR LAYOUT MODE *****/ + else if(layout_method == LAYOUT_CIRCULAR) { + + /* draw process icon */ + nagios_icon_x = 0; + nagios_icon_y = 0; + draw_nagios_icon = TRUE; + + /* calculate coordinates for all hosts */ + calculate_circular_coords(); + } + + return; + } + + + +/* calculate world dimensions */ +void calculate_world_bounds(void) { + host *temp_host; + + min_x_coord = 0.0; + min_y_coord = 0.0; + min_z_coord = 0.0; + max_x_coord = 0.0; + max_y_coord = 0.0; + max_z_coord = 0.0; + + /* check all extended host entries */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(temp_host->have_3d_coords == FALSE) { + temp_host->should_be_drawn = FALSE; + continue; + } + + if(temp_host->should_be_drawn == FALSE) + continue; + + if(temp_host->x_3d < min_x_coord) + min_x_coord = temp_host->x_3d; + else if(temp_host->x_3d > max_x_coord) + max_x_coord = temp_host->x_3d; + if(temp_host->y_3d < min_y_coord) + min_y_coord = temp_host->y_3d; + else if(temp_host->y_3d > max_y_coord) + max_y_coord = temp_host->y_3d; + if(temp_host->z_3d < min_z_coord) + min_z_coord = temp_host->z_3d; + else if(temp_host->z_3d > max_z_coord) + max_z_coord = temp_host->z_3d; + + coordinates_were_specified = TRUE; + } + + /* no drawing coordinates were specified */ + if(coordinates_were_specified == FALSE) { + min_x_coord = 0.0; + max_x_coord = 0.0; + min_y_coord = 0.0; + max_y_coord = 0.0; + min_z_coord = 0.0; + max_z_coord = 6.0; + } + + max_world_size = max_x_coord - min_x_coord; + if(max_world_size < (max_y_coord - min_y_coord)) + max_world_size = max_y_coord - min_y_coord; + if(max_world_size < (max_z_coord - min_z_coord)) + max_world_size = max_z_coord - min_z_coord; + + return; + } + + +/******************************************************************/ +/*********************** DRAWING FUNCTIONS ************************/ +/******************************************************************/ + + +/* write global VRML data */ +void write_global_vrml_data(void) { + host *temp_host; + float visibility_range = 0.0; + float viewpoint_z = 0.0; + + /* write VRML code header */ + printf("#VRML V2.0 utf8\n"); + + /* write world information */ + printf("\n"); + printf("WorldInfo{\n"); + printf("title \"Nagios 3-D Network Status View\"\n"); + printf("info [\"Copyright (c) 1999-2002 Ethan Galstad\"\n"); + printf("\"egalstad@nagios.org\"]\n"); + printf("}\n"); + + /* background color */ + printf("\n"); + printf("Background{\n"); + printf("skyColor 0.1 0.1 0.15\n"); + printf("}\n"); + + /* calculate visibility range - don't let it get too low */ + visibility_range = (max_world_size * 2.0); + if(visibility_range < 25.0) + visibility_range = 25.0; + + /* write fog information */ + printf("\n"); + printf("Fog{\n"); + printf("color 0.1 0.1 0.15\n"); + printf("fogType \"EXPONENTIAL\"\n"); + printf("visibilityRange %2.2f\n", visibility_range); + printf("}\n"); + + /* custom viewpoint */ + if(custom_viewpoint == TRUE) { + printf("\n"); + printf("Viewpoint{\n"); + printf("position %2.2f %2.2f %2.2f\n", custom_viewpoint_x, custom_viewpoint_y, custom_viewpoint_z); + printf("fieldOfView 0.78\n"); + printf("description \"Entry Viewpoint\"\n"); + printf("}\n"); + } + + /* host close-up viewpoint */ + if(show_all_hosts == FALSE) { + + temp_host = find_host(host_name); + if(temp_host != NULL && temp_host->have_3d_coords == TRUE) { + printf("\n"); + printf("Viewpoint{\n"); + printf("position %2.3f %2.3f %2.3f\n", temp_host->x_3d, temp_host->y_3d, temp_host->z_3d + 5.0); + printf("fieldOfView 0.78\n"); + printf("description \"Host Close-Up Viewpoint\"\n"); + printf("}\n"); + } + } + + /* calculate z coord for default viewpoint - don't get too close */ + viewpoint_z = max_world_size; + if(viewpoint_z < 10.0) + viewpoint_z = 10.0; + + /* default viewpoint */ + printf("\n"); + printf("Viewpoint{\n"); + printf("position %2.2f %2.2f %2.2f\n", min_x_coord + ((max_x_coord - min_x_coord) / 2.0), min_y_coord + ((max_y_coord - min_y_coord) / 2.0), viewpoint_z); + printf("fieldOfView 0.78\n"); + printf("description \"Default Viewpoint\"\n"); + printf("}\n"); + + /* problem timer */ + printf("DEF ProblemTimer TimeSensor{\n"); + printf("loop TRUE\n"); + printf("cycleInterval 5\n"); + printf("}\n"); + + /* host text prototype */ + printf("PROTO HostText[\n"); + printf("field MFString the_text [\"\"]\n"); + printf("field SFColor font_color 0.6 0.6 0.6"); + printf("]\n"); + printf("{\n"); + printf("Billboard{\n"); + printf("children[\n"); + printf("Shape{\n"); + printf("appearance Appearance {\n"); + printf("material Material {\n"); + printf("diffuseColor IS font_color\n"); + printf("}\n"); + printf("}\n"); + printf("geometry Text {\n"); + printf("string IS the_text\n"); + printf("fontStyle FontStyle {\n"); + printf("family \"TYPEWRITER\"\n"); + printf("size 0.1\n"); + printf("justify \"MIDDLE\"\n"); + printf("}\n"); + printf("}\n"); + printf("}\n"); + printf("]\n"); + printf("}\n"); + printf("}\n"); + + /* include user-defined world */ + if(statuswrl_include != NULL && coordinates_were_specified == TRUE && layout_method == LAYOUT_USER_SUPPLIED) { + printf("\n"); + printf("Inline{\n"); + printf("url \"%s%s\"\n", url_html_path, statuswrl_include); + printf("}\n"); + } + + return; + } + + + +/* draws a host */ +void draw_host(host *temp_host) { + hoststatus *temp_hoststatus = NULL; + char state_string[16] = ""; + double x, y, z; + char *vrml_safe_hostname = NULL; + int a, ch; + + if(temp_host == NULL) + return; + + /* make sure we have the coordinates */ + if(temp_host->have_3d_coords == FALSE) + return; + else { + x = temp_host->x_3d; + y = temp_host->y_3d; + z = temp_host->z_3d; + } + + /* make the host name safe for embedding in VRML */ + vrml_safe_hostname = (char *)strdup(temp_host->name); + if(vrml_safe_hostname == NULL) + return; + for(a = 0; vrml_safe_hostname[a] != '\x0'; a++) { + ch = vrml_safe_hostname[a]; + if((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z') && (ch < '0' || ch > '9')) + vrml_safe_hostname[a] = '_'; + } + + /* see if user is authorized to view this host */ + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + return; + + /* get the status of the host */ + temp_hoststatus = find_hoststatus(temp_host->name); + + printf("\n"); + + + /* host object */ + printf("Anchor{\n"); + printf("children[\n"); + + printf("Transform {\n"); + printf("translation %2.2f %2.2f %2.2f\n", x, y, z); + printf("children [\n"); + + printf("DEF Host%s Shape{\n", vrml_safe_hostname); + printf("appearance Appearance{\n"); + printf("material DEF HostMat%s Material{\n", vrml_safe_hostname); + if(temp_hoststatus == NULL) + printf("emissiveColor 0.2 0.2 0.2\ndiffuseColor 0.2 0.2 0.2\n"); + else if(temp_hoststatus->status == HOST_UP) + printf("emissiveColor 0.2 1.0 0.2\ndiffuseColor 0.2 1.0 0.2\n"); + else + printf("emissiveColor 1.0 0.2 0.2\ndiffuseColor 1.0 0.2 0.2\n"); + printf("transparency 0.4\n"); + printf("}\n"); + if(use_textures == TRUE && temp_host->vrml_image != NULL) { + printf("texture ImageTexture{\n"); + printf("url \"%s%s\"\n", url_logo_images_path, temp_host->vrml_image); + printf("}\n"); + } + printf("}\n"); + printf("geometry Box{\n"); + printf("size %2.2f %2.2f %2.2f\n", node_width, node_width, node_width); + printf("}\n"); + printf("}\n"); + + printf("]\n"); + printf("}\n"); + + printf("]\n"); + printf("description \"View status details for host '%s' (%s)\"\n", temp_host->name, temp_host->alias); + printf("url \"%s?host=%s\"\n", STATUS_CGI, temp_host->name); + printf("}\n"); + + + /* draw status text */ + if(use_text == TRUE) { + + printf("\n"); + printf("Transform{\n"); + printf("translation %2.3f %2.3f %2.3f\n", x, y + DEFAULT_NODE_WIDTH, z); + printf("children[\n"); + printf("HostText{\n"); + + if(temp_hoststatus != NULL) { + if(temp_hoststatus->status == HOST_UP) + printf("font_color 0 1 0\n"); + else if(temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE) + printf("font_color 1 0 0\n"); + } + printf("the_text [\"%s\", \"%s\", ", temp_host->name, temp_host->alias); + if(temp_hoststatus == NULL) + strcpy(state_string, "UNKNOWN"); + else { + if(temp_hoststatus->status == HOST_DOWN) + strcpy(state_string, "DOWN"); + else if(temp_hoststatus->status == HOST_UNREACHABLE) + strcpy(state_string, "UNREACHABLE"); + else if(temp_hoststatus->status == HOST_PENDING) + strcpy(state_string, "PENDING"); + else + strcpy(state_string, "UP"); + } + printf("\"%s\"]\n", state_string); + + printf("}\n"); + printf("]\n"); + printf("}\n"); + } + + /* host is down or unreachable, so make it fade in and out */ + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) + printf("ROUTE ProblemTimer.fraction_changed TO HostMat%s.set_transparency\n", vrml_safe_hostname); + + free(vrml_safe_hostname); + + return; + } + + + +/* draw links between hosts */ +void draw_host_links(void) { + host *parent_host; + host *child_host; + + if(use_links == FALSE) + return; + + for(child_host = host_list; child_host != NULL; child_host = child_host->next) { + + if(child_host->have_3d_coords == FALSE) + continue; + + /* check authorization */ + if(is_authorized_for_host(child_host, ¤t_authdata) == FALSE) + continue; + + /* draw a link from this host to all of its parent hosts */ + for(parent_host = host_list; parent_host != NULL; parent_host = parent_host->next) { + + if(is_host_immediate_child_of_host(child_host, parent_host) == TRUE) { + + if(parent_host->have_3d_coords == FALSE) + continue; + + /* check authorization */ + if(is_authorized_for_host(parent_host, ¤t_authdata) == FALSE) + continue; + + /* draw the link between the child and parent hosts */ + draw_host_link(parent_host, parent_host->x_3d, parent_host->y_3d, parent_host->z_3d, child_host->x_3d, child_host->y_3d, child_host->z_3d); + } + } + } + + + return; + } + + + + +/* draws a link from a parent host to a child host */ +void draw_host_link(host *hst, double x0, double y0, double z0, double x1, double y1, double z1) { + + printf("\n"); + + if(hst != NULL) + printf("# Host '%s' LINK\n", hst->name); + + printf("Shape{\n"); + + printf("appearance DEF MATslategrey_0_ Appearance {\n"); + printf("material Material {\n"); + printf("diffuseColor 0.6 0.6 0.6\n"); + printf("ambientIntensity 0.5\n"); + printf("emissiveColor 0.6 0.6 0.6\n"); + printf("}\n"); + printf("}\n"); + + printf("geometry IndexedLineSet{\n"); + printf("coord Coordinate{\n"); + printf("point [ %2.3f %2.3f %2.3f, %2.3f %2.3f %2.3f ]\n", x0, y0, z0, x1, y1, z1); + printf("}\n"); + printf("coordIndex [ 0,1,-1 ]\n"); + printf("}\n"); + + printf("}\n"); + + return; + } + + + +/* draw process icon */ +void draw_process_icon(void) { + host *child_host; + + if(draw_nagios_icon == FALSE) + return; + + /* draw process icon */ + printf("\n"); + + + printf("Anchor{\n"); + printf("children[\n"); + + printf("Transform {\n"); + printf("translation %2.2f %2.2f %2.2f\n", nagios_icon_x, nagios_icon_y, 0.0); + printf("children [\n"); + + printf("DEF ProcessNode Shape{\n"); + printf("appearance Appearance{\n"); + printf("material Material{\n"); + printf("emissiveColor 0.5 0.5 0.5\n"); + printf("diffuseColor 0.5 0.5 0.5\n"); + printf("transparency 0.2\n"); + printf("}\n"); + if(use_textures == TRUE) { + printf("texture ImageTexture{\n"); + printf("url \"%s%s\"\n", url_logo_images_path, NAGIOS_VRML_IMAGE); + printf("}\n"); + } + printf("}\n"); + printf("geometry Box{\n"); + printf("size %2.2f %2.2f %2.2f\n", node_width * 3.0, node_width * 3.0, node_width * 3.0); + printf("}\n"); + printf("}\n"); + + printf("]\n"); + printf("}\n"); + + printf("]\n"); + printf("description \"View Nagios Process Information\"\n"); + printf("url \"%s?type=%d\"\n", EXTINFO_CGI, DISPLAY_PROCESS_INFO); + printf("}\n"); + + + if(use_links == FALSE) + return; + + /* draw links to immediate child hosts */ + for(child_host = host_list; child_host != NULL; child_host = child_host->next) { + + if(child_host->have_3d_coords == FALSE) + continue; + + /* check authorization */ + if(is_authorized_for_host(child_host, ¤t_authdata) == FALSE) + continue; + + /* draw a link to the host */ + if(is_host_immediate_child_of_host(NULL, child_host) == TRUE) + draw_host_link(NULL, nagios_icon_x, nagios_icon_y, 0.0, child_host->x_3d, child_host->y_3d, child_host->z_3d); + } + + return; + } + + + + +/******************************************************************/ +/***************** COORDINATE CALCULATION FUNCTIONS ***************/ +/******************************************************************/ + +/* calculates coords of a host's children - used by balanced tree layout method */ +void calculate_balanced_tree_coords(host *parent, int x, int y) { + int parent_drawing_width; + int start_drawing_x; + int current_drawing_x; + int this_drawing_width; + host *temp_host; + + /* calculate total drawing width of parent host */ + parent_drawing_width = max_child_host_drawing_width(parent); + + /* calculate starting x coord */ + start_drawing_x = x - (((DEFAULT_NODE_WIDTH * parent_drawing_width) + (DEFAULT_NODE_HSPACING * (parent_drawing_width - 1))) / 2); + current_drawing_x = start_drawing_x; + + + /* calculate coords for children */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + /* get drawing width of child host */ + this_drawing_width = max_child_host_drawing_width(temp_host); + + temp_host->x_3d = current_drawing_x + (((DEFAULT_NODE_WIDTH * this_drawing_width) + (DEFAULT_NODE_HSPACING * (this_drawing_width - 1))) / 2); + temp_host->y_3d = y + DEFAULT_NODE_HEIGHT + DEFAULT_NODE_VSPACING; + temp_host->have_3d_coords = TRUE; + temp_host->should_be_drawn = TRUE; + + current_drawing_x += (this_drawing_width * DEFAULT_NODE_WIDTH) + ((this_drawing_width - 1) * DEFAULT_NODE_HSPACING) + DEFAULT_NODE_HSPACING; + + /* recurse into child host ... */ + calculate_balanced_tree_coords(temp_host, temp_host->x_3d, temp_host->y_3d); + } + + } + + return; + } + + +/* calculate coords of all hosts in circular layout method */ +void calculate_circular_coords(void) { + + /* calculate all host coords, starting with first layer */ + calculate_circular_layer_coords(NULL, 0.0, 360.0, 1, CIRCULAR_DRAWING_RADIUS); + + return; + } + + +/* calculates coords of all hosts in a particular "layer" in circular layout method */ +void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius) { + int parent_drawing_width = 0; + int this_drawing_width = 0; + int immediate_children = 0; + double current_drawing_angle = 0.0; + double this_drawing_angle = 0.0; + double available_angle = 0.0; + double clipped_available_angle = 0.0; + double average_child_angle = 0.0; + double x_coord = 0.0; + double y_coord = 0.0; + host *temp_host; + + + /* get the total number of immediate children to this host */ + immediate_children = number_of_immediate_child_hosts(parent); + + /* bail out if we're done */ + if(immediate_children == 0) + return; + + /* calculate total drawing "width" of parent host */ + parent_drawing_width = max_child_host_drawing_width(parent); + + /* calculate average angle given to each child host */ + average_child_angle = (double)(useable_angle / (double)immediate_children); + + /* calculate initial drawing angle */ + current_drawing_angle = start_angle; + + + /* calculate coords for children */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(is_host_immediate_child_of_host(parent, temp_host) == TRUE) { + + /* get drawing width of child host */ + this_drawing_width = max_child_host_drawing_width(temp_host); + + /* calculate angle this host gets for drawing */ + available_angle = useable_angle * ((double)this_drawing_width / (double)parent_drawing_width); + + /* clip available angle if necessary */ + /* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */ + clipped_available_angle = 360.0 / layer; + if(available_angle < clipped_available_angle) + clipped_available_angle = available_angle; + + /* calculate the exact angle at which we should draw this child */ + this_drawing_angle = current_drawing_angle + (available_angle / 2.0); + + /* compensate for angle overflow */ + while(this_drawing_angle >= 360.0) + this_drawing_angle -= 360.0; + while(this_drawing_angle < 0.0) + this_drawing_angle += 360.0; + + /* calculate drawing coords of this host using good ol' geometry... */ + x_coord = -(sin(-this_drawing_angle * (M_PI / 180.0)) * radius); + y_coord = -(sin((90 + this_drawing_angle) * (M_PI / 180.0)) * radius); + + temp_host->x_3d = (int)x_coord; + temp_host->y_3d = (int)y_coord; + temp_host->have_3d_coords = TRUE; + temp_host->should_be_drawn = TRUE; + + /* recurse into child host ... */ + calculate_circular_layer_coords(temp_host, current_drawing_angle + ((available_angle - clipped_available_angle) / 2), clipped_available_angle, layer + 1, radius + CIRCULAR_DRAWING_RADIUS); + + /* increment current drawing angle */ + current_drawing_angle += available_angle; + } + } + + return; + } + + diff --git a/cgi/summary.c b/cgi/summary.c new file mode 100644 index 0000000..810b1af --- /dev/null +++ b/cgi/summary.c @@ -0,0 +1,2808 @@ +/************************************************************************** + * + * SUMMARY.C - Nagios Alert Summary CGI + * + * Copyright (c) 2002-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 01-23-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 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 host *host_list; +extern hostgroup *hostgroup_list; +extern service *service_list; +extern servicegroup *servicegroup_list; + +extern int log_rotation_method; + + +/* output types */ +#define HTML_OUTPUT 0 +#define CSV_OUTPUT 1 + +/* custom report types */ +#define REPORT_NONE 0 +#define REPORT_RECENT_ALERTS 1 +#define REPORT_ALERT_TOTALS 2 +#define REPORT_TOP_ALERTS 3 +#define REPORT_HOSTGROUP_ALERT_TOTALS 4 +#define REPORT_HOST_ALERT_TOTALS 5 +#define REPORT_SERVICE_ALERT_TOTALS 6 +#define REPORT_SERVICEGROUP_ALERT_TOTALS 7 + +/* standard report types */ +#define SREPORT_NONE 0 +#define SREPORT_RECENT_ALERTS 1 +#define SREPORT_RECENT_HOST_ALERTS 2 +#define SREPORT_RECENT_SERVICE_ALERTS 3 +#define SREPORT_TOP_HOST_ALERTS 4 +#define SREPORT_TOP_SERVICE_ALERTS 5 + +/* standard report times */ +#define TIMEPERIOD_CUSTOM 0 +#define TIMEPERIOD_TODAY 1 +#define TIMEPERIOD_YESTERDAY 2 +#define TIMEPERIOD_THISWEEK 3 +#define TIMEPERIOD_LASTWEEK 4 +#define TIMEPERIOD_THISMONTH 5 +#define TIMEPERIOD_LASTMONTH 6 +#define TIMEPERIOD_THISQUARTER 7 +#define TIMEPERIOD_LASTQUARTER 8 +#define TIMEPERIOD_THISYEAR 9 +#define TIMEPERIOD_LASTYEAR 10 +#define TIMEPERIOD_LAST24HOURS 11 +#define TIMEPERIOD_LAST7DAYS 12 +#define TIMEPERIOD_LAST31DAYS 13 + +#define AE_SOFT_STATE 1 +#define AE_HARD_STATE 2 + +#define AE_HOST_ALERT 1 +#define AE_SERVICE_ALERT 2 + +#define AE_HOST_PRODUCER 1 +#define AE_SERVICE_PRODUCER 2 + +#define AE_HOST_DOWN 1 +#define AE_HOST_UNREACHABLE 2 +#define AE_HOST_UP 4 +#define AE_SERVICE_WARNING 8 +#define AE_SERVICE_UNKNOWN 16 +#define AE_SERVICE_CRITICAL 32 +#define AE_SERVICE_OK 64 + +typedef struct archived_event_struct { + time_t time_stamp; + int event_type; + int entry_type; + char *host_name; + char *service_description; + int state; + int state_type; + char *event_info; + struct archived_event_struct *next; + } archived_event; + +typedef struct alert_producer_struct { + int producer_type; + char *host_name; + char *service_description; + int total_alerts; + struct alert_producer_struct *next; + } alert_producer; + + +void read_archived_event_data(void); +void scan_log_file_for_archived_event_data(char *); +void convert_timeperiod_to_times(int); +void compute_report_times(void); +void determine_standard_report_options(void); +void add_archived_event(int, time_t, int, int, char *, char *, char *); +alert_producer *find_producer(int, char *, char *); +alert_producer *add_producer(int, char *, char *); +void free_event_list(void); +void free_producer_list(void); + +void display_report(void); +void display_recent_alerts(void); +void display_alert_totals(void); +void display_hostgroup_alert_totals(void); +void display_specific_hostgroup_alert_totals(hostgroup *); +void display_servicegroup_alert_totals(void); +void display_specific_servicegroup_alert_totals(servicegroup *); +void display_host_alert_totals(void); +void display_specific_host_alert_totals(host *); +void display_service_alert_totals(void); +void display_specific_service_alert_totals(service *); +void display_top_alerts(void); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + + +archived_event *event_list = NULL; +alert_producer *producer_list = NULL; + +authdata current_authdata; + +time_t t1; +time_t t2; + +int start_second = 0; +int start_minute = 0; +int start_hour = 0; +int start_day = 1; +int start_month = 1; +int start_year = 2000; +int end_second = 0; +int end_minute = 0; +int end_hour = 24; +int end_day = 1; +int end_month = 1; +int end_year = 2000; + +int compute_time_from_parts = FALSE; +int timeperiod_type = TIMEPERIOD_CUSTOM; + +int state_types = AE_HARD_STATE + AE_SOFT_STATE; +int alert_types = AE_HOST_ALERT + AE_SERVICE_ALERT; +int host_states = AE_HOST_UP + AE_HOST_DOWN + AE_HOST_UNREACHABLE; +int service_states = AE_SERVICE_OK + AE_SERVICE_WARNING + AE_SERVICE_UNKNOWN + AE_SERVICE_CRITICAL; + +int show_all_hostgroups = TRUE; +int show_all_servicegroups = TRUE; +int show_all_hosts = TRUE; + +char *target_hostgroup_name = ""; +char *target_servicegroup_name = ""; +char *target_host_name = ""; +hostgroup *target_hostgroup = NULL; +servicegroup *target_servicegroup = NULL; +host *target_host = NULL; + +int earliest_archive = 0; +int item_limit = 25; +int total_items = 0; + +int embedded = FALSE; +int display_header = TRUE; + +int output_format = HTML_OUTPUT; +int display_type = REPORT_RECENT_ALERTS; +int standard_report = SREPORT_NONE; +int generate_report = FALSE; + + + +int main(int argc, char **argv) { + int result = OK; + char temp_buffer[MAX_INPUT_BUFFER]; + char start_timestring[MAX_DATETIME_LENGTH]; + char end_timestring[MAX_DATETIME_LENGTH]; + host *temp_host; + int days, hours, minutes, seconds; + hostgroup *temp_hostgroup; + servicegroup *temp_servicegroup; + time_t t3; + time_t current_time; + struct tm *t; + int x; + + /* 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; + } + + /* initialize report time period to last 24 hours */ + time(&t2); + t1 = (time_t)(t2 - (60 * 60 * 24)); + + /* get the arguments passed in the URL */ + process_cgivars(); + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + if(standard_report != SREPORT_NONE) + determine_standard_report_options(); + + if(compute_time_from_parts == TRUE) + compute_report_times(); + + /* make sure times are sane, otherwise swap them */ + if(t2 < t1) { + t3 = t2; + t2 = t1; + t1 = t3; + } + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* center column of top row */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Alert Summary Report"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + display_info_table(temp_buffer, FALSE, ¤t_authdata); + + printf("\n"); + + if(generate_report == TRUE) { + + printf("
    \n"); + if(display_type == REPORT_TOP_ALERTS) + printf("Top Alert Producers"); + else if(display_type == REPORT_ALERT_TOTALS || display_type == REPORT_HOSTGROUP_ALERT_TOTALS || display_type == REPORT_SERVICEGROUP_ALERT_TOTALS || display_type == REPORT_HOST_ALERT_TOTALS || display_type == REPORT_SERVICE_ALERT_TOTALS) + printf("Alert Totals"); + else + printf("Most Recent Alerts"); + + if(show_all_hostgroups == FALSE) + printf(" For Hostgroup '%s'", target_hostgroup_name); + else if(show_all_servicegroups == FALSE) + printf(" For Servicegroup '%s'", target_servicegroup_name); + else if(show_all_hosts == FALSE) + printf(" For Host '%s'", target_host_name); + + printf("
    \n"); + + printf("
    \n"); + + get_time_string(&t1, start_timestring, sizeof(start_timestring) - 1, SHORT_DATE_TIME); + get_time_string(&t2, end_timestring, sizeof(end_timestring) - 1, SHORT_DATE_TIME); + printf("
    %s to %s
    \n", start_timestring, end_timestring); + + get_time_breakdown((time_t)(t2 - t1), &days, &hours, &minutes, &seconds); + printf("
    Duration: %dd %dh %dm %ds
    \n", days, hours, minutes, seconds); + } + + printf("
    \n"); + + if(generate_report == TRUE) { + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + /* display context-sensitive help */ + printf("\n"); + + printf("
    Report Options Summary:
    Alert Types:\n"); + if(alert_types & AE_HOST_ALERT) + printf("Host"); + if(alert_types & AE_SERVICE_ALERT) + printf("%sService", (alert_types & AE_HOST_ALERT) ? " & " : ""); + printf(" Alerts
    State Types:"); + if(state_types & AE_SOFT_STATE) + printf("Soft"); + if(state_types & AE_HARD_STATE) + printf("%sHard", (state_types & AE_SOFT_STATE) ? " & " : ""); + printf(" States
    Host States:"); + x = 0; + if(host_states & AE_HOST_UP) { + printf("Up"); + x = 1; + } + if(host_states & AE_HOST_DOWN) { + printf("%sDown", (x == 1) ? ", " : ""); + x = 1; + } + if(host_states & AE_HOST_UNREACHABLE) + printf("%sUnreachable", (x == 1) ? ", " : ""); + if(x == 0) + printf("None"); + printf("
    Service States:"); + x = 0; + if(service_states & AE_SERVICE_OK) { + printf("Ok"); + x = 1; + } + if(service_states & AE_SERVICE_WARNING) { + printf("%sWarning", (x == 1) ? ", " : ""); + x = 1; + } + if(service_states & AE_SERVICE_UNKNOWN) { + printf("%sUnknown", (x == 1) ? ", " : ""); + x = 1; + } + if(service_states & AE_SERVICE_CRITICAL) + printf("%sCritical", (x == 1) ? ", " : ""); + if(x == 0) + printf("None"); + printf("
    \n"); + printf("
    \n", SUMMARY_CGI); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + if(display_type == REPORT_TOP_ALERTS) + display_context_help(CONTEXTHELP_SUMMARY_ALERT_PRODUCERS); + else if(display_type == REPORT_ALERT_TOTALS) + display_context_help(CONTEXTHELP_SUMMARY_ALERT_TOTALS); + else if(display_type == REPORT_HOSTGROUP_ALERT_TOTALS) + display_context_help(CONTEXTHELP_SUMMARY_HOSTGROUP_ALERT_TOTALS); + else if(display_type == REPORT_HOST_ALERT_TOTALS) + display_context_help(CONTEXTHELP_SUMMARY_HOST_ALERT_TOTALS); + else if(display_type == REPORT_SERVICE_ALERT_TOTALS) + display_context_help(CONTEXTHELP_SUMMARY_SERVICE_ALERT_TOTALS); + else if(display_type == REPORT_SERVICEGROUP_ALERT_TOTALS) + display_context_help(CONTEXTHELP_SUMMARY_SERVICEGROUP_ALERT_TOTALS); + else + display_context_help(CONTEXTHELP_SUMMARY_RECENT_ALERTS); + printf("
    \n"); + } + + else { + printf("\n"); + + printf("\n"); + + printf("
    \n"); + display_context_help(CONTEXTHELP_SUMMARY_MENU); + printf("
    \n"); + } + + printf("
    \n"); + } + + + /*********************************/ + /****** GENERATE THE REPORT ******/ + /*********************************/ + + if(generate_report == TRUE) { + read_archived_event_data(); + display_report(); + } + + /* ask user for report options */ + else { + + time(¤t_time); + t = localtime(¤t_time); + + start_day = 1; + start_year = t->tm_year + 1900; + end_day = t->tm_mday; + end_year = t->tm_year + 1900; + + printf("
    Standard Reports:
    \n"); + printf("
    \n"); + printf("
    \n", SUMMARY_CGI); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Report Type:\n"); + printf("\n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + printf("
    Custom Report Options:
    \n"); + printf("
    \n"); + printf("
    \n", SUMMARY_CGI); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Report Type:\n"); + printf("\n"); + printf("
    Report Period:\n"); + printf("\n"); + printf("
    If Custom Report Period...
    Start Date (Inclusive):"); + printf("\n "); + printf(" ", start_day); + printf("", start_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    End Date (Inclusive):"); + printf("\n "); + printf(" ", end_day); + printf("", end_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("

    Limit To Hostgroup:\n"); + printf("\n"); + printf("
    Limit To Servicegroup:\n"); + printf("\n"); + printf("
    Limit To Host:\n"); + printf("\n"); + printf("
    Alert Types:\n"); + printf("\n"); + printf("
    State Types:\n"); + printf("\n"); + printf("
    Host States:\n"); + printf("\n"); + printf("
    Service States:\n"); + printf("\n"); + printf("
    Max List Items:\n"); + printf("\n", item_limit); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + } + + + document_footer(); + + /* free all other allocated memory */ + free_memory(); + free_event_list(); + free_producer_list(); + + 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)0; + get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME); + printf("Expires: %s\r\n", date_time); + + if(output_format == HTML_OUTPUT) + printf("Content-type: text/html\r\n\r\n"); + else { + printf("Content-type: text/plain\r\n\r\n"); + return; + } + + if(embedded == TRUE || output_format == CSV_OUTPUT) + return; + + printf("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios Event Summary\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, SUMMARY_CSS); + } + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(SUMMARY_CGI, SSI_HEADER); + + return; + } + + + +void document_footer(void) { + + if(output_format != HTML_OUTPUT) + return; + + if(embedded == TRUE) + return; + + /* include user SSI footer */ + include_ssi_files(SUMMARY_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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 first time argument */ + else if(!strcmp(variables[x], "t1")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t1 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = FALSE; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t2")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t2 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = FALSE; + } + + /* we found the standard timeperiod argument */ + else if(!strcmp(variables[x], "timeperiod")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "today")) + timeperiod_type = TIMEPERIOD_TODAY; + else if(!strcmp(variables[x], "yesterday")) + timeperiod_type = TIMEPERIOD_YESTERDAY; + else if(!strcmp(variables[x], "thisweek")) + timeperiod_type = TIMEPERIOD_THISWEEK; + else if(!strcmp(variables[x], "lastweek")) + timeperiod_type = TIMEPERIOD_LASTWEEK; + else if(!strcmp(variables[x], "thismonth")) + timeperiod_type = TIMEPERIOD_THISMONTH; + else if(!strcmp(variables[x], "lastmonth")) + timeperiod_type = TIMEPERIOD_LASTMONTH; + else if(!strcmp(variables[x], "thisquarter")) + timeperiod_type = TIMEPERIOD_THISQUARTER; + else if(!strcmp(variables[x], "lastquarter")) + timeperiod_type = TIMEPERIOD_LASTQUARTER; + else if(!strcmp(variables[x], "thisyear")) + timeperiod_type = TIMEPERIOD_THISYEAR; + else if(!strcmp(variables[x], "lastyear")) + timeperiod_type = TIMEPERIOD_LASTYEAR; + else if(!strcmp(variables[x], "last24hours")) + timeperiod_type = TIMEPERIOD_LAST24HOURS; + else if(!strcmp(variables[x], "last7days")) + timeperiod_type = TIMEPERIOD_LAST7DAYS; + else if(!strcmp(variables[x], "last31days")) + timeperiod_type = TIMEPERIOD_LAST31DAYS; + else if(!strcmp(variables[x], "custom")) + timeperiod_type = TIMEPERIOD_CUSTOM; + else + continue; + + convert_timeperiod_to_times(timeperiod_type); + compute_time_from_parts = 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 time argument */ + else if(!strcmp(variables[x], "smon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "sday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "syear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ssec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "shour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + + /* we found time argument */ + else if(!strcmp(variables[x], "emon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eyear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "emin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "esec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ehour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found the item limit argument */ + else if(!strcmp(variables[x], "limit")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + item_limit = atoi(variables[x]); + } + + /* we found the state types argument */ + else if(!strcmp(variables[x], "statetypes")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + state_types = atoi(variables[x]); + } + + /* we found the alert types argument */ + else if(!strcmp(variables[x], "alerttypes")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + alert_types = atoi(variables[x]); + } + + /* we found the host states argument */ + else if(!strcmp(variables[x], "hoststates")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + host_states = atoi(variables[x]); + } + + /* we found the service states argument */ + else if(!strcmp(variables[x], "servicestates")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + service_states = atoi(variables[x]); + } + + /* we found the generate report argument */ + else if(!strcmp(variables[x], "report")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + generate_report = (atoi(variables[x]) > 0) ? TRUE : FALSE; + } + + + /* we found the display type argument */ + else if(!strcmp(variables[x], "displaytype")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + display_type = atoi(variables[x]); + } + + /* we found the standard report argument */ + else if(!strcmp(variables[x], "standardreport")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + standard_report = atoi(variables[x]); + } + + /* we found the hostgroup argument */ + else if(!strcmp(variables[x], "hostgroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((target_hostgroup_name = (char *)strdup(variables[x])) == NULL) + target_hostgroup_name = ""; + strip_html_brackets(target_hostgroup_name); + + if(!strcmp(target_hostgroup_name, "all")) + show_all_hostgroups = TRUE; + else { + show_all_hostgroups = FALSE; + target_hostgroup = find_hostgroup(target_hostgroup_name); + } + } + + /* we found the servicegroup argument */ + else if(!strcmp(variables[x], "servicegroup")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((target_servicegroup_name = (char *)strdup(variables[x])) == NULL) + target_servicegroup_name = ""; + strip_html_brackets(target_servicegroup_name); + + if(!strcmp(target_servicegroup_name, "all")) + show_all_servicegroups = TRUE; + else { + show_all_servicegroups = FALSE; + target_servicegroup = find_servicegroup(target_servicegroup_name); + } + } + + /* we found the host argument */ + else if(!strcmp(variables[x], "host")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if((target_host_name = (char *)strdup(variables[x])) == NULL) + target_host_name = ""; + strip_html_brackets(target_host_name); + + if(!strcmp(target_host_name, "all")) + show_all_hosts = TRUE; + else { + show_all_hosts = FALSE; + target_host = find_host(target_host_name); + } + } + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* reads log files for archived event data */ +void read_archived_event_data(void) { + char filename[MAX_FILENAME_LENGTH]; + int oldest_archive = 0; + int newest_archive = 0; + int current_archive = 0; + + /* determine oldest archive to use when scanning for data */ + oldest_archive = determine_archive_to_use_from_time(t1); + + /* determine most recent archive to use when scanning for data */ + newest_archive = determine_archive_to_use_from_time(t2); + + if(oldest_archive < newest_archive) + oldest_archive = newest_archive; + + /* read in all the necessary archived logs (from most recent to earliest) */ + for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) { + + /* get the name of the log file that contains this archive */ + get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1); + + /* scan the log file for archived state data */ + scan_log_file_for_archived_event_data(filename); + } + + return; + } + + + +/* grabs archived event data from a log file */ +void scan_log_file_for_archived_event_data(char *filename) { + char *input = NULL; + char *input2 = NULL; + char entry_host_name[MAX_INPUT_BUFFER]; + char entry_svc_description[MAX_INPUT_BUFFER]; + int state; + int state_type; + char *temp_buffer; + char *plugin_output; + time_t time_stamp; + mmapfile *thefile; + + + if((thefile = mmap_fopen(filename)) == NULL) + return; + + while(1) { + + /* free memory */ + free(input); + free(input2); + input = NULL; + input2 = NULL; + + /* read the next line */ + if((input = mmap_fgets(thefile)) == NULL) + break; + + strip(input); + + if((input2 = strdup(input)) == NULL) + continue; + + /* get the timestamp */ + temp_buffer = my_strtok(input2, "]"); + time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10); + if(time_stamp < t1 || time_stamp > t2) + continue; + + /* host alerts */ + if(strstr(input, "HOST ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* state type */ + if(strstr(input, ";SOFT;")) + state_type = AE_SOFT_STATE; + else + state_type = AE_HARD_STATE; + + /* get the plugin output */ + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + plugin_output = my_strtok(NULL, "\n"); + + /* state */ + if(strstr(input, ";DOWN;")) + state = AE_HOST_DOWN; + else if(strstr(input, ";UNREACHABLE;")) + state = AE_HOST_UNREACHABLE; + else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) + state = AE_HOST_UP; + else + continue; + + add_archived_event(AE_HOST_ALERT, time_stamp, state, state_type, entry_host_name, NULL, plugin_output); + } + + /* service alerts */ + if(strstr(input, "SERVICE ALERT:")) { + + /* get host name */ + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + /* get service description */ + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); + entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; + + /* state type */ + if(strstr(input, ";SOFT;")) + state_type = AE_SOFT_STATE; + else + state_type = AE_HARD_STATE; + + /* get the plugin output */ + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + plugin_output = my_strtok(NULL, "\n"); + + /* state */ + if(strstr(input, ";WARNING;")) + state = AE_SERVICE_WARNING; + else if(strstr(input, ";UNKNOWN;")) + state = AE_SERVICE_UNKNOWN; + else if(strstr(input, ";CRITICAL;")) + state = AE_SERVICE_CRITICAL; + else if(strstr(input, ";RECOVERY") || strstr(input, ";OK;")) + state = AE_SERVICE_OK; + else + continue; + + add_archived_event(AE_SERVICE_ALERT, time_stamp, state, state_type, entry_host_name, entry_svc_description, plugin_output); + } + } + + /* free memory and close the file */ + free(input); + free(input2); + mmap_fclose(thefile); + + return; + } + + + + +void convert_timeperiod_to_times(int type) { + time_t current_time; + struct tm *t; + + /* get the current time */ + time(¤t_time); + + t = localtime(¤t_time); + + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_isdst = -1; + + switch(type) { + case TIMEPERIOD_LAST24HOURS: + t1 = current_time - (60 * 60 * 24); + t2 = current_time; + break; + case TIMEPERIOD_TODAY: + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_YESTERDAY: + t1 = (time_t)(mktime(t) - (60 * 60 * 24)); + t2 = (time_t)mktime(t); + break; + case TIMEPERIOD_THISWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + t2 = current_time; + break; + case TIMEPERIOD_LASTWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7)); + t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + break; + case TIMEPERIOD_THISMONTH: + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTMONTH: + t->tm_mday = 1; + t2 = mktime(t); + if(t->tm_mon == 0) { + t->tm_mon = 11; + t->tm_year--; + } + else + t->tm_mon--; + t1 = mktime(t); + break; + case TIMEPERIOD_THISQUARTER: + /* not implemented */ + break; + case TIMEPERIOD_LASTQUARTER: + /* not implemented */ + break; + case TIMEPERIOD_THISYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t2 = mktime(t); + t->tm_year--; + t1 = mktime(t); + break; + case TIMEPERIOD_LAST7DAYS: + t2 = current_time; + t1 = current_time - (7 * 24 * 60 * 60); + break; + case TIMEPERIOD_LAST31DAYS: + t2 = current_time; + t1 = current_time - (31 * 24 * 60 * 60); + break; + default: + break; + } + + return; + } + + + +void compute_report_times(void) { + time_t current_time; + struct tm *st; + struct tm *et; + + /* get the current time */ + time(¤t_time); + + st = localtime(¤t_time); + + st->tm_sec = start_second; + st->tm_min = start_minute; + st->tm_hour = start_hour; + st->tm_mday = start_day; + st->tm_mon = start_month - 1; + st->tm_year = start_year - 1900; + st->tm_isdst = -1; + + t1 = mktime(st); + + et = localtime(¤t_time); + + et->tm_sec = end_second; + et->tm_min = end_minute; + et->tm_hour = end_hour; + et->tm_mday = end_day; + et->tm_mon = end_month - 1; + et->tm_year = end_year - 1900; + et->tm_isdst = -1; + + t2 = mktime(et); + } + + + +void free_event_list(void) { + archived_event *this_event = NULL; + archived_event *next_event = NULL; + + for(this_event = event_list; this_event != NULL;) { + next_event = this_event->next; + if(this_event->host_name != NULL) + free(this_event->host_name); + if(this_event->service_description != NULL) + free(this_event->service_description); + if(this_event->event_info != NULL) + free(this_event->event_info); + free(this_event); + this_event = next_event; + } + + event_list = NULL; + + return; + } + + +/* adds an archived event entry to the list in memory */ +void add_archived_event(int event_type, time_t time_stamp, int entry_type, int state_type, char *host_name, char *svc_description, char *event_info) { + archived_event *last_event = NULL; + archived_event *temp_event = NULL; + archived_event *new_event = NULL; + service *temp_service = NULL; + host *temp_host; + + + /* check timestamp sanity */ + if(time_stamp < t1 || time_stamp > t2) + return; + + /* check alert type (host or service alert) */ + if(!(alert_types & event_type)) + return; + + /* check state type (soft or hard state) */ + if(!(state_types & state_type)) + return; + + /* check state (host or service state) */ + if(event_type == AE_HOST_ALERT) { + if(!(host_states & entry_type)) + return; + } + else { + if(!(service_states & entry_type)) + return; + } + + /* find the host this entry is associated with */ + temp_host = find_host(host_name); + + /* check hostgroup match (valid filter for all reports) */ + if(show_all_hostgroups == FALSE && is_host_member_of_hostgroup(target_hostgroup, temp_host) == FALSE) + return; + + /* check host match (valid filter for some reports) */ + if(show_all_hosts == FALSE && (display_type == REPORT_RECENT_ALERTS || display_type == REPORT_HOST_ALERT_TOTALS || display_type == REPORT_SERVICE_ALERT_TOTALS)) { + if(target_host == NULL || temp_host == NULL) + return; + if(strcmp(target_host->name, temp_host->name)) + return; + } + + /* check servicegroup math (valid filter for all reports) */ + if(event_type == AE_SERVICE_ALERT) { + temp_service = find_service(host_name, svc_description); + if(show_all_servicegroups == FALSE && is_service_member_of_servicegroup(target_servicegroup, temp_service) == FALSE) + return; + } + else { + if(show_all_servicegroups == FALSE && is_host_member_of_servicegroup(target_servicegroup, temp_host) == FALSE) + return; + } + + /* check authorization */ + if(event_type == AE_SERVICE_ALERT) { + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + return; + } + else { + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + return; + } + +#ifdef DEBUG + if(event_type == AE_HOST_ALERT) + printf("Adding host alert (%s) @ %lu
    \n", host_name, (unsigned long)time_stamp); + else + printf("Adding service alert (%s/%s) @ %lu
    \n", host_name, svc_description, (unsigned long)time_stamp); +#endif + + /* allocate memory for the new entry */ + new_event = (archived_event *)malloc(sizeof(archived_event)); + if(new_event == NULL) + return; + + /* allocate memory for the host name */ + if(host_name != NULL) { + new_event->host_name = (char *)malloc(strlen(host_name) + 1); + if(new_event->host_name != NULL) + strcpy(new_event->host_name, host_name); + } + else + new_event->host_name = NULL; + + /* allocate memory for the service description */ + if(svc_description != NULL) { + new_event->service_description = (char *)malloc(strlen(svc_description) + 1); + if(new_event->service_description != NULL) + strcpy(new_event->service_description, svc_description); + } + else + new_event->service_description = NULL; + + /* allocate memory for the event info */ + if(event_info != NULL) { + new_event->event_info = (char *)malloc(strlen(event_info) + 1); + if(new_event->event_info != NULL) + strcpy(new_event->event_info, event_info); + } + else + new_event->event_info = NULL; + + new_event->event_type = event_type; + new_event->time_stamp = time_stamp; + new_event->entry_type = entry_type; + new_event->state_type = state_type; + + + /* add the new entry to the list in memory, sorted by time */ + last_event = event_list; + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + if(new_event->time_stamp >= temp_event->time_stamp) { + new_event->next = temp_event; + if(temp_event == event_list) + event_list = new_event; + else + last_event->next = new_event; + break; + } + else + last_event = temp_event; + } + if(event_list == NULL) { + new_event->next = NULL; + event_list = new_event; + } + else if(temp_event == NULL) { + new_event->next = NULL; + last_event->next = new_event; + } + + total_items++; + + return; + } + + + +/* determines standard report options */ +void determine_standard_report_options(void) { + + /* report over last 7 days */ + convert_timeperiod_to_times(TIMEPERIOD_LAST7DAYS); + compute_time_from_parts = FALSE; + + /* common options */ + state_types = AE_HARD_STATE; + item_limit = 25; + + /* report-specific options */ + switch(standard_report) { + + case SREPORT_RECENT_ALERTS: + display_type = REPORT_RECENT_ALERTS; + alert_types = AE_HOST_ALERT + AE_SERVICE_ALERT; + host_states = AE_HOST_UP + AE_HOST_DOWN + AE_HOST_UNREACHABLE; + service_states = AE_SERVICE_OK + AE_SERVICE_WARNING + AE_SERVICE_UNKNOWN + AE_SERVICE_CRITICAL; + break; + + case SREPORT_RECENT_HOST_ALERTS: + display_type = REPORT_RECENT_ALERTS; + alert_types = AE_HOST_ALERT; + host_states = AE_HOST_UP + AE_HOST_DOWN + AE_HOST_UNREACHABLE; + break; + + case SREPORT_RECENT_SERVICE_ALERTS: + display_type = REPORT_RECENT_ALERTS; + alert_types = AE_SERVICE_ALERT; + service_states = AE_SERVICE_OK + AE_SERVICE_WARNING + AE_SERVICE_UNKNOWN + AE_SERVICE_CRITICAL; + break; + + case SREPORT_TOP_HOST_ALERTS: + display_type = REPORT_TOP_ALERTS; + alert_types = AE_HOST_ALERT; + host_states = AE_HOST_UP + AE_HOST_DOWN + AE_HOST_UNREACHABLE; + break; + + case SREPORT_TOP_SERVICE_ALERTS: + display_type = REPORT_TOP_ALERTS; + alert_types = AE_SERVICE_ALERT; + service_states = AE_SERVICE_OK + AE_SERVICE_WARNING + AE_SERVICE_UNKNOWN + AE_SERVICE_CRITICAL; + break; + + default: + break; + } + + return; + } + + + +/* displays report */ +void display_report(void) { + + switch(display_type) { + + case REPORT_ALERT_TOTALS: + display_alert_totals(); + break; + + case REPORT_HOSTGROUP_ALERT_TOTALS: + display_hostgroup_alert_totals(); + break; + + case REPORT_HOST_ALERT_TOTALS: + display_host_alert_totals(); + break; + + case REPORT_SERVICEGROUP_ALERT_TOTALS: + display_servicegroup_alert_totals(); + break; + + case REPORT_SERVICE_ALERT_TOTALS: + display_service_alert_totals(); + break; + + case REPORT_TOP_ALERTS: + display_top_alerts(); + break; + + default: + display_recent_alerts(); + break; + } + + return; + } + + +/* displays recent alerts */ +void display_recent_alerts(void) { + archived_event *temp_event; + int current_item = 0; + int odd = 0; + char *bgclass = ""; + char *status_bgclass = ""; + char *status = ""; + char date_time[MAX_DATETIME_LENGTH]; + + + + printf("
    \n"); + + if(item_limit <= 0 || total_items <= item_limit || total_items == 0) + printf("
    Displaying all %d matching alerts\n", total_items); + else + printf("
    Displaying most recent %d of %d total matching alerts\n", item_limit, total_items); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next, current_item++) { + + if(current_item >= item_limit && item_limit > 0) + break; + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("", bgclass); + + get_time_string(&temp_event->time_stamp, date_time, (int)sizeof(date_time), SHORT_DATE_TIME); + printf("", bgclass, date_time); + + printf("", bgclass, (temp_event->event_type == AE_HOST_ALERT) ? "Host Alert" : "Service Alert"); + + printf("", bgclass, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_event->host_name), temp_event->host_name); + + if(temp_event->event_type == AE_HOST_ALERT) + printf("", bgclass); + else { + printf("", url_encode(temp_event->service_description), temp_event->service_description); + } + + switch(temp_event->entry_type) { + case AE_HOST_UP: + status_bgclass = "hostUP"; + status = "UP"; + break; + case AE_HOST_DOWN: + status_bgclass = "hostDOWN"; + status = "DOWN"; + break; + case AE_HOST_UNREACHABLE: + status_bgclass = "hostUNREACHABLE"; + status = "UNREACHABLE"; + break; + case AE_SERVICE_OK: + status_bgclass = "serviceOK"; + status = "OK"; + break; + case AE_SERVICE_WARNING: + status_bgclass = "serviceWARNING"; + status = "WARNING"; + break; + case AE_SERVICE_UNKNOWN: + status_bgclass = "serviceUNKNOWN"; + status = "UNKNOWN"; + break; + case AE_SERVICE_CRITICAL: + status_bgclass = "serviceCRITICAL"; + status = "CRITICAL"; + break; + default: + status_bgclass = bgclass; + status = "???"; + break; + } + + printf("", status_bgclass, status); + + printf("", bgclass, (temp_event->state_type == AE_SOFT_STATE) ? "SOFT" : "HARD"); + + printf("", bgclass, temp_event->event_info); + + printf("\n"); + } + + printf("
    TimeAlert TypeHostServiceStateState TypeInformation
    %s%s%sN/A%s%s%s%s
    \n"); + printf("
    \n"); + + return; + } + + + +/* displays alerts totals */ +void display_alert_totals(void) { + int hard_host_up_alerts = 0; + int soft_host_up_alerts = 0; + int hard_host_down_alerts = 0; + int soft_host_down_alerts = 0; + int hard_host_unreachable_alerts = 0; + int soft_host_unreachable_alerts = 0; + int hard_service_ok_alerts = 0; + int soft_service_ok_alerts = 0; + int hard_service_warning_alerts = 0; + int soft_service_warning_alerts = 0; + int hard_service_unknown_alerts = 0; + int soft_service_unknown_alerts = 0; + int hard_service_critical_alerts = 0; + int soft_service_critical_alerts = 0; + archived_event *temp_event; + + + /************************/ + /**** OVERALL TOTALS ****/ + /************************/ + + /* process all events */ + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + + /* host alerts */ + if(temp_event->event_type == AE_HOST_ALERT) { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_HOST_UP) + soft_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + soft_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + soft_host_unreachable_alerts++; + } + else { + if(temp_event->entry_type == AE_HOST_UP) + hard_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + hard_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + hard_host_unreachable_alerts++; + } + } + + /* service alerts */ + else { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_SERVICE_OK) + soft_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + soft_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + soft_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + soft_service_critical_alerts++; + } + else { + if(temp_event->entry_type == AE_SERVICE_OK) + hard_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + hard_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + hard_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + hard_service_critical_alerts++; + } + } + } + + printf("
    \n"); + + printf("
    \n"); + printf("
    Overall Totals
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + + if(alert_types & AE_HOST_ALERT) { + + printf("\n"); + } + + if(alert_types & AE_SERVICE_ALERT) { + + printf("\n"); + } + + printf("\n"); + printf("
    \n"); + + printf("
    Host Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_host_up_alerts, hard_host_up_alerts, soft_host_up_alerts + hard_host_up_alerts); + printf("\n", soft_host_down_alerts, hard_host_down_alerts, soft_host_down_alerts + hard_host_down_alerts); + printf("\n", soft_host_unreachable_alerts, hard_host_unreachable_alerts, soft_host_unreachable_alerts + hard_host_unreachable_alerts); + printf("\n", soft_host_up_alerts + soft_host_down_alerts + soft_host_unreachable_alerts, hard_host_up_alerts + hard_host_down_alerts + hard_host_unreachable_alerts, soft_host_up_alerts + hard_host_up_alerts + soft_host_down_alerts + hard_host_down_alerts + soft_host_unreachable_alerts + hard_host_unreachable_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("
    Service Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_service_ok_alerts, hard_service_ok_alerts, soft_service_ok_alerts + hard_service_ok_alerts); + printf("\n", soft_service_warning_alerts, hard_service_warning_alerts, soft_service_warning_alerts + hard_service_warning_alerts); + printf("\n", soft_service_unknown_alerts, hard_service_unknown_alerts, soft_service_unknown_alerts + hard_service_unknown_alerts); + printf("\n", soft_service_critical_alerts, hard_service_critical_alerts, soft_service_critical_alerts + hard_service_critical_alerts); + printf("\n", soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts, hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts, soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts + hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + printf("
    \n"); + + return; + } + + + +/* displays hostgroup alert totals */ +void display_hostgroup_alert_totals(void) { + hostgroup *temp_hostgroup; + + /**************************/ + /**** HOSTGROUP TOTALS ****/ + /**************************/ + + printf("
    \n"); + + printf("
    \n"); + printf("
    Totals By Hostgroup
    \n"); + + if(show_all_hostgroups == FALSE) + display_specific_hostgroup_alert_totals(target_hostgroup); + else { + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) + display_specific_hostgroup_alert_totals(temp_hostgroup); + } + + printf("
    \n"); + + return; + } + + +/* displays alert totals for a specific hostgroup */ +void display_specific_hostgroup_alert_totals(hostgroup *grp) { + int hard_host_up_alerts = 0; + int soft_host_up_alerts = 0; + int hard_host_down_alerts = 0; + int soft_host_down_alerts = 0; + int hard_host_unreachable_alerts = 0; + int soft_host_unreachable_alerts = 0; + int hard_service_ok_alerts = 0; + int soft_service_ok_alerts = 0; + int hard_service_warning_alerts = 0; + int soft_service_warning_alerts = 0; + int hard_service_unknown_alerts = 0; + int soft_service_unknown_alerts = 0; + int hard_service_critical_alerts = 0; + int soft_service_critical_alerts = 0; + archived_event *temp_event; + host *temp_host; + + if(grp == NULL) + return; + + /* make sure the user is authorized to view this hostgroup */ + if(is_authorized_for_hostgroup(grp, ¤t_authdata) == FALSE) + return; + + /* process all events */ + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + + temp_host = find_host(temp_event->host_name); + if(is_host_member_of_hostgroup(grp, temp_host) == FALSE) + continue; + + /* host alerts */ + if(temp_event->event_type == AE_HOST_ALERT) { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_HOST_UP) + soft_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + soft_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + soft_host_unreachable_alerts++; + } + else { + if(temp_event->entry_type == AE_HOST_UP) + hard_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + hard_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + hard_host_unreachable_alerts++; + } + } + + /* service alerts */ + else { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_SERVICE_OK) + soft_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + soft_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + soft_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + soft_service_critical_alerts++; + } + else { + if(temp_event->entry_type == AE_SERVICE_OK) + hard_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + hard_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + hard_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + hard_service_critical_alerts++; + } + } + } + + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + + printf("\n", grp->group_name, grp->alias); + + printf("\n"); + + if(alert_types & AE_HOST_ALERT) { + + printf("\n"); + } + + if(alert_types & AE_SERVICE_ALERT) { + + printf("\n"); + } + + printf("\n"); + + printf("
    Hostgroup '%s' (%s)
    \n"); + + printf("
    Host Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_host_up_alerts, hard_host_up_alerts, soft_host_up_alerts + hard_host_up_alerts); + printf("\n", soft_host_down_alerts, hard_host_down_alerts, soft_host_down_alerts + hard_host_down_alerts); + printf("\n", soft_host_unreachable_alerts, hard_host_unreachable_alerts, soft_host_unreachable_alerts + hard_host_unreachable_alerts); + printf("\n", soft_host_up_alerts + soft_host_down_alerts + soft_host_unreachable_alerts, hard_host_up_alerts + hard_host_down_alerts + hard_host_unreachable_alerts, soft_host_up_alerts + hard_host_up_alerts + soft_host_down_alerts + hard_host_down_alerts + soft_host_unreachable_alerts + hard_host_unreachable_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("
    Service Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_service_ok_alerts, hard_service_ok_alerts, soft_service_ok_alerts + hard_service_ok_alerts); + printf("\n", soft_service_warning_alerts, hard_service_warning_alerts, soft_service_warning_alerts + hard_service_warning_alerts); + printf("\n", soft_service_unknown_alerts, hard_service_unknown_alerts, soft_service_unknown_alerts + hard_service_unknown_alerts); + printf("\n", soft_service_critical_alerts, hard_service_critical_alerts, soft_service_critical_alerts + hard_service_critical_alerts); + printf("\n", soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts, hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts, soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts + hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + return; + } + + + +/* displays host alert totals */ +void display_host_alert_totals(void) { + host *temp_host; + + /*********************/ + /**** HOST TOTALS ****/ + /*********************/ + + printf("
    \n"); + + printf("
    \n"); + printf("
    Totals By Host
    \n"); + + if(show_all_hosts == FALSE) + display_specific_host_alert_totals(target_host); + else { + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) + display_specific_host_alert_totals(temp_host); + } + + printf("
    \n"); + + return; + } + + +/* displays alert totals for a specific host */ +void display_specific_host_alert_totals(host *hst) { + int hard_host_up_alerts = 0; + int soft_host_up_alerts = 0; + int hard_host_down_alerts = 0; + int soft_host_down_alerts = 0; + int hard_host_unreachable_alerts = 0; + int soft_host_unreachable_alerts = 0; + int hard_service_ok_alerts = 0; + int soft_service_ok_alerts = 0; + int hard_service_warning_alerts = 0; + int soft_service_warning_alerts = 0; + int hard_service_unknown_alerts = 0; + int soft_service_unknown_alerts = 0; + int hard_service_critical_alerts = 0; + int soft_service_critical_alerts = 0; + archived_event *temp_event; + + if(hst == NULL) + return; + + /* make sure the user is authorized to view this host */ + if(is_authorized_for_host(hst, ¤t_authdata) == FALSE) + return; + + if(show_all_hostgroups == FALSE && target_hostgroup != NULL) { + if(is_host_member_of_hostgroup(target_hostgroup, hst) == FALSE) + return; + } + + /* process all events */ + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + + if(strcmp(temp_event->host_name, hst->name)) + continue; + + /* host alerts */ + if(temp_event->event_type == AE_HOST_ALERT) { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_HOST_UP) + soft_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + soft_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + soft_host_unreachable_alerts++; + } + else { + if(temp_event->entry_type == AE_HOST_UP) + hard_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + hard_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + hard_host_unreachable_alerts++; + } + } + + /* service alerts */ + else { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_SERVICE_OK) + soft_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + soft_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + soft_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + soft_service_critical_alerts++; + } + else { + if(temp_event->entry_type == AE_SERVICE_OK) + hard_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + hard_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + hard_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + hard_service_critical_alerts++; + } + } + } + + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + + printf("\n", hst->name, hst->alias); + + printf("\n"); + + if(alert_types & AE_HOST_ALERT) { + + printf("\n"); + } + + if(alert_types & AE_SERVICE_ALERT) { + + printf("\n"); + } + + printf("\n"); + + printf("
    Host '%s' (%s)
    \n"); + + printf("
    Host Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_host_up_alerts, hard_host_up_alerts, soft_host_up_alerts + hard_host_up_alerts); + printf("\n", soft_host_down_alerts, hard_host_down_alerts, soft_host_down_alerts + hard_host_down_alerts); + printf("\n", soft_host_unreachable_alerts, hard_host_unreachable_alerts, soft_host_unreachable_alerts + hard_host_unreachable_alerts); + printf("\n", soft_host_up_alerts + soft_host_down_alerts + soft_host_unreachable_alerts, hard_host_up_alerts + hard_host_down_alerts + hard_host_unreachable_alerts, soft_host_up_alerts + hard_host_up_alerts + soft_host_down_alerts + hard_host_down_alerts + soft_host_unreachable_alerts + hard_host_unreachable_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("
    Service Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_service_ok_alerts, hard_service_ok_alerts, soft_service_ok_alerts + hard_service_ok_alerts); + printf("\n", soft_service_warning_alerts, hard_service_warning_alerts, soft_service_warning_alerts + hard_service_warning_alerts); + printf("\n", soft_service_unknown_alerts, hard_service_unknown_alerts, soft_service_unknown_alerts + hard_service_unknown_alerts); + printf("\n", soft_service_critical_alerts, hard_service_critical_alerts, soft_service_critical_alerts + hard_service_critical_alerts); + printf("\n", soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts, hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts, soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts + hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + return; + } + + +/* displays servicegroup alert totals */ +void display_servicegroup_alert_totals(void) { + servicegroup *temp_servicegroup; + + /**************************/ + /**** SERVICEGROUP TOTALS ****/ + /**************************/ + + printf("
    \n"); + + printf("
    \n"); + printf("
    Totals By Servicegroup
    \n"); + + if(show_all_servicegroups == FALSE) + display_specific_servicegroup_alert_totals(target_servicegroup); + else { + for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) + display_specific_servicegroup_alert_totals(temp_servicegroup); + } + + printf("
    \n"); + + return; + } + + +/* displays alert totals for a specific servicegroup */ +void display_specific_servicegroup_alert_totals(servicegroup *grp) { + int hard_host_up_alerts = 0; + int soft_host_up_alerts = 0; + int hard_host_down_alerts = 0; + int soft_host_down_alerts = 0; + int hard_host_unreachable_alerts = 0; + int soft_host_unreachable_alerts = 0; + int hard_service_ok_alerts = 0; + int soft_service_ok_alerts = 0; + int hard_service_warning_alerts = 0; + int soft_service_warning_alerts = 0; + int hard_service_unknown_alerts = 0; + int soft_service_unknown_alerts = 0; + int hard_service_critical_alerts = 0; + int soft_service_critical_alerts = 0; + archived_event *temp_event; + host *temp_host; + service *temp_service; + + if(grp == NULL) + return; + + /* make sure the user is authorized to view this servicegroup */ + if(is_authorized_for_servicegroup(grp, ¤t_authdata) == FALSE) + return; + + /* process all events */ + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + + if(temp_event->event_type == AE_HOST_ALERT) { + + temp_host = find_host(temp_event->host_name); + if(is_host_member_of_servicegroup(grp, temp_host) == FALSE) + continue; + } + else { + + temp_service = find_service(temp_event->host_name, temp_event->service_description); + if(is_service_member_of_servicegroup(grp, temp_service) == FALSE) + continue; + } + + /* host alerts */ + if(temp_event->event_type == AE_HOST_ALERT) { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_HOST_UP) + soft_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + soft_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + soft_host_unreachable_alerts++; + } + else { + if(temp_event->entry_type == AE_HOST_UP) + hard_host_up_alerts++; + else if(temp_event->entry_type == AE_HOST_DOWN) + hard_host_down_alerts++; + else if(temp_event->entry_type == AE_HOST_UNREACHABLE) + hard_host_unreachable_alerts++; + } + } + + /* service alerts */ + else { + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_SERVICE_OK) + soft_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + soft_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + soft_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + soft_service_critical_alerts++; + } + else { + if(temp_event->entry_type == AE_SERVICE_OK) + hard_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + hard_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + hard_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + hard_service_critical_alerts++; + } + } + } + + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + + printf("\n", grp->group_name, grp->alias); + + printf("\n"); + + if(alert_types & AE_HOST_ALERT) { + + printf("\n"); + } + + if(alert_types & AE_SERVICE_ALERT) { + + printf("\n"); + } + + printf("\n"); + + printf("
    Servicegroup '%s' (%s)
    \n"); + + printf("
    Host Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_host_up_alerts, hard_host_up_alerts, soft_host_up_alerts + hard_host_up_alerts); + printf("\n", soft_host_down_alerts, hard_host_down_alerts, soft_host_down_alerts + hard_host_down_alerts); + printf("\n", soft_host_unreachable_alerts, hard_host_unreachable_alerts, soft_host_unreachable_alerts + hard_host_unreachable_alerts); + printf("\n", soft_host_up_alerts + soft_host_down_alerts + soft_host_unreachable_alerts, hard_host_up_alerts + hard_host_down_alerts + hard_host_unreachable_alerts, soft_host_up_alerts + hard_host_up_alerts + soft_host_down_alerts + hard_host_down_alerts + soft_host_unreachable_alerts + hard_host_unreachable_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("
    Service Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_service_ok_alerts, hard_service_ok_alerts, soft_service_ok_alerts + hard_service_ok_alerts); + printf("\n", soft_service_warning_alerts, hard_service_warning_alerts, soft_service_warning_alerts + hard_service_warning_alerts); + printf("\n", soft_service_unknown_alerts, hard_service_unknown_alerts, soft_service_unknown_alerts + hard_service_unknown_alerts); + printf("\n", soft_service_critical_alerts, hard_service_critical_alerts, soft_service_critical_alerts + hard_service_critical_alerts); + printf("\n", soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts, hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts, soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts + hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + return; + } + + + +/* displays service alert totals */ +void display_service_alert_totals(void) { + service *temp_service; + + /************************/ + /**** SERVICE TOTALS ****/ + /************************/ + + printf("
    \n"); + + printf("
    \n"); + printf("
    Totals By Service
    \n"); + + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) + display_specific_service_alert_totals(temp_service); + + printf("
    \n"); + + return; + } + + +/* displays alert totals for a specific service */ +void display_specific_service_alert_totals(service *svc) { + int hard_service_ok_alerts = 0; + int soft_service_ok_alerts = 0; + int hard_service_warning_alerts = 0; + int soft_service_warning_alerts = 0; + int hard_service_unknown_alerts = 0; + int soft_service_unknown_alerts = 0; + int hard_service_critical_alerts = 0; + int soft_service_critical_alerts = 0; + archived_event *temp_event; + host *temp_host; + + if(svc == NULL) + return; + + /* make sure the user is authorized to view this service */ + if(is_authorized_for_service(svc, ¤t_authdata) == FALSE) + return; + + if(show_all_hostgroups == FALSE && target_hostgroup != NULL) { + temp_host = find_host(svc->host_name); + if(is_host_member_of_hostgroup(target_hostgroup, temp_host) == FALSE) + return; + } + + if(show_all_hosts == FALSE && target_host != NULL) { + if(strcmp(target_host->name, svc->host_name)) + return; + } + + /* process all events */ + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + + if(temp_event->event_type != AE_SERVICE_ALERT) + continue; + + if(strcmp(temp_event->host_name, svc->host_name) || strcmp(temp_event->service_description, svc->description)) + continue; + + /* service alerts */ + if(temp_event->state_type == AE_SOFT_STATE) { + if(temp_event->entry_type == AE_SERVICE_OK) + soft_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + soft_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + soft_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + soft_service_critical_alerts++; + } + else { + if(temp_event->entry_type == AE_SERVICE_OK) + hard_service_ok_alerts++; + else if(temp_event->entry_type == AE_SERVICE_WARNING) + hard_service_warning_alerts++; + else if(temp_event->entry_type == AE_SERVICE_UNKNOWN) + hard_service_unknown_alerts++; + else if(temp_event->entry_type == AE_SERVICE_CRITICAL) + hard_service_critical_alerts++; + } + } + + + printf("
    \n"); + printf("
    \n"); + printf("\n"); + + printf("\n", svc->description, svc->host_name); + + printf("\n"); + + if(alert_types & AE_SERVICE_ALERT) { + + printf("\n"); + } + + printf("\n"); + + printf("
    Service '%s' on Host '%s'
    \n"); + + printf("
    Service Alerts
    \n"); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + printf("\n", soft_service_ok_alerts, hard_service_ok_alerts, soft_service_ok_alerts + hard_service_ok_alerts); + printf("\n", soft_service_warning_alerts, hard_service_warning_alerts, soft_service_warning_alerts + hard_service_warning_alerts); + printf("\n", soft_service_unknown_alerts, hard_service_unknown_alerts, soft_service_unknown_alerts + hard_service_unknown_alerts); + printf("\n", soft_service_critical_alerts, hard_service_critical_alerts, soft_service_critical_alerts + hard_service_critical_alerts); + printf("\n", soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts, hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts, soft_service_ok_alerts + soft_service_warning_alerts + soft_service_unknown_alerts + soft_service_critical_alerts + hard_service_ok_alerts + hard_service_warning_alerts + hard_service_unknown_alerts + hard_service_critical_alerts); + + printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); + printf("
    \n"); + + printf("
    \n"); + printf("
    \n"); + + return; + } + + +/* find a specific alert producer */ +alert_producer *find_producer(int type, char *hname, char *sdesc) { + alert_producer *temp_producer; + + for(temp_producer = producer_list; temp_producer != NULL; temp_producer = temp_producer->next) { + + if(temp_producer->producer_type != type) + continue; + if(hname != NULL && strcmp(hname, temp_producer->host_name)) + continue; + if(sdesc != NULL && strcmp(sdesc, temp_producer->service_description)) + continue; + + return temp_producer; + } + + return NULL; + } + + +/* adds a new producer to the list in memory */ +alert_producer *add_producer(int producer_type, char *host_name, char *service_description) { + alert_producer *new_producer = NULL; + + /* allocate memory for the new entry */ + new_producer = (alert_producer *)malloc(sizeof(alert_producer)); + if(new_producer == NULL) + return NULL; + + /* allocate memory for the host name */ + if(host_name != NULL) { + new_producer->host_name = (char *)malloc(strlen(host_name) + 1); + if(new_producer->host_name != NULL) + strcpy(new_producer->host_name, host_name); + } + else + new_producer->host_name = NULL; + + /* allocate memory for the service description */ + if(service_description != NULL) { + new_producer->service_description = (char *)malloc(strlen(service_description) + 1); + if(new_producer->service_description != NULL) + strcpy(new_producer->service_description, service_description); + } + else + new_producer->service_description = NULL; + + new_producer->producer_type = producer_type; + new_producer->total_alerts = 0; + + /* add the new entry to the list in memory, sorted by time */ + new_producer->next = producer_list; + producer_list = new_producer; + + return new_producer; + } + + + +void free_producer_list(void) { + alert_producer *this_producer = NULL; + alert_producer *next_producer = NULL; + + for(this_producer = producer_list; this_producer != NULL;) { + next_producer = this_producer->next; + if(this_producer->host_name != NULL) + free(this_producer->host_name); + if(this_producer->service_description != NULL) + free(this_producer->service_description); + free(this_producer); + this_producer = next_producer; + } + + producer_list = NULL; + + return; + } + + + +/* displays top alerts */ +void display_top_alerts(void) { + archived_event *temp_event = NULL; + alert_producer *temp_producer = NULL; + alert_producer *next_producer = NULL; + alert_producer *last_producer = NULL; + alert_producer *new_producer = NULL; + alert_producer *temp_list = NULL; + int producer_type = AE_HOST_PRODUCER; + int current_item = 0; + int odd = 0; + char *bgclass = ""; + + /* process all events */ + for(temp_event = event_list; temp_event != NULL; temp_event = temp_event->next) { + + producer_type = (temp_event->event_type == AE_HOST_ALERT) ? AE_HOST_PRODUCER : AE_SERVICE_PRODUCER; + + /* see if we already have a record for the producer */ + temp_producer = find_producer(producer_type, temp_event->host_name, temp_event->service_description); + + /* if not, add a record */ + if(temp_producer == NULL) + temp_producer = add_producer(producer_type, temp_event->host_name, temp_event->service_description); + + /* producer record could not be added */ + if(temp_producer == NULL) + continue; + + /* update stats for producer */ + temp_producer->total_alerts++; + } + + + /* sort the producer list by total alerts (descending) */ + total_items = 0; + temp_list = NULL; + for(new_producer = producer_list; new_producer != NULL;) { + next_producer = new_producer->next; + + last_producer = temp_list; + for(temp_producer = temp_list; temp_producer != NULL; temp_producer = temp_producer->next) { + if(new_producer->total_alerts >= temp_producer->total_alerts) { + new_producer->next = temp_producer; + if(temp_producer == temp_list) + temp_list = new_producer; + else + last_producer->next = new_producer; + break; + } + else + last_producer = temp_producer; + } + if(temp_list == NULL) { + new_producer->next = NULL; + temp_list = new_producer; + } + else if(temp_producer == NULL) { + new_producer->next = NULL; + last_producer->next = new_producer; + } + + new_producer = next_producer; + total_items++; + } + producer_list = temp_list; + + + printf("
    \n"); + + if(item_limit <= 0 || total_items <= item_limit || total_items == 0) + printf("
    Displaying all %d matching alert producers\n", total_items); + else + printf("
    Displaying top %d of %d total matching alert producers\n", item_limit, total_items); + + printf("
    \n"); + printf("\n"); + printf("\n"); + + + + /* display top producers */ + for(temp_producer = producer_list; temp_producer != NULL; temp_producer = temp_producer->next) { + + if(current_item >= item_limit && item_limit > 0) + break; + + current_item++; + + if(odd) { + odd = 0; + bgclass = "Odd"; + } + else { + odd = 1; + bgclass = "Even"; + } + + printf("", bgclass); + + printf("", bgclass, current_item); + + printf("", bgclass, (temp_producer->producer_type == AE_HOST_PRODUCER) ? "Host" : "Service"); + + printf("", bgclass, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_producer->host_name), temp_producer->host_name); + + if(temp_producer->producer_type == AE_HOST_PRODUCER) + printf("", bgclass); + else { + printf("", url_encode(temp_producer->service_description), temp_producer->service_description); + } + + printf("", bgclass, temp_producer->total_alerts); + + printf("\n"); + } + + printf("
    RankProducer TypeHostServiceTotal Alerts
    #%d%s%sN/A%s%d
    \n"); + printf("
    \n"); + + return; + } diff --git a/cgi/tac.c b/cgi/tac.c new file mode 100644 index 0000000..3418448 --- /dev/null +++ b/cgi/tac.c @@ -0,0 +1,1666 @@ +/*********************************************************************** + * + * TAC.C - Nagios Tactical Monitoring Overview CGI + * + * Copyright (c) 2001-2010 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 08-05-2010 + * + * 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/statusdata.h" + +#include "../include/getcgi.h" +#include "../include/cgiutils.h" +#include "../include/cgiauth.h" + + +#define HEALTH_WARNING_PERCENTAGE 90 +#define HEALTH_CRITICAL_PERCENTAGE 75 + + +/* HOSTOUTAGE structure */ +typedef struct hostoutage_struct { + host *hst; + int affected_child_hosts; + struct hostoutage_struct *next; + } hostoutage; + + +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 char url_media_path[MAX_FILENAME_LENGTH]; + +extern int refresh_rate; + +extern char *service_critical_sound; +extern char *service_warning_sound; +extern char *service_unknown_sound; +extern char *host_down_sound; +extern char *host_unreachable_sound; +extern char *normal_sound; + +extern host *host_list; +extern hostgroup *hostgroup_list; +extern hoststatus *hoststatus_list; +extern servicestatus *servicestatus_list; + +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int enable_event_handlers; +extern int enable_flap_detection; + +extern int nagios_process_state; + + + + +void analyze_status_data(void); +void display_tac_overview(void); + +void find_hosts_causing_outages(void); +void calculate_outage_effect_of_host(host *, int *); +int is_route_to_host_blocked(host *); +int number_of_host_services(host *); +void add_hostoutage(host *); +void free_hostoutage_list(void); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); + +authdata current_authdata; + +int embedded = FALSE; +int display_header = FALSE; + +hostoutage *hostoutage_list = NULL; + +int total_blocking_outages = 0; +int total_nonblocking_outages = 0; + +int total_service_health = 0; +int total_host_health = 0; +int potential_service_health = 0; +int potential_host_health = 0; +double percent_service_health = 0.0; +double percent_host_health = 0.0; + +int total_hosts = 0; +int total_services = 0; + +int total_active_service_checks = 0; +int total_active_host_checks = 0; +int total_passive_service_checks = 0; +int total_passive_host_checks = 0; + +double min_service_execution_time = -1.0; +double max_service_execution_time = -1.0; +double total_service_execution_time = 0.0; +double average_service_execution_time = -1.0; +double min_host_execution_time = -1.0; +double max_host_execution_time = -1.0; +double total_host_execution_time = 0.0; +double average_host_execution_time = -1.0; +double min_service_latency = -1.0; +double max_service_latency = -1.0; +double total_service_latency = 0.0; +double average_service_latency = -1.0; +double min_host_latency = -1.0; +double max_host_latency = -1.0; +double total_host_latency = 0.0; +double average_host_latency = -1.0; + +int flapping_services = 0; +int flapping_hosts = 0; +int flap_disabled_services = 0; +int flap_disabled_hosts = 0; +int notification_disabled_services = 0; +int notification_disabled_hosts = 0; +int event_handler_disabled_services = 0; +int event_handler_disabled_hosts = 0; +int active_checks_disabled_services = 0; +int active_checks_disabled_hosts = 0; +int passive_checks_disabled_services = 0; +int passive_checks_disabled_hosts = 0; + +int hosts_pending = 0; +int hosts_pending_disabled = 0; +int hosts_up_disabled = 0; +int hosts_up_unacknowledged = 0; +int hosts_up = 0; +int hosts_down_scheduled = 0; +int hosts_down_acknowledged = 0; +int hosts_down_disabled = 0; +int hosts_down_unacknowledged = 0; +int hosts_down = 0; +int hosts_unreachable_scheduled = 0; +int hosts_unreachable_acknowledged = 0; +int hosts_unreachable_disabled = 0; +int hosts_unreachable_unacknowledged = 0; +int hosts_unreachable = 0; + +int services_pending = 0; +int services_pending_disabled = 0; +int services_ok_disabled = 0; +int services_ok_unacknowledged = 0; +int services_ok = 0; +int services_warning_host_problem = 0; +int services_warning_scheduled = 0; +int services_warning_acknowledged = 0; +int services_warning_disabled = 0; +int services_warning_unacknowledged = 0; +int services_warning = 0; +int services_unknown_host_problem = 0; +int services_unknown_scheduled = 0; +int services_unknown_acknowledged = 0; +int services_unknown_disabled = 0; +int services_unknown_unacknowledged = 0; +int services_unknown = 0; +int services_critical_host_problem = 0; +int services_critical_scheduled = 0; +int services_critical_acknowledged = 0; +int services_critical_disabled = 0; +int services_critical_unacknowledged = 0; +int services_critical = 0; + + +/*efine DEBUG 1*/ + +int main(void) { + int result = OK; + char *sound = NULL; +#ifdef DEBUG + time_t t1, t2, t3, t4, t5, t6, t7, t8, t9; +#endif + + +#ifdef DEBUG + time(&t1); +#endif + + /* 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; + } + +#ifdef DEBUG + time(&t2); +#endif + + /* 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; + } + +#ifdef DEBUG + time(&t3); +#endif + + /* 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; + } + +#ifdef DEBUG + time(&t4); +#endif + + /* 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; + } + +#ifdef DEBUG + time(&t5); +#endif + + document_header(TRUE); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + if(display_header == TRUE) { + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of top table - info box */ + printf("\n"); + + /* middle column of top table - log file navigation options */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + display_info_table("Tactical Status Overview", TRUE, ¤t_authdata); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("

    \n"); + + } + + +#ifdef DEBUG + time(&t6); +#endif + + /* analyze current host and service status data for tac overview */ + analyze_status_data(); + +#ifdef DEBUG + time(&t7); +#endif + + /* find all hosts that are causing network outages */ + find_hosts_causing_outages(); + + +#ifdef DEBUG + time(&t8); +#endif + + /* embed sound tag if necessary... */ + if(hosts_unreachable_unacknowledged > 0 && host_unreachable_sound != NULL) + sound = host_unreachable_sound; + else if(hosts_down_unacknowledged > 0 && host_down_sound != NULL) + sound = host_down_sound; + else if(services_critical_unacknowledged > 0 && service_critical_sound != NULL) + sound = service_critical_sound; + else if(services_warning_unacknowledged > 0 && service_warning_sound != NULL) + sound = service_warning_sound; + else if(services_unknown_unacknowledged == 0 && services_warning_unacknowledged == 0 && services_critical_unacknowledged == 0 && hosts_down_unacknowledged == 0 && hosts_unreachable_unacknowledged == 0 && normal_sound != NULL) + sound = normal_sound; + if(sound != NULL) { + printf("", url_media_path, sound); + printf("", url_media_path, sound); + printf(""); + printf(""); + printf(""); + } + + + /**** display main tac screen ****/ + display_tac_overview(); + +#ifdef DEBUG + time(&t9); +#endif + + document_footer(); + + /* free memory allocated to the host outage list */ + free_hostoutage_list(); + + /* free allocated memory */ + free_memory(); + +#ifdef DEBUG + printf("T1: %lu\n", (unsigned long)t1); + printf("T2: %lu\n", (unsigned long)t2); + printf("T3: %lu\n", (unsigned long)t3); + printf("T4: %lu\n", (unsigned long)t4); + printf("T5: %lu\n", (unsigned long)t5); + printf("T6: %lu\n", (unsigned long)t6); + printf("T7: %lu\n", (unsigned long)t7); + printf("T8: %lu\n", (unsigned long)t8); + printf("T9: %lu\n", (unsigned long)t9); +#endif + + 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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios Tactical Monitoring Overview\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, TAC_CSS); + } + + printf("\n"); + printf("\n"); + + /* include user SSI header */ + include_ssi_files(TAC_CGI, SSI_HEADER); + + return; + } + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + /* include user SSI footer */ + include_ssi_files(TAC_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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 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 received an invalid argument */ + else + error = TRUE; + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +void analyze_status_data(void) { + servicestatus *temp_servicestatus; + service *temp_service; + hoststatus *temp_hoststatus; + host *temp_host; + int problem = TRUE; + + + /* check all services */ + for(temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) { + + /* see if user is authorized to view this service */ + temp_service = find_service(temp_servicestatus->host_name, temp_servicestatus->description); + if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + continue; + + /******** CHECK FEATURES *******/ + + /* check flapping */ + if(temp_servicestatus->flap_detection_enabled == FALSE) + flap_disabled_services++; + else if(temp_servicestatus->is_flapping == TRUE) + flapping_services++; + + /* check notifications */ + if(temp_servicestatus->notifications_enabled == FALSE) + notification_disabled_services++; + + /* check event handler */ + if(temp_servicestatus->event_handler_enabled == FALSE) + event_handler_disabled_services++; + + /* active check execution */ + if(temp_servicestatus->checks_enabled == FALSE) + active_checks_disabled_services++; + + /* passive check acceptance */ + if(temp_servicestatus->accept_passive_service_checks == FALSE) + passive_checks_disabled_services++; + + + /********* CHECK STATUS ********/ + + problem = TRUE; + + if(temp_servicestatus->status == SERVICE_OK) { + if(temp_servicestatus->checks_enabled == FALSE) + services_ok_disabled++; + else + services_ok_unacknowledged++; + services_ok++; + } + + else if(temp_servicestatus->status == SERVICE_WARNING) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_warning_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_warning_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_warning_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_warning_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_warning_unacknowledged++; + services_warning++; + } + + else if(temp_servicestatus->status == SERVICE_UNKNOWN) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_unknown_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_unknown_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_unknown_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_unknown_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_unknown_unacknowledged++; + services_unknown++; + } + + else if(temp_servicestatus->status == SERVICE_CRITICAL) { + temp_hoststatus = find_hoststatus(temp_servicestatus->host_name); + if(temp_hoststatus != NULL && (temp_hoststatus->status == HOST_DOWN || temp_hoststatus->status == HOST_UNREACHABLE)) { + services_critical_host_problem++; + problem = FALSE; + } + if(temp_servicestatus->scheduled_downtime_depth > 0) { + services_critical_scheduled++; + problem = FALSE; + } + if(temp_servicestatus->problem_has_been_acknowledged == TRUE) { + services_critical_acknowledged++; + problem = FALSE; + } + if(temp_servicestatus->checks_enabled == FALSE) { + services_critical_disabled++; + problem = FALSE; + } + if(problem == TRUE) + services_critical_unacknowledged++; + services_critical++; + } + + else if(temp_servicestatus->status == SERVICE_PENDING) { + if(temp_servicestatus->checks_enabled == FALSE) + services_pending_disabled++; + services_pending++; + } + + + /* get health stats */ + if(temp_servicestatus->status == SERVICE_OK) + total_service_health += 2; + + else if(temp_servicestatus->status == SERVICE_WARNING || temp_servicestatus->status == SERVICE_UNKNOWN) + total_service_health++; + + if(temp_servicestatus->status != SERVICE_PENDING) + potential_service_health += 2; + + + /* calculate execution time and latency stats */ + if(temp_servicestatus->check_type == SERVICE_CHECK_ACTIVE) { + + total_active_service_checks++; + + if(min_service_latency == -1.0 || temp_servicestatus->latency < min_service_latency) + min_service_latency = temp_servicestatus->latency; + if(max_service_latency == -1.0 || temp_servicestatus->latency > max_service_latency) + max_service_latency = temp_servicestatus->latency; + + if(min_service_execution_time == -1.0 || temp_servicestatus->execution_time < min_service_execution_time) + min_service_execution_time = temp_servicestatus->execution_time; + if(max_service_execution_time == -1.0 || temp_servicestatus->execution_time > max_service_execution_time) + max_service_execution_time = temp_servicestatus->execution_time; + + total_service_latency += temp_servicestatus->latency; + total_service_execution_time += temp_servicestatus->execution_time; + } + else + total_passive_service_checks++; + + + total_services++; + } + + + + /* check all hosts */ + for(temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) { + + /* see if user is authorized to view this host */ + temp_host = find_host(temp_hoststatus->host_name); + if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + continue; + + /******** CHECK FEATURES *******/ + + /* check flapping */ + if(temp_hoststatus->flap_detection_enabled == FALSE) + flap_disabled_hosts++; + else if(temp_hoststatus->is_flapping == TRUE) + flapping_hosts++; + + /* check notifications */ + if(temp_hoststatus->notifications_enabled == FALSE) + notification_disabled_hosts++; + + /* check event handler */ + if(temp_hoststatus->event_handler_enabled == FALSE) + event_handler_disabled_hosts++; + + /* active check execution */ + if(temp_hoststatus->checks_enabled == FALSE) + active_checks_disabled_hosts++; + + /* passive check acceptance */ + if(temp_hoststatus->accept_passive_host_checks == FALSE) + passive_checks_disabled_hosts++; + + + /********* CHECK STATUS ********/ + + problem = TRUE; + + if(temp_hoststatus->status == HOST_UP) { + if(temp_hoststatus->checks_enabled == FALSE) + hosts_up_disabled++; + else + hosts_up_unacknowledged++; + hosts_up++; + } + + else if(temp_hoststatus->status == HOST_DOWN) { + if(temp_hoststatus->scheduled_downtime_depth > 0) { + hosts_down_scheduled++; + problem = FALSE; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + hosts_down_acknowledged++; + problem = FALSE; + } + if(temp_hoststatus->checks_enabled == FALSE) { + hosts_down_disabled++; + problem = FALSE; + } + if(problem == TRUE) + hosts_down_unacknowledged++; + hosts_down++; + } + + else if(temp_hoststatus->status == HOST_UNREACHABLE) { + if(temp_hoststatus->scheduled_downtime_depth > 0) { + hosts_unreachable_scheduled++; + problem = FALSE; + } + if(temp_hoststatus->problem_has_been_acknowledged == TRUE) { + hosts_unreachable_acknowledged++; + problem = FALSE; + } + if(temp_hoststatus->checks_enabled == FALSE) { + hosts_unreachable_disabled++; + problem = FALSE; + } + if(problem == TRUE) + hosts_unreachable_unacknowledged++; + hosts_unreachable++; + } + + else if(temp_hoststatus->status == HOST_PENDING) { + if(temp_hoststatus->checks_enabled == FALSE) + hosts_pending_disabled++; + hosts_pending++; + } + + /* get health stats */ + if(temp_hoststatus->status == HOST_UP) + total_host_health++; + + if(temp_hoststatus->status != HOST_PENDING) + potential_host_health++; + + /* check type stats */ + if(temp_hoststatus->check_type == HOST_CHECK_ACTIVE) { + + total_active_host_checks++; + + if(min_host_latency == -1.0 || temp_hoststatus->latency < min_host_latency) + min_host_latency = temp_hoststatus->latency; + if(max_host_latency == -1.0 || temp_hoststatus->latency > max_host_latency) + max_host_latency = temp_hoststatus->latency; + + if(min_host_execution_time == -1.0 || temp_hoststatus->execution_time < min_host_execution_time) + min_host_execution_time = temp_hoststatus->execution_time; + if(max_host_execution_time == -1.0 || temp_hoststatus->execution_time > max_host_execution_time) + max_host_execution_time = temp_hoststatus->execution_time; + + total_host_latency += temp_hoststatus->latency; + total_host_execution_time += temp_hoststatus->execution_time; + } + else + total_passive_host_checks++; + + total_hosts++; + } + + + /* calculate service health */ + if(potential_service_health == 0) + percent_service_health = 0.0; + else + percent_service_health = ((double)total_service_health / (double)potential_service_health) * 100.0; + + /* calculate host health */ + if(potential_host_health == 0) + percent_host_health = 0.0; + else + percent_host_health = ((double)total_host_health / (double)potential_host_health) * 100.0; + + /* calculate service latency */ + if(total_service_latency == 0L) + average_service_latency = 0.0; + else + average_service_latency = ((double)total_service_latency / (double)total_active_service_checks); + + /* calculate host latency */ + if(total_host_latency == 0L) + average_host_latency = 0.0; + else + average_host_latency = ((double)total_host_latency / (double)total_active_host_checks); + + /* calculate service execution time */ + if(total_service_execution_time == 0.0) + average_service_execution_time = 0.0; + else + average_service_execution_time = ((double)total_service_execution_time / (double)total_active_service_checks); + + /* calculate host execution time */ + if(total_host_execution_time == 0.0) + average_host_execution_time = 0.0; + else + average_host_execution_time = ((double)total_host_execution_time / (double)total_active_host_checks); + + return; + } + + + + +/* determine what hosts are causing network outages */ +void find_hosts_causing_outages(void) { + hoststatus *temp_hoststatus; + hostoutage *temp_hostoutage; + host *temp_host; + + /* user must be authorized for all hosts in order to see outages */ + if(is_authorized_for_all_hosts(¤t_authdata) == FALSE) + return; + + /* 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); + } + } + + + /* check all hosts that are causing problems and calculate the extent of the problem */ + 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); + + if(temp_hostoutage->affected_child_hosts > 1) + total_blocking_outages++; + else + total_nonblocking_outages++; + } + + 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->affected_child_hosts = 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; + + for(this_hostoutage = hostoutage_list; this_hostoutage != NULL; this_hostoutage = next_hostoutage) { + next_hostoutage = this_hostoutage->next; + free(this_hostoutage); + } + + 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 total_child_hosts_affected = 0; + int temp_child_hosts_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); + + /* keep a running total of outage effects */ + total_child_hosts_affected += temp_child_hosts_affected; + } + + *affected_hosts = total_child_hosts_affected + 1; + + 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; + } + + + + + + +void display_tac_overview(void) { + char host_health_image[16]; + char service_health_image[16]; + + + printf("

    \n"); + + printf("\n"); + printf("\n"); + + /* left column */ + printf("\n"); + + + /* right column */ + printf("\n"); + + printf("\n"); + printf("
    \n"); + + display_info_table("Tactical Monitoring Overview", TRUE, ¤t_authdata); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("
    \n"); + + /* display context-sensitive help */ + display_context_help(CONTEXTHELP_TAC); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n", EXTINFO_CGI, DISPLAY_PERFORMANCE); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("
     Monitoring Performance
    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("", EXTINFO_CGI, DISPLAY_PERFORMANCE); + printf("\n", EXTINFO_CGI, DISPLAY_PERFORMANCE, min_service_execution_time, max_service_execution_time, average_service_execution_time); + printf("\n"); + printf("\n"); + printf("", EXTINFO_CGI, DISPLAY_PERFORMANCE); + printf("\n", EXTINFO_CGI, DISPLAY_PERFORMANCE, min_service_latency, max_service_latency, average_service_latency); + printf("\n"); + printf("\n"); + printf("", EXTINFO_CGI, DISPLAY_PERFORMANCE); + printf("\n", EXTINFO_CGI, DISPLAY_PERFORMANCE, min_host_execution_time, max_host_execution_time, average_host_execution_time); + printf("\n"); + printf("\n"); + printf("", EXTINFO_CGI, DISPLAY_PERFORMANCE); + printf("\n", EXTINFO_CGI, DISPLAY_PERFORMANCE, min_host_latency, max_host_latency, average_host_latency); + printf("\n"); + printf("\n"); + printf("", STATUS_CGI, SERVICE_ACTIVE_CHECK); + printf("\n", STATUS_CGI, HOST_ACTIVE_CHECK, total_active_host_checks, STATUS_CGI, SERVICE_ACTIVE_CHECK, total_active_service_checks); + printf("\n"); + printf("\n"); + printf("", STATUS_CGI, SERVICE_PASSIVE_CHECK); + printf("\n", STATUS_CGI, HOST_PASSIVE_CHECK, total_passive_host_checks, STATUS_CGI, SERVICE_PASSIVE_CHECK, total_passive_service_checks); + printf("\n"); + printf("
    Service Check Execution Time:%.2f / %.2f / %.3f sec
    Service Check Latency:%.2f / %.2f / %.3f sec
    Host Check Execution Time:%.2f / %.2f / %.3f sec
    Host Check Latency:%.2f / %.2f / %2.3f sec
    # Active Host / Service Checks:%d / %d
    # Passive Host / Service Checks:%d / %d
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("
    \n"); + + printf("
    \n"); + printf("

    \n"); + + printf("
    \n"); + printf("
    \n"); + + + + + printf("\n"); + printf("\n"); + printf("\n"); + + + + /* right column */ + printf("\n"); + printf("\n"); + printf("
    \n"); + + + /******* OUTAGES ********/ + + printf("

    \n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
     Network Outages
    ", OUTAGES_CGI); + if(is_authorized_for_all_hosts(¤t_authdata) == FALSE) + printf("N/A"); + else + printf("%d Outages", total_blocking_outages); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
        \n"); + printf("\n"); + + if(total_blocking_outages > 0) + printf("\n", OUTAGES_CGI, total_blocking_outages); + + /* + if(total_nonblocking_outages>0) + printf("\n",OUTAGES_CGI,total_nonblocking_outages); + */ + + printf("
    %d Blocking Outages
    %d Nonblocking Outages
    \n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + + printf("
    \n"); + + if(percent_host_health < HEALTH_CRITICAL_PERCENTAGE) + strncpy(host_health_image, THERM_CRITICAL_IMAGE, sizeof(host_health_image)); + else if(percent_host_health < HEALTH_WARNING_PERCENTAGE) + strncpy(host_health_image, THERM_WARNING_IMAGE, sizeof(host_health_image)); + else + strncpy(host_health_image, THERM_OK_IMAGE, sizeof(host_health_image)); + host_health_image[sizeof(host_health_image) - 1] = '\x0'; + + if(percent_service_health < HEALTH_CRITICAL_PERCENTAGE) + strncpy(service_health_image, THERM_CRITICAL_IMAGE, sizeof(service_health_image)); + else if(percent_service_health < HEALTH_WARNING_PERCENTAGE) + strncpy(service_health_image, THERM_WARNING_IMAGE, sizeof(service_health_image)); + else + strncpy(service_health_image, THERM_OK_IMAGE, sizeof(service_health_image)); + service_health_image[sizeof(service_health_image) - 1] = '\x0'; + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("
     Network Health
    \n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf(""); + printf("\n", url_images_path, host_health_image, (percent_host_health < 5.0) ? 5 : (int)percent_host_health, percent_host_health, percent_host_health); + printf("\n"); + printf("\n"); + printf(""); + printf("\n", url_images_path, service_health_image, (percent_service_health < 5.0) ? 5 : (int)percent_service_health, percent_service_health, percent_service_health); + printf("\n"); + printf("
    Host Health:%2.1f%% Health
    Service Health:%2.1f%% Health
    \n"); + printf("
    \n"); + + printf("
    \n"); + + printf("
    \n"); + + printf("
    \n"); + + + + + + + /******* HOSTS ********/ + + printf("

    \n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n", STATUS_CGI, HOST_DOWN, hosts_down); + printf("\n", STATUS_CGI, HOST_UNREACHABLE, hosts_unreachable); + printf("\n", STATUS_CGI, HOST_UP, hosts_up); + printf("\n", STATUS_CGI, HOST_PENDING, hosts_pending); + printf("\n"); + + printf("\n"); + + + printf("\n"); + + + + + printf("\n"); + + + + + printf("\n"); + + + + + printf("\n"); + + + + + printf("\n"); + printf("
     Hosts
    %d Down%d Unreachable%d Up%d Pending
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
        \n"); + printf("\n"); + + if(hosts_down_unacknowledged > 0) + printf("\n", STATUS_CGI, HOST_DOWN, HOST_NO_SCHEDULED_DOWNTIME | HOST_STATE_UNACKNOWLEDGED | HOST_CHECKS_ENABLED, hosts_down_unacknowledged); + + if(hosts_down_scheduled > 0) + printf("\n", STATUS_CGI, HOST_DOWN, HOST_SCHEDULED_DOWNTIME, hosts_down_scheduled); + + if(hosts_down_acknowledged > 0) + printf("\n", STATUS_CGI, HOST_DOWN, HOST_STATE_ACKNOWLEDGED, hosts_down_acknowledged); + + if(hosts_down_disabled > 0) + printf("\n", STATUS_CGI, HOST_DOWN, HOST_CHECKS_DISABLED, hosts_down_disabled); + + printf("
    %d Unhandled Problems
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(hosts_unreachable_unacknowledged > 0) + printf("\n", STATUS_CGI, HOST_UNREACHABLE, HOST_NO_SCHEDULED_DOWNTIME | HOST_STATE_UNACKNOWLEDGED | HOST_CHECKS_ENABLED, hosts_unreachable_unacknowledged); + + if(hosts_unreachable_scheduled > 0) + printf("\n", STATUS_CGI, HOST_UNREACHABLE, HOST_SCHEDULED_DOWNTIME, hosts_unreachable_scheduled); + + if(hosts_unreachable_acknowledged > 0) + printf("\n", STATUS_CGI, HOST_UNREACHABLE, HOST_STATE_ACKNOWLEDGED, hosts_unreachable_acknowledged); + + if(hosts_unreachable_disabled > 0) + printf("\n", STATUS_CGI, HOST_UNREACHABLE, HOST_CHECKS_DISABLED, hosts_unreachable_disabled); + + printf("
    %d Unhandled Problems
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(hosts_up_disabled > 0) + printf("\n", STATUS_CGI, HOST_UP, HOST_CHECKS_DISABLED, hosts_up_disabled); + + printf("
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(hosts_pending_disabled > 0) + printf("\n", STATUS_CGI, HOST_PENDING, HOST_CHECKS_DISABLED, hosts_pending_disabled); + + printf("
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + + /* + printf("\n"); + printf("\n"); + */ + + printf("

    \n"); + + + + + /*printf("
    \n");*/ + + + + + /******* SERVICES ********/ + + printf("

    \n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n", STATUS_CGI, SERVICE_CRITICAL, services_critical); + printf("\n", STATUS_CGI, SERVICE_WARNING, services_warning); + printf("\n", STATUS_CGI, SERVICE_UNKNOWN, services_unknown); + printf("\n", STATUS_CGI, SERVICE_OK, services_ok); + printf("\n", STATUS_CGI, SERVICE_PENDING, services_pending); + printf("\n"); + + printf("\n"); + + + printf("\n"); + + + + + + printf("\n"); + + + + + + printf("\n"); + + + + + printf("\n"); + + + + printf("\n"); + + + + printf("\n"); + printf("
     Services
    %d Critical%d Warning%d Unknown%d Ok%d Pending
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
        \n"); + printf("\n"); + + if(services_critical_unacknowledged > 0) + printf("\n", STATUS_CGI, SERVICE_CRITICAL, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_critical_unacknowledged); + + if(services_critical_host_problem > 0) + printf("\n", STATUS_CGI, SERVICE_CRITICAL, HOST_DOWN | HOST_UNREACHABLE, services_critical_host_problem); + + if(services_critical_scheduled > 0) + printf("\n", STATUS_CGI, SERVICE_CRITICAL, SERVICE_SCHEDULED_DOWNTIME, services_critical_scheduled); + + if(services_critical_acknowledged > 0) + printf("\n", STATUS_CGI, SERVICE_CRITICAL, SERVICE_STATE_ACKNOWLEDGED, services_critical_acknowledged); + + if(services_critical_disabled > 0) + printf("\n", STATUS_CGI, SERVICE_CRITICAL, SERVICE_CHECKS_DISABLED, services_critical_disabled); + + printf("
    %d Unhandled Problems
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(services_warning_unacknowledged > 0) + printf("\n", STATUS_CGI, SERVICE_WARNING, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_warning_unacknowledged); + + if(services_warning_host_problem > 0) + printf("\n", STATUS_CGI, SERVICE_WARNING, HOST_DOWN | HOST_UNREACHABLE, services_warning_host_problem); + + if(services_warning_scheduled > 0) + printf("\n", STATUS_CGI, SERVICE_WARNING, SERVICE_SCHEDULED_DOWNTIME, services_warning_scheduled); + + if(services_warning_acknowledged > 0) + printf("\n", STATUS_CGI, SERVICE_WARNING, SERVICE_STATE_ACKNOWLEDGED, services_warning_acknowledged); + + if(services_warning_disabled > 0) + printf("\n", STATUS_CGI, SERVICE_WARNING, SERVICE_CHECKS_DISABLED, services_warning_disabled); + + printf("
    %d Unhandled Problems
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(services_unknown_unacknowledged > 0) + printf("\n", STATUS_CGI, SERVICE_UNKNOWN, HOST_UP | HOST_PENDING, SERVICE_NO_SCHEDULED_DOWNTIME | SERVICE_STATE_UNACKNOWLEDGED | SERVICE_CHECKS_ENABLED, services_unknown_unacknowledged); + + if(services_unknown_host_problem > 0) + printf("\n", STATUS_CGI, SERVICE_UNKNOWN, HOST_DOWN | HOST_UNREACHABLE, services_unknown_host_problem); + + if(services_unknown_scheduled > 0) + printf("\n", STATUS_CGI, SERVICE_UNKNOWN, SERVICE_SCHEDULED_DOWNTIME, services_unknown_scheduled); + + if(services_unknown_acknowledged > 0) + printf("\n", STATUS_CGI, SERVICE_UNKNOWN, SERVICE_STATE_ACKNOWLEDGED, services_unknown_acknowledged); + + if(services_unknown_disabled > 0) + printf("\n", STATUS_CGI, SERVICE_UNKNOWN, SERVICE_CHECKS_DISABLED, services_unknown_disabled); + + printf("
    %d Unhandled Problems
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(services_ok_disabled > 0) + printf("\n", STATUS_CGI, SERVICE_OK, SERVICE_CHECKS_DISABLED, services_ok_disabled); + + printf("
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("
      \n"); + printf("\n"); + + if(services_pending_disabled > 0) + printf("\n", STATUS_CGI, SERVICE_PENDING, SERVICE_CHECKS_DISABLED, services_pending_disabled); + + printf("
    %d Disabled
    \n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + + + + + /*printf("
    \n");*/ + + + + + + /******* MONITORING FEATURES ********/ + + printf("

    \n"); + + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + + + + + printf("\n"); + + + + + + printf("\n"); + + + + + + printf("\n"); + + + + + + printf("\n"); + + printf("\n"); + + printf("
     Monitoring Features
    Flap DetectionNotificationsEvent HandlersActive ChecksPassive Checks
    \n"); + printf("\n"); + printf("\n"); + printf("\n", COMMAND_CGI, (enable_flap_detection == TRUE) ? CMD_DISABLE_FLAP_DETECTION : CMD_ENABLE_FLAP_DETECTION, url_images_path, (enable_flap_detection == TRUE) ? TAC_ENABLED_ICON : TAC_DISABLED_ICON, (enable_flap_detection == TRUE) ? "Enabled" : "Disabled", (enable_flap_detection == TRUE) ? "Enabled" : "Disabled"); + printf("\n"); + if(enable_flap_detection == TRUE) { + printf("\n"); + } + else + printf("\n"); + printf("\n"); + printf("
    Flap Detection %s \n"); + printf("\n"); + + if(flap_disabled_services > 0) + printf("\n", STATUS_CGI, SERVICE_FLAP_DETECTION_DISABLED, flap_disabled_services, (flap_disabled_services == 1) ? "" : "s"); + else + printf("\n"); + + if(flapping_services > 0) + printf("\n", STATUS_CGI, SERVICE_IS_FLAPPING, flapping_services, (flapping_services == 1) ? "" : "s"); + else + printf("\n"); + + if(flap_disabled_hosts > 0) + printf("\n", STATUS_CGI, HOST_FLAP_DETECTION_DISABLED, flap_disabled_hosts, (flap_disabled_hosts == 1) ? "" : "s"); + else + printf("\n"); + + if(flapping_hosts > 0) + printf("\n", STATUS_CGI, HOST_IS_FLAPPING, flapping_hosts, (flapping_hosts == 1) ? "" : "s"); + else + printf("\n"); + + printf("
    %d Service%s Disabled
    All Services Enabled
    %d Service%s Flapping
    No Services Flapping
    %d Host%s Disabled
    All Hosts Enabled
    %d Host%s Flapping
    No Hosts Flapping
    \n"); + printf("
    N/A
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n", COMMAND_CGI, (enable_notifications == TRUE) ? CMD_DISABLE_NOTIFICATIONS : CMD_ENABLE_NOTIFICATIONS, url_images_path, (enable_notifications == TRUE) ? TAC_ENABLED_ICON : TAC_DISABLED_ICON, (enable_notifications == TRUE) ? "Enabled" : "Disabled", (enable_notifications == TRUE) ? "Enabled" : "Disabled"); + printf("\n"); + if(enable_notifications == TRUE) { + printf("\n"); + } + else + printf("\n"); + printf("\n"); + printf("
    Notifications %s \n"); + printf("\n"); + + if(notification_disabled_services > 0) + printf("\n", STATUS_CGI, SERVICE_NOTIFICATIONS_DISABLED, notification_disabled_services, (notification_disabled_services == 1) ? "" : "s"); + else + printf("\n"); + + if(notification_disabled_hosts > 0) + printf("\n", STATUS_CGI, HOST_NOTIFICATIONS_DISABLED, notification_disabled_hosts, (notification_disabled_hosts == 1) ? "" : "s"); + else + printf("\n"); + + printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); + printf("
    N/A
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n", COMMAND_CGI, (enable_event_handlers == TRUE) ? CMD_DISABLE_EVENT_HANDLERS : CMD_ENABLE_EVENT_HANDLERS, url_images_path, (enable_event_handlers == TRUE) ? TAC_ENABLED_ICON : TAC_DISABLED_ICON, (enable_event_handlers == TRUE) ? "Enabled" : "Disabled", (enable_event_handlers == TRUE) ? "Enabled" : "Disabled"); + printf("\n"); + if(enable_event_handlers == TRUE) { + printf("\n"); + } + else + printf("\n"); + printf("\n"); + printf("
    Event Handlers %s \n"); + printf("\n"); + + if(event_handler_disabled_services > 0) + printf("\n", STATUS_CGI, SERVICE_EVENT_HANDLER_DISABLED, event_handler_disabled_services, (event_handler_disabled_services == 1) ? "" : "s"); + else + printf("\n"); + + if(event_handler_disabled_hosts > 0) + printf("\n", STATUS_CGI, HOST_EVENT_HANDLER_DISABLED, event_handler_disabled_hosts, (event_handler_disabled_hosts == 1) ? "" : "s"); + else + printf("\n"); + + printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); + printf("
    N/A
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n", EXTINFO_CGI, DISPLAY_PROCESS_INFO, url_images_path, (execute_service_checks == TRUE) ? TAC_ENABLED_ICON : TAC_DISABLED_ICON, (execute_service_checks == TRUE) ? "Enabled" : "Disabled", (execute_service_checks == TRUE) ? "Enabled" : "Disabled"); + printf("\n"); + if(execute_service_checks == TRUE) { + printf("\n"); + } + else + printf("\n"); + printf("\n"); + printf("
    Active Checks %s \n"); + printf("\n"); + + if(active_checks_disabled_services > 0) + printf("\n", STATUS_CGI, SERVICE_CHECKS_DISABLED, active_checks_disabled_services, (active_checks_disabled_services == 1) ? "" : "s"); + else + printf("\n"); + + if(active_checks_disabled_hosts > 0) + printf("\n", STATUS_CGI, HOST_CHECKS_DISABLED, active_checks_disabled_hosts, (active_checks_disabled_hosts == 1) ? "" : "s"); + else + printf("\n"); + + printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); + printf("
    N/A
    \n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("\n", EXTINFO_CGI, DISPLAY_PROCESS_INFO, url_images_path, (accept_passive_service_checks == TRUE) ? TAC_ENABLED_ICON : TAC_DISABLED_ICON, (accept_passive_service_checks == TRUE) ? "Enabled" : "Disabled", (accept_passive_service_checks == TRUE) ? "Enabled" : "Disabled"); + printf("\n"); + if(accept_passive_service_checks == TRUE) { + + printf("\n"); + } + else + printf("\n"); + printf("\n"); + printf("
    Passive Checks %s \n"); + printf("\n"); + + if(passive_checks_disabled_services > 0) + printf("\n", STATUS_CGI, SERVICE_PASSIVE_CHECKS_DISABLED, passive_checks_disabled_services, (passive_checks_disabled_services == 1) ? "" : "s"); + else + printf("\n"); + + if(passive_checks_disabled_hosts > 0) + printf("\n", STATUS_CGI, HOST_PASSIVE_CHECKS_DISABLED, passive_checks_disabled_hosts, (passive_checks_disabled_hosts == 1) ? "" : "s"); + else + printf("\n"); + + printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); + printf("
    N/A
    \n"); + printf("
    \n"); + + printf("

    \n"); + + + return; + } + diff --git a/cgi/trends.c b/cgi/trends.c new file mode 100644 index 0000000..3d16af5 --- /dev/null +++ b/cgi/trends.c @@ -0,0 +1,3052 @@ +/************************************************************************** + * + * TRENDS.C - Nagios State Trends CGI + * + * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-15-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *************************************************************************/ + +#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" + +#include /* Boutell's GD library function */ +#include /* GD library small font definition */ + + +/*#define DEBUG 1*/ + + +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 char physical_images_path[MAX_FILENAME_LENGTH]; + +extern int log_rotation_method; + +extern host *host_list; +extern service *service_list; + +#include "../include/skiplist.h" +extern skiplist *object_skiplists[NUM_OBJECT_SKIPLISTS]; + +/* archived state types */ +#define AS_CURRENT_STATE -1 /* special case for initial assumed state */ +#define AS_NO_DATA 0 +#define AS_PROGRAM_END 1 +#define AS_PROGRAM_START 2 +#define AS_HOST_UP 3 +#define AS_HOST_DOWN 4 +#define AS_HOST_UNREACHABLE 5 +#define AS_SVC_OK 6 +#define AS_SVC_UNKNOWN 7 +#define AS_SVC_WARNING 8 +#define AS_SVC_CRITICAL 9 + +#define AS_SOFT_STATE 1 +#define AS_HARD_STATE 2 + +/* display types */ +#define DISPLAY_HOST_TRENDS 0 +#define DISPLAY_SERVICE_TRENDS 1 +#define DISPLAY_NO_TRENDS 2 + +/* input types */ +#define GET_INPUT_NONE 0 +#define GET_INPUT_TARGET_TYPE 1 +#define GET_INPUT_HOST_TARGET 2 +#define GET_INPUT_SERVICE_TARGET 3 +#define GET_INPUT_OPTIONS 4 + +/* modes */ +#define CREATE_HTML 0 +#define CREATE_IMAGE 1 + +/* standard report times */ +#define TIMEPERIOD_CUSTOM 0 +#define TIMEPERIOD_TODAY 1 +#define TIMEPERIOD_YESTERDAY 2 +#define TIMEPERIOD_THISWEEK 3 +#define TIMEPERIOD_LASTWEEK 4 +#define TIMEPERIOD_THISMONTH 5 +#define TIMEPERIOD_LASTMONTH 6 +#define TIMEPERIOD_THISQUARTER 7 +#define TIMEPERIOD_LASTQUARTER 8 +#define TIMEPERIOD_THISYEAR 9 +#define TIMEPERIOD_LASTYEAR 10 +#define TIMEPERIOD_LAST24HOURS 11 +#define TIMEPERIOD_LAST7DAYS 12 +#define TIMEPERIOD_LAST31DAYS 13 +#define TIMEPERIOD_NEXTPROBLEM 14 + +#define MIN_TIMESTAMP_SPACING 10 + +#define MAX_ARCHIVE_SPREAD 65 +#define MAX_ARCHIVE 65 +#define MAX_ARCHIVE_BACKTRACKS 60 + +authdata current_authdata; + +typedef struct archived_state_struct { + time_t time_stamp; + int entry_type; + int processed_state; + int state_type; + char *state_info; + struct archived_state_struct *next; + } archived_state; + + +archived_state *as_list = NULL; + +time_t t1; +time_t t2; + +int start_second = 0; +int start_minute = 0; +int start_hour = 0; +int start_day = 1; +int start_month = 1; +int start_year = 2000; +int end_second = 0; +int end_minute = 0; +int end_hour = 24; +int end_day = 1; +int end_month = 1; +int end_year = 2000; + +int display_type = DISPLAY_NO_TRENDS; +int mode = CREATE_HTML; +int input_type = GET_INPUT_NONE; +int timeperiod_type = TIMEPERIOD_LAST24HOURS; +int compute_time_from_parts = FALSE; + +int display_popups = TRUE; +int use_map = TRUE; +int small_image = FALSE; +int embedded = FALSE; +int display_header = TRUE; + +int assume_initial_states = TRUE; +int assume_state_retention = TRUE; +int assume_states_during_notrunning = TRUE; +int include_soft_states = FALSE; + +char *host_name = ""; +char *svc_description = ""; + + + +void graph_all_trend_data(void); +void graph_trend_data(int, int, time_t, time_t, time_t, char *); +void draw_timestamps(void); +void draw_timestamp(int, time_t); +void draw_time_breakdowns(void); +void draw_horizontal_grid_lines(void); +void draw_dashed_line(int, int, int, int, int); + +int convert_host_state_to_archived_state(int); +int convert_service_state_to_archived_state(int); +void add_archived_state(int, int, time_t, char *); +void free_archived_state_list(void); +void read_archived_state_data(void); +void scan_log_file_for_archived_state_data(char *); +void convert_timeperiod_to_times(int); +void compute_report_times(void); +void get_time_breakdown_string(unsigned long, unsigned long, char *, char *buffer, int); + +void document_header(int); +void document_footer(void); +int process_cgivars(void); +void write_popup_code(void); + +gdImagePtr trends_image = 0; +int color_white = 0; +int color_black = 0; +int color_red = 0; +int color_darkred = 0; +int color_green = 0; +int color_darkgreen = 0; +int color_yellow = 0; +int color_orange = 0; +FILE *image_file = NULL; + +int image_width = 900; +int image_height = 300; + +#define HOST_DRAWING_WIDTH 498 +#define HOST_DRAWING_HEIGHT 70 +#define HOST_DRAWING_X_OFFSET 116 +#define HOST_DRAWING_Y_OFFSET 55 + +#define SVC_DRAWING_WIDTH 498 +#define SVC_DRAWING_HEIGHT 90 +#define SVC_DRAWING_X_OFFSET 116 +#define SVC_DRAWING_Y_OFFSET 55 + +#define SMALL_HOST_DRAWING_WIDTH 500 +#define SMALL_HOST_DRAWING_HEIGHT 20 +#define SMALL_HOST_DRAWING_X_OFFSET 0 +#define SMALL_HOST_DRAWING_Y_OFFSET 0 + +#define SMALL_SVC_DRAWING_WIDTH 500 +#define SMALL_SVC_DRAWING_HEIGHT 20 +#define SMALL_SVC_DRAWING_X_OFFSET 0 +#define SMALL_SVC_DRAWING_Y_OFFSET 0 + +int drawing_width = 0; +int drawing_height = 0; + +int drawing_x_offset = 0; +int drawing_y_offset = 0; + +int last_known_state = AS_NO_DATA; + +int zoom_factor = 4; +int backtrack_archives = 2; +int earliest_archive = 0; +time_t earliest_time; +time_t latest_time; +int earliest_state = AS_NO_DATA; +int latest_state = AS_NO_DATA; + +int initial_assumed_host_state = AS_NO_DATA; +int initial_assumed_service_state = AS_NO_DATA; + +unsigned long time_up = 0L; +unsigned long time_down = 0L; +unsigned long time_unreachable = 0L; +unsigned long time_ok = 0L; +unsigned long time_warning = 0L; +unsigned long time_unknown = 0L; +unsigned long time_critical = 0L; + +int problem_found; + + + +int main(int argc, char **argv) { + int result = OK; + char temp_buffer[MAX_INPUT_BUFFER]; + char image_template[MAX_INPUT_BUFFER]; + char start_time[MAX_INPUT_BUFFER]; + char end_time[MAX_INPUT_BUFFER]; + int string_width; + int string_height; + char start_timestring[MAX_INPUT_BUFFER]; + char end_timestring[MAX_INPUT_BUFFER]; + host *temp_host; + service *temp_service; + int is_authorized = TRUE; + int found = FALSE; + int days, hours, minutes, seconds; + char *first_service = NULL; + time_t t3; + time_t current_time; + struct tm *t; + + + /* reset internal CGI variables */ + reset_cgi_vars(); + + /* read the CGI configuration file */ + result = read_cgi_config_file(get_cgi_config_location()); + if(result == ERROR) { + if(mode == CREATE_HTML) { + 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) { + if(mode == CREATE_HTML) { + document_header(FALSE); + main_config_file_error(main_config_file); + document_footer(); + } + return ERROR; + } + + + /* initialize time period to last 24 hours */ + time(¤t_time); + t2 = current_time; + t1 = (time_t)(current_time - (60 * 60 * 24)); + + /* default number of backtracked archives */ + switch(log_rotation_method) { + case LOG_ROTATION_MONTHLY: + backtrack_archives = 1; + break; + case LOG_ROTATION_WEEKLY: + backtrack_archives = 2; + break; + case LOG_ROTATION_DAILY: + backtrack_archives = 4; + break; + case LOG_ROTATION_HOURLY: + backtrack_archives = 8; + break; + default: + backtrack_archives = 2; + break; + } + + /* get the arguments passed in the URL */ + process_cgivars(); + + /* get authentication information */ + get_authentication_information(¤t_authdata); + + result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA); + if(result == ERROR) { + if(mode == CREATE_HTML) { + 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) { + if(mode == CREATE_HTML) { + document_header(FALSE); + status_data_error(); + document_footer(); + } + return ERROR; + } + + document_header(TRUE); + + if(compute_time_from_parts == TRUE) + compute_report_times(); + + /* make sure times are sane, otherwise swap them */ + if(t2 < t1) { + t3 = t2; + t2 = t1; + t1 = t3; + } + + /* don't let user create reports in the future */ + if(t2 > current_time) { + t2 = current_time; + if(t1 > t2) + t1 = t2 - (60 * 60 * 24); + } + + if(mode == CREATE_HTML && display_header == TRUE) { + time_t old_t1 = t1, old_t2 = t2; + + /* begin top table */ + printf("\n"); + printf("\n"); + + /* left column of the first row */ + printf("\n"); + + /* center column of top row */ + printf("\n"); + + /* right hand column of top row */ + printf("\n"); + + /* end of top table */ + printf("\n"); + printf("
    \n"); + + if(display_type == DISPLAY_HOST_TRENDS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host State Trends"); + else if(display_type == DISPLAY_SERVICE_TRENDS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service State Trends"); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host and Service State Trends"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + display_info_table(temp_buffer, FALSE, ¤t_authdata); + + if(timeperiod_type == TIMEPERIOD_NEXTPROBLEM) { + archived_state *temp_as; + time_t problem_t1, problem_t2 = 0; + + t1 = t2; + t2 = current_time; + read_archived_state_data(); + + problem_found = FALSE; + if(display_type == DISPLAY_HOST_TRENDS) { + for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) { + if((temp_as->entry_type == HOST_DOWN || temp_as->entry_type == HOST_UNREACHABLE) && temp_as->time_stamp > t1) { + problem_t1 = temp_as->time_stamp; + problem_found = TRUE; + break; + } + } + if(problem_found == TRUE) { + for(; temp_as != NULL; temp_as = temp_as->next) { + if(temp_as->entry_type == AS_HOST_UP && temp_as->time_stamp > problem_t1) { + problem_t2 = temp_as->time_stamp; + break; + } + } + } + } + else { + for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) { + if((temp_as->entry_type == AS_SVC_UNKNOWN || temp_as->entry_type == AS_SVC_CRITICAL || temp_as->entry_type == AS_SVC_WARNING) && temp_as->time_stamp > t1) { + problem_t1 = temp_as->time_stamp; + problem_found = TRUE; + break; + } + } + if(problem_found == TRUE) { + for(; temp_as != NULL; temp_as = temp_as->next) { + if(temp_as->entry_type == AS_SVC_OK && temp_as->time_stamp > problem_t1) { + problem_t2 = temp_as->time_stamp; + break; + } + } + } + } + if(problem_found == TRUE) { + time_t margin; + + if(problem_t2 == 0) { + margin = 12 * 60 * 60; + problem_t2 = problem_t1; + } + else + margin = (problem_t2 - problem_t1) / 2; + + t1 = problem_t1 - margin; + t2 = problem_t2 + margin; + } + } + + if(timeperiod_type == TIMEPERIOD_NEXTPROBLEM && problem_found == FALSE) { + t1 = old_t1; + t2 = old_t2; + } + + if(display_type != DISPLAY_NO_TRENDS && input_type == GET_INPUT_NONE) { + + printf("\n"); + printf("\n"); + printf("\n"); + } + + printf("\n"); + + if(display_type != DISPLAY_NO_TRENDS && input_type == GET_INPUT_NONE) { + + printf("
    \n"); + if(display_type == DISPLAY_HOST_TRENDS) + printf("Host '%s'", host_name); + else if(display_type == DISPLAY_SERVICE_TRENDS) + printf("Service '%s' On Host '%s'", svc_description, host_name); + printf("
    \n"); + + printf("
    \n"); + + printf("%s State Trends\n", url_images_path, TRENDS_ICON, (display_type == DISPLAY_HOST_TRENDS) ? "Host" : "Service", (display_type == DISPLAY_HOST_TRENDS) ? "Host" : "Service"); + + printf("
    \n"); + + get_time_string(&t1, start_timestring, sizeof(start_timestring) - 1, SHORT_DATE_TIME); + get_time_string(&t2, end_timestring, sizeof(end_timestring) - 1, SHORT_DATE_TIME); + printf("
    %s to %s
    \n", start_timestring, end_timestring); + + get_time_breakdown((time_t)(t2 - t1), &days, &hours, &minutes, &seconds); + printf("
    Duration: %dd %dh %dm %ds
    \n", days, hours, minutes, seconds); + } + + printf("
    \n"); + + printf("
    \n", TRENDS_CGI); + printf("\n"); + + if(display_type != DISPLAY_NO_TRENDS && input_type == GET_INPUT_NONE) { + + printf("\n", (display_type == DISPLAY_HOST_TRENDS) ? "host" : "service"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + } + + /* display context-sensitive help */ + printf("\n"); + + printf("
    First assumed %s state:Backtracked archives:
    "); + if(display_popups == FALSE) + printf("\n"); + if(use_map == FALSE) + printf("\n"); + printf("\n", (unsigned long)t1); + printf("\n", (unsigned long)t2); + printf("\n", escape_string(host_name)); + if(display_type == DISPLAY_SERVICE_TRENDS) + printf("\n", escape_string(svc_description)); + + printf("\n", (assume_initial_states == TRUE) ? "yes" : "no"); + printf("\n", (assume_state_retention == TRUE) ? "yes" : "no"); + printf("\n", (assume_states_during_notrunning == TRUE) ? "yes" : "no"); + printf("\n", (include_soft_states == TRUE) ? "yes" : "no"); + + if(display_type == DISPLAY_HOST_TRENDS) { + printf("", initial_assumed_service_state); + printf("", initial_assumed_host_state); + printf("\n"); + printf("\n"); + printf("\n", backtrack_archives); + printf("
    Report period:Zoom factor:
    \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("\n"); + printf("
    \n"); + if(display_type != DISPLAY_NO_TRENDS && input_type == GET_INPUT_NONE) { + if(display_type == DISPLAY_HOST_TRENDS) + display_context_help(CONTEXTHELP_TRENDS_HOST); + else + display_context_help(CONTEXTHELP_TRENDS_SERVICE); + } + else if(display_type == DISPLAY_NO_TRENDS || input_type != GET_INPUT_NONE) { + if(input_type == GET_INPUT_NONE) + display_context_help(CONTEXTHELP_TRENDS_MENU1); + else if(input_type == GET_INPUT_TARGET_TYPE) + display_context_help(CONTEXTHELP_TRENDS_MENU1); + else if(input_type == GET_INPUT_HOST_TARGET) + display_context_help(CONTEXTHELP_TRENDS_MENU2); + else if(input_type == GET_INPUT_SERVICE_TARGET) + display_context_help(CONTEXTHELP_TRENDS_MENU3); + else if(input_type == GET_INPUT_OPTIONS) + display_context_help(CONTEXTHELP_TRENDS_MENU4); + } + printf("
    \n"); + printf("
    \n"); + + printf("
    \n"); + } + + +#ifndef DEBUG + + /* check authorization... */ + if(display_type == DISPLAY_HOST_TRENDS) { + temp_host = find_host(host_name); + if(temp_host == NULL || is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) + is_authorized = FALSE; + } + else if(display_type == DISPLAY_SERVICE_TRENDS) { + temp_service = find_service(host_name, svc_description); + if(temp_service == NULL || is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) + is_authorized = FALSE; + } + if(is_authorized == FALSE) { + + if(mode == CREATE_HTML) + printf("

    It appears as though you are not authorized to view information for the specified %s...

    \n", (display_type == DISPLAY_HOST_TRENDS) ? "host" : "service"); + + document_footer(); + free_memory(); + return ERROR; + } +#endif + + + if(timeperiod_type == TIMEPERIOD_NEXTPROBLEM && problem_found == FALSE) { + printf("

    No problem found between end of display and end of recording

    \n"); + + document_footer(); + free_memory(); + return ERROR; + } + /* set drawing parameters, etc */ + + if(small_image == TRUE) { + image_height = 20; + image_width = 500; + } + else { + image_height = 300; + image_width = 900; + } + + if(display_type == DISPLAY_HOST_TRENDS) { + + if(small_image == TRUE) { + drawing_width = SMALL_HOST_DRAWING_WIDTH; + drawing_height = SMALL_HOST_DRAWING_HEIGHT; + drawing_x_offset = SMALL_HOST_DRAWING_X_OFFSET; + drawing_y_offset = SMALL_HOST_DRAWING_Y_OFFSET; + } + else { + drawing_width = HOST_DRAWING_WIDTH; + drawing_height = HOST_DRAWING_HEIGHT; + drawing_x_offset = HOST_DRAWING_X_OFFSET; + drawing_y_offset = HOST_DRAWING_Y_OFFSET; + } + } + else if(display_type == DISPLAY_SERVICE_TRENDS) { + + if(small_image == TRUE) { + drawing_width = SMALL_SVC_DRAWING_WIDTH; + drawing_height = SMALL_SVC_DRAWING_HEIGHT; + drawing_x_offset = SMALL_SVC_DRAWING_X_OFFSET; + drawing_y_offset = SMALL_SVC_DRAWING_Y_OFFSET; + } + else { + drawing_width = SVC_DRAWING_WIDTH; + drawing_height = SVC_DRAWING_HEIGHT; + drawing_x_offset = SVC_DRAWING_X_OFFSET; + drawing_y_offset = SVC_DRAWING_Y_OFFSET; + } + } + + /* last known state should always be initially set to indeterminate! */ + last_known_state = AS_NO_DATA; + + + /* initialize PNG image */ + if(display_type != DISPLAY_NO_TRENDS && mode == CREATE_IMAGE) { + + if(small_image == TRUE) { + trends_image = gdImageCreate(image_width, image_height); + if(trends_image == NULL) { +#ifdef DEBUG + printf("Error: Could not allocate memory for image\n"); +#endif + return ERROR; + } + } + + else { + + if(display_type == DISPLAY_HOST_TRENDS) + snprintf(image_template, sizeof(image_template) - 1, "%s/trendshost.png", physical_images_path); + else + snprintf(image_template, sizeof(image_template) - 1, "%s/trendssvc.png", physical_images_path); + image_template[sizeof(image_template) - 1] = '\x0'; + + /* allocate buffer for storing image */ + trends_image = NULL; + image_file = fopen(image_template, "r"); + if(image_file != NULL) { + trends_image = gdImageCreateFromPng(image_file); + fclose(image_file); + } + if(trends_image == NULL) + trends_image = gdImageCreate(image_width, image_height); + if(trends_image == NULL) { +#ifdef DEBUG + printf("Error: Could not allocate memory for image\n"); +#endif + return ERROR; + } + } + + /* allocate colors used for drawing */ + color_white = gdImageColorAllocate(trends_image, 255, 255, 255); + color_black = gdImageColorAllocate(trends_image, 0, 0, 0); + color_red = gdImageColorAllocate(trends_image, 255, 0, 0); + color_darkred = gdImageColorAllocate(trends_image, 128, 0, 0); + color_green = gdImageColorAllocate(trends_image, 0, 210, 0); + color_darkgreen = gdImageColorAllocate(trends_image, 0, 128, 0); + color_yellow = gdImageColorAllocate(trends_image, 176, 178, 20); + color_orange = gdImageColorAllocate(trends_image, 255, 100, 25); + + /* set transparency index */ + gdImageColorTransparent(trends_image, color_white); + + /* make sure the graphic is interlaced */ + gdImageInterlace(trends_image, 1); + + if(small_image == FALSE) { + + /* title */ + snprintf(start_time, sizeof(start_time) - 1, "%s", ctime(&t1)); + start_time[sizeof(start_time) - 1] = '\x0'; + start_time[strlen(start_time) - 1] = '\x0'; + snprintf(end_time, sizeof(end_time) - 1, "%s", ctime(&t2)); + end_time[sizeof(end_time) - 1] = '\x0'; + end_time[strlen(end_time) - 1] = '\x0'; + + string_height = gdFontSmall->h; + + if(display_type == DISPLAY_HOST_TRENDS) + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "State History For Host '%s'", host_name); + else + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "State History For Service '%s' On Host '%s'", svc_description, host_name); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(trends_image, gdFontSmall, (drawing_width / 2) - (string_width / 2) + drawing_x_offset, string_height, (unsigned char *)temp_buffer, color_black); + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s to %s", start_time, end_time); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageString(trends_image, gdFontSmall, (drawing_width / 2) - (string_width / 2) + drawing_x_offset, (string_height * 2) + 5, (unsigned char *)temp_buffer, color_black); + + + /* first time stamp */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s", start_time); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + string_width = gdFontSmall->w * strlen(temp_buffer); + gdImageStringUp(trends_image, gdFontSmall, drawing_x_offset - (string_height / 2), drawing_y_offset + drawing_height + string_width + 5, (unsigned char *)temp_buffer, color_black); + } + } + + if(display_type != DISPLAY_NO_TRENDS && input_type == GET_INPUT_NONE) { + + + if(mode == CREATE_IMAGE || (mode == CREATE_HTML && use_map == TRUE)) { + + /* read in all necessary archived state data */ + read_archived_state_data(); + + /* graph archived state trend data */ + graph_all_trend_data(); + } + + /* print URL to image */ + if(mode == CREATE_HTML) { + + printf("

    \n"); + printf("
    \n"); + printf("\n", image_width); + printf("
    \n"); + } + + if(mode == CREATE_IMAGE || (mode == CREATE_HTML && use_map == TRUE)) { + + /* draw timestamps */ + draw_timestamps(); + + /* draw horizontal lines */ + draw_horizontal_grid_lines(); + + /* draw state time breakdowns */ + draw_time_breakdowns(); + } + + if(mode == CREATE_IMAGE) { + + /* use STDOUT for writing the image data... */ + image_file = stdout; + +#ifndef DEBUG + /* write the image to file */ + gdImagePng(trends_image, image_file); +#endif +#ifdef DEBUG + image_file = fopen("trends.png", "w"); + if(image_file == NULL) + printf("Could not open trends.png for writing!\n"); + else { + gdImagePng(trends_image, image_file); + fclose(image_file); + } +#endif + + /* free memory allocated to image */ + gdImageDestroy(trends_image); + } + } + + + /* show user a selection of hosts and services to choose from... */ + if(display_type == DISPLAY_NO_TRENDS || input_type != GET_INPUT_NONE) { + + /* ask the user for what host they want a report for */ + if(input_type == GET_INPUT_HOST_TARGET) { + + printf("

    \n"); + printf("
    Step 2: Select Host
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", TRENDS_CGI); + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Host:\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + /* ask the user for what service they want a report for */ + else if(input_type == GET_INPUT_SERVICE_TARGET) { + + printf("\n"); + + + printf("

    \n"); + printf("
    Step 2: Select Service
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", TRENDS_CGI); + printf("\n"); + printf("\n", (first_service == NULL) ? "unknown" : (char *)escape_string(first_service)); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Service:\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + /* ask the user for report range and options */ + else if(input_type == GET_INPUT_OPTIONS) { + + time(¤t_time); + t = localtime(¤t_time); + + start_day = 1; + start_year = t->tm_year + 1900; + end_day = t->tm_mday; + end_year = t->tm_year + 1900; + + printf("

    \n"); + printf("
    Step 3: Select Report Options
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", TRENDS_CGI); + printf("\n", escape_string(host_name)); + if(display_type == DISPLAY_SERVICE_TRENDS) + printf("\n", escape_string(svc_description)); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf(""); + printf("\n"); + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n", (display_type == DISPLAY_HOST_TRENDS) ? "Host" : "Service"); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf(""); + printf("\n"); + + printf("\n"); + + printf("
    Report period:\n"); + printf("\n"); + printf("
    If Custom Report Period...
    Start Date (Inclusive):"); + printf("\n "); + printf(" ", start_day); + printf("", start_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("
    End Date (Inclusive):"); + printf("\n "); + printf(" ", end_day); + printf("", end_year); + printf("\n"); + printf("\n"); + printf("\n"); + printf("

    Assume Initial States:\n"); + printf("\n"); + printf("
    Assume State Retention:\n"); + printf("\n"); + printf("
    Assume States During Program Downtime:\n"); + printf("\n"); + printf("
    Include Soft States:\n"); + printf("\n"); + printf("
    First Assumed %s State:\n"); + if(display_type == DISPLAY_HOST_TRENDS) { + printf("\n"); + printf("
    Backtracked Archives (To Scan For Initial States):\n"); + printf("\n", backtrack_archives); + printf("
    Suppress image map:
    Suppress popups:
    \n"); + printf("
    \n"); + + printf("

    \n"); + + /* + printf("

    \n"); + printf("Note: Choosing the 'suppress image map' option will make the report run approximately twice as fast as it would otherwise, but it will prevent you from being able to zoom in on specific time periods.\n"); + printf("

    \n"); + */ + } + + /* as the user whether they want a graph for a host or service */ + else { + printf("

    \n"); + printf("
    Step 1: Select Report Type
    \n"); + printf("

    \n"); + + printf("

    \n"); + + printf("
    \n", TRENDS_CGI); + printf("\n"); + + printf("\n"); + printf("\n"); + + printf("\n"); + + printf("
    Type:\n"); + printf("\n"); + printf("
    \n"); + printf("\n"); + printf("
    \n"); + printf("
    \n"); + + printf("

    \n"); + } + + } + + document_footer(); + + /* free memory allocated to the archived state data list */ + free_archived_state_list(); + + /* free all other 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; + + if(mode == CREATE_HTML) { + 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)0; + 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("\n"); + printf("\n"); + printf("\n", url_images_path); + printf("\n"); + printf("Nagios Trends\n"); + printf("\n"); + + if(use_stylesheet == TRUE) { + printf("\n", url_stylesheets_path, COMMON_CSS); + printf("\n", url_stylesheets_path, TRENDS_CSS); + } + + /* write JavaScript code for popup window */ + if(display_type != DISPLAY_NO_TRENDS) + write_popup_code(); + + printf("\n"); + + printf("\n"); + + /* include user SSI header */ + include_ssi_files(TRENDS_CGI, SSI_HEADER); + + printf("
    \n"); + } + + else { + 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: image/png\r\n\r\n"); + } + + return; + } + + + +void document_footer(void) { + + if(embedded == TRUE) + return; + + if(mode == CREATE_HTML) { + + /* include user SSI footer */ + include_ssi_files(TRENDS_CGI, SSI_FOOTER); + + printf("\n"); + printf("\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")) { + 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_HOST_TRENDS; + } + + /* we found the node width 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_SERVICE_TRENDS; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t1")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t1 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + } + + /* we found first time argument */ + else if(!strcmp(variables[x], "t2")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + t2 = (time_t)strtoul(variables[x], NULL, 10); + timeperiod_type = TIMEPERIOD_CUSTOM; + } + + /* we found the image creation option */ + else if(!strcmp(variables[x], "createimage")) { + mode = CREATE_IMAGE; + } + + /* we found the assume initial states option */ + else if(!strcmp(variables[x], "assumeinitialstates")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_initial_states = TRUE; + else + assume_initial_states = FALSE; + } + + /* we found the initial assumed host state option */ + else if(!strcmp(variables[x], "initialassumedhoststate")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + initial_assumed_host_state = atoi(variables[x]); + } + + /* we found the initial assumed service state option */ + else if(!strcmp(variables[x], "initialassumedservicestate")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + initial_assumed_service_state = atoi(variables[x]); + } + + /* we found the assume state during program not running option */ + else if(!strcmp(variables[x], "assumestatesduringnotrunning")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_states_during_notrunning = TRUE; + else + assume_states_during_notrunning = FALSE; + } + + /* we found the assume state retention option */ + else if(!strcmp(variables[x], "assumestateretention")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + assume_state_retention = TRUE; + else + assume_state_retention = FALSE; + } + + /* we found the include soft states option */ + else if(!strcmp(variables[x], "includesoftstates")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "yes")) + include_soft_states = TRUE; + else + include_soft_states = FALSE; + } + + /* we found the zoom factor argument */ + else if(!strcmp(variables[x], "zoom")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + zoom_factor = atoi(variables[x]); + if(zoom_factor == 0) + zoom_factor = 1; + } + + /* we found the backtrack archives argument */ + else if(!strcmp(variables[x], "backtrack")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + backtrack_archives = atoi(variables[x]); + if(backtrack_archives < 0) + backtrack_archives = 0; + if(backtrack_archives > MAX_ARCHIVE_BACKTRACKS) + backtrack_archives = MAX_ARCHIVE_BACKTRACKS; + } + + /* we found the standard timeperiod argument */ + else if(!strcmp(variables[x], "timeperiod")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "today")) + timeperiod_type = TIMEPERIOD_TODAY; + else if(!strcmp(variables[x], "yesterday")) + timeperiod_type = TIMEPERIOD_YESTERDAY; + else if(!strcmp(variables[x], "thisweek")) + timeperiod_type = TIMEPERIOD_THISWEEK; + else if(!strcmp(variables[x], "lastweek")) + timeperiod_type = TIMEPERIOD_LASTWEEK; + else if(!strcmp(variables[x], "thismonth")) + timeperiod_type = TIMEPERIOD_THISMONTH; + else if(!strcmp(variables[x], "lastmonth")) + timeperiod_type = TIMEPERIOD_LASTMONTH; + else if(!strcmp(variables[x], "thisquarter")) + timeperiod_type = TIMEPERIOD_THISQUARTER; + else if(!strcmp(variables[x], "lastquarter")) + timeperiod_type = TIMEPERIOD_LASTQUARTER; + else if(!strcmp(variables[x], "thisyear")) + timeperiod_type = TIMEPERIOD_THISYEAR; + else if(!strcmp(variables[x], "lastyear")) + timeperiod_type = TIMEPERIOD_LASTYEAR; + else if(!strcmp(variables[x], "nextproblem")) + timeperiod_type = TIMEPERIOD_NEXTPROBLEM; + else if(!strcmp(variables[x], "last24hours")) + timeperiod_type = TIMEPERIOD_LAST24HOURS; + else if(!strcmp(variables[x], "last7days")) + timeperiod_type = TIMEPERIOD_LAST7DAYS; + else if(!strcmp(variables[x], "last31days")) + timeperiod_type = TIMEPERIOD_LAST31DAYS; + else if(!strcmp(variables[x], "custom")) + timeperiod_type = TIMEPERIOD_CUSTOM; + else + continue; + + convert_timeperiod_to_times(timeperiod_type); + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "sday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "syear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "smin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ssec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "shour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + start_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + + /* we found time argument */ + else if(!strcmp(variables[x], "emon")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_month = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eday")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_day = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "eyear")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_year = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "emin")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_minute = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "esec")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_second = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* we found time argument */ + else if(!strcmp(variables[x], "ehour")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(timeperiod_type != TIMEPERIOD_CUSTOM) + continue; + + end_hour = atoi(variables[x]); + timeperiod_type = TIMEPERIOD_CUSTOM; + compute_time_from_parts = TRUE; + } + + /* 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 nopopups option */ + else if(!strcmp(variables[x], "nopopups")) + display_popups = FALSE; + + /* we found the nomap option */ + else if(!strcmp(variables[x], "nomap")) { + display_popups = FALSE; + use_map = FALSE; + } + + /* we found the input option */ + else if(!strcmp(variables[x], "input")) { + x++; + if(variables[x] == NULL) { + error = TRUE; + break; + } + + if(!strcmp(variables[x], "gethost")) + input_type = GET_INPUT_HOST_TARGET; + else if(!strcmp(variables[x], "getservice")) + input_type = GET_INPUT_SERVICE_TARGET; + else if(!strcmp(variables[x], "getoptions")) + input_type = GET_INPUT_OPTIONS; + else + input_type = GET_INPUT_TARGET_TYPE; + } + + /* we found the small image option */ + else if(!strcmp(variables[x], "smallimage")) + small_image = TRUE; + + } + + /* free memory allocated to the CGI variables */ + free_cgivars(variables); + + return error; + } + + + +/* top level routine for graphic all trend data */ +void graph_all_trend_data(void) { + archived_state *temp_as; + archived_state *last_as; + time_t a; + time_t b; + time_t current_time; + int current_state = AS_NO_DATA; + int have_some_real_data = FALSE; + hoststatus *hststatus = NULL; + servicestatus *svcstatus = NULL; + unsigned long wobble = 300; + int first_real_state = AS_NO_DATA; + time_t initial_assumed_time; + int initial_assumed_state = AS_SVC_OK; + int error = FALSE; + + + time(¤t_time); + + /* if left hand of graph is after current time, we can't do anything at all.... */ + if(t1 > current_time) + return; + + /* find current state for host or service */ + if(display_type == DISPLAY_HOST_TRENDS) + hststatus = find_hoststatus(host_name); + else + svcstatus = find_servicestatus(host_name, svc_description); + + + /************************************/ + /* INSERT CURRENT STATE (IF WE CAN) */ + /************************************/ + + /* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */ + /* the "wobble" value is necessary because when the CGI is called to do the PNG generation, t2 will actually be less that current_time by a bit */ + + /* if we don't have any data, assume current state (if possible) */ + if(as_list == NULL && current_time > t1 && current_time < (t2 + wobble)) { + + /* we don't have any historical information, but the current time falls within the reporting period, so use */ + /* the current status of the host/service as the starting data */ + if(display_type == DISPLAY_HOST_TRENDS) { + if(hststatus != NULL) { + + if(hststatus->status == HOST_DOWN) + last_known_state = AS_HOST_DOWN; + else if(hststatus->status == HOST_UNREACHABLE) + last_known_state = AS_HOST_UNREACHABLE; + else + last_known_state = AS_HOST_UP; + + /* add a dummy archived state item, so something can get graphed */ + add_archived_state(last_known_state, AS_HARD_STATE, t1, "Current Host State Assumed (Faked Log Entry)"); + + /* use the current state as the last known real state */ + first_real_state = last_known_state; + } + } + else { + if(svcstatus != NULL) { + + if(svcstatus->status == SERVICE_OK) + last_known_state = AS_SVC_OK; + else if(svcstatus->status == SERVICE_WARNING) + last_known_state = AS_SVC_WARNING; + else if(svcstatus->status == SERVICE_CRITICAL) + last_known_state = AS_SVC_CRITICAL; + else if(svcstatus->status == SERVICE_UNKNOWN) + last_known_state = AS_SVC_UNKNOWN; + + /* add a dummy archived state item, so something can get graphed */ + add_archived_state(last_known_state, AS_HARD_STATE, t1, "Current Service State Assumed (Faked Log Entry)"); + + /* use the current state as the last known real state */ + first_real_state = last_known_state; + } + } + } + + + /******************************************/ + /* INSERT FIRST ASSUMED STATE (IF WE CAN) */ + /******************************************/ + + if((display_type == DISPLAY_HOST_TRENDS && initial_assumed_host_state != AS_NO_DATA) || (display_type == DISPLAY_SERVICE_TRENDS && initial_assumed_service_state != AS_NO_DATA)) { + + /* see if its okay to assume initial state for this subject */ + error = FALSE; + if(display_type == DISPLAY_SERVICE_TRENDS) { + if(initial_assumed_service_state != AS_SVC_OK && initial_assumed_service_state != AS_SVC_WARNING && initial_assumed_service_state != AS_SVC_UNKNOWN && initial_assumed_service_state != AS_SVC_CRITICAL && initial_assumed_service_state != AS_CURRENT_STATE) + error = TRUE; + else + initial_assumed_state = initial_assumed_service_state; + if(initial_assumed_service_state == AS_CURRENT_STATE && svcstatus == NULL) + error = TRUE; + } + else { + if(initial_assumed_host_state != AS_HOST_UP && initial_assumed_host_state != AS_HOST_DOWN && initial_assumed_host_state != AS_HOST_UNREACHABLE && initial_assumed_host_state != AS_CURRENT_STATE) + error = TRUE; + else + initial_assumed_state = initial_assumed_host_state; + if(initial_assumed_host_state == AS_CURRENT_STATE && hststatus == NULL) + error = TRUE; + } + + /* get the current state if applicable */ + if(((display_type == DISPLAY_HOST_TRENDS && initial_assumed_host_state == AS_CURRENT_STATE) || (display_type == DISPLAY_SERVICE_TRENDS && initial_assumed_service_state == AS_CURRENT_STATE)) && error == FALSE) { + if(display_type == DISPLAY_HOST_TRENDS) { + switch(hststatus->status) { + case HOST_DOWN: + initial_assumed_state = AS_HOST_DOWN; + break; + case HOST_UNREACHABLE: + initial_assumed_state = AS_HOST_UNREACHABLE; + break; + case HOST_UP: + initial_assumed_state = AS_HOST_UP; + break; + default: + error = TRUE; + break; + } + } + else { + switch(svcstatus->status) { + case SERVICE_OK: + initial_assumed_state = AS_SVC_OK; + break; + case SERVICE_WARNING: + initial_assumed_state = AS_SVC_WARNING; + break; + case SERVICE_UNKNOWN: + initial_assumed_state = AS_SVC_UNKNOWN; + break; + case SERVICE_CRITICAL: + initial_assumed_state = AS_SVC_CRITICAL; + break; + default: + error = TRUE; + break; + } + } + } + + if(error == FALSE) { + + /* add this assumed state entry before any entries in the list and <= t1 */ + if(as_list == NULL) + initial_assumed_time = t1; + else if(as_list->time_stamp > t1) + initial_assumed_time = t1; + else + initial_assumed_time = as_list->time_stamp - 1; + + if(display_type == DISPLAY_HOST_TRENDS) + add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Host State Assumed (Faked Log Entry)"); + else + add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Service State Assumed (Faked Log Entry)"); + } + } + + + + + /**************************************/ + /* BAIL OUT IF WE DON'T HAVE ANYTHING */ + /**************************************/ + + have_some_real_data = FALSE; + for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) { + if(temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_START && temp_as->entry_type != AS_PROGRAM_END) { + have_some_real_data = TRUE; + break; + } + } + if(have_some_real_data == FALSE) + return; + + + + + /* if we're creating the HTML, start map code... */ + if(mode == CREATE_HTML) + printf("\n"); + + last_as = NULL; + earliest_time = t2; + latest_time = t1; + + + +#ifdef DEBUG + printf("--- BEGINNING/MIDDLE SECTION ---
    \n"); +#endif + + /**********************************/ + /* BEGINNING/MIDDLE SECTION */ + /**********************************/ + + for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) { + + /* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */ + if((temp_as->time_stamp <= t1 || temp_as == as_list) && (temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_END && temp_as->entry_type != AS_PROGRAM_START)) { + last_known_state = temp_as->entry_type; +#ifdef DEBUG + printf("SETTING LAST KNOWN STATE=%d
    \n", last_known_state); +#endif + } + + /* skip this entry if it occurs before the starting point of the graph */ + if(temp_as->time_stamp <= t1) { +#ifdef DEBUG + printf("SKIPPING PRE-EVENT: %d @ %lu
    \n", temp_as->entry_type, temp_as->time_stamp); +#endif + last_as = temp_as; + continue; + } + + /* graph this span if we're not on the first item */ + if(last_as != NULL) { + + a = last_as->time_stamp; + b = temp_as->time_stamp; + + /* we've already passed the last time displayed in the graph */ + if(a > t2) + break; + + /* only graph this data if its on the graph */ + else if(b > t1) { + + /* clip last time if it exceeds graph limits */ + if(b > t2) + b = t2; + + /* clip first time if it precedes graph limits */ + if(a < t1) + a = t1; + + /* save this time if its the earliest we've graphed */ + if(a < earliest_time) { + earliest_time = a; + earliest_state = last_as->entry_type; + } + + /* save this time if its the latest we've graphed */ + if(b > latest_time) { + latest_time = b; + latest_state = last_as->entry_type; + } + + /* compute availability times for this chunk */ + graph_trend_data(last_as->entry_type, temp_as->entry_type, last_as->time_stamp, a, b, last_as->state_info); + + /* return if we've reached the end of the graph limits */ + if(b >= t2) { + last_as = temp_as; + break; + } + } + } + + + /* keep track of the last item */ + last_as = temp_as; + } + + +#ifdef DEBUG + printf("--- END SECTION ---
    \n"); +#endif + + /**********************************/ + /* END SECTION */ + /**********************************/ + + if(last_as != NULL) { + + /* don't process an entry that is beyond the limits of the graph */ + if(last_as->time_stamp < t2) { + + time(¤t_time); + b = current_time; + if(b > t2) + b = t2; + + a = last_as->time_stamp; + if(a < t1) + a = t1; + + /* fake the current state (it doesn't really matter for graphing) */ + if(display_type == DISPLAY_HOST_TRENDS) + current_state = AS_HOST_UP; + else + current_state = AS_SVC_OK; + + /* compute availability times for last state */ + graph_trend_data(last_as->entry_type, current_state, a, a, b, last_as->state_info); + } + } + + + + /* if we're creating the HTML, close the map code */ + if(mode == CREATE_HTML) + printf("
    \n"); + + return; + } + + + +/* graphs trend data */ +void graph_trend_data(int first_state, int last_state, time_t real_start_time, time_t start_time, time_t end_time, char *state_info) { + int start_state; + int end_state; + int start_pixel = 0; + int end_pixel = 0; + int color_to_use = 0; + int height = 0; + double start_pixel_ratio; + double end_pixel_ratio; + char temp_buffer[MAX_INPUT_BUFFER]; + char state_string[MAX_INPUT_BUFFER]; + char end_timestring[MAX_INPUT_BUFFER]; + char start_timestring[MAX_INPUT_BUFFER]; + time_t center_time; + time_t next_start_time; + time_t next_end_time; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + /* can't graph if we don't have data... */ + if(first_state == AS_NO_DATA || last_state == AS_NO_DATA) + return; + if(first_state == AS_PROGRAM_START && (last_state == AS_PROGRAM_END || last_state == AS_PROGRAM_START)) { + if(assume_initial_states == FALSE) + return; + } + if(first_state == AS_PROGRAM_END) { + if(assume_states_during_notrunning == TRUE) + first_state = last_known_state; + else + return; + } + + /* special case if first entry was program start */ + if(first_state == AS_PROGRAM_START) { +#ifdef DEBUG + printf("First state=program start!\n"); +#endif + if(assume_initial_states == TRUE) { +#ifdef DEBUG + printf("\tWe are assuming initial states...\n"); +#endif + if(assume_state_retention == TRUE) { + start_state = last_known_state; +#ifdef DEBUG + printf("\tWe are assuming state retention (%d)...\n", start_state); +#endif + } + else { +#ifdef DEBUG + printf("\tWe are NOT assuming state retention...\n"); +#endif + if(display_type == DISPLAY_HOST_TRENDS) + start_state = AS_HOST_UP; + else + start_state = AS_SVC_OK; + } + } + else { +#ifdef DEBUG + printf("We ARE NOT assuming initial states!\n"); +#endif + return; + } + } + else { + start_state = first_state; + last_known_state = first_state; + } + + /* special case if last entry was program stop */ + if(last_state == AS_PROGRAM_END) + end_state = first_state; + else + end_state = last_state; + +#ifdef DEBUG + printf("Graphing state %d\n", start_state); + printf("\tfrom %s", ctime(&start_time)); + printf("\tto %s", ctime(&end_time)); +#endif + + if(start_time < t1) + start_time = t1; + if(end_time > t2) + end_time = t2; + if(end_time < t1 || start_time > t2) + return; + + /* calculate the first and last pixels to use */ + if(start_time == t1) + start_pixel = 0; + else { + start_pixel_ratio = ((double)(start_time - t1)) / ((double)(t2 - t1)); + start_pixel = (int)(start_pixel_ratio * (drawing_width - 1)); + } + if(end_time == t1) + end_pixel = 0; + else { + end_pixel_ratio = ((double)(end_time - t1)) / ((double)(t2 - t1)); + end_pixel = (int)(end_pixel_ratio * (drawing_width - 1)); + } + +#ifdef DEBUG + printf("\tPixel %d to %d\n\n", start_pixel, end_pixel); +#endif + + + /* we're creating the image, so draw... */ + if(mode == CREATE_IMAGE) { + + /* figure out the color to use for drawing */ + switch(start_state) { + case AS_HOST_UP: + color_to_use = color_green; + height = 60; + break; + case AS_HOST_DOWN: + color_to_use = color_red; + height = 40; + break; + case AS_HOST_UNREACHABLE: + color_to_use = color_darkred; + height = 20; + break; + case AS_SVC_OK: + color_to_use = color_green; + height = 80; + break; + case AS_SVC_WARNING: + color_to_use = color_yellow; + height = 60; + break; + case AS_SVC_UNKNOWN: + color_to_use = color_orange; + height = 40; + break; + case AS_SVC_CRITICAL: + color_to_use = color_red; + height = 20; + break; + default: + color_to_use = color_black; + height = 0; + break; + } + + /* draw a rectangle */ + if(start_state != AS_NO_DATA) + gdImageFilledRectangle(trends_image, start_pixel + drawing_x_offset, drawing_height - height + drawing_y_offset, end_pixel + drawing_x_offset, drawing_height + drawing_y_offset, color_to_use); + } + + /* else we're creating the HTML, so write map area code... */ + else { + + + /* figure out the the state string to use */ + switch(start_state) { + case AS_HOST_UP: + strcpy(state_string, "UP"); + height = 60; + break; + case AS_HOST_DOWN: + strcpy(state_string, "DOWN"); + height = 40; + break; + case AS_HOST_UNREACHABLE: + strcpy(state_string, "UNREACHABLE"); + height = 20; + break; + case AS_SVC_OK: + strcpy(state_string, "OK"); + height = 80; + break; + case AS_SVC_WARNING: + strcpy(state_string, "WARNING"); + height = 60; + break; + case AS_SVC_UNKNOWN: + strcpy(state_string, "UNKNOWN"); + height = 40; + break; + case AS_SVC_CRITICAL: + strcpy(state_string, "CRITICAL"); + height = 20; + break; + default: + strcpy(state_string, "?"); + height = 5; + break; + } + + /* get the center of this time range */ + center_time = start_time + ((end_time - start_time) / 2); + + /* determine next start and end time range with zoom factor */ + if(zoom_factor > 0) { + next_start_time = center_time - (((t2 - t1) / 2) / zoom_factor); + next_end_time = center_time + (((t2 - t1) / 2) / zoom_factor); + } + else { + next_start_time = center_time + (((t2 - t1) / 2) * zoom_factor); + next_end_time = center_time - (((t2 - t1) / 2) * zoom_factor); + } + + printf("\n"); + + } + + + /* calculate time in this state */ + switch(start_state) { + case AS_HOST_UP: + time_up += (unsigned long)(end_time - start_time); + break; + case AS_HOST_DOWN: + time_down += (unsigned long)(end_time - start_time); + break; + case AS_HOST_UNREACHABLE: + time_unreachable += (unsigned long)(end_time - start_time); + break; + case AS_SVC_OK: + time_ok += (unsigned long)(end_time - start_time); + break; + case AS_SVC_WARNING: + time_warning += (unsigned long)(end_time - start_time); + break; + case AS_SVC_UNKNOWN: + time_unknown += (unsigned long)(end_time - start_time); + break; + case AS_SVC_CRITICAL: + time_critical += (unsigned long)(end_time - start_time); + break; + default: + break; + } + + return; + } + + + +/* convert current host state to archived state value */ +int convert_host_state_to_archived_state(int current_status) { + + if(current_status == HOST_UP) + return AS_HOST_UP; + if(current_status == HOST_DOWN) + return AS_HOST_DOWN; + if(current_status == HOST_UNREACHABLE) + return AS_HOST_UNREACHABLE; + + return AS_NO_DATA; + } + + +/* convert current service state to archived state value */ +int convert_service_state_to_archived_state(int current_status) { + + if(current_status == SERVICE_OK) + return AS_SVC_OK; + if(current_status == SERVICE_UNKNOWN) + return AS_SVC_UNKNOWN; + if(current_status == SERVICE_WARNING) + return AS_SVC_WARNING; + if(current_status == SERVICE_CRITICAL) + return AS_SVC_CRITICAL; + + return AS_NO_DATA; + } + + + +/* adds an archived state entry */ +void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info) { + archived_state *last_as = NULL; + archived_state *temp_as = NULL; + archived_state *new_as = NULL; + +#ifdef DEBUG + printf("Added state %d @ %s", state_type, ctime(&time_stamp)); +#endif + + /* allocate memory for the new entry */ + new_as = (archived_state *)malloc(sizeof(archived_state)); + if(new_as == NULL) + return; + + /* allocate memory fo the state info */ + if(state_info != NULL) { + new_as->state_info = (char *)malloc(strlen(state_info) + 1); + if(new_as->state_info != NULL) + strcpy(new_as->state_info, state_info); + } + else new_as->state_info = NULL; + + new_as->entry_type = entry_type; + new_as->processed_state = entry_type; + new_as->state_type = state_type; + new_as->time_stamp = time_stamp; + + /* add the new entry to the list in memory, sorted by time */ + last_as = as_list; + for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) { + if(new_as->time_stamp < temp_as->time_stamp) { + new_as->next = temp_as; + if(temp_as == as_list) + as_list = new_as; + else + last_as->next = new_as; + break; + } + else + last_as = temp_as; + } + if(as_list == NULL) { + new_as->next = NULL; + as_list = new_as; + } + else if(temp_as == NULL) { + new_as->next = NULL; + last_as->next = new_as; + } + + return; + } + + +/* frees memory allocated to the archived state list */ +void free_archived_state_list(void) { + archived_state *this_as = NULL; + archived_state *next_as = NULL; + + for(this_as = as_list; this_as != NULL;) { + next_as = this_as->next; + if(this_as->state_info != NULL) + free(this_as->state_info); + free(this_as); + this_as = next_as; + } + + as_list = NULL; + + return; + } + + +/* reads log files for archived state data */ +void read_archived_state_data(void) { + char filename[MAX_FILENAME_LENGTH]; + int newest_archive = 0; + int oldest_archive = 0; + int current_archive; + +#ifdef DEBUG + printf("Determining archives to use...\n"); +#endif + + /* determine earliest archive to use */ + oldest_archive = determine_archive_to_use_from_time(t1); + if(log_rotation_method != LOG_ROTATION_NONE) + oldest_archive += backtrack_archives; + + /* determine most recent archive to use */ + newest_archive = determine_archive_to_use_from_time(t2); + + if(oldest_archive < newest_archive) + oldest_archive = newest_archive; + +#ifdef DEBUG + printf("Oldest archive: %d\n", oldest_archive); + printf("Newest archive: %d\n", newest_archive); +#endif + + /* read in all the necessary archived logs */ + for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) { + + /* get the name of the log file that contains this archive */ + get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1); + +#ifdef DEBUG + printf("\tCurrent archive: %d (%s)\n", current_archive, filename); +#endif + + /* scan the log file for archived state data */ + scan_log_file_for_archived_state_data(filename); + } + + return; + } + + + +/* grabs archives state data from a log file */ +void scan_log_file_for_archived_state_data(char *filename) { + char *input = NULL; + char *input2 = NULL; + char entry_host_name[MAX_INPUT_BUFFER]; + char entry_svc_description[MAX_INPUT_BUFFER]; + char *plugin_output = NULL; + char *temp_buffer = NULL; + time_t time_stamp; + mmapfile *thefile = NULL; + int state_type = 0; + + /* print something so browser doesn't time out */ + if(mode == CREATE_HTML) { + printf(" "); + fflush(NULL); + } + + if((thefile = mmap_fopen(filename)) == NULL) { +#ifdef DEBUG + printf("Could not open file '%s' for reading.\n", filename); +#endif + return; + } + +#ifdef DEBUG + printf("Scanning log file '%s' for archived state data...\n", filename); +#endif + + while(1) { + + /* free memory */ + free(input); + free(input2); + input = NULL; + input2 = NULL; + + /* read the next line */ + if((input = mmap_fgets(thefile)) == NULL) + break; + + strip(input); + + if((input2 = strdup(input)) == NULL) + continue; + + temp_buffer = my_strtok(input2, "]"); + time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10); + + /* program starts/restarts */ + if(strstr(input, " starting...")) + add_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program start"); + if(strstr(input, " restarting...")) + add_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program restart"); + + /* program stops */ + if(strstr(input, " shutting down...")) + add_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Normal program termination"); + if(strstr(input, "Bailing out")) + add_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Abnormal program termination"); + + if(display_type == DISPLAY_HOST_TRENDS) { + if(strstr(input, "HOST ALERT:") || strstr(input, "INITIAL HOST STATE:") || strstr(input, "CURRENT HOST STATE:")) { + + free(input2); + if((input2 = strdup(input)) == NULL) + continue; + + /* get host name */ + temp_buffer = my_strtok(input2, "]"); + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + if(strcmp(host_name, entry_host_name)) + continue; + + /* state types */ + if(strstr(input, ";SOFT;")) { + if(include_soft_states == FALSE) + continue; + state_type = AS_SOFT_STATE; + } + if(strstr(input, ";HARD;")) + state_type = AS_HARD_STATE; + + /* get the plugin output */ + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + plugin_output = my_strtok(NULL, "\n"); + + if(strstr(input, ";DOWN;")) + add_archived_state(AS_HOST_DOWN, state_type, time_stamp, plugin_output); + else if(strstr(input, ";UNREACHABLE;")) + add_archived_state(AS_HOST_UNREACHABLE, state_type, time_stamp, plugin_output); + else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) + add_archived_state(AS_HOST_UP, state_type, time_stamp, plugin_output); + else + add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output); + } + } + if(display_type == DISPLAY_SERVICE_TRENDS) { + if(strstr(input, "SERVICE ALERT:") || strstr(input, "INITIAL SERVICE STATE:") || strstr(input, "CURRENT SERVICE STATE:")) { + + free(input2); + if((input2 = strdup(input)) == NULL) + continue; + + /* get host name */ + temp_buffer = my_strtok(input2, "]"); + temp_buffer = my_strtok(NULL, ":"); + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); + entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; + + if(strcmp(host_name, entry_host_name)) + continue; + + /* get service description */ + temp_buffer = my_strtok(NULL, ";"); + strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); + entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; + + if(strcmp(svc_description, entry_svc_description)) + continue; + + /* state types */ + if(strstr(input, ";SOFT;")) { + if(include_soft_states == FALSE) + continue; + state_type = AS_SOFT_STATE; + } + if(strstr(input, ";HARD;")) + state_type = AS_HARD_STATE; + + /* get the plugin output */ + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + temp_buffer = my_strtok(NULL, ";"); + plugin_output = my_strtok(NULL, "\n"); + + if(strstr(input, ";CRITICAL;")) + add_archived_state(AS_SVC_CRITICAL, state_type, time_stamp, plugin_output); + else if(strstr(input, ";WARNING;")) + add_archived_state(AS_SVC_WARNING, state_type, time_stamp, plugin_output); + else if(strstr(input, ";UNKNOWN;")) + add_archived_state(AS_SVC_UNKNOWN, state_type, time_stamp, plugin_output); + else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) + add_archived_state(AS_SVC_OK, state_type, time_stamp, plugin_output); + else + add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output); + + } + } + + } + + /* free memory and close the file */ + free(input); + free(input2); + mmap_fclose(thefile); + + return; + } + + + +/* write JavaScript code and layer for popup window */ +void write_popup_code(void) { + char *border_color = "#000000"; + char *background_color = "#ffffcc"; + int border = 1; + int padding = 3; + int x_offset = 3; + int y_offset = 3; + + printf("\n"); + + return; + } + + + + +/* write timestamps */ +void draw_timestamps(void) { + int last_timestamp = 0; + archived_state *temp_as; + double start_pixel_ratio; + int start_pixel; + + if(mode != CREATE_IMAGE) + return; + + /* draw first timestamp */ + draw_timestamp(0, t1); + last_timestamp = 0; + + for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) { + + if(temp_as->time_stamp < t1 || temp_as->time_stamp > t2) + continue; + + start_pixel_ratio = ((double)(temp_as->time_stamp - t1)) / ((double)(t2 - t1)); + start_pixel = (int)(start_pixel_ratio * (drawing_width - 1)); + + /* draw start timestamp if possible */ + if((start_pixel > last_timestamp + MIN_TIMESTAMP_SPACING) && (start_pixel < drawing_width - 1 - MIN_TIMESTAMP_SPACING)) { + draw_timestamp(start_pixel, temp_as->time_stamp); + last_timestamp = start_pixel; + } + } + + /* draw last timestamp */ + draw_timestamp(drawing_width - 1, t2); + + return; + } + + +/* write timestamp below graph */ +void draw_timestamp(int ts_pixel, time_t ts_time) { + char temp_buffer[MAX_INPUT_BUFFER]; + int string_height; + int string_width; + + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s", ctime(&ts_time)); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + temp_buffer[strlen(temp_buffer) - 1] = '\x0'; + + string_height = gdFontSmall->h; + string_width = gdFontSmall->w * strlen(temp_buffer); + + if(small_image == FALSE) + gdImageStringUp(trends_image, gdFontSmall, ts_pixel + drawing_x_offset - (string_height / 2), drawing_y_offset + drawing_height + string_width + 5, (unsigned char *)temp_buffer, color_black); + + /* draw a dashed vertical line at this point */ + if(ts_pixel > 0 && ts_pixel < (drawing_width - 1)) + draw_dashed_line(ts_pixel + drawing_x_offset, drawing_y_offset, ts_pixel + drawing_x_offset, drawing_y_offset + drawing_height, color_black); + + return; + } + + + +/* draw total state times */ +void draw_time_breakdowns(void) { + char temp_buffer[MAX_INPUT_BUFFER]; + unsigned long total_time = 0L; + unsigned long total_state_time; + unsigned long time_indeterminate = 0L; + int string_height; + + if(mode == CREATE_HTML) + return; + + if(small_image == TRUE) + return; + + total_time = (unsigned long)(t2 - t1); + + if(display_type == DISPLAY_HOST_TRENDS) + total_state_time = time_up + time_down + time_unreachable; + else + total_state_time = time_ok + time_warning + time_unknown + time_critical; + + if(total_state_time >= total_time) + time_indeterminate = 0L; + else + time_indeterminate = total_time - total_state_time; + + string_height = gdFontSmall->h; + + if(display_type == DISPLAY_HOST_TRENDS) { + + get_time_breakdown_string(total_time, time_up, "Up", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 5, (unsigned char *)temp_buffer, color_darkgreen); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 2), drawing_y_offset + 5, (unsigned char *)"Up", color_darkgreen); + + get_time_breakdown_string(total_time, time_down, "Down", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 25, (unsigned char *)temp_buffer, color_red); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 4), drawing_y_offset + 25, (unsigned char *)"Down", color_red); + + get_time_breakdown_string(total_time, time_unreachable, "Unreachable", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 45, (unsigned char *)temp_buffer, color_darkred); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 11), drawing_y_offset + 45, (unsigned char *)"Unreachable", color_darkred); + + get_time_breakdown_string(total_time, time_indeterminate, "Indeterminate", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 65, (unsigned char *)temp_buffer, color_black); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 13), drawing_y_offset + 65, (unsigned char *)"Indeterminate", color_black); + } + else { + get_time_breakdown_string(total_time, time_ok, "Ok", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 5, (unsigned char *)temp_buffer, color_darkgreen); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 2), drawing_y_offset + 5, (unsigned char *)"Ok", color_darkgreen); + + get_time_breakdown_string(total_time, time_warning, "Warning", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 25, (unsigned char *)temp_buffer, color_yellow); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 7), drawing_y_offset + 25, (unsigned char *)"Warning", color_yellow); + + get_time_breakdown_string(total_time, time_unknown, "Unknown", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 45, (unsigned char *)temp_buffer, color_orange); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 7), drawing_y_offset + 45, (unsigned char *)"Unknown", color_orange); + + get_time_breakdown_string(total_time, time_critical, "Critical", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 65, (unsigned char *)temp_buffer, color_red); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 8), drawing_y_offset + 65, (unsigned char *)"Critical", color_red); + + get_time_breakdown_string(total_time, time_indeterminate, "Indeterminate", &temp_buffer[0], sizeof(temp_buffer)); + gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 85, (unsigned char *)temp_buffer, color_black); + gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 13), drawing_y_offset + 85, (unsigned char *)"Indeterminate", color_black); + } + + return; + } + + +void get_time_breakdown_string(unsigned long total_time, unsigned long state_time, char *state_string, char *buffer, int buffer_length) { + int days; + int hours; + int minutes; + int seconds; + double percent_time; + + get_time_breakdown(state_time, &days, &hours, &minutes, &seconds); + if(total_time == 0L) + percent_time = 0.0; + else + percent_time = ((double)state_time / total_time) * 100.0; + snprintf(buffer, buffer_length - 1, "%-13s: (%.3f%%) %dd %dh %dm %ds", state_string, percent_time, days, hours, minutes, seconds); + buffer[buffer_length - 1] = '\x0'; + + return; + } + + +void convert_timeperiod_to_times(int type) { + time_t current_time; + struct tm *t; + + /* get the current time */ + time(¤t_time); + + t = localtime(¤t_time); + + t->tm_sec = 0; + t->tm_min = 0; + t->tm_hour = 0; + t->tm_isdst = -1; + + switch(type) { + case TIMEPERIOD_LAST24HOURS: + t1 = current_time - (60 * 60 * 24); + t2 = current_time; + break; + case TIMEPERIOD_TODAY: + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_YESTERDAY: + t1 = (time_t)(mktime(t) - (60 * 60 * 24)); + t2 = (time_t)mktime(t); + break; + case TIMEPERIOD_THISWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + t2 = current_time; + break; + case TIMEPERIOD_LASTWEEK: + t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7)); + t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); + break; + case TIMEPERIOD_THISMONTH: + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTMONTH: + t->tm_mday = 1; + t2 = mktime(t); + if(t->tm_mon == 0) { + t->tm_mon = 11; + t->tm_year--; + } + else + t->tm_mon--; + t1 = mktime(t); + break; + case TIMEPERIOD_THISQUARTER: + break; + case TIMEPERIOD_LASTQUARTER: + break; + case TIMEPERIOD_THISYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t1 = mktime(t); + t2 = current_time; + break; + case TIMEPERIOD_LASTYEAR: + t->tm_mon = 0; + t->tm_mday = 1; + t2 = mktime(t); + t->tm_year--; + t1 = mktime(t); + break; + case TIMEPERIOD_NEXTPROBLEM: + /* Time period will be defined later */ + break; + case TIMEPERIOD_LAST7DAYS: + t2 = current_time; + t1 = current_time - (7 * 24 * 60 * 60); + break; + case TIMEPERIOD_LAST31DAYS: + t2 = current_time; + t1 = current_time - (31 * 24 * 60 * 60); + break; + default: + break; + } + + return; + } + + +void compute_report_times(void) { + time_t current_time; + struct tm *st; + struct tm *et; + + /* get the current time */ + time(¤t_time); + + st = localtime(¤t_time); + + st->tm_sec = start_second; + st->tm_min = start_minute; + st->tm_hour = start_hour; + st->tm_mday = start_day; + st->tm_mon = start_month - 1; + st->tm_year = start_year - 1900; + st->tm_isdst = -1; + + t1 = mktime(st); + + et = localtime(¤t_time); + + et->tm_sec = end_second; + et->tm_min = end_minute; + et->tm_hour = end_hour; + et->tm_mday = end_day; + et->tm_mon = end_month - 1; + et->tm_year = end_year - 1900; + et->tm_isdst = -1; + + t2 = mktime(et); + } + + + +/* draws a dashed line */ +void draw_dashed_line(int x1, int y1, int x2, int y2, int color) { + int styleDashed[12]; + + styleDashed[0] = color; + styleDashed[1] = color; + styleDashed[2] = gdTransparent; + styleDashed[3] = gdTransparent; + styleDashed[4] = color; + styleDashed[5] = color; + styleDashed[6] = gdTransparent; + styleDashed[7] = gdTransparent; + styleDashed[8] = color; + styleDashed[9] = color; + styleDashed[10] = gdTransparent; + styleDashed[11] = gdTransparent; + + /* sets current style to a dashed line */ + gdImageSetStyle(trends_image, styleDashed, 12); + + /* draws a line (dashed) */ + gdImageLine(trends_image, x1, y1, x2, y2, gdStyled); + + return; + } + + +/* draws horizontal grid lines */ +void draw_horizontal_grid_lines(void) { + + if(mode == CREATE_HTML) + return; + + if(small_image == TRUE) + return; + + draw_dashed_line(drawing_x_offset, drawing_y_offset + 10, drawing_x_offset + drawing_width, drawing_y_offset + 10, color_black); + draw_dashed_line(drawing_x_offset, drawing_y_offset + 30, drawing_x_offset + drawing_width, drawing_y_offset + 30, color_black); + draw_dashed_line(drawing_x_offset, drawing_y_offset + 50, drawing_x_offset + drawing_width, drawing_y_offset + 50, color_black); + if(display_type == DISPLAY_SERVICE_TRENDS) + draw_dashed_line(drawing_x_offset, drawing_y_offset + 70, drawing_x_offset + drawing_width, drawing_y_offset + 70, color_black); + + return; + } diff --git a/common/.gitignore b/common/.gitignore new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/common/.gitignore @@ -0,0 +1 @@ +Makefile diff --git a/common/Makefile.in b/common/Makefile.in new file mode 100644 index 0000000..b0d74f6 --- /dev/null +++ b/common/Makefile.in @@ -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: + diff --git a/common/comments.c b/common/comments.c new file mode 100644 index 0000000..72070bb --- /dev/null +++ b/common/comments.c @@ -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; + } + + + + + diff --git a/common/downtime.c b/common/downtime.c new file mode 100644 index 0000000..a749163 --- /dev/null +++ b/common/downtime.c @@ -0,0 +1,1260 @@ +/***************************************************************************** + * + * DOWNTIME.C - Scheduled downtime functions for Nagios + * + * Copyright (c) 2000-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-17-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/comments.h" +#include "../include/downtime.h" +#include "../include/objects.h" +#include "../include/statusdata.h" + +/***** IMPLEMENTATION-SPECIFIC INCLUDES *****/ + +#ifdef USE_XDDDEFAULT +#include "../xdata/xdddefault.h" +#endif + +#ifdef NSCORE +#include "../include/nagios.h" +#include "../include/broker.h" +#endif + +#ifdef NSCGI +#include "../include/cgiutils.h" +#endif + + +scheduled_downtime *scheduled_downtime_list = NULL; +int defer_downtime_sorting = 0; + +#ifdef NSCORE +extern timed_event *event_list_high; +extern timed_event *event_list_high_tail; +pthread_mutex_t nagios_downtime_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + + + +#ifdef NSCORE + +/******************************************************************/ +/**************** INITIALIZATION/CLEANUP FUNCTIONS ****************/ +/******************************************************************/ + + +/* initializes scheduled downtime data */ +int initialize_downtime_data(char *config_file) { + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "initialize_downtime_data()\n"); + + /**** IMPLEMENTATION-SPECIFIC CALLS ****/ +#ifdef USE_XDDDEFAULT + result = xdddefault_initialize_downtime_data(config_file); +#endif + + return result; + } + + +/* cleans up scheduled downtime data */ +int cleanup_downtime_data(char *config_file) { + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "cleanup_downtime_data()\n"); + + /**** IMPLEMENTATION-SPECIFIC CALLS ****/ +#ifdef USE_XDDDEFAULT + result = xdddefault_cleanup_downtime_data(config_file); +#endif + + /* free memory allocated to downtime data */ + free_downtime_data(); + + return result; + } + + +/******************************************************************/ +/********************** SCHEDULING FUNCTIONS **********************/ +/******************************************************************/ + +/* schedules a host or service downtime */ +int schedule_downtime(int type, char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *new_downtime_id) { + unsigned long downtime_id = 0L; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "schedule_downtime()\n"); + + /* don't add old or invalid downtimes */ + + if(start_time >= end_time || end_time <= time(NULL)) { + log_debug_info(DEBUGL_DOWNTIME, 1, "Invalid start (%lu) or end (%lu) times\n", + start_time, end_time); + return ERROR; + } + + + /* add a new downtime entry */ + add_new_downtime(type, host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &downtime_id, FALSE, FALSE); + + /* register the scheduled downtime */ + register_downtime(type, downtime_id); + + /* return downtime id */ + if(new_downtime_id != NULL) + *new_downtime_id = downtime_id; + + return OK; + } + + +/* unschedules a host or service downtime */ +int unschedule_downtime(int type, unsigned long downtime_id) { + scheduled_downtime *temp_downtime = NULL; + scheduled_downtime *next_downtime = NULL; + host *hst = NULL; + service *svc = NULL; + timed_event *temp_event = NULL; +#ifdef USE_EVENT_BROKER + int attr = 0; +#endif + + log_debug_info(DEBUGL_FUNCTIONS, 0, "unschedule_downtime()\n"); + + /* find the downtime entry in the list in memory */ + if((temp_downtime = find_downtime(type, downtime_id)) == NULL) + return ERROR; + + /* find the host or service associated with this downtime */ + if(temp_downtime->type == HOST_DOWNTIME) { + if((hst = find_host(temp_downtime->host_name)) == NULL) + return ERROR; + } + else { + if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) + return ERROR; + } + + /* decrement pending flex downtime if necessary ... */ + if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) { + if(temp_downtime->type == HOST_DOWNTIME) + hst->pending_flex_downtime--; + else + svc->pending_flex_downtime--; + } + + /* decrement the downtime depth variable and update status data if necessary */ + if(temp_downtime->is_in_effect == TRUE) { + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + attr = NEBATTR_DOWNTIME_STOP_CANCELLED; + broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL); +#endif + + if(temp_downtime->type == HOST_DOWNTIME) { + + hst->scheduled_downtime_depth--; + update_host_status(hst, FALSE); + + /* log a notice - this is parsed by the history CGI */ + if(hst->scheduled_downtime_depth == 0) { + + logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;CANCELLED; Scheduled downtime for host has been cancelled.\n", hst->name); + + /* send a notification */ + host_notification(hst, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE); + } + } + + else { + + svc->scheduled_downtime_depth--; + update_service_status(svc, FALSE); + + /* log a notice - this is parsed by the history CGI */ + if(svc->scheduled_downtime_depth == 0) { + + logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;CANCELLED; Scheduled downtime for service has been cancelled.\n", svc->host_name, svc->description); + + /* send a notification */ + service_notification(svc, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE); + } + } + } + + /* remove scheduled entry from event queue */ + for(temp_event = event_list_high; temp_event != NULL; temp_event = temp_event->next) { + if(temp_event->event_type != EVENT_SCHEDULED_DOWNTIME) + continue; + if(((unsigned long)temp_event->event_data) == downtime_id) + break; + } + if(temp_event != NULL) { + remove_event(temp_event, &event_list_high, &event_list_high_tail); + my_free(temp_event->event_data); + my_free(temp_event); + } + + /* delete downtime entry */ + if(temp_downtime->type == HOST_DOWNTIME) + delete_host_downtime(downtime_id); + else + delete_service_downtime(downtime_id); + + /* unschedule all downtime entries that were triggered by this one */ + while(1) { + + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { + next_downtime = temp_downtime->next; + if(temp_downtime->triggered_by == downtime_id) { + unschedule_downtime(ANY_DOWNTIME, temp_downtime->downtime_id); + break; + } + } + + if(temp_downtime == NULL) + break; + } + + return OK; + } + + + +/* registers scheduled downtime (schedules it, adds comments, etc.) */ +int register_downtime(int type, unsigned long downtime_id) { + char *temp_buffer = NULL; + char start_time_string[MAX_DATETIME_LENGTH] = ""; + char flex_start_string[MAX_DATETIME_LENGTH] = ""; + char end_time_string[MAX_DATETIME_LENGTH] = ""; + scheduled_downtime *temp_downtime = NULL; + host *hst = NULL; + service *svc = NULL; + char *type_string = NULL; + int hours = 0; + int minutes = 0; + int seconds = 0; + unsigned long *new_downtime_id = NULL; + int was_in_effect = FALSE; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "register_downtime( %d, %lu)\n", type, + downtime_id); + + /* find the downtime entry in memory */ + temp_downtime = find_downtime(type, downtime_id); + if(temp_downtime == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 0, "Cannot find downtime ID: %lu\n", downtime_id); + return ERROR; + } + + /* find the host or service associated with this downtime */ + if(temp_downtime->type == HOST_DOWNTIME) { + if((hst = find_host(temp_downtime->host_name)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Cannot find host (%s) for downtime ID: %lu\n", + temp_downtime->host_name, downtime_id); + return ERROR; + } + } + else { + if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Cannot find service (%s) for host (%s) for downtime ID: %lu\n", + temp_downtime->service_description, temp_downtime->host_name, + downtime_id); + return ERROR; + } + } + + /* create the comment */ + get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME); + get_datetime_string(&(temp_downtime->flex_downtime_start), flex_start_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME); + get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME); + hours = temp_downtime->duration / 3600; + minutes = ((temp_downtime->duration - (hours * 3600)) / 60); + seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60); + if(temp_downtime->type == HOST_DOWNTIME) + type_string = "host"; + else + type_string = "service"; + if(temp_downtime->fixed == TRUE) + asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s. Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string); + else + asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes. Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string); + + + log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n"); + if(temp_downtime->type == HOST_DOWNTIME) { + log_debug_info(DEBUGL_DOWNTIME, 0, " Type: Host Downtime\n"); + log_debug_info(DEBUGL_DOWNTIME, 0, " Host: %s\n", hst->name); + } + else { + log_debug_info(DEBUGL_DOWNTIME, 0, " Type: Service Downtime\n"); + log_debug_info(DEBUGL_DOWNTIME, 0, " Host: %s\n", svc->host_name); + log_debug_info(DEBUGL_DOWNTIME, 0, " Service: %s\n", svc->description); + } + log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex: %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible"); + log_debug_info(DEBUGL_DOWNTIME, 0, " Start: %s\n", start_time_string); + if(temp_downtime->flex_downtime_start) { + log_debug_info(DEBUGL_DOWNTIME, 0, " Flex Start: %s\n", flex_start_string); + } + log_debug_info(DEBUGL_DOWNTIME, 0, " End: %s\n", end_time_string); + log_debug_info(DEBUGL_DOWNTIME, 0, " Duration: %dh %dm %ds\n", hours, minutes, seconds); + log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id); + log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID: %lu\n", temp_downtime->triggered_by); + + + /* add a non-persistent comment to the host or service regarding the scheduled outage */ + if(temp_downtime->type == SERVICE_DOWNTIME) + add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id)); + else + add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id)); + + my_free(temp_buffer); + + /*** SCHEDULE DOWNTIME - FLEXIBLE (NON-FIXED) DOWNTIME IS HANDLED AT A LATER POINT ***/ + + /* only non-triggered downtime is scheduled... */ + if((temp_downtime->triggered_by == 0) && ((TRUE == temp_downtime->fixed) || + ((FALSE == temp_downtime->fixed) && + (TRUE == temp_downtime->is_in_effect)))) { + /* If this is a fixed downtime, schedule the event to start it. If this + is a flexible downtime, normally we wait for one of the + check_pending_flex_*_downtime() functions to start it, but if the + downtime is already in effect, this means that we are restarting + Nagios and the downtime was in effect when we last shutdown + Nagios, so we should restart the flexible downtime now. This + should work even if the downtime has ended because the + handle_scheduled_dowtime() function will immediately schedule + another downtime event which will end the downtime. */ + if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { + *new_downtime_id = downtime_id; + /*temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); */ + schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); + /* Turn off is_in_effect flag so handle_scheduled_downtime() will + handle it correctly */ + was_in_effect = temp_downtime->is_in_effect; + temp_downtime->is_in_effect = FALSE; + } + } + + /* If the downtime is triggered and was in effect, mark it as not in + effect so it gets scheduled correctly */ + if((temp_downtime->triggered_by != 0) && + (TRUE == temp_downtime->is_in_effect)) { + was_in_effect = temp_downtime->is_in_effect; + temp_downtime->is_in_effect = FALSE; + } + + if((FALSE == temp_downtime->fixed) && (FALSE == was_in_effect)) { + /* increment pending flex downtime counter */ + if(temp_downtime->type == HOST_DOWNTIME) + hst->pending_flex_downtime++; + else + svc->pending_flex_downtime++; + temp_downtime->incremented_pending_downtime = TRUE; + + /* Since a flex downtime may never start, schedule an expiring event in + case the event is never triggered. The expire event will NOT cancel + a downtime event that is in effect */ + log_debug_info(DEBUGL_DOWNTIME, 1, "Scheduling downtime expire event in case flexible downtime is never triggered\n"); + /*temp_downtime->stop_event = schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);*/ + schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0); + } + + +#ifdef PROBABLY_NOT_NEEDED + /*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/ + + /* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */ + /* this is new logic added in 3.0rc3 */ + if(temp_downtime->fixed == FALSE) { + if(temp_downtime->type == HOST_DOWNTIME) + check_pending_flex_host_downtime(hst); + else + check_pending_flex_service_downtime(svc); + } +#endif + + return OK; + } + + + +/* handles scheduled downtime (id passed from timed event queue) */ +int handle_scheduled_downtime_by_id(unsigned long downtime_id) { + scheduled_downtime *temp_downtime = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime_by_id()\n"); + + /* find the downtime entry */ + if((temp_downtime = find_downtime(ANY_DOWNTIME, downtime_id)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find downtime id: %lu\n", + downtime_id); + return ERROR; + } + + /* handle the downtime */ + return handle_scheduled_downtime(temp_downtime); + } + + + +/* handles scheduled host or service downtime */ +int handle_scheduled_downtime(scheduled_downtime *temp_downtime) { + scheduled_downtime *this_downtime = NULL; + host *hst = NULL; + service *svc = NULL; + time_t event_time = 0L; + //time_t current_time = 0L; + unsigned long *new_downtime_id = NULL; +#ifdef USE_EVENT_BROKER + int attr = 0; +#endif + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime()\n"); + + if(temp_downtime == NULL) + return ERROR; + + /* find the host or service associated with this downtime */ + if(temp_downtime->type == HOST_DOWNTIME) { + if((hst = find_host(temp_downtime->host_name)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find host (%s) for downtime\n", temp_downtime->host_name); + return ERROR; + } + } + else { + if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find service (%s) host (%s) for downtime\n", temp_downtime->service_description, temp_downtime->host_name); + return ERROR; + + } + } + + + /* have we come to the end of the scheduled downtime? */ + if(temp_downtime->is_in_effect == TRUE) { + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + attr = NEBATTR_DOWNTIME_STOP_NORMAL; + broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL); +#endif + + /* decrement the downtime depth variable */ + if(temp_downtime->type == HOST_DOWNTIME) + hst->scheduled_downtime_depth--; + else + svc->scheduled_downtime_depth--; + + if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id); + + /* log a notice - this one is parsed by the history CGI */ + logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name); + + /* send a notification */ + host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); + } + + else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id); + + /* log a notice - this one is parsed by the history CGI */ + logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description); + + /* send a notification */ + service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); + } + + + /* update the status data */ + if(temp_downtime->type == HOST_DOWNTIME) + update_host_status(hst, FALSE); + else + update_service_status(svc, FALSE); + + /* decrement pending flex downtime if necessary */ + if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) { + if(temp_downtime->type == HOST_DOWNTIME) { + if(hst->pending_flex_downtime > 0) + hst->pending_flex_downtime--; + } + else { + if(svc->pending_flex_downtime > 0) + svc->pending_flex_downtime--; + } + } + + /* handle (stop) downtime that is triggered by this one */ + while(1) { + + /* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */ + for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) { + if(this_downtime->triggered_by == temp_downtime->downtime_id) { + handle_scheduled_downtime(this_downtime); + break; + } + } + + if(this_downtime == NULL) + break; + } + + /* delete downtime entry */ + if(temp_downtime->type == HOST_DOWNTIME) + delete_host_downtime(temp_downtime->downtime_id); + else + delete_service_downtime(temp_downtime->downtime_id); + } + + /* else we are just starting the scheduled downtime */ + else { + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL); +#endif + + if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id); + + /* log a notice - this one is parsed by the history CGI */ + logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name); + + /* send a notification */ + if(FALSE == temp_downtime->start_notification_sent) { + host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); + temp_downtime->start_notification_sent = TRUE; + } + } + + else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id); + + /* log a notice - this one is parsed by the history CGI */ + logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description); + + /* send a notification */ + if(FALSE == temp_downtime->start_notification_sent) { + service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); + temp_downtime->start_notification_sent = TRUE; + } + } + + /* increment the downtime depth variable */ + if(temp_downtime->type == HOST_DOWNTIME) + hst->scheduled_downtime_depth++; + else + svc->scheduled_downtime_depth++; + + /* set the in effect flag */ + temp_downtime->is_in_effect = TRUE; + + /* update the status data */ + if(temp_downtime->type == HOST_DOWNTIME) + update_host_status(hst, FALSE); + else + update_service_status(svc, FALSE); + + /* schedule an event to end the downtime */ + if(temp_downtime->fixed == FALSE) { + event_time = (time_t)((unsigned long)temp_downtime->flex_downtime_start + + temp_downtime->duration); + } + else { + event_time = temp_downtime->end_time; + } + if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { + *new_downtime_id = temp_downtime->downtime_id; + schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); + } + + /* handle (start) downtime that is triggered by this one */ + for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) { + if(this_downtime->triggered_by == temp_downtime->downtime_id) + handle_scheduled_downtime(this_downtime); + } + } + + return OK; + } + + + +/* checks for flexible (non-fixed) host downtime that should start now */ +int check_pending_flex_host_downtime(host *hst) { + scheduled_downtime *temp_downtime = NULL; + time_t current_time = 0L; + unsigned long * new_downtime_id = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_pending_flex_host_downtime()\n"); + + if(hst == NULL) + return ERROR; + + time(¤t_time); + + /* if host is currently up, nothing to do */ + if(hst->current_state == HOST_UP) + return OK; + + /* check all downtime entries */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + + if(temp_downtime->type != HOST_DOWNTIME) + continue; + + if(temp_downtime->fixed == TRUE) + continue; + + if(temp_downtime->is_in_effect == TRUE) + continue; + + /* triggered downtime entries should be ignored here */ + if(temp_downtime->triggered_by != 0) + continue; + + /* this entry matches our host! */ + if(find_host(temp_downtime->host_name) == hst) { + + /* if the time boundaries are okay, start this scheduled downtime */ + if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Flexible downtime (id=%lu) for host '%s' starting now...\n", temp_downtime->downtime_id, hst->name); + + temp_downtime->flex_downtime_start = current_time; + if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { + *new_downtime_id = temp_downtime->downtime_id; + /*temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);*/ + schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); + } + } + } + } + + return OK; + } + + +/* checks for flexible (non-fixed) service downtime that should start now */ +int check_pending_flex_service_downtime(service *svc) { + scheduled_downtime *temp_downtime = NULL; + time_t current_time = 0L; + unsigned long * new_downtime_id = NULL; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_pending_flex_service_downtime()\n"); + + if(svc == NULL) + return ERROR; + + time(¤t_time); + + /* if service is currently ok, nothing to do */ + if(svc->current_state == STATE_OK) + return OK; + + /* check all downtime entries */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + + if(temp_downtime->type != SERVICE_DOWNTIME) + continue; + + if(temp_downtime->fixed == TRUE) + continue; + + if(temp_downtime->is_in_effect == TRUE) + continue; + + /* triggered downtime entries should be ignored here */ + if(temp_downtime->triggered_by != 0) + continue; + + /* this entry matches our service! */ + if(find_service(temp_downtime->host_name, temp_downtime->service_description) == svc) { + + /* if the time boundaries are okay, start this scheduled downtime */ + if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Flexible downtime (id=%lu) for service '%s' on host '%s' starting now...\n", temp_downtime->downtime_id, svc->description, svc->host_name); + + temp_downtime->flex_downtime_start = current_time; + if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { + *new_downtime_id = temp_downtime->downtime_id; + schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); + } + } + } + } + + return OK; + } + + +/* checks for (and removes) expired downtime entries */ +int check_for_expired_downtime(void) { + scheduled_downtime *temp_downtime = NULL; + scheduled_downtime *next_downtime = NULL; + time_t current_time = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_expired_downtime()\n"); + + time(¤t_time); + + /* check all downtime entries... */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { + + next_downtime = temp_downtime->next; + + /* this entry should be removed */ + if(temp_downtime->is_in_effect == FALSE && temp_downtime->end_time < current_time) { + + log_debug_info(DEBUGL_DOWNTIME, 0, "Expiring %s downtime (id=%lu)...\n", (temp_downtime->type == HOST_DOWNTIME) ? "host" : "service", temp_downtime->downtime_id); + + /* delete the downtime entry */ + if(temp_downtime->type == HOST_DOWNTIME) + delete_host_downtime(temp_downtime->downtime_id); + else + delete_service_downtime(temp_downtime->downtime_id); + } + } + + return OK; + } + + + +/******************************************************************/ +/************************* SAVE FUNCTIONS *************************/ +/******************************************************************/ + + +/* save a host or service downtime */ +int add_new_downtime(int type, char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent) { + int result = OK; + + if(type == HOST_DOWNTIME) + result = add_new_host_downtime(host_name, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + else + result = add_new_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + + return result; + } + + +/* saves a host downtime entry */ +int add_new_host_downtime(char *host_name, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent) { + int result = OK; + unsigned long new_downtime_id = 0L; + + if(host_name == NULL) + return ERROR; + + /**** IMPLEMENTATION-SPECIFIC CALLS ****/ +#ifdef USE_XDDDEFAULT + result = xdddefault_add_new_host_downtime(host_name, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &new_downtime_id, is_in_effect, start_notification_sent); +#endif + + /* save downtime id */ + if(downtime_id != NULL) + *downtime_id = new_downtime_id; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_downtime_data(NEBTYPE_DOWNTIME_ADD, NEBFLAG_NONE, NEBATTR_NONE, HOST_DOWNTIME, host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, new_downtime_id, NULL); +#endif + + return result; + } + + +/* saves a service downtime entry */ +int add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent) { + int result = OK; + unsigned long new_downtime_id = 0L; + + if(host_name == NULL || service_description == NULL) + return ERROR; + + /**** IMPLEMENTATION-SPECIFIC CALLS ****/ +#ifdef USE_XDDDEFAULT + result = xdddefault_add_new_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &new_downtime_id, is_in_effect, start_notification_sent); +#endif + + /* save downtime id */ + if(downtime_id != NULL) + *downtime_id = new_downtime_id; + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_downtime_data(NEBTYPE_DOWNTIME_ADD, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_DOWNTIME, host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, new_downtime_id, NULL); +#endif + + return result; + } + + + +/******************************************************************/ +/*********************** DELETION FUNCTIONS ***********************/ +/******************************************************************/ + + +/* deletes a scheduled host or service downtime entry from the list in memory */ +int delete_downtime(int type, unsigned long downtime_id) { + int result = OK; + scheduled_downtime *this_downtime = NULL; + scheduled_downtime *last_downtime = NULL; + scheduled_downtime *next_downtime = NULL; + +#ifdef NSCORE + pthread_mutex_lock(&nagios_downtime_lock); +#endif + /* find the downtime we should remove */ + for(this_downtime = scheduled_downtime_list, last_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = next_downtime) { + next_downtime = this_downtime->next; + + /* we found the downtime we should delete */ + if(this_downtime->downtime_id == downtime_id && this_downtime->type == type) + break; + + last_downtime = this_downtime; + } + + /* remove the downtime from the list in memory */ + if(this_downtime != NULL) { + + /* first remove the comment associated with this downtime */ + if(this_downtime->type == HOST_DOWNTIME) + delete_host_comment(this_downtime->comment_id); + else + delete_service_comment(this_downtime->comment_id); + +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_downtime_data(NEBTYPE_DOWNTIME_DELETE, NEBFLAG_NONE, NEBATTR_NONE, type, this_downtime->host_name, this_downtime->service_description, this_downtime->entry_time, this_downtime->author, this_downtime->comment, this_downtime->start_time, this_downtime->end_time, this_downtime->fixed, this_downtime->triggered_by, this_downtime->duration, downtime_id, NULL); +#endif + + if(scheduled_downtime_list == this_downtime) + scheduled_downtime_list = this_downtime->next; + else + last_downtime->next = next_downtime; + + /* free memory */ + my_free(this_downtime->host_name); + my_free(this_downtime->service_description); + my_free(this_downtime->author); + my_free(this_downtime->comment); + my_free(this_downtime); + + result = OK; + } + else + result = ERROR; + +#ifdef NSCORE + pthread_mutex_unlock(&nagios_downtime_lock); +#endif + + return result; + } + + +/* deletes a scheduled host downtime entry */ +int delete_host_downtime(unsigned long downtime_id) { + int result = OK; + + /* delete the downtime from memory */ + delete_downtime(HOST_DOWNTIME, downtime_id); + + /**** IMPLEMENTATION-SPECIFIC CALLS ****/ +#ifdef USE_XDDDEFAULT + result = xdddefault_delete_host_downtime(downtime_id); +#endif + + return result; + } + + +/* deletes a scheduled service downtime entry */ +int delete_service_downtime(unsigned long downtime_id) { + int result = OK; + + /* delete the downtime from memory */ + delete_downtime(SERVICE_DOWNTIME, downtime_id); + + /**** IMPLEMENTATION-SPECIFIC CALLS ****/ +#ifdef USE_XDDDEFAULT + result = xdddefault_delete_service_downtime(downtime_id); +#endif + + return result; + } + +/* +Deletes all host and service downtimes on a host by hostname, optionally filtered by service description, start time and comment. +All char* must be set or NULL - "" will silently fail to match +Returns number deleted +*/ +int delete_downtime_by_hostname_service_description_start_time_comment(char *hostname, char *service_description, time_t start_time, char *comment) { + scheduled_downtime *temp_downtime; + scheduled_downtime *next_downtime; + int deleted = 0; + + /* Do not allow deletion of everything - must have at least 1 filter on */ + if(hostname == NULL && service_description == NULL && start_time == 0 && comment == NULL) + return deleted; + + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { + next_downtime = temp_downtime->next; + if(start_time != 0 && temp_downtime->start_time != start_time) { + continue; + } + if(comment != NULL && strcmp(temp_downtime->comment, comment) != 0) + continue; + if(temp_downtime->type == HOST_DOWNTIME) { + /* If service is specified, then do not delete the host downtime */ + if(service_description != NULL) + continue; + if(hostname != NULL && strcmp(temp_downtime->host_name, hostname) != 0) + continue; + } + else if(temp_downtime->type == SERVICE_DOWNTIME) { + if(hostname != NULL && strcmp(temp_downtime->host_name, hostname) != 0) + continue; + if(service_description != NULL && strcmp(temp_downtime->service_description, service_description) != 0) + continue; + } + + unschedule_downtime(temp_downtime->type, temp_downtime->downtime_id); + deleted++; + } + return deleted; + } + +#endif + + + + + +/******************************************************************/ +/******************** ADDITION FUNCTIONS **************************/ +/******************************************************************/ + +/* adds a host downtime entry to the list in memory */ +int add_host_downtime(char *host_name, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t flex_downtime_start, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, int is_in_effect, int start_notification_sent) { + int result = OK; + + result = add_downtime(HOST_DOWNTIME, host_name, NULL, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + + return result; + } + + +/* adds a service downtime entry to the list in memory */ +int add_service_downtime(char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t flex_downtime_start, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, int is_in_effect, int start_notification_sent) { + int result = OK; + + result = add_downtime(SERVICE_DOWNTIME, host_name, svc_description, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + + return result; + } + + +/* adds a host or service downtime entry to the list in memory */ +int add_downtime(int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t flex_downtime_start, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, int is_in_effect, int start_notification_sent) { + scheduled_downtime *new_downtime = NULL; + scheduled_downtime *last_downtime = NULL; + scheduled_downtime *temp_downtime = NULL; + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "add_downtime()\n"); + + /* don't add triggered downtimes that don't have a valid parent */ + if(triggered_by > 0 && find_downtime(ANY_DOWNTIME, triggered_by) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Downtime is triggered, but has no valid parent\n"); + return ERROR; + } + + /* we don't have enough info */ + if(host_name == NULL || (downtime_type == SERVICE_DOWNTIME && svc_description == NULL)) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Host name (%s) or service description (%s) is null\n", + ((NULL == host_name) ? "null" : host_name), + ((NULL == svc_description) ? "null" : svc_description)); + return ERROR; + } + + /* allocate memory for the downtime */ + if((new_downtime = (scheduled_downtime *)calloc(1, sizeof(scheduled_downtime))) == NULL) + return ERROR; + + /* duplicate vars */ + if((new_downtime->host_name = (char *)strdup(host_name)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Unable to allocate memory for new downtime's host name\n"); + result = ERROR; + } + if(downtime_type == SERVICE_DOWNTIME) { + if((new_downtime->service_description = (char *)strdup(svc_description)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Unable to allocate memory for new downtime's service description\n"); + result = ERROR; + } + } + if(author) { + if((new_downtime->author = (char *)strdup(author)) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Unable to allocate memory for new downtime's author\n"); + result = ERROR; + } + } + if(comment_data) { + if((new_downtime->comment = (char *)strdup(comment_data)) == NULL) + result = ERROR; + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_downtime->comment); + my_free(new_downtime->author); + my_free(new_downtime->service_description); + my_free(new_downtime->host_name); + my_free(new_downtime); + return ERROR; + } + + new_downtime->type = downtime_type; + new_downtime->entry_time = entry_time; + new_downtime->start_time = start_time; + new_downtime->flex_downtime_start = flex_downtime_start; + new_downtime->end_time = end_time; + new_downtime->fixed = (fixed > 0) ? TRUE : FALSE; + new_downtime->triggered_by = triggered_by; + new_downtime->duration = duration; + new_downtime->downtime_id = downtime_id; + new_downtime->is_in_effect = is_in_effect; + new_downtime->start_notification_sent = start_notification_sent; + + if(defer_downtime_sorting) { + new_downtime->next = scheduled_downtime_list; + scheduled_downtime_list = new_downtime; + } + else { + /* + * add new downtime to downtime list, sorted by start time, + * but lock the lists first so broker modules fiddling + * with them at the same time doesn't crash out. + */ +#ifdef NSCORE + pthread_mutex_lock(&nagios_downtime_lock); +#endif + last_downtime = scheduled_downtime_list; + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + if(new_downtime->start_time < temp_downtime->start_time) { + new_downtime->next = temp_downtime; + if(temp_downtime == scheduled_downtime_list) + scheduled_downtime_list = new_downtime; + else + last_downtime->next = new_downtime; + break; + } + else + last_downtime = temp_downtime; + } + if(scheduled_downtime_list == NULL) { + new_downtime->next = NULL; + scheduled_downtime_list = new_downtime; + } + else if(temp_downtime == NULL) { + new_downtime->next = NULL; + last_downtime->next = new_downtime; + } +#ifdef NSCORE + pthread_mutex_unlock(&nagios_downtime_lock); +#endif + } +#ifdef NSCORE +#ifdef USE_EVENT_BROKER + /* send data to event broker */ + broker_downtime_data(NEBTYPE_DOWNTIME_LOAD, NEBFLAG_NONE, NEBATTR_NONE, downtime_type, host_name, svc_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, NULL); +#endif +#endif + + return OK; + } + +static int downtime_compar(const void *p1, const void *p2) { + scheduled_downtime *d1 = *(scheduled_downtime **)p1; + scheduled_downtime *d2 = *(scheduled_downtime **)p2; + + /* + If the start times of two downtimes are equal and one is triggered but + but the other is not, the triggered downtime should be later in the + list than the untriggered one. This is so they are written to the + retention.dat and status.dat in the correct order. + + Previously the triggered downtime always appeared before its + triggering downtime in those files. When the downtimes were read + from those files, either on a core restart or by the CGIs, the + triggered downtime would be discarded because the triggering + downtime did not yet exist. + + The most common case for this is when a downtime is created and + the option is selected to create triggered downtimes on all child + objects. This change in the sort order does NOT resolve the + case where a manually created, triggered downtime is created with + a start time earlier than the triggering downtime. + + This would need to be resolved by comparing the triggered_by value + with the downtime ID regardless of the start time. However, this + should be a relatively rare case and only caused by intentional + scheduling by a human. This change was not implemented because it + would cause the downtime list to be out of time order and the + implications of this were not well understood. + */ + + if(d1->start_time == d2->start_time) { + if(( d1->triggered_by == 0 && d2->triggered_by != 0) || + ( d1->triggered_by != 0 && d2->triggered_by == 0)) { + return d1->triggered_by == 0 ? -1 : 1; + } + } + return (d1->start_time < d2->start_time) ? -1 : (d1->start_time - d2->start_time); + } + +int sort_downtime(void) { + scheduled_downtime **array, *temp_downtime; + unsigned long i = 0, unsorted_downtimes = 0; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "sort_downtime()\n"); + + if(!defer_downtime_sorting) + return OK; + defer_downtime_sorting = 0; + + temp_downtime = scheduled_downtime_list; + while(temp_downtime != NULL) { + temp_downtime = temp_downtime->next; + unsorted_downtimes++; + } + + if(!unsorted_downtimes) + return OK; + + if(!(array = malloc(sizeof(*array) * unsorted_downtimes))) + return ERROR; + while(scheduled_downtime_list) { + array[i++] = scheduled_downtime_list; + scheduled_downtime_list = scheduled_downtime_list->next; + } + + qsort((void *)array, i, sizeof(*array), downtime_compar); + scheduled_downtime_list = temp_downtime = array[0]; + for(i = 1; i < unsorted_downtimes; i++) { + temp_downtime->next = array[i]; + temp_downtime = temp_downtime->next; + } + temp_downtime->next = NULL; + my_free(array); + return OK; + } + + + +/******************************************************************/ +/************************ SEARCH FUNCTIONS ************************/ +/******************************************************************/ + +/* finds a specific downtime entry */ +scheduled_downtime *find_downtime(int type, unsigned long downtime_id) { + scheduled_downtime *temp_downtime = NULL; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "find_downtime()\n"); + + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + log_debug_info(DEBUGL_DOWNTIME, 2, "find_downtime() looking at type %d, id: %lu\n", type, downtime_id); + + if(type != ANY_DOWNTIME && temp_downtime->type != type) + continue; + if(temp_downtime->downtime_id == downtime_id) + return temp_downtime; + } + + return NULL; + } + + +/* finds a specific host downtime entry */ +scheduled_downtime *find_host_downtime(unsigned long downtime_id) { + + return find_downtime(HOST_DOWNTIME, downtime_id); + } + + +/* finds a specific service downtime entry */ +scheduled_downtime *find_service_downtime(unsigned long downtime_id) { + + return find_downtime(SERVICE_DOWNTIME, downtime_id); + } + + + +/******************************************************************/ +/********************* CLEANUP FUNCTIONS **************************/ +/******************************************************************/ + +/* frees memory allocated for the scheduled downtime data */ +void free_downtime_data(void) { + scheduled_downtime *this_downtime = NULL; + scheduled_downtime *next_downtime = NULL; + + /* free memory for the scheduled_downtime list */ + for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = next_downtime) { + next_downtime = this_downtime->next; + my_free(this_downtime->host_name); + my_free(this_downtime->service_description); + my_free(this_downtime->author); + my_free(this_downtime->comment); + my_free(this_downtime); + } + + /* reset list pointer */ + scheduled_downtime_list = NULL; + + return; + } + + diff --git a/common/macros.c b/common/macros.c new file mode 100644 index 0000000..815b2b3 --- /dev/null +++ b/common/macros.c @@ -0,0 +1,3356 @@ +/***************************************************************************** + * + * MACROS.C - Common macro functions for Nagios + * + * Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 08-06-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/macros.h" +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/statusdata.h" +#include "../include/comments.h" +#ifdef NSCORE +#include "../include/nagios.h" +#else +#include "../include/cgiutils.h" +#endif + +#ifdef NSCORE +extern int use_large_installation_tweaks; +extern int enable_environment_macros; +#endif + +extern char *illegal_output_chars; + +extern contact *contact_list; +extern contactgroup *contactgroup_list; +extern host *host_list; +extern hostgroup *hostgroup_list; +extern service *service_list; +extern servicegroup *servicegroup_list; +extern command *command_list; +extern timeperiod *timeperiod_list; + +char *macro_x_names[MACRO_X_COUNT]; /* the macro names */ +char *macro_user[MAX_USER_MACROS]; /* $USERx$ macros */ + +struct macro_key_code { + char *name; /* macro key name */ + int code; /* numeric macro code, usable in case statements */ + int clean_options; + char *value; + }; + +struct macro_key_code macro_keys[MACRO_X_COUNT]; + +/* + * These point to their corresponding pointer arrays in global_macros + * AFTER macros have been initialized. + * + * They really only exist so that eventbroker modules that reference + * them won't need to be re-compiled, although modules that rely + * on their values after having run a certain command will require an + * update + */ +char **macro_x = NULL; + +/* + * scoped to this file to prevent (unintentional) mischief, + * but see base/notifications.c for how to use it + */ +static nagios_macros global_macros; + + +nagios_macros *get_global_macros(void) { + return &global_macros; + } + +/******************************************************************/ +/************************ MACRO FUNCTIONS *************************/ +/******************************************************************/ + +/* + * locate a macro key based on its name by using a binary search + * over all keys. O(log(n)) complexity and a vast improvement over + * the previous linear scan + */ +const struct macro_key_code *find_macro_key(const char *name) { + unsigned int high, low = 0; + int value; + struct macro_key_code *key; + + high = MACRO_X_COUNT; + while(high - low > 0) { + unsigned int mid = low + ((high - low) / 2); + key = ¯o_keys[mid]; + value = strcmp(name, key->name); + if(value == 0) { + return key; + } + if(value > 0) + low = mid + 1; + else + high = mid; + } + return NULL; + } + + +/* + * replace macros in notification commands with their values, + * the thread-safe version + */ +int process_macros_r(nagios_macros *mac, char *input_buffer, char **output_buffer, int options) { + char *temp_buffer = NULL; + char *save_buffer = NULL; + char *buf_ptr = NULL; + char *delim_ptr = NULL; + int in_macro = FALSE; + int x = 0; + char *selected_macro = NULL; + char *original_macro = NULL; + char *cleaned_macro = NULL; + int clean_macro = FALSE; + int found_macro_x = FALSE; + int result = OK; + int clean_options = 0; + int free_macro = FALSE; + int macro_options = 0; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_macros_r()\n"); + + if(output_buffer == NULL) + return ERROR; + + *output_buffer = (char *)strdup(""); + + if(input_buffer == NULL) + return ERROR; + + in_macro = FALSE; + + log_debug_info(DEBUGL_MACROS, 1, "**** BEGIN MACRO PROCESSING ***********\n"); + log_debug_info(DEBUGL_MACROS, 1, "Processing: '%s'\n", input_buffer); + + /* use a duplicate of original buffer, so we don't modify the original */ + save_buffer = buf_ptr = (input_buffer ? strdup(input_buffer) : NULL); + + while(buf_ptr) { + + /* save pointer to this working part of buffer */ + temp_buffer = buf_ptr; + + /* find the next delimiter - terminate preceding string and advance buffer pointer for next run */ + if((delim_ptr = strchr(buf_ptr, '$'))) { + delim_ptr[0] = '\x0'; + buf_ptr = (char *)delim_ptr + 1; + } + /* no delimiter found - we already have the last of the buffer */ + else + buf_ptr = NULL; + + log_debug_info(DEBUGL_MACROS, 2, " Processing part: '%s'\n", temp_buffer); + + selected_macro = NULL; + found_macro_x = FALSE; + clean_macro = FALSE; + + /* we're in plain text... */ + if(in_macro == FALSE) { + + /* add the plain text to the end of the already processed buffer */ + *output_buffer = (char *)realloc(*output_buffer, strlen(*output_buffer) + strlen(temp_buffer) + 1); + strcat(*output_buffer, temp_buffer); + + log_debug_info(DEBUGL_MACROS, 2, " Not currently in macro. Running output (%lu): '%s'\n", (unsigned long)strlen(*output_buffer), *output_buffer); + in_macro = TRUE; + } + + /* looks like we're in a macro, so process it... */ + else { + + /* reset clean options */ + clean_options = 0; + + /* grab the macro value */ + result = grab_macro_value_r(mac, temp_buffer, &selected_macro, &clean_options, &free_macro); + log_debug_info(DEBUGL_MACROS, 2, " Processed '%s', Clean Options: %d, Free: %d\n", temp_buffer, clean_options, free_macro); + + /* an error occurred - we couldn't parse the macro, so continue on */ + if(result == ERROR) { + log_debug_info(DEBUGL_MACROS, 0, " WARNING: An error occurred processing macro '%s'!\n", temp_buffer); + if(free_macro == TRUE) + my_free(selected_macro); + } + + /* we already have a macro... */ + if(result == OK) + x = 0; + + /* an escaped $ is done by specifying two $$ next to each other */ + else if(!strcmp(temp_buffer, "")) { + log_debug_info(DEBUGL_MACROS, 2, " Escaped $. Running output (%lu): '%s'\n", (unsigned long)strlen(*output_buffer), *output_buffer); + *output_buffer = (char *)realloc(*output_buffer, strlen(*output_buffer) + 2); + strcat(*output_buffer, "$"); + } + + /* a non-macro, just some user-defined string between two $s */ + else { + log_debug_info(DEBUGL_MACROS, 2, " Non-macro. Running output (%lu): '%s'\n", (unsigned long)strlen(*output_buffer), *output_buffer); + + /* add the plain text to the end of the already processed buffer */ + *output_buffer = (char *)realloc(*output_buffer, strlen(*output_buffer) + strlen(temp_buffer) + 3); + strcat(*output_buffer, "$"); + strcat(*output_buffer, temp_buffer); + strcat(*output_buffer, "$"); + } + + /* insert macro */ + if(selected_macro != NULL) { + log_debug_info(DEBUGL_MACROS, 2, " Processed '%s', Clean Options: %d, Free: %d\n", temp_buffer, clean_options, free_macro); + + /* include any cleaning options passed back to us */ + macro_options = (options | clean_options); + + log_debug_info(DEBUGL_MACROS, 2, " Cleaning options: global=%d, local=%d, effective=%d\n", options, clean_options, macro_options); + + /* URL encode the macro if requested - this allocates new memory */ + if(macro_options & URL_ENCODE_MACRO_CHARS) { + original_macro = selected_macro; + selected_macro = get_url_encoded_string(selected_macro); + if(free_macro == TRUE) { + my_free(original_macro); + } + free_macro = TRUE; + } + + /* some macros are cleaned... */ + if(clean_macro == TRUE || ((macro_options & STRIP_ILLEGAL_MACRO_CHARS) || (macro_options & ESCAPE_MACRO_CHARS))) { + + /* add the (cleaned) processed macro to the end of the already processed buffer */ + if(selected_macro != NULL && (cleaned_macro = clean_macro_chars(selected_macro, macro_options)) != NULL) { + *output_buffer = (char *)realloc(*output_buffer, strlen(*output_buffer) + strlen(cleaned_macro) + 1); + strcat(*output_buffer, cleaned_macro); + + log_debug_info(DEBUGL_MACROS, 2, " Cleaned macro. Running output (%lu): '%s'\n", (unsigned long)strlen(*output_buffer), *output_buffer); + } + } + + /* others are not cleaned */ + else { + /* add the processed macro to the end of the already processed buffer */ + if(selected_macro != NULL) { + *output_buffer = (char *)realloc(*output_buffer, strlen(*output_buffer) + strlen(selected_macro) + 1); + strcat(*output_buffer, selected_macro); + + log_debug_info(DEBUGL_MACROS, 2, " Uncleaned macro. Running output (%lu): '%s'\n", (unsigned long)strlen(*output_buffer), *output_buffer); + } + } + + /* free memory if necessary (if we URL encoded the macro or we were told to do so by grab_macro_value()) */ + if(free_macro == TRUE) + my_free(selected_macro); + + log_debug_info(DEBUGL_MACROS, 2, " Just finished macro. Running output (%lu): '%s'\n", (unsigned long)strlen(*output_buffer), *output_buffer); + } + + in_macro = FALSE; + } + } + + /* free copy of input buffer */ + my_free(save_buffer); + + log_debug_info(DEBUGL_MACROS, 1, " Done. Final output: '%s'\n", *output_buffer); + log_debug_info(DEBUGL_MACROS, 1, "**** END MACRO PROCESSING *************\n"); + + return OK; + } + +int process_macros(char *input_buffer, char **output_buffer, int options) { + return process_macros_r(&global_macros, input_buffer, output_buffer, options); + } + +/******************************************************************/ +/********************** MACRO GRAB FUNCTIONS **********************/ +/******************************************************************/ + +/* grab macros that are specific to a particular host */ +int grab_host_macros_r(nagios_macros *mac, host *hst) { + /* clear host-related macros */ + clear_host_macros_r(mac); + clear_hostgroup_macros_r(mac); + + /* save pointer to host */ + mac->host_ptr = hst; + mac->hostgroup_ptr = NULL; + + if(hst == NULL) + return ERROR; + +#ifdef NSCORE + /* save pointer to host's first/primary hostgroup */ + if(hst->hostgroups_ptr) + mac->hostgroup_ptr = (hostgroup *)hst->hostgroups_ptr->object_ptr; +#endif + + return OK; + } + +int grab_host_macros(host *hst) { + return grab_host_macros_r(&global_macros, hst); + } + + +/* grab hostgroup macros */ +int grab_hostgroup_macros_r(nagios_macros *mac, hostgroup *hg) { + /* clear hostgroup macros */ + clear_hostgroup_macros_r(mac); + + /* save the hostgroup pointer for later */ + mac->hostgroup_ptr = hg; + + if(hg == NULL) + return ERROR; + + return OK; + } + +int grab_hostgroup_macros(hostgroup *hg) { + return grab_hostgroup_macros_r(&global_macros, hg); + } + + +/* grab macros that are specific to a particular service */ +int grab_service_macros_r(nagios_macros *mac, service *svc) { + + /* clear service-related macros */ + clear_service_macros_r(mac); + clear_servicegroup_macros_r(mac); + + /* save pointer for later */ + mac->service_ptr = svc; + mac->servicegroup_ptr = NULL; + + if(svc == NULL) + return ERROR; + +#ifdef NSCORE + /* save first/primary servicegroup pointer for later */ + if(svc->servicegroups_ptr) + mac->servicegroup_ptr = (servicegroup *)svc->servicegroups_ptr->object_ptr; +#endif + + return OK; + } + +int grab_service_macros(service *svc) { + return grab_service_macros_r(&global_macros, svc); + } + + +/* grab macros that are specific to a particular servicegroup */ +int grab_servicegroup_macros_r(nagios_macros *mac, servicegroup *sg) { + /* clear servicegroup macros */ + clear_servicegroup_macros_r(mac); + + /* save the pointer for later */ + mac->servicegroup_ptr = sg; + + if(sg == NULL) + return ERROR; + + return OK; + } + +int grab_servicegroup_macros(servicegroup *sg) { + return grab_servicegroup_macros_r(&global_macros, sg); + } + + +/* grab macros that are specific to a particular contact */ +int grab_contact_macros_r(nagios_macros *mac, contact *cntct) { + /* clear contact-related macros */ + clear_contact_macros_r(mac); + clear_contactgroup_macros_r(mac); + + /* save pointer to contact for later */ + mac->contact_ptr = cntct; + mac->contactgroup_ptr = NULL; + + if(cntct == NULL) + return ERROR; + +#ifdef NSCORE + /* save pointer to first/primary contactgroup for later */ + if(cntct->contactgroups_ptr) + mac->contactgroup_ptr = (contactgroup *)cntct->contactgroups_ptr->object_ptr; +#endif + + return OK; + } + +int grab_contact_macros(contact *cntct) { + return grab_contact_macros_r(&global_macros, cntct); + } + + +/******************************************************************/ +/******************* MACRO GENERATION FUNCTIONS *******************/ +/******************************************************************/ + +/* this is the big one */ +int grab_macro_value_r(nagios_macros *mac, char *macro_buffer, char **output, int *clean_options, int *free_macro) { + char *buf = NULL; + char *ptr = NULL; + char *macro_name = NULL; + char *arg[2] = {NULL, NULL}; + contact *temp_contact = NULL; + contactgroup *temp_contactgroup = NULL; + contactsmember *temp_contactsmember = NULL; + char *temp_buffer = NULL; + int delimiter_len = 0; + int x, result = OK; + const struct macro_key_code *mkey; + + /* for the early cases, this is the default */ + *free_macro = FALSE; + + if(output == NULL) + return ERROR; + + /* clear the old macro value */ + my_free(*output); + + if(macro_buffer == NULL || clean_options == NULL || free_macro == NULL) + return ERROR; + + + /* + * We handle argv and user macros first, since those are by far + * the most commonly accessed ones (3.4 and 1.005 per check, + * respectively). Since neither of them requires that we copy + * the original buffer, we can also get away with some less + * code for these simple cases. + */ + if(strstr(macro_buffer, "ARG") == macro_buffer) { + + /* which arg do we want? */ + x = atoi(macro_buffer + 3); + + if(x <= 0 || x > MAX_COMMAND_ARGUMENTS) { + return ERROR; + } + + /* use a pre-computed macro value */ + *output = mac->argv[x - 1]; + return OK; + } + + if(strstr(macro_buffer, "USER") == macro_buffer) { + + /* which macro do we want? */ + x = atoi(macro_buffer + 4); + + if(x <= 0 || x > MAX_USER_MACROS) { + return ERROR; + } + + /* use a pre-computed macro value */ + *output = macro_user[x - 1]; + return OK; + } + + /* most frequently used "x" macro gets a shortcut */ + if(mac->host_ptr && !strcmp(macro_buffer, "HOSTADDRESS")) { + if(mac->host_ptr->address) + *output = mac->host_ptr->address; + return OK; + } + + /* work with a copy of the original buffer */ + if((buf = (char *)strdup(macro_buffer)) == NULL) + return ERROR; + + /* BY DEFAULT, TELL CALLER TO FREE MACRO BUFFER WHEN DONE */ + *free_macro = TRUE; + + /* macro name is at start of buffer */ + macro_name = buf; + + /* see if there's an argument - if so, this is most likely an on-demand macro */ + if((ptr = strchr(buf, ':'))) { + + ptr[0] = '\x0'; + ptr++; + + /* save the first argument - host name, hostgroup name, etc. */ + arg[0] = ptr; + + /* try and find a second argument */ + if((ptr = strchr(ptr, ':'))) { + + ptr[0] = '\x0'; + ptr++; + + /* save second argument - service description or delimiter */ + arg[1] = ptr; + } + } + + if((mkey = find_macro_key(macro_name))) { + log_debug_info(DEBUGL_MACROS, 2, " macros[%d] (%s) match.\n", mkey->code, macro_x_names[mkey->code]); + if(mkey->clean_options) { + *clean_options |= mkey->clean_options; + log_debug_info(DEBUGL_MACROS, 2, " New clean options: %d\n", *clean_options); + } + + /* get the macro value */ + result = grab_macrox_value_r(mac, mkey->code, arg[0], arg[1], output, free_macro); + } + /***** CONTACT ADDRESS MACROS *****/ + /* NOTE: the code below should be broken out into a separate function */ + else if(strstr(macro_name, "CONTACTADDRESS") == macro_name) { + + /* which address do we want? */ + x = atoi(macro_name + 14) - 1; + + /* regular macro */ + if(arg[0] == NULL) { + + /* use the saved pointer */ + if((temp_contact = mac->contact_ptr) == NULL) { + my_free(buf); + return ERROR; + } + + /* get the macro value by reference, so no need to free() */ + *free_macro = FALSE; + result = grab_contact_address_macro(x, temp_contact, output); + } + + /* on-demand macro */ + else { + + /* on-demand contact macro with a contactgroup and a delimiter */ + if(arg[1] != NULL) { + + if((temp_contactgroup = find_contactgroup(arg[0])) == NULL) + return ERROR; + + delimiter_len = strlen(arg[1]); + + /* concatenate macro values for all contactgroup members */ + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + +#ifdef NSCORE + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; + if((temp_contact = find_contact(temp_contactsmember->contact_name)) == NULL) + continue; +#endif + + /* get the macro value for this contact */ + grab_contact_address_macro(x, temp_contact, &temp_buffer); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg[1]); + strcat(*output, temp_buffer); + } + my_free(temp_buffer); + } + } + + /* else on-demand contact macro */ + else { + + /* find the contact */ + if((temp_contact = find_contact(arg[0])) == NULL) { + my_free(buf); + return ERROR; + } + + /* get the macro value */ + result = grab_contact_address_macro(x, temp_contact, output); + } + } + } + + /***** CUSTOM VARIABLE MACROS *****/ + else if(macro_name[0] == '_') { + + /* get the macro value */ + result = grab_custom_macro_value_r(mac, macro_name, arg[0], arg[1], output); + } + + /* no macro matched... */ + else { + log_debug_info(DEBUGL_MACROS, 0, " WARNING: Could not find a macro matching '%s'!\n", macro_name); + result = ERROR; + } + + /* free memory */ + my_free(buf); + + return result; + } + +int grab_macro_value(char *macro_buffer, char **output, int *clean_options, int *free_macro) { + return grab_macro_value_r(&global_macros, macro_buffer, output, clean_options, free_macro); + } + + +int grab_macrox_value_r(nagios_macros *mac, int macro_type, char *arg1, char *arg2, char **output, int *free_macro) { + host *temp_host = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_hostsmember = NULL; + service *temp_service = NULL; + servicegroup *temp_servicegroup = NULL; + servicesmember *temp_servicesmember = NULL; + contact *temp_contact = NULL; + contactgroup *temp_contactgroup = NULL; + contactsmember *temp_contactsmember = NULL; + char *temp_buffer = NULL; + int result = OK; + int delimiter_len = 0; + int free_sub_macro = FALSE; +#ifdef NSCORE + register int x; + int authorized = TRUE; + int problem = TRUE; + int hosts_up = 0; + int hosts_down = 0; + int hosts_unreachable = 0; + int hosts_down_unhandled = 0; + int hosts_unreachable_unhandled = 0; + int host_problems = 0; + int host_problems_unhandled = 0; + int services_ok = 0; + int services_warning = 0; + int services_unknown = 0; + int services_critical = 0; + int services_warning_unhandled = 0; + int services_unknown_unhandled = 0; + int services_critical_unhandled = 0; + int service_problems = 0; + int service_problems_unhandled = 0; +#endif + + + if(output == NULL || free_macro == NULL) + return ERROR; + + /* BY DEFAULT, TELL CALLER TO FREE MACRO BUFFER WHEN DONE */ + *free_macro = TRUE; + + /* handle the macro */ + switch(macro_type) { + + /***************/ + /* HOST MACROS */ + /***************/ + case MACRO_HOSTNAME: + case MACRO_HOSTALIAS: + case MACRO_HOSTADDRESS: + case MACRO_LASTHOSTCHECK: + case MACRO_LASTHOSTSTATECHANGE: + case MACRO_HOSTOUTPUT: + case MACRO_HOSTPERFDATA: + case MACRO_HOSTSTATE: + case MACRO_HOSTSTATEID: + case MACRO_HOSTATTEMPT: + case MACRO_HOSTEXECUTIONTIME: + case MACRO_HOSTLATENCY: + case MACRO_HOSTDURATION: + case MACRO_HOSTDURATIONSEC: + case MACRO_HOSTDOWNTIME: + case MACRO_HOSTSTATETYPE: + case MACRO_HOSTPERCENTCHANGE: + case MACRO_HOSTACKAUTHOR: + case MACRO_HOSTACKCOMMENT: + case MACRO_LASTHOSTUP: + case MACRO_LASTHOSTDOWN: + case MACRO_LASTHOSTUNREACHABLE: + case MACRO_HOSTCHECKCOMMAND: + case MACRO_HOSTDISPLAYNAME: + case MACRO_HOSTACTIONURL: + case MACRO_HOSTNOTESURL: + case MACRO_HOSTNOTES: + case MACRO_HOSTCHECKTYPE: + case MACRO_LONGHOSTOUTPUT: + case MACRO_HOSTNOTIFICATIONNUMBER: + case MACRO_HOSTNOTIFICATIONID: + case MACRO_HOSTEVENTID: + case MACRO_LASTHOSTEVENTID: + case MACRO_HOSTGROUPNAMES: + case MACRO_HOSTACKAUTHORNAME: + case MACRO_HOSTACKAUTHORALIAS: + case MACRO_MAXHOSTATTEMPTS: + case MACRO_TOTALHOSTSERVICES: + case MACRO_TOTALHOSTSERVICESOK: + case MACRO_TOTALHOSTSERVICESWARNING: + case MACRO_TOTALHOSTSERVICESUNKNOWN: + case MACRO_TOTALHOSTSERVICESCRITICAL: + case MACRO_HOSTPROBLEMID: + case MACRO_LASTHOSTPROBLEMID: + case MACRO_LASTHOSTSTATE: + case MACRO_LASTHOSTSTATEID: + + /* a standard host macro */ + if(arg2 == NULL) { + + /* find the host for on-demand macros */ + if(arg1) { + if((temp_host = find_host(arg1)) == NULL) + return ERROR; + } + + /* else use saved host pointer */ + else if((temp_host = mac->host_ptr) == NULL) + return ERROR; + + /* get the host macro value */ + result = grab_standard_host_macro_r(mac, macro_type, temp_host, output, free_macro); + } + + /* a host macro with a hostgroup name and delimiter */ + else { + + if((temp_hostgroup = find_hostgroup(arg1)) == NULL) + return ERROR; + + delimiter_len = strlen(arg2); + + /* concatenate macro values for all hostgroup members */ + for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + +#ifdef NSCORE + if((temp_host = temp_hostsmember->host_ptr) == NULL) + continue; +#else + if((temp_host = find_host(temp_hostsmember->host_name)) == NULL) + continue; +#endif + + /* get the macro value for this host */ + grab_standard_host_macro_r(mac, macro_type, temp_host, &temp_buffer, &free_sub_macro); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg2); + strcat(*output, temp_buffer); + } + if(free_sub_macro == TRUE) + my_free(temp_buffer); + } + } + break; + + /********************/ + /* HOSTGROUP MACROS */ + /********************/ + case MACRO_HOSTGROUPNAME: + case MACRO_HOSTGROUPALIAS: + case MACRO_HOSTGROUPNOTES: + case MACRO_HOSTGROUPNOTESURL: + case MACRO_HOSTGROUPACTIONURL: + case MACRO_HOSTGROUPMEMBERS: + + /* a standard hostgroup macro */ + /* use the saved hostgroup pointer */ + if(arg1 == NULL) { + if((temp_hostgroup = mac->hostgroup_ptr) == NULL) + return ERROR; + } + + /* else find the hostgroup for on-demand macros */ + else { + if((temp_hostgroup = find_hostgroup(arg1)) == NULL) + return ERROR; + } + + /* get the hostgroup macro value */ + result = grab_standard_hostgroup_macro_r(mac, macro_type, temp_hostgroup, output); + break; + + /******************/ + /* SERVICE MACROS */ + /******************/ + case MACRO_SERVICEDESC: + case MACRO_SERVICESTATE: + case MACRO_SERVICESTATEID: + case MACRO_SERVICEATTEMPT: + case MACRO_LASTSERVICECHECK: + case MACRO_LASTSERVICESTATECHANGE: + case MACRO_SERVICEOUTPUT: + case MACRO_SERVICEPERFDATA: + case MACRO_SERVICEEXECUTIONTIME: + case MACRO_SERVICELATENCY: + case MACRO_SERVICEDURATION: + case MACRO_SERVICEDURATIONSEC: + case MACRO_SERVICEDOWNTIME: + case MACRO_SERVICESTATETYPE: + case MACRO_SERVICEPERCENTCHANGE: + case MACRO_SERVICEACKAUTHOR: + case MACRO_SERVICEACKCOMMENT: + case MACRO_LASTSERVICEOK: + case MACRO_LASTSERVICEWARNING: + case MACRO_LASTSERVICEUNKNOWN: + case MACRO_LASTSERVICECRITICAL: + case MACRO_SERVICECHECKCOMMAND: + case MACRO_SERVICEDISPLAYNAME: + case MACRO_SERVICEACTIONURL: + case MACRO_SERVICENOTESURL: + case MACRO_SERVICENOTES: + case MACRO_SERVICECHECKTYPE: + case MACRO_LONGSERVICEOUTPUT: + case MACRO_SERVICENOTIFICATIONNUMBER: + case MACRO_SERVICENOTIFICATIONID: + case MACRO_SERVICEEVENTID: + case MACRO_LASTSERVICEEVENTID: + case MACRO_SERVICEGROUPNAMES: + case MACRO_SERVICEACKAUTHORNAME: + case MACRO_SERVICEACKAUTHORALIAS: + case MACRO_MAXSERVICEATTEMPTS: + case MACRO_SERVICEISVOLATILE: + case MACRO_SERVICEPROBLEMID: + case MACRO_LASTSERVICEPROBLEMID: + case MACRO_LASTSERVICESTATE: + case MACRO_LASTSERVICESTATEID: + + /* use saved service pointer */ + if(arg1 == NULL && arg2 == NULL) { + + if((temp_service = mac->service_ptr) == NULL) + return ERROR; + + result = grab_standard_service_macro_r(mac, macro_type, temp_service, output, free_macro); + } + + /* else and ondemand macro... */ + else { + + /* if first arg is blank, it means use the current host name */ + if(arg1 == NULL || arg1[0] == '\x0') { + + if(mac->host_ptr == NULL) + return ERROR; + + if((temp_service = find_service(mac->host_ptr->name, arg2))) { + + /* get the service macro value */ + result = grab_standard_service_macro_r(mac, macro_type, temp_service, output, free_macro); + } + } + + /* on-demand macro with both host and service name */ + else if((temp_service = find_service(arg1, arg2))) { + + /* get the service macro value */ + result = grab_standard_service_macro_r(mac, macro_type, temp_service, output, free_macro); + } + + /* else we have a service macro with a servicegroup name and a delimiter... */ + else if(arg1 && arg2) { + + if((temp_servicegroup = find_servicegroup(arg1)) == NULL) + return ERROR; + + delimiter_len = strlen(arg2); + + /* concatenate macro values for all servicegroup members */ + for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + +#ifdef NSCORE + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; +#else + if((temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description)) == NULL) + continue; +#endif + + /* get the macro value for this service */ + grab_standard_service_macro_r(mac, macro_type, temp_service, &temp_buffer, &free_sub_macro); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg2); + strcat(*output, temp_buffer); + } + if(free_sub_macro == TRUE) + my_free(temp_buffer); + } + } + else + return ERROR; + } + break; + + /***********************/ + /* SERVICEGROUP MACROS */ + /***********************/ + case MACRO_SERVICEGROUPNAME: + case MACRO_SERVICEGROUPALIAS: + case MACRO_SERVICEGROUPNOTES: + case MACRO_SERVICEGROUPNOTESURL: + case MACRO_SERVICEGROUPACTIONURL: + case MACRO_SERVICEGROUPMEMBERS: + /* a standard servicegroup macro */ + /* use the saved servicegroup pointer */ + if(arg1 == NULL) { + if((temp_servicegroup = mac->servicegroup_ptr) == NULL) + return ERROR; + } + + /* else find the servicegroup for on-demand macros */ + else { + if((temp_servicegroup = find_servicegroup(arg1)) == NULL) + return ERROR; + } + + /* get the servicegroup macro value */ + result = grab_standard_servicegroup_macro_r(mac, macro_type, temp_servicegroup, output); + break; + + /******************/ + /* CONTACT MACROS */ + /******************/ + case MACRO_CONTACTNAME: + case MACRO_CONTACTALIAS: + case MACRO_CONTACTEMAIL: + case MACRO_CONTACTPAGER: + case MACRO_CONTACTGROUPNAMES: + /* a standard contact macro */ + if(arg2 == NULL) { + + /* find the contact for on-demand macros */ + if(arg1) { + if((temp_contact = find_contact(arg1)) == NULL) + return ERROR; + } + + /* else use saved contact pointer */ + else if((temp_contact = mac->contact_ptr) == NULL) + return ERROR; + + /* get the contact macro value */ + result = grab_standard_contact_macro_r(mac, macro_type, temp_contact, output); + } + + /* a contact macro with a contactgroup name and delimiter */ + else { + + if((temp_contactgroup = find_contactgroup(arg1)) == NULL) + return ERROR; + + delimiter_len = strlen(arg2); + + /* concatenate macro values for all contactgroup members */ + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + +#ifdef NSCORE + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; +#else + if((temp_contact = find_contact(temp_contactsmember->contact_name)) == NULL) + continue; +#endif + + /* get the macro value for this contact */ + grab_standard_contact_macro_r(mac, macro_type, temp_contact, &temp_buffer); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg2); + strcat(*output, temp_buffer); + } + my_free(temp_buffer); + } + } + break; + + /***********************/ + /* CONTACTGROUP MACROS */ + /***********************/ + case MACRO_CONTACTGROUPNAME: + case MACRO_CONTACTGROUPALIAS: + case MACRO_CONTACTGROUPMEMBERS: + /* a standard contactgroup macro */ + /* use the saved contactgroup pointer */ + if(arg1 == NULL) { + if((temp_contactgroup = mac->contactgroup_ptr) == NULL) + return ERROR; + } + + /* else find the contactgroup for on-demand macros */ + else { + if((temp_contactgroup = find_contactgroup(arg1)) == NULL) + return ERROR; + } + + /* get the contactgroup macro value */ + result = grab_standard_contactgroup_macro(macro_type, temp_contactgroup, output); + break; + + /***********************/ + /* NOTIFICATION MACROS */ + /***********************/ + case MACRO_NOTIFICATIONTYPE: + case MACRO_NOTIFICATIONNUMBER: + case MACRO_NOTIFICATIONRECIPIENTS: + case MACRO_NOTIFICATIONISESCALATED: + case MACRO_NOTIFICATIONAUTHOR: + case MACRO_NOTIFICATIONAUTHORNAME: + case MACRO_NOTIFICATIONAUTHORALIAS: + case MACRO_NOTIFICATIONCOMMENT: + + /* notification macros have already been pre-computed */ + *output = mac->x[macro_type]; + *free_macro = FALSE; + break; + + /********************/ + /* DATE/TIME MACROS */ + /********************/ + case MACRO_LONGDATETIME: + case MACRO_SHORTDATETIME: + case MACRO_DATE: + case MACRO_TIME: + case MACRO_TIMET: + case MACRO_ISVALIDTIME: + case MACRO_NEXTVALIDTIME: + + /* calculate macros */ + result = grab_datetime_macro_r(mac, macro_type, arg1, arg2, output); + break; + + /*****************/ + /* STATIC MACROS */ + /*****************/ + case MACRO_ADMINEMAIL: + case MACRO_ADMINPAGER: + case MACRO_MAINCONFIGFILE: + case MACRO_STATUSDATAFILE: + case MACRO_RETENTIONDATAFILE: + case MACRO_OBJECTCACHEFILE: + case MACRO_TEMPFILE: + case MACRO_LOGFILE: + case MACRO_RESOURCEFILE: + case MACRO_COMMANDFILE: + case MACRO_HOSTPERFDATAFILE: + case MACRO_SERVICEPERFDATAFILE: + case MACRO_PROCESSSTARTTIME: + case MACRO_TEMPPATH: + case MACRO_EVENTSTARTTIME: + + /* no need to do any more work - these are already precomputed for us */ + *output = global_macros.x[macro_type]; + *free_macro = FALSE; + break; + + /******************/ + /* SUMMARY MACROS */ + /******************/ + case MACRO_TOTALHOSTSUP: + case MACRO_TOTALHOSTSDOWN: + case MACRO_TOTALHOSTSUNREACHABLE: + case MACRO_TOTALHOSTSDOWNUNHANDLED: + case MACRO_TOTALHOSTSUNREACHABLEUNHANDLED: + case MACRO_TOTALHOSTPROBLEMS: + case MACRO_TOTALHOSTPROBLEMSUNHANDLED: + case MACRO_TOTALSERVICESOK: + case MACRO_TOTALSERVICESWARNING: + case MACRO_TOTALSERVICESCRITICAL: + case MACRO_TOTALSERVICESUNKNOWN: + case MACRO_TOTALSERVICESWARNINGUNHANDLED: + case MACRO_TOTALSERVICESCRITICALUNHANDLED: + case MACRO_TOTALSERVICESUNKNOWNUNHANDLED: + case MACRO_TOTALSERVICEPROBLEMS: + case MACRO_TOTALSERVICEPROBLEMSUNHANDLED: + +#ifdef NSCORE + /* generate summary macros if needed */ + if(mac->x[MACRO_TOTALHOSTSUP] == NULL) { + + /* get host totals */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* filter totals based on contact if necessary */ + if(mac->contact_ptr != NULL) + authorized = is_contact_for_host(temp_host, mac->contact_ptr); + + if(authorized == TRUE) { + problem = TRUE; + + if(temp_host->current_state == HOST_UP && temp_host->has_been_checked == TRUE) + hosts_up++; + else if(temp_host->current_state == HOST_DOWN) { + if(temp_host->scheduled_downtime_depth > 0) + problem = FALSE; + if(temp_host->problem_has_been_acknowledged == TRUE) + problem = FALSE; + if(temp_host->checks_enabled == FALSE) + problem = FALSE; + if(problem == TRUE) + hosts_down_unhandled++; + hosts_down++; + } + else if(temp_host->current_state == HOST_UNREACHABLE) { + if(temp_host->scheduled_downtime_depth > 0) + problem = FALSE; + if(temp_host->problem_has_been_acknowledged == TRUE) + problem = FALSE; + if(temp_host->checks_enabled == FALSE) + problem = FALSE; + if(problem == TRUE) + hosts_down_unhandled++; + hosts_unreachable++; + } + } + } + + host_problems = hosts_down + hosts_unreachable; + host_problems_unhandled = hosts_down_unhandled + hosts_unreachable_unhandled; + + /* get service totals */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* filter totals based on contact if necessary */ + if(mac->contact_ptr != NULL) + authorized = is_contact_for_service(temp_service, mac->contact_ptr); + + if(authorized == TRUE) { + problem = TRUE; + + if(temp_service->current_state == STATE_OK && temp_service->has_been_checked == TRUE) + services_ok++; + else if(temp_service->current_state == STATE_WARNING) { + temp_host = find_host(temp_service->host_name); + if(temp_host != NULL && (temp_host->current_state == HOST_DOWN || temp_host->current_state == HOST_UNREACHABLE)) + problem = FALSE; + if(temp_service->scheduled_downtime_depth > 0) + problem = FALSE; + if(temp_service->problem_has_been_acknowledged == TRUE) + problem = FALSE; + if(temp_service->checks_enabled == FALSE) + problem = FALSE; + if(problem == TRUE) + services_warning_unhandled++; + services_warning++; + } + else if(temp_service->current_state == STATE_UNKNOWN) { + temp_host = find_host(temp_service->host_name); + if(temp_host != NULL && (temp_host->current_state == HOST_DOWN || temp_host->current_state == HOST_UNREACHABLE)) + problem = FALSE; + if(temp_service->scheduled_downtime_depth > 0) + problem = FALSE; + if(temp_service->problem_has_been_acknowledged == TRUE) + problem = FALSE; + if(temp_service->checks_enabled == FALSE) + problem = FALSE; + if(problem == TRUE) + services_unknown_unhandled++; + services_unknown++; + } + else if(temp_service->current_state == STATE_CRITICAL) { + temp_host = find_host(temp_service->host_name); + if(temp_host != NULL && (temp_host->current_state == HOST_DOWN || temp_host->current_state == HOST_UNREACHABLE)) + problem = FALSE; + if(temp_service->scheduled_downtime_depth > 0) + problem = FALSE; + if(temp_service->problem_has_been_acknowledged == TRUE) + problem = FALSE; + if(temp_service->checks_enabled == FALSE) + problem = FALSE; + if(problem == TRUE) + services_critical_unhandled++; + services_critical++; + } + } + } + + service_problems = services_warning + services_critical + services_unknown; + service_problems_unhandled = services_warning_unhandled + services_critical_unhandled + services_unknown_unhandled; + + /* these macros are time-intensive to compute, and will likely be used together, so save them all for future use */ + for(x = MACRO_TOTALHOSTSUP; x <= MACRO_TOTALSERVICEPROBLEMSUNHANDLED; x++) + my_free(mac->x[x]); + asprintf(&mac->x[MACRO_TOTALHOSTSUP], "%d", hosts_up); + asprintf(&mac->x[MACRO_TOTALHOSTSDOWN], "%d", hosts_down); + asprintf(&mac->x[MACRO_TOTALHOSTSUNREACHABLE], "%d", hosts_unreachable); + asprintf(&mac->x[MACRO_TOTALHOSTSDOWNUNHANDLED], "%d", hosts_down_unhandled); + asprintf(&mac->x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED], "%d", hosts_unreachable_unhandled); + asprintf(&mac->x[MACRO_TOTALHOSTPROBLEMS], "%d", host_problems); + asprintf(&mac->x[MACRO_TOTALHOSTPROBLEMSUNHANDLED], "%d", host_problems_unhandled); + asprintf(&mac->x[MACRO_TOTALSERVICESOK], "%d", services_ok); + asprintf(&mac->x[MACRO_TOTALSERVICESWARNING], "%d", services_warning); + asprintf(&mac->x[MACRO_TOTALSERVICESCRITICAL], "%d", services_critical); + asprintf(&mac->x[MACRO_TOTALSERVICESUNKNOWN], "%d", services_unknown); + asprintf(&mac->x[MACRO_TOTALSERVICESWARNINGUNHANDLED], "%d", services_warning_unhandled); + asprintf(&mac->x[MACRO_TOTALSERVICESCRITICALUNHANDLED], "%d", services_critical_unhandled); + asprintf(&mac->x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED], "%d", services_unknown_unhandled); + asprintf(&mac->x[MACRO_TOTALSERVICEPROBLEMS], "%d", service_problems); + asprintf(&mac->x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED], "%d", service_problems_unhandled); + } + + /* return only the macro the user requested */ + *output = mac->x[macro_type]; + + /* tell caller to NOT free memory when done */ + *free_macro = FALSE; +#endif + break; + + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + break; + } + + return result; + } + +int grab_macrox_value(int macro_type, char *arg1, char *arg2, char **output, int *free_macro) { + return grab_macrox_value_r(&global_macros, macro_type, arg1, arg2, output, free_macro); + } + + +/* calculates the value of a custom macro */ +int grab_custom_macro_value_r(nagios_macros *mac, char *macro_name, char *arg1, char *arg2, char **output) { + host *temp_host = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_hostsmember = NULL; + service *temp_service = NULL; + servicegroup *temp_servicegroup = NULL; + servicesmember *temp_servicesmember = NULL; + contact *temp_contact = NULL; + contactgroup *temp_contactgroup = NULL; + contactsmember *temp_contactsmember = NULL; + int delimiter_len = 0; + char *temp_buffer = NULL; + int result = OK; + + if(macro_name == NULL || output == NULL) + return ERROR; + + /***** CUSTOM HOST MACRO *****/ + if(strstr(macro_name, "_HOST") == macro_name) { + + /* a standard host macro */ + if(arg2 == NULL) { + + /* find the host for on-demand macros */ + if(arg1) { + if((temp_host = find_host(arg1)) == NULL) + return ERROR; + } + + /* else use saved host pointer */ + else if((temp_host = mac->host_ptr) == NULL) + return ERROR; + + /* get the host macro value */ + result = grab_custom_object_macro_r(mac, macro_name + 5, temp_host->custom_variables, output); + } + + /* a host macro with a hostgroup name and delimiter */ + else { + if((temp_hostgroup = find_hostgroup(arg1)) == NULL) + return ERROR; + + delimiter_len = strlen(arg2); + + /* concatenate macro values for all hostgroup members */ + for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + +#ifdef NSCORE + if((temp_host = temp_hostsmember->host_ptr) == NULL) + continue; +#else + if((temp_host = find_host(temp_hostsmember->host_name)) == NULL) + continue; +#endif + + /* get the macro value for this host */ + grab_custom_macro_value_r(mac, macro_name, temp_host->name, NULL, &temp_buffer); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg2); + strcat(*output, temp_buffer); + } + my_free(temp_buffer); + } + } + } + + /***** CUSTOM SERVICE MACRO *****/ + else if(strstr(macro_name, "_SERVICE") == macro_name) { + + /* use saved service pointer */ + if(arg1 == NULL && arg2 == NULL) { + + if((temp_service = mac->service_ptr) == NULL) + return ERROR; + + /* get the service macro value */ + result = grab_custom_object_macro_r(mac, macro_name + 8, temp_service->custom_variables, output); + } + + /* else and ondemand macro... */ + else { + + /* if first arg is blank, it means use the current host name */ + if(mac->host_ptr == NULL) + return ERROR; + if((temp_service = find_service((mac->host_ptr) ? mac->host_ptr->name : NULL, arg2))) { + + /* get the service macro value */ + result = grab_custom_object_macro_r(mac, macro_name + 8, temp_service->custom_variables, output); + } + + /* else we have a service macro with a servicegroup name and a delimiter... */ + else { + + if((temp_servicegroup = find_servicegroup(arg1)) == NULL) + return ERROR; + + delimiter_len = strlen(arg2); + + /* concatenate macro values for all servicegroup members */ + for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + +#ifdef NSCORE + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; +#else + if((temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description)) == NULL) + continue; +#endif + + /* get the macro value for this service */ + grab_custom_macro_value_r(mac, macro_name, temp_service->host_name, temp_service->description, &temp_buffer); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg2); + strcat(*output, temp_buffer); + } + my_free(temp_buffer); + } + } + } + } + + /***** CUSTOM CONTACT VARIABLE *****/ + else if(strstr(macro_name, "_CONTACT") == macro_name) { + + /* a standard contact macro */ + if(arg2 == NULL) { + + /* find the contact for on-demand macros */ + if(arg1) { + if((temp_contact = find_contact(arg1)) == NULL) + return ERROR; + } + + /* else use saved contact pointer */ + else if((temp_contact = mac->contact_ptr) == NULL) + return ERROR; + + /* get the contact macro value */ + result = grab_custom_object_macro_r(mac, macro_name + 8, temp_contact->custom_variables, output); + } + + /* a contact macro with a contactgroup name and delimiter */ + else { + + if((temp_contactgroup = find_contactgroup(arg1)) == NULL) + return ERROR; + + delimiter_len = strlen(arg2); + + /* concatenate macro values for all contactgroup members */ + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + +#ifdef NSCORE + if((temp_contact = temp_contactsmember->contact_ptr) == NULL) + continue; +#else + if((temp_contact = find_contact(temp_contactsmember->contact_name)) == NULL) + continue; +#endif + + /* get the macro value for this contact */ + grab_custom_macro_value_r(mac, macro_name, temp_contact->name, NULL, &temp_buffer); + + if(temp_buffer == NULL) + continue; + + /* add macro value to already running macro */ + if(*output == NULL) + *output = (char *)strdup(temp_buffer); + else { + if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_buffer) + delimiter_len + 1)) == NULL) + continue; + strcat(*output, arg2); + strcat(*output, temp_buffer); + } + my_free(temp_buffer); + } + } + } + + else + return ERROR; + + return result; + } + +int grab_custom_macro_value(char *macro_name, char *arg1, char *arg2, char **output) { + return grab_custom_macro_value_r(&global_macros, macro_name, arg1, arg2, output); + } + + +/* calculates a date/time macro */ +int grab_datetime_macro_r(nagios_macros *mac, int macro_type, char *arg1, char *arg2, char **output) { + time_t current_time = 0L; + timeperiod *temp_timeperiod = NULL; + time_t test_time = 0L; +#ifdef NSCORE + time_t next_valid_time = 0L; +#endif + + if(output == NULL) + return ERROR; + + /* get the current time */ + time(¤t_time); + + /* parse args, do prep work */ + switch(macro_type) { + + case MACRO_ISVALIDTIME: + case MACRO_NEXTVALIDTIME: + + /* find the timeperiod */ + if((temp_timeperiod = find_timeperiod(arg1)) == NULL) + return ERROR; + + /* what timestamp should we use? */ + if(arg2) + test_time = (time_t)strtoul(arg2, NULL, 0); + else + test_time = current_time; + break; + + default: + break; + } + + /* calculate the value */ + switch(macro_type) { + + case MACRO_LONGDATETIME: + if(*output == NULL) + *output = (char *)malloc(MAX_DATETIME_LENGTH); + if(*output) + get_datetime_string(¤t_time, *output, MAX_DATETIME_LENGTH, LONG_DATE_TIME); + break; + + case MACRO_SHORTDATETIME: + if(*output == NULL) + *output = (char *)malloc(MAX_DATETIME_LENGTH); + if(*output) + get_datetime_string(¤t_time, *output, MAX_DATETIME_LENGTH, SHORT_DATE_TIME); + break; + + case MACRO_DATE: + if(*output == NULL) + *output = (char *)malloc(MAX_DATETIME_LENGTH); + if(*output) + get_datetime_string(¤t_time, *output, MAX_DATETIME_LENGTH, SHORT_DATE); + break; + + case MACRO_TIME: + if(*output == NULL) + *output = (char *)malloc(MAX_DATETIME_LENGTH); + if(*output) + get_datetime_string(¤t_time, *output, MAX_DATETIME_LENGTH, SHORT_TIME); + break; + + case MACRO_TIMET: + asprintf(output, "%lu", (unsigned long)current_time); + break; + +#ifdef NSCORE + case MACRO_ISVALIDTIME: + asprintf(output, "%d", (check_time_against_period(test_time, temp_timeperiod) == OK) ? 1 : 0); + break; + + case MACRO_NEXTVALIDTIME: + get_next_valid_time(test_time, &next_valid_time, temp_timeperiod); + if(next_valid_time == test_time && check_time_against_period(test_time, temp_timeperiod) == ERROR) + next_valid_time = (time_t)0L; + asprintf(output, "%lu", (unsigned long)next_valid_time); + break; +#endif + + default: + return ERROR; + break; + } + + return OK; + } + +int grab_datetime_macro(int macro_type, char *arg1, char *arg2, char **output) { + return grab_datetime_macro_r(&global_macros, macro_type, arg1, arg2, output); + } + + +/* calculates a host macro */ +int grab_standard_host_macro_r(nagios_macros *mac, int macro_type, host *temp_host, char **output, int *free_macro) { + char *temp_buffer = NULL; +#ifdef NSCORE + hostgroup *temp_hostgroup = NULL; + servicesmember *temp_servicesmember = NULL; + service *temp_service = NULL; + objectlist *temp_objectlist = NULL; + time_t current_time = 0L; + unsigned long duration = 0L; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + char *buf1 = NULL; + char *buf2 = NULL; + int total_host_services = 0; + int total_host_services_ok = 0; + int total_host_services_warning = 0; + int total_host_services_unknown = 0; + int total_host_services_critical = 0; +#endif + + if(temp_host == NULL || output == NULL || free_macro == NULL) + return ERROR; + + /* BY DEFAULT TELL CALLER TO FREE MACRO BUFFER WHEN DONE */ + *free_macro = TRUE; + + /* get the macro */ + switch(macro_type) { + + case MACRO_HOSTNAME: + *output = (char *)strdup(temp_host->name); + break; + case MACRO_HOSTDISPLAYNAME: + if(temp_host->display_name) + *output = (char *)strdup(temp_host->display_name); + break; + case MACRO_HOSTALIAS: + *output = (char *)strdup(temp_host->alias); + break; + case MACRO_HOSTADDRESS: + *output = (char *)strdup(temp_host->address); + break; +#ifdef NSCORE + case MACRO_HOSTSTATE: + if(temp_host->current_state == HOST_DOWN) + *output = (char *)strdup("DOWN"); + else if(temp_host->current_state == HOST_UNREACHABLE) + *output = (char *)strdup("UNREACHABLE"); + else + *output = (char *)strdup("UP"); + break; + case MACRO_HOSTSTATEID: + asprintf(output, "%d", temp_host->current_state); + break; + case MACRO_LASTHOSTSTATE: + if(temp_host->last_state == HOST_DOWN) + *output = (char *)strdup("DOWN"); + else if(temp_host->last_state == HOST_UNREACHABLE) + *output = (char *)strdup("UNREACHABLE"); + else + *output = (char *)strdup("UP"); + break; + case MACRO_LASTHOSTSTATEID: + asprintf(output, "%d", temp_host->last_state); + break; + case MACRO_HOSTCHECKTYPE: + asprintf(output, "%s", (temp_host->check_type == HOST_CHECK_PASSIVE) ? "PASSIVE" : "ACTIVE"); + break; + case MACRO_HOSTSTATETYPE: + asprintf(output, "%s", (temp_host->state_type == HARD_STATE) ? "HARD" : "SOFT"); + break; + case MACRO_HOSTOUTPUT: + if(temp_host->plugin_output) + *output = (char *)strdup(temp_host->plugin_output); + break; + case MACRO_LONGHOSTOUTPUT: + if(temp_host->long_plugin_output) + *output = (char *)strdup(temp_host->long_plugin_output); + break; + case MACRO_HOSTPERFDATA: + if(temp_host->perf_data) + *output = (char *)strdup(temp_host->perf_data); + break; +#endif + case MACRO_HOSTCHECKCOMMAND: + if(temp_host->host_check_command) + *output = (char *)strdup(temp_host->host_check_command); + break; +#ifdef NSCORE + case MACRO_HOSTATTEMPT: + asprintf(output, "%d", temp_host->current_attempt); + break; + case MACRO_MAXHOSTATTEMPTS: + asprintf(output, "%d", temp_host->max_attempts); + break; + case MACRO_HOSTDOWNTIME: + asprintf(output, "%d", temp_host->scheduled_downtime_depth); + break; + case MACRO_HOSTPERCENTCHANGE: + asprintf(output, "%.2f", temp_host->percent_state_change); + break; + case MACRO_HOSTDURATIONSEC: + case MACRO_HOSTDURATION: + time(¤t_time); + duration = (unsigned long)(current_time - temp_host->last_state_change); + + if(macro_type == MACRO_HOSTDURATIONSEC) + asprintf(output, "%lu", duration); + else { + + days = duration / 86400; + duration -= (days * 86400); + hours = duration / 3600; + duration -= (hours * 3600); + minutes = duration / 60; + duration -= (minutes * 60); + seconds = duration; + asprintf(output, "%dd %dh %dm %ds", days, hours, minutes, seconds); + } + break; + case MACRO_HOSTEXECUTIONTIME: + asprintf(output, "%.3f", temp_host->execution_time); + break; + case MACRO_HOSTLATENCY: + asprintf(output, "%.3f", temp_host->latency); + break; + case MACRO_LASTHOSTCHECK: + asprintf(output, "%lu", (unsigned long)temp_host->last_check); + break; + case MACRO_LASTHOSTSTATECHANGE: + asprintf(output, "%lu", (unsigned long)temp_host->last_state_change); + break; + case MACRO_LASTHOSTUP: + asprintf(output, "%lu", (unsigned long)temp_host->last_time_up); + break; + case MACRO_LASTHOSTDOWN: + asprintf(output, "%lu", (unsigned long)temp_host->last_time_down); + break; + case MACRO_LASTHOSTUNREACHABLE: + asprintf(output, "%lu", (unsigned long)temp_host->last_time_unreachable); + break; + case MACRO_HOSTNOTIFICATIONNUMBER: + asprintf(output, "%d", temp_host->current_notification_number); + break; + case MACRO_HOSTNOTIFICATIONID: + asprintf(output, "%lu", temp_host->current_notification_id); + break; + case MACRO_HOSTEVENTID: + asprintf(output, "%lu", temp_host->current_event_id); + break; + case MACRO_LASTHOSTEVENTID: + asprintf(output, "%lu", temp_host->last_event_id); + break; + case MACRO_HOSTPROBLEMID: + asprintf(output, "%lu", temp_host->current_problem_id); + break; + case MACRO_LASTHOSTPROBLEMID: + asprintf(output, "%lu", temp_host->last_problem_id); + break; +#endif + case MACRO_HOSTACTIONURL: + if(temp_host->action_url) + *output = (char *)strdup(temp_host->action_url); + break; + case MACRO_HOSTNOTESURL: + if(temp_host->notes_url) + *output = (char *)strdup(temp_host->notes_url); + break; + case MACRO_HOSTNOTES: + if(temp_host->notes) + *output = (char *)strdup(temp_host->notes); + break; +#ifdef NSCORE + case MACRO_HOSTGROUPNAMES: + /* find all hostgroups this host is associated with */ + for(temp_objectlist = temp_host->hostgroups_ptr; temp_objectlist != NULL; temp_objectlist = temp_objectlist->next) { + + if((temp_hostgroup = (hostgroup *)temp_objectlist->object_ptr) == NULL) + continue; + + asprintf(&buf1, "%s%s%s", (buf2) ? buf2 : "", (buf2) ? "," : "", temp_hostgroup->group_name); + my_free(buf2); + buf2 = buf1; + } + if(buf2) { + *output = (char *)strdup(buf2); + my_free(buf2); + } + break; + case MACRO_TOTALHOSTSERVICES: + case MACRO_TOTALHOSTSERVICESOK: + case MACRO_TOTALHOSTSERVICESWARNING: + case MACRO_TOTALHOSTSERVICESUNKNOWN: + case MACRO_TOTALHOSTSERVICESCRITICAL: + + /* generate host service summary macros (if they haven't already been computed) */ + if(mac->x[MACRO_TOTALHOSTSERVICES] == NULL) { + + for(temp_servicesmember = temp_host->services; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if((temp_service = temp_servicesmember->service_ptr) == NULL) + continue; + + total_host_services++; + + switch(temp_service->current_state) { + case STATE_OK: + total_host_services_ok++; + break; + case STATE_WARNING: + total_host_services_warning++; + break; + case STATE_UNKNOWN: + total_host_services_unknown++; + break; + case STATE_CRITICAL: + total_host_services_critical++; + break; + default: + break; + } + } + + /* these macros are time-intensive to compute, and will likely be used together, so save them all for future use */ + my_free(mac->x[MACRO_TOTALHOSTSERVICES]); + asprintf(&mac->x[MACRO_TOTALHOSTSERVICES], "%d", total_host_services); + my_free(mac->x[MACRO_TOTALHOSTSERVICESOK]); + asprintf(&mac->x[MACRO_TOTALHOSTSERVICESOK], "%d", total_host_services_ok); + my_free(mac->x[MACRO_TOTALHOSTSERVICESWARNING]); + asprintf(&mac->x[MACRO_TOTALHOSTSERVICESWARNING], "%d", total_host_services_warning); + my_free(mac->x[MACRO_TOTALHOSTSERVICESUNKNOWN]); + asprintf(&mac->x[MACRO_TOTALHOSTSERVICESUNKNOWN], "%d", total_host_services_unknown); + my_free(mac->x[MACRO_TOTALHOSTSERVICESCRITICAL]); + asprintf(&mac->x[MACRO_TOTALHOSTSERVICESCRITICAL], "%d", total_host_services_critical); + } + + /* return only the macro the user requested */ + *output = mac->x[macro_type]; + + /* tell caller to NOT free memory when done */ + *free_macro = FALSE; + break; +#endif + /***************/ + /* MISC MACROS */ + /***************/ + case MACRO_HOSTACKAUTHOR: + case MACRO_HOSTACKAUTHORNAME: + case MACRO_HOSTACKAUTHORALIAS: + case MACRO_HOSTACKCOMMENT: + /* no need to do any more work - these are already precomputed elsewhere */ + /* NOTE: these macros won't work as on-demand macros */ + *output = mac->x[macro_type]; + *free_macro = FALSE; + break; + + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED HOST MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + break; + } + + /* post-processing */ + /* notes, notes URL and action URL macros may themselves contain macros, so process them... */ + switch(macro_type) { + case MACRO_HOSTACTIONURL: + case MACRO_HOSTNOTESURL: + process_macros_r(mac, *output, &temp_buffer, URL_ENCODE_MACRO_CHARS); + my_free(*output); + *output = temp_buffer; + break; + case MACRO_HOSTNOTES: + process_macros_r(mac, *output, &temp_buffer, 0); + my_free(*output); + *output = temp_buffer; + break; + default: + break; + } + + return OK; + } + +int grab_standard_host_macro(int macro_type, host *temp_host, char **output, int *free_macro) { + return grab_standard_host_macro_r(&global_macros, macro_type, temp_host, output, free_macro); + } + + +/* computes a hostgroup macro */ +int grab_standard_hostgroup_macro_r(nagios_macros *mac, int macro_type, hostgroup *temp_hostgroup, char **output) { + hostsmember *temp_hostsmember = NULL; + char *temp_buffer = NULL; + unsigned int temp_len = 0; + unsigned int init_len = 0; + + if(temp_hostgroup == NULL || output == NULL) + return ERROR; + + /* get the macro value */ + switch(macro_type) { + case MACRO_HOSTGROUPNAME: + *output = (char *)strdup(temp_hostgroup->group_name); + break; + case MACRO_HOSTGROUPALIAS: + if(temp_hostgroup->alias) + *output = (char *)strdup(temp_hostgroup->alias); + break; + case MACRO_HOSTGROUPMEMBERS: + /* make the calculations for total string length */ + for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if(temp_hostsmember->host_name == NULL) + continue; + if(temp_len == 0) { + temp_len += strlen(temp_hostsmember->host_name) + 1; + } + else { + temp_len += strlen(temp_hostsmember->host_name) + 2; + } + } + /* allocate or reallocate the memory buffer */ + if(*output == NULL) { + *output = (char *)malloc(temp_len); + } + else { + init_len = strlen(*output); + temp_len += init_len; + *output = (char *)realloc(*output, temp_len); + } + /* now fill in the string with the member names */ + for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { + if(temp_hostsmember->host_name == NULL) + continue; + temp_buffer = *output + init_len; + if(init_len == 0) { /* If our buffer didn't contain anything, we just need to write "%s,%s" */ + init_len += sprintf(temp_buffer, "%s", temp_hostsmember->host_name); + } + else { + init_len += sprintf(temp_buffer, ",%s", temp_hostsmember->host_name); + } + } + break; + case MACRO_HOSTGROUPACTIONURL: + if(temp_hostgroup->action_url) + *output = (char *)strdup(temp_hostgroup->action_url); + break; + case MACRO_HOSTGROUPNOTESURL: + if(temp_hostgroup->notes_url) + *output = (char *)strdup(temp_hostgroup->notes_url); + break; + case MACRO_HOSTGROUPNOTES: + if(temp_hostgroup->notes) + *output = (char *)strdup(temp_hostgroup->notes); + break; + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED HOSTGROUP MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + break; + } + + /* post-processing */ + /* notes, notes URL and action URL macros may themselves contain macros, so process them... */ + switch(macro_type) { + case MACRO_HOSTGROUPACTIONURL: + case MACRO_HOSTGROUPNOTESURL: + process_macros_r(mac, *output, &temp_buffer, URL_ENCODE_MACRO_CHARS); + my_free(*output); + *output = temp_buffer; + break; + case MACRO_HOSTGROUPNOTES: + process_macros_r(mac, *output, &temp_buffer, 0); + my_free(*output); + *output = temp_buffer; + break; + default: + break; + } + + return OK; + } + +int grab_standard_hostgroup_macro(int macro_type, hostgroup *temp_hostgroup, char **output) { + return grab_standard_hostgroup_macro_r(&global_macros, macro_type, temp_hostgroup, output); + } + + +/* computes a service macro */ +int grab_standard_service_macro_r(nagios_macros *mac, int macro_type, service *temp_service, char **output, int *free_macro) { + char *temp_buffer = NULL; +#ifdef NSCORE + servicegroup *temp_servicegroup = NULL; + objectlist *temp_objectlist = NULL; + time_t current_time = 0L; + unsigned long duration = 0L; + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + char *buf1 = NULL; + char *buf2 = NULL; +#endif + + if(temp_service == NULL || output == NULL) + return ERROR; + + /* BY DEFAULT TELL CALLER TO FREE MACRO BUFFER WHEN DONE */ + *free_macro = TRUE; + + /* get the macro value */ + switch(macro_type) { + case MACRO_SERVICEDESC: + *output = (char *)strdup(temp_service->description); + break; + case MACRO_SERVICEDISPLAYNAME: + if(temp_service->display_name) + *output = (char *)strdup(temp_service->display_name); + break; +#ifdef NSCORE + case MACRO_SERVICEOUTPUT: + if(temp_service->plugin_output) + *output = (char *)strdup(temp_service->plugin_output); + break; + case MACRO_LONGSERVICEOUTPUT: + if(temp_service->long_plugin_output) + *output = (char *)strdup(temp_service->long_plugin_output); + break; + case MACRO_SERVICEPERFDATA: + if(temp_service->perf_data) + *output = (char *)strdup(temp_service->perf_data); + break; +#endif + case MACRO_SERVICECHECKCOMMAND: + if(temp_service->service_check_command) + *output = (char *)strdup(temp_service->service_check_command); + break; +#ifdef NSCORE + case MACRO_SERVICECHECKTYPE: + *output = (char *)strdup((temp_service->check_type == SERVICE_CHECK_PASSIVE) ? "PASSIVE" : "ACTIVE"); + break; + case MACRO_SERVICESTATETYPE: + *output = (char *)strdup((temp_service->state_type == HARD_STATE) ? "HARD" : "SOFT"); + break; + case MACRO_SERVICESTATE: + if(temp_service->current_state == STATE_OK) + *output = (char *)strdup("OK"); + else if(temp_service->current_state == STATE_WARNING) + *output = (char *)strdup("WARNING"); + else if(temp_service->current_state == STATE_CRITICAL) + *output = (char *)strdup("CRITICAL"); + else + *output = (char *)strdup("UNKNOWN"); + break; + case MACRO_SERVICESTATEID: + asprintf(output, "%d", temp_service->current_state); + break; + case MACRO_LASTSERVICESTATE: + if(temp_service->last_state == STATE_OK) + *output = (char *)strdup("OK"); + else if(temp_service->last_state == STATE_WARNING) + *output = (char *)strdup("WARNING"); + else if(temp_service->last_state == STATE_CRITICAL) + *output = (char *)strdup("CRITICAL"); + else + *output = (char *)strdup("UNKNOWN"); + break; + case MACRO_LASTSERVICESTATEID: + asprintf(output, "%d", temp_service->last_state); + break; +#endif + case MACRO_SERVICEISVOLATILE: + asprintf(output, "%d", temp_service->is_volatile); + break; +#ifdef NSCORE + case MACRO_SERVICEATTEMPT: + asprintf(output, "%d", temp_service->current_attempt); + break; + case MACRO_MAXSERVICEATTEMPTS: + asprintf(output, "%d", temp_service->max_attempts); + break; + case MACRO_SERVICEEXECUTIONTIME: + asprintf(output, "%.3f", temp_service->execution_time); + break; + case MACRO_SERVICELATENCY: + asprintf(output, "%.3f", temp_service->latency); + break; + case MACRO_LASTSERVICECHECK: + asprintf(output, "%lu", (unsigned long)temp_service->last_check); + break; + case MACRO_LASTSERVICESTATECHANGE: + asprintf(output, "%lu", (unsigned long)temp_service->last_state_change); + break; + case MACRO_LASTSERVICEOK: + asprintf(output, "%lu", (unsigned long)temp_service->last_time_ok); + break; + case MACRO_LASTSERVICEWARNING: + asprintf(output, "%lu", (unsigned long)temp_service->last_time_warning); + break; + case MACRO_LASTSERVICEUNKNOWN: + asprintf(output, "%lu", (unsigned long)temp_service->last_time_unknown); + break; + case MACRO_LASTSERVICECRITICAL: + asprintf(output, "%lu", (unsigned long)temp_service->last_time_critical); + break; + case MACRO_SERVICEDOWNTIME: + asprintf(output, "%d", temp_service->scheduled_downtime_depth); + break; + case MACRO_SERVICEPERCENTCHANGE: + asprintf(output, "%.2f", temp_service->percent_state_change); + break; + case MACRO_SERVICEDURATIONSEC: + case MACRO_SERVICEDURATION: + + time(¤t_time); + duration = (unsigned long)(current_time - temp_service->last_state_change); + + /* get the state duration in seconds */ + if(macro_type == MACRO_SERVICEDURATIONSEC) + asprintf(output, "%lu", duration); + + /* get the state duration */ + else { + days = duration / 86400; + duration -= (days * 86400); + hours = duration / 3600; + duration -= (hours * 3600); + minutes = duration / 60; + duration -= (minutes * 60); + seconds = duration; + asprintf(output, "%dd %dh %dm %ds", days, hours, minutes, seconds); + } + break; + case MACRO_SERVICENOTIFICATIONNUMBER: + asprintf(output, "%d", temp_service->current_notification_number); + break; + case MACRO_SERVICENOTIFICATIONID: + asprintf(output, "%lu", temp_service->current_notification_id); + break; + case MACRO_SERVICEEVENTID: + asprintf(output, "%lu", temp_service->current_event_id); + break; + case MACRO_LASTSERVICEEVENTID: + asprintf(output, "%lu", temp_service->last_event_id); + break; + case MACRO_SERVICEPROBLEMID: + asprintf(output, "%lu", temp_service->current_problem_id); + break; + case MACRO_LASTSERVICEPROBLEMID: + asprintf(output, "%lu", temp_service->last_problem_id); + break; +#endif + case MACRO_SERVICEACTIONURL: + if(temp_service->action_url) + *output = (char *)strdup(temp_service->action_url); + break; + case MACRO_SERVICENOTESURL: + if(temp_service->notes_url) + *output = (char *)strdup(temp_service->notes_url); + break; + case MACRO_SERVICENOTES: + if(temp_service->notes) + *output = (char *)strdup(temp_service->notes); + break; +#ifdef NSCORE + case MACRO_SERVICEGROUPNAMES: + /* find all servicegroups this service is associated with */ + for(temp_objectlist = temp_service->servicegroups_ptr; temp_objectlist != NULL; temp_objectlist = temp_objectlist->next) { + + if((temp_servicegroup = (servicegroup *)temp_objectlist->object_ptr) == NULL) + continue; + + asprintf(&buf1, "%s%s%s", (buf2) ? buf2 : "", (buf2) ? "," : "", temp_servicegroup->group_name); + my_free(buf2); + buf2 = buf1; + } + if(buf2) { + *output = (char *)strdup(buf2); + my_free(buf2); + } + break; +#endif + /***************/ + /* MISC MACROS */ + /***************/ + case MACRO_SERVICEACKAUTHOR: + case MACRO_SERVICEACKAUTHORNAME: + case MACRO_SERVICEACKAUTHORALIAS: + case MACRO_SERVICEACKCOMMENT: + /* no need to do any more work - these are already precomputed elsewhere */ + /* NOTE: these macros won't work as on-demand macros */ + *output = mac->x[macro_type]; + *free_macro = FALSE; + break; + + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED SERVICE MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + break; + } + + /* post-processing */ + /* notes, notes URL and action URL macros may themselves contain macros, so process them... */ + switch(macro_type) { + case MACRO_SERVICEACTIONURL: + case MACRO_SERVICENOTESURL: + process_macros_r(mac, *output, &temp_buffer, URL_ENCODE_MACRO_CHARS); + my_free(*output); + *output = temp_buffer; + break; + case MACRO_SERVICENOTES: + process_macros_r(mac, *output, &temp_buffer, 0); + my_free(*output); + *output = temp_buffer; + break; + default: + break; + } + + return OK; + } + +int grab_standard_service_macro(int macro_type, service *temp_service, char **output, int *free_macro) { + return grab_standard_service_macro_r(&global_macros, macro_type, temp_service, output, free_macro); + } + + +/* computes a servicegroup macro */ +int grab_standard_servicegroup_macro_r(nagios_macros *mac, int macro_type, servicegroup *temp_servicegroup, char **output) { + servicesmember *temp_servicesmember = NULL; + char *temp_buffer = NULL; + unsigned int temp_len = 0; + unsigned int init_len = 0; + + if(temp_servicegroup == NULL || output == NULL) + return ERROR; + + /* get the macro value */ + switch(macro_type) { + case MACRO_SERVICEGROUPNAME: + *output = (char *)strdup(temp_servicegroup->group_name); + break; + case MACRO_SERVICEGROUPALIAS: + if(temp_servicegroup->alias) + *output = (char *)strdup(temp_servicegroup->alias); + break; + case MACRO_SERVICEGROUPMEMBERS: + /* make the calculations for total string length */ + for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if(temp_servicesmember->host_name == NULL || temp_servicesmember->service_description == NULL) + continue; + if(temp_len == 0) { + temp_len += strlen(temp_servicesmember->host_name) + strlen(temp_servicesmember->service_description) + 2; + } + else { + temp_len += strlen(temp_servicesmember->host_name) + strlen(temp_servicesmember->service_description) + 3; + } + } + /* allocate or reallocate the memory buffer */ + if(*output == NULL) { + *output = (char *)malloc(temp_len); + } + else { + init_len = strlen(*output); + temp_len += init_len; + *output = (char *)realloc(*output, temp_len); + } + /* now fill in the string with the group members */ + for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { + if(temp_servicesmember->host_name == NULL || temp_servicesmember->service_description == NULL) + continue; + temp_buffer = *output + init_len; + if(init_len == 0) { /* If our buffer didn't contain anything, we just need to write "%s,%s" */ + init_len += sprintf(temp_buffer, "%s,%s", temp_servicesmember->host_name, temp_servicesmember->service_description); + } + else { /* Now we need to write ",%s,%s" */ + init_len += sprintf(temp_buffer, ",%s,%s", temp_servicesmember->host_name, temp_servicesmember->service_description); + } + } + break; + case MACRO_SERVICEGROUPACTIONURL: + if(temp_servicegroup->action_url) + *output = (char *)strdup(temp_servicegroup->action_url); + break; + case MACRO_SERVICEGROUPNOTESURL: + if(temp_servicegroup->notes_url) + *output = (char *)strdup(temp_servicegroup->notes_url); + break; + case MACRO_SERVICEGROUPNOTES: + if(temp_servicegroup->notes) + *output = (char *)strdup(temp_servicegroup->notes); + break; + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED SERVICEGROUP MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + } + + /* post-processing */ + /* notes, notes URL and action URL macros may themselves contain macros, so process them... */ + switch(macro_type) { + case MACRO_SERVICEGROUPACTIONURL: + case MACRO_SERVICEGROUPNOTESURL: + process_macros_r(mac, *output, &temp_buffer, URL_ENCODE_MACRO_CHARS); + my_free(*output); + *output = temp_buffer; + break; + case MACRO_SERVICEGROUPNOTES: + process_macros_r(mac, *output, &temp_buffer, 0); + my_free(*output); + *output = temp_buffer; + break; + default: + break; + } + + return OK; + } + +int grab_standard_servicegroup_macro(int macro_type, servicegroup *temp_servicegroup, char **output) { + return grab_standard_servicegroup_macro_r(&global_macros, macro_type, temp_servicegroup, output); + } + + +/* computes a contact macro */ +int grab_standard_contact_macro_r(nagios_macros *mac, int macro_type, contact *temp_contact, char **output) { +#ifdef NSCORE + contactgroup *temp_contactgroup = NULL; + objectlist *temp_objectlist = NULL; + char *buf1 = NULL; + char *buf2 = NULL; +#endif + + if(temp_contact == NULL || output == NULL) + return ERROR; + + /* get the macro value */ + switch(macro_type) { + case MACRO_CONTACTNAME: + *output = (char *)strdup(temp_contact->name); + break; + case MACRO_CONTACTALIAS: + *output = (char *)strdup(temp_contact->alias); + break; + case MACRO_CONTACTEMAIL: + if(temp_contact->email) + *output = (char *)strdup(temp_contact->email); + break; + case MACRO_CONTACTPAGER: + if(temp_contact->pager) + *output = (char *)strdup(temp_contact->pager); + break; +#ifdef NSCORE + case MACRO_CONTACTGROUPNAMES: + /* get the contactgroup names */ + /* find all contactgroups this contact is a member of */ + for(temp_objectlist = temp_contact->contactgroups_ptr; temp_objectlist != NULL; temp_objectlist = temp_objectlist->next) { + + if((temp_contactgroup = (contactgroup *)temp_objectlist->object_ptr) == NULL) + continue; + + asprintf(&buf1, "%s%s%s", (buf2) ? buf2 : "", (buf2) ? "," : "", temp_contactgroup->group_name); + my_free(buf2); + buf2 = buf1; + } + if(buf2) { + *output = (char *)strdup(buf2); + my_free(buf2); + } + break; +#endif + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED CONTACT MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + } + + return OK; + } + +int grab_standard_contact_macro(int macro_type, contact *temp_contact, char **output) { + return grab_standard_contact_macro_r(&global_macros, macro_type, temp_contact, output); + } + + +/* computes a contact address macro */ +int grab_contact_address_macro(int macro_num, contact *temp_contact, char **output) { + if(macro_num < 0 || macro_num >= MAX_CONTACT_ADDRESSES) + return ERROR; + + if(temp_contact == NULL || output == NULL) + return ERROR; + + /* get the macro */ + if(temp_contact->address[macro_num]) + *output = temp_contact->address[macro_num]; + + return OK; + } + + + +/* computes a contactgroup macro */ +int grab_standard_contactgroup_macro(int macro_type, contactgroup *temp_contactgroup, char **output) { + contactsmember *temp_contactsmember = NULL; + + if(temp_contactgroup == NULL || output == NULL) + return ERROR; + + /* get the macro value */ + switch(macro_type) { + case MACRO_CONTACTGROUPNAME: + *output = (char *)strdup(temp_contactgroup->group_name); + break; + case MACRO_CONTACTGROUPALIAS: + if(temp_contactgroup->alias) + *output = (char *)strdup(temp_contactgroup->alias); + break; + case MACRO_CONTACTGROUPMEMBERS: + /* get the member list */ + for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { + if(temp_contactsmember->contact_name == NULL) + continue; + if(*output == NULL) + *output = (char *)strdup(temp_contactsmember->contact_name); + else if((*output = (char *)realloc(*output, strlen(*output) + strlen(temp_contactsmember->contact_name) + 2))) { + strcat(*output, ","); + strcat(*output, temp_contactsmember->contact_name); + } + } + break; + default: + log_debug_info(DEBUGL_MACROS, 0, "UNHANDLED CONTACTGROUP MACRO #%d! THIS IS A BUG!\n", macro_type); + return ERROR; + } + + return OK; + } + + +/* computes a custom object macro */ +int grab_custom_object_macro_r(nagios_macros *mac, char *macro_name, customvariablesmember *vars, char **output) { + customvariablesmember *temp_customvariablesmember = NULL; + int result = ERROR; + + if(macro_name == NULL || vars == NULL || output == NULL) + return ERROR; + + /* get the custom variable */ + for(temp_customvariablesmember = vars; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + + if(temp_customvariablesmember->variable_name == NULL) + continue; + + if(!strcmp(macro_name, temp_customvariablesmember->variable_name)) { + if(temp_customvariablesmember->variable_value) + *output = (char *)strdup(temp_customvariablesmember->variable_value); + result = OK; + break; + } + } + + return result; + } + +int grab_custom_object_macro(char *macro_name, customvariablesmember *vars, char **output) { + return grab_custom_object_macro_r(&global_macros, macro_name, vars, output); + } + + +/******************************************************************/ +/********************* MACRO STRING FUNCTIONS *********************/ +/******************************************************************/ + +/* cleans illegal characters in macros before output */ +char *clean_macro_chars(char *macro, int options) { + register int x = 0; + register int y = 0; + register int z = 0; + register int ch = 0; + register int len = 0; + register int illegal_char = 0; + + if(macro == NULL) + return ""; + + len = (int)strlen(macro); + + /* strip illegal characters out of macro */ + if(options & STRIP_ILLEGAL_MACRO_CHARS) { + + for(y = 0, x = 0; x < len; x++) { + + /*ch=(int)macro[x];*/ + /* allow non-ASCII characters (Japanese, etc) */ + ch = macro[x] & 0xff; + + /* illegal ASCII characters */ + if(ch < 32 || ch == 127) + continue; + + /* illegal user-specified characters */ + illegal_char = FALSE; + if(illegal_output_chars != NULL) { + for(z = 0; illegal_output_chars[z] != '\x0'; z++) { + if(ch == (int)illegal_output_chars[z]) { + illegal_char = TRUE; + break; + } + } + } + + if(illegal_char == FALSE) + macro[y++] = macro[x]; + } + + macro[y++] = '\x0'; + } + +#ifdef ON_HOLD_FOR_NOW + /* escape nasty character in macro */ + if(options & ESCAPE_MACRO_CHARS) { + } +#endif + + return macro; + } + + + +/* encodes a string in proper URL format */ +char *get_url_encoded_string(char *input) { + register int x = 0; + register int y = 0; + char *encoded_url_string = NULL; + char temp_expansion[6] = ""; + + + /* bail if no input */ + if(input == NULL) + return NULL; + + /* allocate enough memory to escape all characters if necessary */ + if((encoded_url_string = (char *)malloc((strlen(input) * 3) + 1)) == NULL) + return NULL; + + /* check/encode all characters */ + for(x = 0, y = 0; input[x] != (char)'\x0'; x++) { + + /* alpha-numeric characters and a few other characters don't get encoded */ + if(((char)input[x] >= '0' && (char)input[x] <= '9') || ((char)input[x] >= 'A' && (char)input[x] <= 'Z') || ((char)input[x] >= (char)'a' && (char)input[x] <= (char)'z') || (char)input[x] == (char)'.' || (char)input[x] == (char)'-' || (char)input[x] == (char)'_' || (char)input[x] == (char)':' || (char)input[x] == (char)'/' || (char)input[x] == (char)'?' || (char)input[x] == (char)'=' || (char)input[x] == (char)'&') { + encoded_url_string[y] = input[x]; + y++; + } + + /* spaces are pluses */ + else if((char)input[x] <= (char)' ') { + encoded_url_string[y] = '+'; + y++; + } + + /* anything else gets represented by its hex value */ + else { + encoded_url_string[y] = '\x0'; + sprintf(temp_expansion, "%%%02X", (unsigned int)(input[x] & 0xFF)); + strcat(encoded_url_string, temp_expansion); + y += 3; + } + } + + /* terminate encoded string */ + encoded_url_string[y] = '\x0'; + + return encoded_url_string; + } + + +static int macro_key_cmp(const void *a_, const void *b_) { + struct macro_key_code *a = (struct macro_key_code *)a_; + struct macro_key_code *b = (struct macro_key_code *)b_; + + return strcmp(a->name, b->name); + } + + +/******************************************************************/ +/***************** MACRO INITIALIZATION FUNCTIONS *****************/ +/******************************************************************/ + +/* initializes global macros */ +int init_macros(void) { + init_macrox_names(); + int x; + + /* + * non-volatile macros are free()'d when they're set. + * We must do this in order to not lose the constant + * ones when we get SIGHUP or a RESTART_PROGRAM event + * from the command fifo. Otherwise a memset() would + * have been better. + */ + clear_volatile_macros_r(&global_macros); + + /* backwards compatibility hack */ + macro_x = global_macros.x; + + /* + * Now build an ordered list of X macro names so we can + * do binary lookups later and avoid a ton of strcmp()'s + * for each and every check that gets run. A hash table + * is actually slower, since the most frequently used + * keys are so long and a binary lookup is completed in + * 7 steps for up to ~200 keys, worst case. + */ + for(x = 0; x < MACRO_X_COUNT; x++) { + macro_keys[x].code = x; + macro_keys[x].name = macro_x_names[x]; + macro_keys[x].clean_options = 0; + + /* host/service output/perfdata and author/comment macros should get cleaned */ + if((x >= 16 && x <= 19) || (x >= 49 && x <= 52) || (x >= 99 && x <= 100) || (x >= 124 && x <= 127)) { + macro_keys[x].clean_options = (STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS); + } + /* url macros should get cleaned */ + if((x >= 125 && x <= 126) || (x >= 128 && x <= 129) || (x >= 77 && x <= 78) || (x >= 74 && x <= 75)) { + macro_keys[x].clean_options = URL_ENCODE_MACRO_CHARS; + } + } + + qsort(macro_keys, x, sizeof(struct macro_key_code), macro_key_cmp); + return OK; + } + +/* + * initializes the names of macros, using this nifty little macro + * which ensures we never add any typos to the list + */ +#define add_macrox_name(name) macro_x_names[MACRO_##name] = strdup(#name) +int init_macrox_names(void) { + register int x = 0; + + /* initialize macro names */ + for(x = 0; x < MACRO_X_COUNT; x++) + macro_x_names[x] = NULL; + + /* initialize each macro name */ + add_macrox_name(HOSTNAME); + add_macrox_name(HOSTALIAS); + add_macrox_name(HOSTADDRESS); + add_macrox_name(SERVICEDESC); + add_macrox_name(SERVICESTATE); + add_macrox_name(SERVICESTATEID); + add_macrox_name(SERVICEATTEMPT); + add_macrox_name(SERVICEISVOLATILE); + add_macrox_name(LONGDATETIME); + add_macrox_name(SHORTDATETIME); + add_macrox_name(DATE); + add_macrox_name(TIME); + add_macrox_name(TIMET); + add_macrox_name(LASTHOSTCHECK); + add_macrox_name(LASTSERVICECHECK); + add_macrox_name(LASTHOSTSTATECHANGE); + add_macrox_name(LASTSERVICESTATECHANGE); + add_macrox_name(HOSTOUTPUT); + add_macrox_name(SERVICEOUTPUT); + add_macrox_name(HOSTPERFDATA); + add_macrox_name(SERVICEPERFDATA); + add_macrox_name(CONTACTNAME); + add_macrox_name(CONTACTALIAS); + add_macrox_name(CONTACTEMAIL); + add_macrox_name(CONTACTPAGER); + add_macrox_name(ADMINEMAIL); + add_macrox_name(ADMINPAGER); + add_macrox_name(HOSTSTATE); + add_macrox_name(HOSTSTATEID); + add_macrox_name(HOSTATTEMPT); + add_macrox_name(NOTIFICATIONTYPE); + add_macrox_name(NOTIFICATIONNUMBER); + add_macrox_name(NOTIFICATIONISESCALATED); + add_macrox_name(HOSTEXECUTIONTIME); + add_macrox_name(SERVICEEXECUTIONTIME); + add_macrox_name(HOSTLATENCY); + add_macrox_name(SERVICELATENCY); + add_macrox_name(HOSTDURATION); + add_macrox_name(SERVICEDURATION); + add_macrox_name(HOSTDURATIONSEC); + add_macrox_name(SERVICEDURATIONSEC); + add_macrox_name(HOSTDOWNTIME); + add_macrox_name(SERVICEDOWNTIME); + add_macrox_name(HOSTSTATETYPE); + add_macrox_name(SERVICESTATETYPE); + add_macrox_name(HOSTPERCENTCHANGE); + add_macrox_name(SERVICEPERCENTCHANGE); + add_macrox_name(HOSTGROUPNAME); + add_macrox_name(HOSTGROUPALIAS); + add_macrox_name(SERVICEGROUPNAME); + add_macrox_name(SERVICEGROUPALIAS); + add_macrox_name(HOSTACKAUTHOR); + add_macrox_name(HOSTACKCOMMENT); + add_macrox_name(SERVICEACKAUTHOR); + add_macrox_name(SERVICEACKCOMMENT); + add_macrox_name(LASTSERVICEOK); + add_macrox_name(LASTSERVICEWARNING); + add_macrox_name(LASTSERVICEUNKNOWN); + add_macrox_name(LASTSERVICECRITICAL); + add_macrox_name(LASTHOSTUP); + add_macrox_name(LASTHOSTDOWN); + add_macrox_name(LASTHOSTUNREACHABLE); + add_macrox_name(SERVICECHECKCOMMAND); + add_macrox_name(HOSTCHECKCOMMAND); + add_macrox_name(MAINCONFIGFILE); + add_macrox_name(STATUSDATAFILE); + add_macrox_name(HOSTDISPLAYNAME); + add_macrox_name(SERVICEDISPLAYNAME); + add_macrox_name(RETENTIONDATAFILE); + add_macrox_name(OBJECTCACHEFILE); + add_macrox_name(TEMPFILE); + add_macrox_name(LOGFILE); + add_macrox_name(RESOURCEFILE); + add_macrox_name(COMMANDFILE); + add_macrox_name(HOSTPERFDATAFILE); + add_macrox_name(SERVICEPERFDATAFILE); + add_macrox_name(HOSTACTIONURL); + add_macrox_name(HOSTNOTESURL); + add_macrox_name(HOSTNOTES); + add_macrox_name(SERVICEACTIONURL); + add_macrox_name(SERVICENOTESURL); + add_macrox_name(SERVICENOTES); + add_macrox_name(TOTALHOSTSUP); + add_macrox_name(TOTALHOSTSDOWN); + add_macrox_name(TOTALHOSTSUNREACHABLE); + add_macrox_name(TOTALHOSTSDOWNUNHANDLED); + add_macrox_name(TOTALHOSTSUNREACHABLEUNHANDLED); + add_macrox_name(TOTALHOSTPROBLEMS); + add_macrox_name(TOTALHOSTPROBLEMSUNHANDLED); + add_macrox_name(TOTALSERVICESOK); + add_macrox_name(TOTALSERVICESWARNING); + add_macrox_name(TOTALSERVICESCRITICAL); + add_macrox_name(TOTALSERVICESUNKNOWN); + add_macrox_name(TOTALSERVICESWARNINGUNHANDLED); + add_macrox_name(TOTALSERVICESCRITICALUNHANDLED); + add_macrox_name(TOTALSERVICESUNKNOWNUNHANDLED); + add_macrox_name(TOTALSERVICEPROBLEMS); + add_macrox_name(TOTALSERVICEPROBLEMSUNHANDLED); + add_macrox_name(PROCESSSTARTTIME); + add_macrox_name(HOSTCHECKTYPE); + add_macrox_name(SERVICECHECKTYPE); + add_macrox_name(LONGHOSTOUTPUT); + add_macrox_name(LONGSERVICEOUTPUT); + add_macrox_name(TEMPPATH); + add_macrox_name(HOSTNOTIFICATIONNUMBER); + add_macrox_name(SERVICENOTIFICATIONNUMBER); + add_macrox_name(HOSTNOTIFICATIONID); + add_macrox_name(SERVICENOTIFICATIONID); + add_macrox_name(HOSTEVENTID); + add_macrox_name(LASTHOSTEVENTID); + add_macrox_name(SERVICEEVENTID); + add_macrox_name(LASTSERVICEEVENTID); + add_macrox_name(HOSTGROUPNAMES); + add_macrox_name(SERVICEGROUPNAMES); + add_macrox_name(HOSTACKAUTHORNAME); + add_macrox_name(HOSTACKAUTHORALIAS); + add_macrox_name(SERVICEACKAUTHORNAME); + add_macrox_name(SERVICEACKAUTHORALIAS); + add_macrox_name(MAXHOSTATTEMPTS); + add_macrox_name(MAXSERVICEATTEMPTS); + add_macrox_name(TOTALHOSTSERVICES); + add_macrox_name(TOTALHOSTSERVICESOK); + add_macrox_name(TOTALHOSTSERVICESWARNING); + add_macrox_name(TOTALHOSTSERVICESUNKNOWN); + add_macrox_name(TOTALHOSTSERVICESCRITICAL); + add_macrox_name(HOSTGROUPNOTES); + add_macrox_name(HOSTGROUPNOTESURL); + add_macrox_name(HOSTGROUPACTIONURL); + add_macrox_name(SERVICEGROUPNOTES); + add_macrox_name(SERVICEGROUPNOTESURL); + add_macrox_name(SERVICEGROUPACTIONURL); + add_macrox_name(HOSTGROUPMEMBERS); + add_macrox_name(SERVICEGROUPMEMBERS); + add_macrox_name(CONTACTGROUPNAME); + add_macrox_name(CONTACTGROUPALIAS); + add_macrox_name(CONTACTGROUPMEMBERS); + add_macrox_name(CONTACTGROUPNAMES); + add_macrox_name(NOTIFICATIONRECIPIENTS); + add_macrox_name(NOTIFICATIONAUTHOR); + add_macrox_name(NOTIFICATIONAUTHORNAME); + add_macrox_name(NOTIFICATIONAUTHORALIAS); + add_macrox_name(NOTIFICATIONCOMMENT); + add_macrox_name(EVENTSTARTTIME); + add_macrox_name(HOSTPROBLEMID); + add_macrox_name(LASTHOSTPROBLEMID); + add_macrox_name(SERVICEPROBLEMID); + add_macrox_name(LASTSERVICEPROBLEMID); + add_macrox_name(ISVALIDTIME); + add_macrox_name(NEXTVALIDTIME); + add_macrox_name(LASTHOSTSTATE); + add_macrox_name(LASTHOSTSTATEID); + add_macrox_name(LASTSERVICESTATE); + add_macrox_name(LASTSERVICESTATEID); + + return OK; + } + + +/******************************************************************/ +/********************* MACRO CLEANUP FUNCTIONS ********************/ +/******************************************************************/ + +/* free memory associated with the macrox names */ +int free_macrox_names(void) { + register int x = 0; + + /* free each macro name */ + for(x = 0; x < MACRO_X_COUNT; x++) + my_free(macro_x_names[x]); + + return OK; + } + + + +/* clear argv macros - used in commands */ +int clear_argv_macros_r(nagios_macros *mac) { + register int x = 0; + + /* command argument macros */ + for(x = 0; x < MAX_COMMAND_ARGUMENTS; x++) + my_free(mac->argv[x]); + + return OK; + } + +int clear_argv_macros(void) { + return clear_argv_macros_r(&global_macros); + } + +/* + * copies non-volatile macros from global macro_x to **dest, which + * must be large enough to hold at least MACRO_X_COUNT entries. + * We use a shortlived macro to save up on typing + */ +#define cp_macro(name) dest[MACRO_##name] = global_macros.x[MACRO_##name] +void copy_constant_macros(char **dest) { + cp_macro(ADMINEMAIL); + cp_macro(ADMINPAGER); + cp_macro(MAINCONFIGFILE); + cp_macro(STATUSDATAFILE); + cp_macro(RETENTIONDATAFILE); + cp_macro(OBJECTCACHEFILE); + cp_macro(TEMPFILE); + cp_macro(LOGFILE); + cp_macro(RESOURCEFILE); + cp_macro(COMMANDFILE); + cp_macro(HOSTPERFDATAFILE); + cp_macro(SERVICEPERFDATAFILE); + cp_macro(PROCESSSTARTTIME); + cp_macro(TEMPPATH); + cp_macro(EVENTSTARTTIME); + } +#undef cp_macro + +/* clear all macros that are not "constant" (i.e. they change throughout the course of monitoring) */ +int clear_volatile_macros_r(nagios_macros *mac) { + customvariablesmember *this_customvariablesmember = NULL; + customvariablesmember *next_customvariablesmember = NULL; + register int x = 0; + + for(x = 0; x < MACRO_X_COUNT; x++) { + switch(x) { + + case MACRO_ADMINEMAIL: + case MACRO_ADMINPAGER: + case MACRO_MAINCONFIGFILE: + case MACRO_STATUSDATAFILE: + case MACRO_RETENTIONDATAFILE: + case MACRO_OBJECTCACHEFILE: + case MACRO_TEMPFILE: + case MACRO_LOGFILE: + case MACRO_RESOURCEFILE: + case MACRO_COMMANDFILE: + case MACRO_HOSTPERFDATAFILE: + case MACRO_SERVICEPERFDATAFILE: + case MACRO_PROCESSSTARTTIME: + case MACRO_TEMPPATH: + case MACRO_EVENTSTARTTIME: + /* these don't change during the course of monitoring, so no need to free them */ + break; + default: + my_free(mac->x[x]); + break; + } + } + + /* contact address macros */ + for(x = 0; x < MAX_CONTACT_ADDRESSES; x++) + my_free(mac->contactaddress[x]); + + /* clear macro pointers */ + mac->host_ptr = NULL; + mac->hostgroup_ptr = NULL; + mac->service_ptr = NULL; + mac->servicegroup_ptr = NULL; + mac->contact_ptr = NULL; + mac->contactgroup_ptr = NULL; + + /* clear on-demand macro */ + my_free(mac->ondemand); + + /* clear ARGx macros */ + clear_argv_macros_r(mac); + + /* clear custom host variables */ + for(this_customvariablesmember = mac->custom_host_vars; this_customvariablesmember != NULL; this_customvariablesmember = next_customvariablesmember) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + } + mac->custom_host_vars = NULL; + + /* clear custom service variables */ + for(this_customvariablesmember = mac->custom_service_vars; this_customvariablesmember != NULL; this_customvariablesmember = next_customvariablesmember) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + } + mac->custom_service_vars = NULL; + + /* clear custom contact variables */ + for(this_customvariablesmember = mac->custom_contact_vars; this_customvariablesmember != NULL; this_customvariablesmember = next_customvariablesmember) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + } + mac->custom_contact_vars = NULL; + + return OK; + } + + +int clear_volatile_macros(void) { + return clear_volatile_macros_r(&global_macros); + } + + +/* clear service macros */ +int clear_service_macros_r(nagios_macros *mac) { + customvariablesmember *this_customvariablesmember = NULL; + customvariablesmember *next_customvariablesmember = NULL; + + /* FIXME: strings. make these not be strdup()'s anymore */ + my_free(mac->x[MACRO_SERVICEDESC]); + my_free(mac->x[MACRO_SERVICEDISPLAYNAME]); + my_free(mac->x[MACRO_SERVICEOUTPUT]); + my_free(mac->x[MACRO_LONGSERVICEOUTPUT]); + my_free(mac->x[MACRO_SERVICEPERFDATA]); + + /* these are recursive but persistent. what to do? */ + my_free(mac->x[MACRO_SERVICECHECKCOMMAND]); + my_free(mac->x[MACRO_SERVICEACTIONURL]); + my_free(mac->x[MACRO_SERVICENOTESURL]); + my_free(mac->x[MACRO_SERVICENOTES]); + + my_free(mac->x[MACRO_SERVICECHECKTYPE]); + my_free(mac->x[MACRO_SERVICESTATETYPE]); + my_free(mac->x[MACRO_SERVICESTATE]); + my_free(mac->x[MACRO_SERVICEISVOLATILE]); + my_free(mac->x[MACRO_SERVICESTATEID]); + my_free(mac->x[MACRO_SERVICEATTEMPT]); + my_free(mac->x[MACRO_MAXSERVICEATTEMPTS]); + my_free(mac->x[MACRO_SERVICEEXECUTIONTIME]); + my_free(mac->x[MACRO_SERVICELATENCY]); + my_free(mac->x[MACRO_LASTSERVICECHECK]); + my_free(mac->x[MACRO_LASTSERVICESTATECHANGE]); + my_free(mac->x[MACRO_LASTSERVICEOK]); + my_free(mac->x[MACRO_LASTSERVICEWARNING]); + my_free(mac->x[MACRO_LASTSERVICEUNKNOWN]); + my_free(mac->x[MACRO_LASTSERVICECRITICAL]); + my_free(mac->x[MACRO_SERVICEDOWNTIME]); + my_free(mac->x[MACRO_SERVICEPERCENTCHANGE]); + my_free(mac->x[MACRO_SERVICEDURATIONSEC]); + my_free(mac->x[MACRO_SERVICEDURATION]); + my_free(mac->x[MACRO_SERVICENOTIFICATIONNUMBER]); + my_free(mac->x[MACRO_SERVICENOTIFICATIONID]); + my_free(mac->x[MACRO_SERVICEEVENTID]); + my_free(mac->x[MACRO_LASTSERVICEEVENTID]); + my_free(mac->x[MACRO_SERVICEGROUPNAMES]); + my_free(mac->x[MACRO_SERVICEPROBLEMID]); + my_free(mac->x[MACRO_LASTSERVICEPROBLEMID]); + + /* clear custom service variables */ + for(this_customvariablesmember = mac->custom_service_vars; this_customvariablesmember != NULL; this_customvariablesmember = next_customvariablesmember) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + } + mac->custom_service_vars = NULL; + + /* clear pointers */ + mac->service_ptr = NULL; + + return OK; + } + +int clear_service_macros(void) { + return clear_service_macros_r(&global_macros); + } + +/* clear host macros */ +int clear_host_macros_r(nagios_macros *mac) { + customvariablesmember *this_customvariablesmember = NULL; + customvariablesmember *next_customvariablesmember = NULL; + + /* FIXME: strings; Fix these to not be strdup()'s anymore */ + my_free(mac->x[MACRO_HOSTNAME]); + my_free(mac->x[MACRO_HOSTDISPLAYNAME]); + my_free(mac->x[MACRO_HOSTALIAS]); + my_free(mac->x[MACRO_HOSTADDRESS]); + my_free(mac->x[MACRO_HOSTOUTPUT]); + my_free(mac->x[MACRO_LONGHOSTOUTPUT]); + my_free(mac->x[MACRO_HOSTPERFDATA]); + + /* these are recursive but persistent. what to do? */ + my_free(mac->x[MACRO_HOSTCHECKCOMMAND]); + my_free(mac->x[MACRO_HOSTACTIONURL]); + my_free(mac->x[MACRO_HOSTNOTESURL]); + my_free(mac->x[MACRO_HOSTNOTES]); + + /* numbers or by necessity autogenerated strings */ + my_free(mac->x[MACRO_HOSTSTATE]); + my_free(mac->x[MACRO_HOSTSTATEID]); + my_free(mac->x[MACRO_HOSTCHECKTYPE]); + my_free(mac->x[MACRO_HOSTSTATETYPE]); + my_free(mac->x[MACRO_HOSTATTEMPT]); + my_free(mac->x[MACRO_MAXHOSTATTEMPTS]); + my_free(mac->x[MACRO_HOSTDOWNTIME]); + my_free(mac->x[MACRO_HOSTPERCENTCHANGE]); + my_free(mac->x[MACRO_HOSTDURATIONSEC]); + my_free(mac->x[MACRO_HOSTDURATION]); + my_free(mac->x[MACRO_HOSTEXECUTIONTIME]); + my_free(mac->x[MACRO_HOSTLATENCY]); + my_free(mac->x[MACRO_LASTHOSTCHECK]); + my_free(mac->x[MACRO_LASTHOSTSTATECHANGE]); + my_free(mac->x[MACRO_LASTHOSTUP]); + my_free(mac->x[MACRO_LASTHOSTDOWN]); + my_free(mac->x[MACRO_LASTHOSTUNREACHABLE]); + my_free(mac->x[MACRO_HOSTNOTIFICATIONNUMBER]); + my_free(mac->x[MACRO_HOSTNOTIFICATIONID]); + my_free(mac->x[MACRO_HOSTEVENTID]); + my_free(mac->x[MACRO_LASTHOSTEVENTID]); + my_free(mac->x[MACRO_HOSTGROUPNAMES]); + my_free(mac->x[MACRO_TOTALHOSTSERVICES]); + my_free(mac->x[MACRO_TOTALHOSTSERVICESOK]); + my_free(mac->x[MACRO_TOTALHOSTSERVICESWARNING]); + my_free(mac->x[MACRO_TOTALHOSTSERVICESUNKNOWN]); + my_free(mac->x[MACRO_TOTALHOSTSERVICESCRITICAL]); + my_free(mac->x[MACRO_HOSTPROBLEMID]); + my_free(mac->x[MACRO_LASTHOSTPROBLEMID]); + + + /* clear custom host variables */ + for(this_customvariablesmember = mac->custom_host_vars; this_customvariablesmember != NULL; this_customvariablesmember = next_customvariablesmember) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + } + mac->custom_host_vars = NULL; + + /* clear pointers */ + mac->host_ptr = NULL; + + return OK; + } + +int clear_host_macros(void) { + return clear_host_macros_r(&global_macros); + } + + +/* clear hostgroup macros */ +int clear_hostgroup_macros_r(nagios_macros *mac) { + /* FIXME: make these not strdup()'s */ + my_free(mac->x[MACRO_HOSTGROUPNAME]); + my_free(mac->x[MACRO_HOSTGROUPALIAS]); + + /* generated but persistent. what to do? */ + my_free(mac->x[MACRO_HOSTGROUPACTIONURL]); + my_free(mac->x[MACRO_HOSTGROUPNOTESURL]); + my_free(mac->x[MACRO_HOSTGROUPNOTES]); + + /* generated */ + my_free(mac->x[MACRO_HOSTGROUPMEMBERS]); + + /* clear pointers */ + mac->hostgroup_ptr = NULL; + + return OK; + } + +int clear_hostgroup_macros(void) { + return clear_hostgroup_macros_r(&global_macros); + } + + +/* clear servicegroup macros */ +int clear_servicegroup_macros_r(nagios_macros *mac) { + /* FIXME: these should not be strdup()'s */ + my_free(mac->x[MACRO_SERVICEGROUPNAME]); + my_free(mac->x[MACRO_SERVICEGROUPALIAS]); + + /* generated but persistent. what to do? */ + my_free(mac->x[MACRO_SERVICEGROUPACTIONURL]); + my_free(mac->x[MACRO_SERVICEGROUPNOTESURL]); + my_free(mac->x[MACRO_SERVICEGROUPNOTES]); + + /* generated */ + my_free(mac->x[MACRO_SERVICEGROUPMEMBERS]); + + /* clear pointers */ + mac->servicegroup_ptr = NULL; + + return OK; + } + +int clear_servicegroup_macros(void) { + return clear_servicegroup_macros_r(&global_macros); + } + + +/* clear contact macros */ +int clear_contact_macros_r(nagios_macros *mac) { + register int x; + customvariablesmember *this_customvariablesmember = NULL; + customvariablesmember *next_customvariablesmember = NULL; + + /* FIXME: these should not be strdup()'d */ + my_free(mac->x[MACRO_CONTACTNAME]); + my_free(mac->x[MACRO_CONTACTALIAS]); + my_free(mac->x[MACRO_CONTACTEMAIL]); + my_free(mac->x[MACRO_CONTACTPAGER]); + + /* generated per contact */ + my_free(mac->x[MACRO_CONTACTGROUPNAMES]); + + /* clear contact addresses */ + for(x = 0; x < MAX_CONTACT_ADDRESSES; x++) + my_free(mac->contactaddress[x]); + + /* clear custom contact variables */ + for(this_customvariablesmember = mac->custom_contact_vars; this_customvariablesmember != NULL; this_customvariablesmember = next_customvariablesmember) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + } + mac->custom_contact_vars = NULL; + + /* clear pointers */ + mac->contact_ptr = NULL; + + return OK; + } + +int clear_contact_macros(void) { + return clear_contact_macros_r(&global_macros); + } + + +/* clear contactgroup macros */ +int clear_contactgroup_macros_r(nagios_macros *mac) { + my_free(mac->x[MACRO_CONTACTGROUPNAME]); + my_free(mac->x[MACRO_CONTACTGROUPALIAS]); + my_free(mac->x[MACRO_CONTACTGROUPMEMBERS]); + + /* clear pointers */ + mac->contactgroup_ptr = NULL; + + return OK; + } + +int clear_contactgroup_macros(void) { + return clear_contactgroup_macros_r(&global_macros); + } + + +/* clear summary macros */ +int clear_summary_macros_r(nagios_macros *mac) { + register int x; + + for(x = MACRO_TOTALHOSTSUP; x <= MACRO_TOTALSERVICEPROBLEMSUNHANDLED; x++) + my_free(mac->x[x]); + + return OK; + } + +int clear_summary_macros(void) { + return clear_summary_macros_r(&global_macros); + } + + +/******************************************************************/ +/****************** ENVIRONMENT MACRO FUNCTIONS *******************/ +/******************************************************************/ + +#ifdef NSCORE + +/* sets or unsets all macro environment variables */ +int set_all_macro_environment_vars_r(nagios_macros *mac, int set) { + if(enable_environment_macros == FALSE) + return ERROR; + + set_macrox_environment_vars_r(mac, set); + set_argv_macro_environment_vars_r(mac, set); + set_custom_macro_environment_vars_r(mac, set); + set_contact_address_environment_vars_r(mac, set); + + return OK; + } + +int set_all_macro_environment_vars(int set) { + return set_all_macro_environment_vars_r(&global_macros, set); + } + + +/* sets or unsets macrox environment variables */ +int set_macrox_environment_vars_r(nagios_macros *mac, int set) { + register int x = 0; + int free_macro = FALSE; + int generate_macro = TRUE; + + /* set each of the macrox environment variables */ + for(x = 0; x < MACRO_X_COUNT; x++) { + + free_macro = FALSE; + + /* generate the macro value if it hasn't already been done */ + /* THIS IS EXPENSIVE */ + if(set == TRUE) { + + generate_macro = TRUE; + + /* skip summary macro generation if lage installation tweaks are enabled */ + if((x >= MACRO_TOTALHOSTSUP && x <= MACRO_TOTALSERVICEPROBLEMSUNHANDLED) && use_large_installation_tweaks == TRUE) + generate_macro = FALSE; + + if(mac->x[x] == NULL && generate_macro == TRUE) + grab_macrox_value_r(mac, x, NULL, NULL, &mac->x[x], &free_macro); + } + + /* set the value */ + set_macro_environment_var(macro_x_names[x], mac->x[x], set); + } + + return OK; + } + +int set_macrox_environment_vars(int set) { + return set_macrox_environment_vars_r(&global_macros, set); + } + + +/* sets or unsets argv macro environment variables */ +int set_argv_macro_environment_vars_r(nagios_macros *mac, int set) { + char *macro_name = NULL; + register int x = 0; + + /* set each of the argv macro environment variables */ + for(x = 0; x < MAX_COMMAND_ARGUMENTS; x++) { + asprintf(¯o_name, "ARG%d", x + 1); + set_macro_environment_var(macro_name, mac->argv[x], set); + my_free(macro_name); + } + + return OK; + } + +int set_argv_macro_environment_vars(int set) { + return set_argv_macro_environment_vars_r(&global_macros, set); + } + + +/* sets or unsets custom host/service/contact macro environment variables */ +int set_custom_macro_environment_vars_r(nagios_macros *mac, int set) { + customvariablesmember *temp_customvariablesmember = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + contact *temp_contact = NULL; + char *customvarname = NULL; + + /***** CUSTOM HOST VARIABLES *****/ + /* generate variables and save them for later */ + if((temp_host = mac->host_ptr) && set == TRUE) { + for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + asprintf(&customvarname, "_HOST%s", temp_customvariablesmember->variable_name); + add_custom_variable_to_object(&mac->custom_host_vars, customvarname, temp_customvariablesmember->variable_value); + my_free(customvarname); + } + } + /* set variables */ + for(temp_customvariablesmember = mac->custom_host_vars; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + set_macro_environment_var(temp_customvariablesmember->variable_name, clean_macro_chars(temp_customvariablesmember->variable_value, STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS), set); + } + + /***** CUSTOM SERVICE VARIABLES *****/ + /* generate variables and save them for later */ + if((temp_service = mac->service_ptr) && set == TRUE) { + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + asprintf(&customvarname, "_SERVICE%s", temp_customvariablesmember->variable_name); + add_custom_variable_to_object(&mac->custom_service_vars, customvarname, temp_customvariablesmember->variable_value); + my_free(customvarname); + } + } + /* set variables */ + for(temp_customvariablesmember = mac->custom_service_vars; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) + set_macro_environment_var(temp_customvariablesmember->variable_name, clean_macro_chars(temp_customvariablesmember->variable_value, STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS), set); + + /***** CUSTOM CONTACT VARIABLES *****/ + /* generate variables and save them for later */ + if((temp_contact = mac->contact_ptr) && set == TRUE) { + for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + asprintf(&customvarname, "_CONTACT%s", temp_customvariablesmember->variable_name); + add_custom_variable_to_object(&mac->custom_contact_vars, customvarname, temp_customvariablesmember->variable_value); + my_free(customvarname); + } + } + /* set variables */ + for(temp_customvariablesmember = mac->custom_contact_vars; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) + set_macro_environment_var(temp_customvariablesmember->variable_name, clean_macro_chars(temp_customvariablesmember->variable_value, STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS), set); + + return OK; + } + +int set_custom_macro_environment_vars(int set) { + return set_custom_macro_environment_vars_r(&global_macros, set); + } + + +/* sets or unsets contact address environment variables */ +int set_contact_address_environment_vars_r(nagios_macros *mac, int set) { + char *varname = NULL; + register int x; + + /* these only get set during notifications */ + if(mac->contact_ptr == NULL) + return OK; + + for(x = 0; x < MAX_CONTACT_ADDRESSES; x++) { + asprintf(&varname, "CONTACTADDRESS%d", x); + set_macro_environment_var(varname, mac->contact_ptr->address[x], set); + my_free(varname); + } + + return OK; + } + +int set_contact_address_environment_vars(int set) { + return set_contact_address_environment_vars_r(&global_macros, set); + } + + +/* sets or unsets a macro environment variable */ +int set_macro_environment_var(char *name, char *value, int set) { + char *env_macro_name = NULL; + + /* we won't mess with null variable names */ + if(name == NULL) + return ERROR; + + /* create environment var name */ + asprintf(&env_macro_name, "%s%s", MACRO_ENV_VAR_PREFIX, name); + + /* set or unset the environment variable */ + set_environment_var(env_macro_name, value, set); + + /* free allocated memory */ + my_free(env_macro_name); + + return OK; + } + + +#endif diff --git a/common/objects.c b/common/objects.c new file mode 100644 index 0000000..d16f75d --- /dev/null +++ b/common/objects.c @@ -0,0 +1,3613 @@ +/***************************************************************************** + * + * OBJECTS.C - Object addition and search functions for Nagios + * + * 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/skiplist.h" + +#ifdef NSCORE +#include "../include/nagios.h" +#endif + +#ifdef NSCGI +#include "../include/cgiutils.h" +#endif + +/**** IMPLEMENTATION-SPECIFIC HEADER FILES ****/ + +#ifdef USE_XODTEMPLATE /* template-based routines */ +#include "../xdata/xodtemplate.h" +#endif + + +host *host_list = NULL, *host_list_tail = NULL; +service *service_list = NULL, *service_list_tail = NULL; +contact *contact_list = NULL, *contact_list_tail = NULL; +contactgroup *contactgroup_list = NULL, *contactgroup_list_tail = NULL; +hostgroup *hostgroup_list = NULL, *hostgroup_list_tail = NULL; +servicegroup *servicegroup_list = NULL, *servicegroup_list_tail = NULL; +command *command_list = NULL, *command_list_tail = NULL; +timeperiod *timeperiod_list = NULL, *timeperiod_list_tail = NULL; +serviceescalation *serviceescalation_list = NULL, *serviceescalation_list_tail = NULL; +servicedependency *servicedependency_list = NULL, *servicedependency_list_tail = NULL; +hostdependency *hostdependency_list = NULL, *hostdependency_list_tail = NULL; +hostescalation *hostescalation_list = NULL, *hostescalation_list_tail = NULL; + +skiplist *object_skiplists[NUM_OBJECT_SKIPLISTS]; + + +#ifdef NSCORE +int __nagios_object_structure_version = CURRENT_OBJECT_STRUCTURE_VERSION; +extern int use_precached_objects; +#endif + + + +/******************************************************************/ +/******* TOP-LEVEL HOST CONFIGURATION DATA INPUT FUNCTION *********/ +/******************************************************************/ + + +/* read all host configuration data from external source */ +int read_object_config_data(char *main_config_file, int options, int cache, int precache) { + int result = OK; + + /* initialize object skiplists */ + init_object_skiplists(); + + /********* IMPLEMENTATION-SPECIFIC INPUT FUNCTION ********/ +#ifdef USE_XODTEMPLATE + /* read in data from all text host config files (template-based) */ + result = xodtemplate_read_config_data(main_config_file, options, cache, precache); + if(result != OK) + return ERROR; +#endif + + return result; + } + + + +/******************************************************************/ +/******************** SKIPLIST FUNCTIONS **************************/ +/******************************************************************/ + +int init_object_skiplists(void) { + int x = 0; + + for(x = 0; x < NUM_OBJECT_SKIPLISTS; x++) + object_skiplists[x] = NULL; + + object_skiplists[HOST_SKIPLIST] = skiplist_new(15, 0.5, FALSE, FALSE, skiplist_compare_host); + object_skiplists[SERVICE_SKIPLIST] = skiplist_new(15, 0.5, FALSE, FALSE, skiplist_compare_service); + + object_skiplists[COMMAND_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, skiplist_compare_command); + object_skiplists[TIMEPERIOD_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, skiplist_compare_timeperiod); + object_skiplists[CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, skiplist_compare_contact); + object_skiplists[CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, skiplist_compare_contactgroup); + object_skiplists[HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, skiplist_compare_hostgroup); + object_skiplists[SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, skiplist_compare_servicegroup); + + object_skiplists[HOSTESCALATION_SKIPLIST] = skiplist_new(15, 0.5, TRUE, FALSE, skiplist_compare_hostescalation); + object_skiplists[SERVICEESCALATION_SKIPLIST] = skiplist_new(15, 0.5, TRUE, FALSE, skiplist_compare_serviceescalation); + object_skiplists[HOSTDEPENDENCY_SKIPLIST] = skiplist_new(15, 0.5, TRUE, FALSE, skiplist_compare_hostdependency); + object_skiplists[SERVICEDEPENDENCY_SKIPLIST] = skiplist_new(15, 0.5, TRUE, FALSE, skiplist_compare_servicedependency); + + return OK; + } + + + +int free_object_skiplists(void) { + int x = 0; + + for(x = 0; x < NUM_OBJECT_SKIPLISTS; x++) + skiplist_free(&object_skiplists[x]); + + return OK; + } + + +int skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b) { + int result = 0; + + /* 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; + } + + +int skiplist_compare_host(void *a, void *b) { + host *oa = NULL; + host *ob = NULL; + + oa = (host *)a; + ob = (host *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + +int skiplist_compare_service(void *a, void *b) { + service *oa = NULL; + service *ob = NULL; + + oa = (service *)a; + ob = (service *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, oa->description, ob->host_name, ob->description); + } + + +int skiplist_compare_command(void *a, void *b) { + command *oa = NULL; + command *ob = NULL; + + oa = (command *)a; + ob = (command *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + +int skiplist_compare_timeperiod(void *a, void *b) { + timeperiod *oa = NULL; + timeperiod *ob = NULL; + + oa = (timeperiod *)a; + ob = (timeperiod *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + +int skiplist_compare_contact(void *a, void *b) { + contact *oa = NULL; + contact *ob = NULL; + + oa = (contact *)a; + ob = (contact *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + +int skiplist_compare_contactgroup(void *a, void *b) { + contactgroup *oa = NULL; + contactgroup *ob = NULL; + + oa = (contactgroup *)a; + ob = (contactgroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->group_name, NULL, ob->group_name, NULL); + } + + +int skiplist_compare_hostgroup(void *a, void *b) { + hostgroup *oa = NULL; + hostgroup *ob = NULL; + + oa = (hostgroup *)a; + ob = (hostgroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->group_name, NULL, ob->group_name, NULL); + } + + +int skiplist_compare_servicegroup(void *a, void *b) { + servicegroup *oa = NULL; + servicegroup *ob = NULL; + + oa = (servicegroup *)a; + ob = (servicegroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->group_name, NULL, ob->group_name, NULL); + } + + +int skiplist_compare_hostescalation(void *a, void *b) { + hostescalation *oa = NULL; + hostescalation *ob = NULL; + + oa = (hostescalation *)a; + ob = (hostescalation *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL); + } + + +int skiplist_compare_serviceescalation(void *a, void *b) { + serviceescalation *oa = NULL; + serviceescalation *ob = NULL; + + oa = (serviceescalation *)a; + ob = (serviceescalation *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, oa->description, ob->host_name, ob->description); + } + + +int skiplist_compare_hostdependency(void *a, void *b) { + hostdependency *oa = NULL; + hostdependency *ob = NULL; + + oa = (hostdependency *)a; + ob = (hostdependency *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->dependent_host_name, NULL, ob->dependent_host_name, NULL); + } + + +int skiplist_compare_servicedependency(void *a, void *b) { + servicedependency *oa = NULL; + servicedependency *ob = NULL; + + oa = (servicedependency *)a; + ob = (servicedependency *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->dependent_host_name, oa->dependent_service_description, ob->dependent_host_name, ob->dependent_service_description); + } + + +int get_host_count(void) { + + if(object_skiplists[HOST_SKIPLIST]) + return object_skiplists[HOST_SKIPLIST]->items; + + return 0; + } + + +int get_service_count(void) { + + if(object_skiplists[SERVICE_SKIPLIST]) + return object_skiplists[SERVICE_SKIPLIST]->items; + + return 0; + } + + + + +/******************************************************************/ +/**************** OBJECT ADDITION FUNCTIONS ***********************/ +/******************************************************************/ + + + +/* add a new timeperiod to the list in memory */ +timeperiod *add_timeperiod(char *name, char *alias) { + timeperiod *new_timeperiod = NULL; + int result = OK; + + /* make sure we have the data we need */ + if((name == NULL || !strcmp(name, "")) || (alias == NULL || !strcmp(alias, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Name or alias for timeperiod is NULL\n"); + return NULL; + } + + /* allocate memory for the new timeperiod */ + if((new_timeperiod = calloc(1, sizeof(timeperiod))) == NULL) + return NULL; + + /* copy string vars */ + if((new_timeperiod->name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_timeperiod->alias = (char *)strdup(alias)) == NULL) + result = ERROR; + + /* add new timeperiod to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[TIMEPERIOD_SKIPLIST], (void *)new_timeperiod); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Timeperiod '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add timeperiod '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_timeperiod->alias); + my_free(new_timeperiod->name); + my_free(new_timeperiod); + return NULL; + } + + /* timeperiods are registered alphabetically, so add new items to tail of list */ + if(timeperiod_list == NULL) { + timeperiod_list = new_timeperiod; + timeperiod_list_tail = timeperiod_list; + } + else { + timeperiod_list_tail->next = new_timeperiod; + timeperiod_list_tail = new_timeperiod; + } + + return new_timeperiod; + } + + + + +/* adds a new exclusion to a timeperiod */ +timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *period, char *name) { + timeperiodexclusion *new_timeperiodexclusion = NULL; + + /* make sure we have enough data */ + if(period == NULL || name == NULL) + return NULL; + + if((new_timeperiodexclusion = (timeperiodexclusion *)malloc(sizeof(timeperiodexclusion))) == NULL) + return NULL; + + new_timeperiodexclusion->timeperiod_name = (char *)strdup(name); + + new_timeperiodexclusion->next = period->exclusions; + period->exclusions = new_timeperiodexclusion; + + return new_timeperiodexclusion; + } + + + + +/* add a new timerange to a timeperiod */ +timerange *add_timerange_to_timeperiod(timeperiod *period, int day, unsigned long start_time, unsigned long end_time) { + timerange *new_timerange = NULL; + + /* make sure we have the data we need */ + if(period == NULL) + return NULL; + + if(day < 0 || day > 6) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Day %d is not valid for timeperiod '%s'\n", day, period->name); + return NULL; + } + if(start_time < 0 || start_time > 86400) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Start time %lu on day %d is not valid for timeperiod '%s'\n", start_time, day, period->name); + return NULL; + } + if(end_time < 0 || end_time > 86400) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: End time %lu on day %d is not value for timeperiod '%s'\n", end_time, day, period->name); + return NULL; + } + + /* allocate memory for the new time range */ + if((new_timerange = malloc(sizeof(timerange))) == NULL) + return NULL; + + new_timerange->range_start = start_time; + new_timerange->range_end = end_time; + + /* add the new time range to the head of the range list for this day */ + new_timerange->next = period->days[day]; + period->days[day] = new_timerange; + + return new_timerange; + } + + +/* add a new exception to a timeperiod */ +daterange *add_exception_to_timeperiod(timeperiod *period, int type, int syear, int smon, int smday, int swday, int swday_offset, int eyear, int emon, int emday, int ewday, int ewday_offset, int skip_interval) { + daterange *new_daterange = NULL; + + /* make sure we have the data we need */ + if(period == NULL) + return NULL; + + /* allocate memory for the date range range */ + if((new_daterange = malloc(sizeof(daterange))) == NULL) + return NULL; + + new_daterange->times = NULL; + new_daterange->next = NULL; + + new_daterange->type = type; + new_daterange->syear = syear; + new_daterange->smon = smon; + new_daterange->smday = smday; + new_daterange->swday = swday; + new_daterange->swday_offset = swday_offset; + new_daterange->eyear = eyear; + new_daterange->emon = emon; + new_daterange->emday = emday; + new_daterange->ewday = ewday; + new_daterange->ewday_offset = ewday_offset; + new_daterange->skip_interval = skip_interval; + + /* add the new date range to the head of the range list for this exception type */ + new_daterange->next = period->exceptions[type]; + period->exceptions[type] = new_daterange; + + return new_daterange; + } + + + +/* add a new timerange to a daterange */ +timerange *add_timerange_to_daterange(daterange *drange, unsigned long start_time, unsigned long end_time) { + timerange *new_timerange = NULL; + + /* make sure we have the data we need */ + if(drange == NULL) + return NULL; + + if(start_time < 0 || start_time > 86400) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Start time %lu is not valid for timeperiod\n", start_time); + return NULL; + } + if(end_time < 0 || end_time > 86400) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: End time %lu is not value for timeperiod\n", end_time); + return NULL; + } + + /* allocate memory for the new time range */ + if((new_timerange = malloc(sizeof(timerange))) == NULL) + return NULL; + + new_timerange->range_start = start_time; + new_timerange->range_end = end_time; + + /* add the new time range to the head of the range list for this date range */ + new_timerange->next = drange->times; + drange->times = new_timerange; + + return new_timerange; + } + + + +/* add a new host definition */ +host *add_host(char *name, char *display_name, char *alias, char *address, char *check_period, int initial_state, double check_interval, double retry_interval, int max_attempts, int notify_up, int notify_down, int notify_unreachable, int notify_flapping, int notify_downtime, double notification_interval, double first_notification_delay, char *notification_period, int notifications_enabled, char *check_command, int checks_enabled, int accept_passive_checks, char *event_handler, int event_handler_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_on_up, int flap_detection_on_down, int flap_detection_on_unreachable, int stalk_on_up, int stalk_on_down, int stalk_on_unreachable, int process_perfdata, int failure_prediction_enabled, char *failure_prediction_options, int check_freshness, int freshness_threshold, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt, char *vrml_image, char *statusmap_image, int x_2d, int y_2d, int have_2d_coords, double x_3d, double y_3d, double z_3d, int have_3d_coords, int should_be_drawn, int retain_status_information, int retain_nonstatus_information, int obsess_over_host) { + host *new_host = NULL; + int result = OK; +#ifdef NSCORE + int x = 0; +#endif + + /* make sure we have the data we need */ + if((name == NULL || !strcmp(name, "")) || (address == NULL || !strcmp(address, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host name or address is NULL\n"); + return NULL; + } + + /* check values */ + if(max_attempts <= 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid max_check_attempts value for host '%s'\n", name); + return NULL; + } + if(check_interval < 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid check_interval value for host '%s'\n", name); + return NULL; + } + if(notification_interval < 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification_interval value for host '%s'\n", name); + return NULL; + } + if(first_notification_delay < 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid first_notification_delay value for host '%s'\n", name); + return NULL; + } + if(freshness_threshold < 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid freshness_threshold value for host '%s'\n", name); + return NULL; + } + + /* allocate memory for a new host */ + if((new_host = (host *)calloc(1, sizeof(host))) == NULL) + return NULL; + + /* duplicate string vars */ + if((new_host->name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_host->display_name = (char *)strdup((display_name == NULL) ? name : display_name)) == NULL) + result = ERROR; + if((new_host->alias = (char *)strdup((alias == NULL) ? name : alias)) == NULL) + result = ERROR; + if((new_host->address = (char *)strdup(address)) == NULL) + result = ERROR; + if(check_period) { + if((new_host->check_period = (char *)strdup(check_period)) == NULL) + result = ERROR; + } + if(notification_period) { + if((new_host->notification_period = (char *)strdup(notification_period)) == NULL) + result = ERROR; + } + if(check_command) { + if((new_host->host_check_command = (char *)strdup(check_command)) == NULL) + result = ERROR; + } + if(event_handler) { + if((new_host->event_handler = (char *)strdup(event_handler)) == NULL) + result = ERROR; + } + if(failure_prediction_options) { + if((new_host->failure_prediction_options = (char *)strdup(failure_prediction_options)) == NULL) + result = ERROR; + } + if(notes) { + if((new_host->notes = (char *)strdup(notes)) == NULL) + result = ERROR; + } + if(notes_url) { + if((new_host->notes_url = (char *)strdup(notes_url)) == NULL) + result = ERROR; + } + if(action_url) { + if((new_host->action_url = (char *)strdup(action_url)) == NULL) + result = ERROR; + } + if(icon_image) { + if((new_host->icon_image = (char *)strdup(icon_image)) == NULL) + result = ERROR; + } + if(icon_image_alt) { + if((new_host->icon_image_alt = (char *)strdup(icon_image_alt)) == NULL) + result = ERROR; + } + if(vrml_image) { + if((new_host->vrml_image = (char *)strdup(vrml_image)) == NULL) + result = ERROR; + } + if(statusmap_image) { + if((new_host->statusmap_image = (char *)strdup(statusmap_image)) == NULL) + result = ERROR; + } + + + /* duplicate non-string vars */ + new_host->max_attempts = max_attempts; + new_host->check_interval = check_interval; + new_host->retry_interval = retry_interval; + new_host->notification_interval = notification_interval; + new_host->first_notification_delay = first_notification_delay; + new_host->notify_on_recovery = (notify_up > 0) ? TRUE : FALSE; + new_host->notify_on_down = (notify_down > 0) ? TRUE : FALSE; + new_host->notify_on_unreachable = (notify_unreachable > 0) ? TRUE : FALSE; + new_host->notify_on_flapping = (notify_flapping > 0) ? TRUE : FALSE; + new_host->notify_on_downtime = (notify_downtime > 0) ? TRUE : FALSE; + new_host->flap_detection_enabled = (flap_detection_enabled > 0) ? TRUE : FALSE; + new_host->low_flap_threshold = low_flap_threshold; + new_host->high_flap_threshold = high_flap_threshold; + new_host->flap_detection_on_up = (flap_detection_on_up > 0) ? TRUE : FALSE; + new_host->flap_detection_on_down = (flap_detection_on_down > 0) ? TRUE : FALSE; + new_host->flap_detection_on_unreachable = (flap_detection_on_unreachable > 0) ? TRUE : FALSE; + new_host->stalk_on_up = (stalk_on_up > 0) ? TRUE : FALSE; + new_host->stalk_on_down = (stalk_on_down > 0) ? TRUE : FALSE; + new_host->stalk_on_unreachable = (stalk_on_unreachable > 0) ? TRUE : FALSE; + new_host->process_performance_data = (process_perfdata > 0) ? TRUE : FALSE; + new_host->check_freshness = (check_freshness > 0) ? TRUE : FALSE; + new_host->freshness_threshold = freshness_threshold; + new_host->checks_enabled = (checks_enabled > 0) ? TRUE : FALSE; + new_host->accept_passive_host_checks = (accept_passive_checks > 0) ? TRUE : FALSE; + new_host->event_handler_enabled = (event_handler_enabled > 0) ? TRUE : FALSE; + new_host->failure_prediction_enabled = (failure_prediction_enabled > 0) ? TRUE : FALSE; + new_host->x_2d = x_2d; + new_host->y_2d = y_2d; + new_host->have_2d_coords = (have_2d_coords > 0) ? TRUE : FALSE; + new_host->x_3d = x_3d; + new_host->y_3d = y_3d; + new_host->z_3d = z_3d; + new_host->have_3d_coords = (have_3d_coords > 0) ? TRUE : FALSE; + new_host->should_be_drawn = (should_be_drawn > 0) ? TRUE : FALSE; + new_host->obsess_over_host = (obsess_over_host > 0) ? TRUE : FALSE; + new_host->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE; + new_host->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE; +#ifdef NSCORE + new_host->current_state = initial_state; + new_host->current_event_id = 0L; + new_host->last_event_id = 0L; + new_host->current_problem_id = 0L; + new_host->last_problem_id = 0L; + new_host->last_state = initial_state; + new_host->last_hard_state = initial_state; + new_host->check_type = HOST_CHECK_ACTIVE; + new_host->last_host_notification = (time_t)0; + new_host->next_host_notification = (time_t)0; + new_host->next_check = (time_t)0; + new_host->should_be_scheduled = TRUE; + new_host->last_check = (time_t)0; + new_host->current_attempt = (initial_state == HOST_UP) ? 1 : max_attempts; + new_host->state_type = HARD_STATE; + new_host->execution_time = 0.0; + new_host->is_executing = FALSE; + new_host->latency = 0.0; + new_host->last_state_change = (time_t)0; + new_host->last_hard_state_change = (time_t)0; + new_host->last_time_up = (time_t)0; + new_host->last_time_down = (time_t)0; + new_host->last_time_unreachable = (time_t)0; + new_host->has_been_checked = FALSE; + new_host->is_being_freshened = FALSE; + new_host->problem_has_been_acknowledged = FALSE; + new_host->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + new_host->notifications_enabled = (notifications_enabled > 0) ? TRUE : FALSE; + new_host->notified_on_down = FALSE; + new_host->notified_on_unreachable = FALSE; + new_host->current_notification_number = 0; + new_host->current_notification_id = 0L; + new_host->no_more_notifications = FALSE; + new_host->check_flapping_recovery_notification = FALSE; + new_host->scheduled_downtime_depth = 0; + new_host->check_options = CHECK_OPTION_NONE; + new_host->pending_flex_downtime = 0; + for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) + new_host->state_history[x] = STATE_OK; + new_host->state_history_index = 0; + new_host->last_state_history_update = (time_t)0; + new_host->is_flapping = FALSE; + new_host->flapping_comment_id = 0; + new_host->percent_state_change = 0.0; + new_host->total_services = 0; + new_host->total_service_check_interval = 0L; + new_host->modified_attributes = MODATTR_NONE; + new_host->circular_path_checked = FALSE; + new_host->contains_circular_path = FALSE; +#endif + + /* add new host to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[HOST_SKIPLIST], (void *)new_host); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { +#ifdef NSCORE + my_free(new_host->plugin_output); + my_free(new_host->long_plugin_output); + my_free(new_host->perf_data); +#endif + my_free(new_host->statusmap_image); + my_free(new_host->vrml_image); + my_free(new_host->icon_image_alt); + my_free(new_host->icon_image); + my_free(new_host->action_url); + my_free(new_host->notes_url); + my_free(new_host->notes); + my_free(new_host->failure_prediction_options); + my_free(new_host->event_handler); + my_free(new_host->host_check_command); + my_free(new_host->notification_period); + my_free(new_host->check_period); + my_free(new_host->address); + my_free(new_host->alias); + my_free(new_host->display_name); + my_free(new_host->name); + my_free(new_host); + return NULL; + } + + /* hosts are sorted alphabetically, so add new items to tail of list */ + if(host_list == NULL) { + host_list = new_host; + host_list_tail = host_list; + } + else { + host_list_tail->next = new_host; + host_list_tail = new_host; + } + + return new_host; + } + + + +hostsmember *add_parent_host_to_host(host *hst, char *host_name) { + hostsmember *new_hostsmember = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(hst == NULL || host_name == NULL || !strcmp(host_name, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host is NULL or parent host name is NULL\n"); + return NULL; + } + + /* a host cannot be a parent/child of itself */ + if(!strcmp(host_name, hst->name)) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host '%s' cannot be a child/parent of itself\n", hst->name); + return NULL; + } + + /* allocate memory */ + if((new_hostsmember = (hostsmember *)calloc(1, sizeof(hostsmember))) == NULL) + return NULL; + + /* duplicate string vars */ + if((new_hostsmember->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_hostsmember->host_name); + my_free(new_hostsmember); + return NULL; + } + + /* add the parent host entry to the host definition */ + new_hostsmember->next = hst->parent_hosts; + hst->parent_hosts = new_hostsmember; + + return new_hostsmember; + } + + + +hostsmember *add_child_link_to_host(host *hst, host *child_ptr) { + hostsmember *new_hostsmember = NULL; + + /* make sure we have the data we need */ + if(hst == NULL || child_ptr == NULL) + return NULL; + + /* allocate memory */ + if((new_hostsmember = (hostsmember *)malloc(sizeof(hostsmember))) == NULL) + return NULL; + + /* initialize values */ + new_hostsmember->host_name = NULL; +#ifdef NSCORE + new_hostsmember->host_ptr = child_ptr; +#endif + + /* add the child entry to the host definition */ + new_hostsmember->next = hst->child_hosts; + hst->child_hosts = new_hostsmember; + + return new_hostsmember; + } + + + +servicesmember *add_service_link_to_host(host *hst, service *service_ptr) { + servicesmember *new_servicesmember = NULL; + + /* make sure we have the data we need */ + if(hst == NULL || service_ptr == NULL) + return NULL; + + /* allocate memory */ + if((new_servicesmember = (servicesmember *)calloc(1, sizeof(servicesmember))) == NULL) + return NULL; + + /* initialize values */ +#ifdef NSCORE + new_servicesmember->service_ptr = service_ptr; +#endif + + /* add the child entry to the host definition */ + new_servicesmember->next = hst->services; + hst->services = new_servicesmember; + + return new_servicesmember; + } + + + +/* add a new contactgroup to a host */ +contactgroupsmember *add_contactgroup_to_host(host *hst, char *group_name) { + contactgroupsmember *new_contactgroupsmember = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(hst == NULL || (group_name == NULL || !strcmp(group_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host or contactgroup member is NULL\n"); + return NULL; + } + + /* allocate memory for a new member */ + if((new_contactgroupsmember = calloc(1, sizeof(contactgroupsmember))) == NULL) + return NULL; + + /* duplicate string vars */ + if((new_contactgroupsmember->group_name = (char *)strdup(group_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_contactgroupsmember->group_name); + my_free(new_contactgroupsmember); + return NULL; + } + + /* add the new member to the head of the member list */ + new_contactgroupsmember->next = hst->contact_groups; + hst->contact_groups = new_contactgroupsmember;; + + return new_contactgroupsmember; + } + + + +/* adds a contact to a host */ +contactsmember *add_contact_to_host(host *hst, char *contact_name) { + + return add_contact_to_object(&hst->contacts, contact_name); + } + + + +/* adds a custom variable to a host */ +customvariablesmember *add_custom_variable_to_host(host *hst, char *varname, char *varvalue) { + + return add_custom_variable_to_object(&hst->custom_variables, varname, varvalue); + } + + + +/* add a new host group to the list in memory */ +hostgroup *add_hostgroup(char *name, char *alias, char *notes, char *notes_url, char *action_url) { + hostgroup *new_hostgroup = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(name == NULL || !strcmp(name, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroup name is NULL\n"); + return NULL; + } + + /* allocate memory */ + if((new_hostgroup = (hostgroup *)calloc(1, sizeof(hostgroup))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_hostgroup->group_name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_hostgroup->alias = (char *)strdup((alias == NULL) ? name : alias)) == NULL) + result = ERROR; + if(notes) { + if((new_hostgroup->notes = (char *)strdup(notes)) == NULL) + result = ERROR; + } + if(notes_url) { + if((new_hostgroup->notes_url = (char *)strdup(notes_url)) == NULL) + result = ERROR; + } + if(action_url) { + if((new_hostgroup->action_url = (char *)strdup(action_url)) == NULL) + result = ERROR; + } + + /* add new host group to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[HOSTGROUP_SKIPLIST], (void *)new_hostgroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroup '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add hostgroup '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_hostgroup->alias); + my_free(new_hostgroup->group_name); + my_free(new_hostgroup); + return NULL; + } + + /* hostgroups are sorted alphabetically, so add new items to tail of list */ + if(hostgroup_list == NULL) { + hostgroup_list = new_hostgroup; + hostgroup_list_tail = hostgroup_list; + } + else { + hostgroup_list_tail->next = new_hostgroup; + hostgroup_list_tail = new_hostgroup; + } + + return new_hostgroup; + } + + +/* add a new host to a host group */ +hostsmember *add_host_to_hostgroup(hostgroup *temp_hostgroup, char *host_name) { + hostsmember *new_member = NULL; + hostsmember *last_member = NULL; + hostsmember *temp_member = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(temp_hostgroup == NULL || (host_name == NULL || !strcmp(host_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroup or group member is NULL\n"); + return NULL; + } + + /* allocate memory for a new member */ + if((new_member = calloc(1, sizeof(hostsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_member->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_member->host_name); + my_free(new_member); + return NULL; + } + + /* add the new member to the member list, sorted by host name */ + last_member = temp_hostgroup->members; + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + if(strcmp(new_member->host_name, temp_member->host_name) < 0) { + new_member->next = temp_member; + if(temp_member == temp_hostgroup->members) + temp_hostgroup->members = new_member; + else + last_member->next = new_member; + break; + } + else + last_member = temp_member; + } + if(temp_hostgroup->members == NULL) { + new_member->next = NULL; + temp_hostgroup->members = new_member; + } + else if(temp_member == NULL) { + new_member->next = NULL; + last_member->next = new_member; + } + + return new_member; + } + + +/* add a new service group to the list in memory */ +servicegroup *add_servicegroup(char *name, char *alias, char *notes, char *notes_url, char *action_url) { + servicegroup *new_servicegroup = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(name == NULL || !strcmp(name, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup name is NULL\n"); + return NULL; + } + + /* allocate memory */ + if((new_servicegroup = (servicegroup *)calloc(1, sizeof(servicegroup))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_servicegroup->group_name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_servicegroup->alias = (char *)strdup((alias == NULL) ? name : alias)) == NULL) + result = ERROR; + if(notes) { + if((new_servicegroup->notes = (char *)strdup(notes)) == NULL) + result = ERROR; + } + if(notes_url) { + if((new_servicegroup->notes_url = (char *)strdup(notes_url)) == NULL) + result = ERROR; + } + if(action_url) { + if((new_servicegroup->action_url = (char *)strdup(action_url)) == NULL) + result = ERROR; + } + + /* add new service group to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[SERVICEGROUP_SKIPLIST], (void *)new_servicegroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add servicegroup '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_servicegroup->alias); + my_free(new_servicegroup->group_name); + my_free(new_servicegroup); + return NULL; + } + + /* servicegroups are sorted alphabetically, so add new items to tail of list */ + if(servicegroup_list == NULL) { + servicegroup_list = new_servicegroup; + servicegroup_list_tail = servicegroup_list; + } + else { + servicegroup_list_tail->next = new_servicegroup; + servicegroup_list_tail = new_servicegroup; + } + + return new_servicegroup; + } + + +/* add a new service to a service group */ +servicesmember *add_service_to_servicegroup(servicegroup *temp_servicegroup, char *host_name, char *svc_description) { + servicesmember *new_member = NULL; + servicesmember *last_member = NULL; + servicesmember *temp_member = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(temp_servicegroup == NULL || (host_name == NULL || !strcmp(host_name, "")) || (svc_description == NULL || !strcmp(svc_description, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup or group member is NULL\n"); + return NULL; + } + + /* allocate memory for a new member */ + if((new_member = calloc(1, sizeof(servicesmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_member->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + if((new_member->service_description = (char *)strdup(svc_description)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_member->service_description); + my_free(new_member->host_name); + my_free(new_member); + return NULL; + } + + /* add new member to member list, sorted by host name then service description */ + last_member = temp_servicegroup->members; + for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) { + + if(strcmp(new_member->host_name, temp_member->host_name) < 0) { + new_member->next = temp_member; + if(temp_member == temp_servicegroup->members) + temp_servicegroup->members = new_member; + else + last_member->next = new_member; + break; + } + + else if(strcmp(new_member->host_name, temp_member->host_name) == 0 && strcmp(new_member->service_description, temp_member->service_description) < 0) { + new_member->next = temp_member; + if(temp_member == temp_servicegroup->members) + temp_servicegroup->members = new_member; + else + last_member->next = new_member; + break; + } + + else + last_member = temp_member; + } + if(temp_servicegroup->members == NULL) { + new_member->next = NULL; + temp_servicegroup->members = new_member; + } + else if(temp_member == NULL) { + new_member->next = NULL; + last_member->next = new_member; + } + + return new_member; + } + + +/* add a new contact to the list in memory */ +contact *add_contact(char *name, char *alias, char *email, char *pager, char **addresses, char *svc_notification_period, char *host_notification_period, int notify_service_ok, int notify_service_critical, int notify_service_warning, int notify_service_unknown, int notify_service_flapping, int notify_service_downtime, int notify_host_up, int notify_host_down, int notify_host_unreachable, int notify_host_flapping, int notify_host_downtime, int host_notifications_enabled, int service_notifications_enabled, int can_submit_commands, int retain_status_information, int retain_nonstatus_information) { + contact *new_contact = NULL; + int x = 0; + int result = OK; + + /* make sure we have the data we need */ + if(name == NULL || !strcmp(name, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact name is NULL\n"); + return NULL; + } + + /* allocate memory for a new contact */ + if((new_contact = (contact *)calloc(1, sizeof(contact))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_contact->name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_contact->alias = (char *)strdup((alias == NULL) ? name : alias)) == NULL) + result = ERROR; + if(email) { + if((new_contact->email = (char *)strdup(email)) == NULL) + result = ERROR; + } + if(pager) { + if((new_contact->pager = (char *)strdup(pager)) == NULL) + result = ERROR; + } + if(svc_notification_period) { + if((new_contact->service_notification_period = (char *)strdup(svc_notification_period)) == NULL) + result = ERROR; + } + if(host_notification_period) { + if((new_contact->host_notification_period = (char *)strdup(host_notification_period)) == NULL) + result = ERROR; + } + if(addresses) { + for(x = 0; x < MAX_CONTACT_ADDRESSES; x++) { + if(addresses[x]) { + if((new_contact->address[x] = (char *)strdup(addresses[x])) == NULL) + result = ERROR; + } + } + } + + new_contact->notify_on_service_recovery = (notify_service_ok > 0) ? TRUE : FALSE; + new_contact->notify_on_service_critical = (notify_service_critical > 0) ? TRUE : FALSE; + new_contact->notify_on_service_warning = (notify_service_warning > 0) ? TRUE : FALSE; + new_contact->notify_on_service_unknown = (notify_service_unknown > 0) ? TRUE : FALSE; + new_contact->notify_on_service_flapping = (notify_service_flapping > 0) ? TRUE : FALSE; + new_contact->notify_on_service_downtime = (notify_service_downtime > 0) ? TRUE : FALSE; + new_contact->notify_on_host_recovery = (notify_host_up > 0) ? TRUE : FALSE; + new_contact->notify_on_host_down = (notify_host_down > 0) ? TRUE : FALSE; + new_contact->notify_on_host_unreachable = (notify_host_unreachable > 0) ? TRUE : FALSE; + new_contact->notify_on_host_flapping = (notify_host_flapping > 0) ? TRUE : FALSE; + new_contact->notify_on_host_downtime = (notify_host_downtime > 0) ? TRUE : FALSE; + new_contact->host_notifications_enabled = (host_notifications_enabled > 0) ? TRUE : FALSE; + new_contact->service_notifications_enabled = (service_notifications_enabled > 0) ? TRUE : FALSE; + new_contact->can_submit_commands = (can_submit_commands > 0) ? TRUE : FALSE; + new_contact->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE; + new_contact->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE; +#ifdef NSCORE + new_contact->last_host_notification = (time_t)0L; + new_contact->last_service_notification = (time_t)0L; + new_contact->modified_attributes = MODATTR_NONE; + new_contact->modified_host_attributes = MODATTR_NONE; + new_contact->modified_service_attributes = MODATTR_NONE; + + new_contact->host_notification_period_ptr = NULL; + new_contact->service_notification_period_ptr = NULL; + new_contact->contactgroups_ptr = NULL; +#endif + + /* add new contact to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[CONTACT_SKIPLIST], (void *)new_contact); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + for(x = 0; x < MAX_CONTACT_ADDRESSES; x++) + my_free(new_contact->address[x]); + my_free(new_contact->name); + my_free(new_contact->alias); + my_free(new_contact->email); + my_free(new_contact->pager); + my_free(new_contact->service_notification_period); + my_free(new_contact->host_notification_period); + my_free(new_contact); + return NULL; + } + + /* contacts are sorted alphabetically, so add new items to tail of list */ + if(contact_list == NULL) { + contact_list = new_contact; + contact_list_tail = contact_list; + } + else { + contact_list_tail->next = new_contact; + contact_list_tail = new_contact; + } + + return new_contact; + } + + + +/* adds a host notification command to a contact definition */ +commandsmember *add_host_notification_command_to_contact(contact *cntct, char *command_name) { + commandsmember *new_commandsmember = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(cntct == NULL || (command_name == NULL || !strcmp(command_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact or host notification command is NULL\n"); + return NULL; + } + + /* allocate memory */ + if((new_commandsmember = calloc(1, sizeof(commandsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_commandsmember->command = (char *)strdup(command_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_commandsmember->command); + my_free(new_commandsmember); + return NULL; + } + + /* add the notification command */ + new_commandsmember->next = cntct->host_notification_commands; + cntct->host_notification_commands = new_commandsmember; + + return new_commandsmember; + } + + + +/* adds a service notification command to a contact definition */ +commandsmember *add_service_notification_command_to_contact(contact *cntct, char *command_name) { + commandsmember *new_commandsmember = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(cntct == NULL || (command_name == NULL || !strcmp(command_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact or service notification command is NULL\n"); + return NULL; + } + + /* allocate memory */ + if((new_commandsmember = calloc(1, sizeof(commandsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_commandsmember->command = (char *)strdup(command_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_commandsmember->command); + my_free(new_commandsmember); + return NULL; + } + + /* add the notification command */ + new_commandsmember->next = cntct->service_notification_commands; + cntct->service_notification_commands = new_commandsmember; + + return new_commandsmember; + } + + + +/* adds a custom variable to a contact */ +customvariablesmember *add_custom_variable_to_contact(contact *cntct, char *varname, char *varvalue) { + + return add_custom_variable_to_object(&cntct->custom_variables, varname, varvalue); + } + + + +/* add a new contact group to the list in memory */ +contactgroup *add_contactgroup(char *name, char *alias) { + contactgroup *new_contactgroup = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(name == NULL || !strcmp(name, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup name is NULL\n"); + return NULL; + } + + /* allocate memory for a new contactgroup entry */ + if((new_contactgroup = calloc(1, sizeof(contactgroup))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_contactgroup->group_name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_contactgroup->alias = (char *)strdup((alias == NULL) ? name : alias)) == NULL) + result = ERROR; + + /* add new contact group to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[CONTACTGROUP_SKIPLIST], (void *)new_contactgroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_contactgroup->alias); + my_free(new_contactgroup->group_name); + my_free(new_contactgroup); + return NULL; + } + + /* contactgroups are sorted alphabetically, so add new items to tail of list */ + if(contactgroup_list == NULL) { + contactgroup_list = new_contactgroup; + contactgroup_list_tail = contactgroup_list; + } + else { + contactgroup_list_tail->next = new_contactgroup; + contactgroup_list_tail = new_contactgroup; + } + + return new_contactgroup; + } + + + +/* add a new member to a contact group */ +contactsmember *add_contact_to_contactgroup(contactgroup *grp, char *contact_name) { + contactsmember *new_contactsmember = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(grp == NULL || (contact_name == NULL || !strcmp(contact_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup or contact name is NULL\n"); + return NULL; + } + + /* allocate memory for a new member */ + if((new_contactsmember = calloc(1, sizeof(contactsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_contactsmember->contact_name = (char *)strdup(contact_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_contactsmember->contact_name); + my_free(new_contactsmember); + return NULL; + } + + /* add the new member to the head of the member list */ + new_contactsmember->next = grp->members; + grp->members = new_contactsmember; + + return new_contactsmember; + } + + + +/* add a new service to the list in memory */ +service *add_service(char *host_name, char *description, char *display_name, char *check_period, int initial_state, int max_attempts, int parallelize, int accept_passive_checks, double check_interval, double retry_interval, double notification_interval, double first_notification_delay, char *notification_period, int notify_recovery, int notify_unknown, int notify_warning, int notify_critical, int notify_flapping, int notify_downtime, int notifications_enabled, int is_volatile, char *event_handler, int event_handler_enabled, char *check_command, int checks_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_on_ok, int flap_detection_on_warning, int flap_detection_on_unknown, int flap_detection_on_critical, int stalk_on_ok, int stalk_on_warning, int stalk_on_unknown, int stalk_on_critical, int process_perfdata, int failure_prediction_enabled, char *failure_prediction_options, int check_freshness, int freshness_threshold, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt, int retain_status_information, int retain_nonstatus_information, int obsess_over_service) { + service *new_service = NULL; + int result = OK; +#ifdef NSCORE + int x = 0; +#endif + + /* make sure we have everything we need */ + if((host_name == NULL || !strcmp(host_name, "")) || (description == NULL || !strcmp(description, "")) || (check_command == NULL || !strcmp(check_command, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service description, host name, or check command is NULL\n"); + return NULL; + } + + /* check values */ + if(max_attempts <= 0 || check_interval < 0 || retry_interval <= 0 || notification_interval < 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid max_attempts, check_interval, retry_interval, or notification_interval value for service '%s' on host '%s'\n", description, host_name); + return NULL; + } + + if(first_notification_delay < 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid first_notification_delay value for service '%s' on host '%s'\n", description, host_name); + return NULL; + } + + /* allocate memory */ + if((new_service = (service *)calloc(1, sizeof(service))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_service->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + if((new_service->description = (char *)strdup(description)) == NULL) + result = ERROR; + if((new_service->display_name = (char *)strdup((display_name == NULL) ? description : display_name)) == NULL) + result = ERROR; + if((new_service->service_check_command = (char *)strdup(check_command)) == NULL) + result = ERROR; + if(event_handler) { + if((new_service->event_handler = (char *)strdup(event_handler)) == NULL) + result = ERROR; + } + if(notification_period) { + if((new_service->notification_period = (char *)strdup(notification_period)) == NULL) + result = ERROR; + } + if(check_period) { + if((new_service->check_period = (char *)strdup(check_period)) == NULL) + result = ERROR; + } + if(failure_prediction_options) { + if((new_service->failure_prediction_options = (char *)strdup(failure_prediction_options)) == NULL) + result = ERROR; + } + if(notes) { + if((new_service->notes = (char *)strdup(notes)) == NULL) + result = ERROR; + } + if(notes_url) { + if((new_service->notes_url = (char *)strdup(notes_url)) == NULL) + result = ERROR; + } + if(action_url) { + if((new_service->action_url = (char *)strdup(action_url)) == NULL) + result = ERROR; + } + if(icon_image) { + if((new_service->icon_image = (char *)strdup(icon_image)) == NULL) + result = ERROR; + } + if(icon_image_alt) { + if((new_service->icon_image_alt = (char *)strdup(icon_image_alt)) == NULL) + result = ERROR; + } + + new_service->check_interval = check_interval; + new_service->retry_interval = retry_interval; + new_service->max_attempts = max_attempts; + new_service->parallelize = (parallelize > 0) ? TRUE : FALSE; + new_service->notification_interval = notification_interval; + new_service->first_notification_delay = first_notification_delay; + new_service->notify_on_unknown = (notify_unknown > 0) ? TRUE : FALSE; + new_service->notify_on_warning = (notify_warning > 0) ? TRUE : FALSE; + new_service->notify_on_critical = (notify_critical > 0) ? TRUE : FALSE; + new_service->notify_on_recovery = (notify_recovery > 0) ? TRUE : FALSE; + new_service->notify_on_flapping = (notify_flapping > 0) ? TRUE : FALSE; + new_service->notify_on_downtime = (notify_downtime > 0) ? TRUE : FALSE; + new_service->is_volatile = (is_volatile > 0) ? TRUE : FALSE; + new_service->flap_detection_enabled = (flap_detection_enabled > 0) ? TRUE : FALSE; + new_service->low_flap_threshold = low_flap_threshold; + new_service->high_flap_threshold = high_flap_threshold; + new_service->flap_detection_on_ok = (flap_detection_on_ok > 0) ? TRUE : FALSE; + new_service->flap_detection_on_warning = (flap_detection_on_warning > 0) ? TRUE : FALSE; + new_service->flap_detection_on_unknown = (flap_detection_on_unknown > 0) ? TRUE : FALSE; + new_service->flap_detection_on_critical = (flap_detection_on_critical > 0) ? TRUE : FALSE; + new_service->stalk_on_ok = (stalk_on_ok > 0) ? TRUE : FALSE; + new_service->stalk_on_warning = (stalk_on_warning > 0) ? TRUE : FALSE; + new_service->stalk_on_unknown = (stalk_on_unknown > 0) ? TRUE : FALSE; + new_service->stalk_on_critical = (stalk_on_critical > 0) ? TRUE : FALSE; + new_service->process_performance_data = (process_perfdata > 0) ? TRUE : FALSE; + new_service->check_freshness = (check_freshness > 0) ? TRUE : FALSE; + new_service->freshness_threshold = freshness_threshold; + new_service->accept_passive_service_checks = (accept_passive_checks > 0) ? TRUE : FALSE; + new_service->event_handler_enabled = (event_handler_enabled > 0) ? TRUE : FALSE; + new_service->checks_enabled = (checks_enabled > 0) ? TRUE : FALSE; + new_service->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE; + new_service->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE; + new_service->notifications_enabled = (notifications_enabled > 0) ? TRUE : FALSE; + new_service->obsess_over_service = (obsess_over_service > 0) ? TRUE : FALSE; + new_service->failure_prediction_enabled = (failure_prediction_enabled > 0) ? TRUE : FALSE; +#ifdef NSCORE + new_service->problem_has_been_acknowledged = FALSE; + new_service->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + new_service->check_type = SERVICE_CHECK_ACTIVE; + new_service->current_attempt = (initial_state == STATE_OK) ? 1 : max_attempts; + new_service->current_state = initial_state; + new_service->current_event_id = 0L; + new_service->last_event_id = 0L; + new_service->current_problem_id = 0L; + new_service->last_problem_id = 0L; + new_service->last_state = initial_state; + new_service->last_hard_state = initial_state; + new_service->state_type = HARD_STATE; + new_service->host_problem_at_last_check = FALSE; + new_service->check_flapping_recovery_notification = FALSE; + new_service->next_check = (time_t)0; + new_service->should_be_scheduled = TRUE; + new_service->last_check = (time_t)0; + new_service->last_notification = (time_t)0; + new_service->next_notification = (time_t)0; + new_service->no_more_notifications = FALSE; + new_service->last_state_change = (time_t)0; + new_service->last_hard_state_change = (time_t)0; + new_service->last_time_ok = (time_t)0; + new_service->last_time_warning = (time_t)0; + new_service->last_time_unknown = (time_t)0; + new_service->last_time_critical = (time_t)0; + new_service->has_been_checked = FALSE; + new_service->is_being_freshened = FALSE; + new_service->notified_on_unknown = FALSE; + new_service->notified_on_warning = FALSE; + new_service->notified_on_critical = FALSE; + new_service->current_notification_number = 0; + new_service->current_notification_id = 0L; + new_service->latency = 0.0; + new_service->execution_time = 0.0; + new_service->is_executing = FALSE; + new_service->check_options = CHECK_OPTION_NONE; + new_service->scheduled_downtime_depth = 0; + new_service->pending_flex_downtime = 0; + for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) + new_service->state_history[x] = STATE_OK; + new_service->state_history_index = 0; + new_service->is_flapping = FALSE; + new_service->flapping_comment_id = 0; + new_service->percent_state_change = 0.0; + new_service->modified_attributes = MODATTR_NONE; +#endif + + /* add new service to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[SERVICE_SKIPLIST], (void *)new_service); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service '%s' on host '%s' has already been defined\n", description, host_name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service '%s' on host '%s' to skiplist\n", description, host_name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { +#ifdef NSCORE + my_free(new_service->perf_data); + my_free(new_service->plugin_output); + my_free(new_service->long_plugin_output); +#endif + my_free(new_service->failure_prediction_options); + my_free(new_service->notification_period); + my_free(new_service->event_handler); + my_free(new_service->service_check_command); + my_free(new_service->description); + my_free(new_service->host_name); + my_free(new_service->display_name); + my_free(new_service); + return NULL; + } + + /* services are sorted alphabetically, so add new items to tail of list */ + if(service_list == NULL) { + service_list = new_service; + service_list_tail = service_list; + } + else { + service_list_tail->next = new_service; + service_list_tail = new_service; + } + + return new_service; + } + + + +/* adds a contact group to a service */ +contactgroupsmember *add_contactgroup_to_service(service *svc, char *group_name) { + contactgroupsmember *new_contactgroupsmember = NULL; + int result = OK; + + /* bail out if we weren't given the data we need */ + if(svc == NULL || (group_name == NULL || !strcmp(group_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service or contactgroup name is NULL\n"); + return NULL; + } + + /* allocate memory for the contactgroups member */ + if((new_contactgroupsmember = calloc(1, sizeof(contactgroupsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_contactgroupsmember->group_name = (char *)strdup(group_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_contactgroupsmember); + return NULL; + } + + /* add this contactgroup to the service */ + new_contactgroupsmember->next = svc->contact_groups; + svc->contact_groups = new_contactgroupsmember; + + return new_contactgroupsmember; + } + + + +/* adds a contact to a service */ +contactsmember *add_contact_to_service(service *svc, char *contact_name) { + + return add_contact_to_object(&svc->contacts, contact_name); + } + + + +/* adds a custom variable to a service */ +customvariablesmember *add_custom_variable_to_service(service *svc, char *varname, char *varvalue) { + + return add_custom_variable_to_object(&svc->custom_variables, varname, varvalue); + } + + + +/* add a new command to the list in memory */ +command *add_command(char *name, char *value) { + command *new_command = NULL; + int result = OK; + + /* make sure we have the data we need */ + if((name == NULL || !strcmp(name, "")) || (value == NULL || !strcmp(value, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Command name of command line is NULL\n"); + return NULL; + } + + /* allocate memory for the new command */ + if((new_command = (command *)calloc(1, sizeof(command))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_command->name = (char *)strdup(name)) == NULL) + result = ERROR; + if((new_command->command_line = (char *)strdup(value)) == NULL) + result = ERROR; + + /* add new command to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[COMMAND_SKIPLIST], (void *)new_command); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Command '%s' has already been defined\n", name); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add command '%s' to skiplist\n", name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_command->command_line); + my_free(new_command->name); + my_free(new_command); + return NULL; + } + + /* commands are sorted alphabetically, so add new items to tail of list */ + if(command_list == NULL) { + command_list = new_command; + command_list_tail = command_list; + } + else { + command_list_tail->next = new_command; + command_list_tail = new_command; + } + + return new_command; + } + + + +/* add a new service escalation to the list in memory */ +serviceescalation *add_serviceescalation(char *host_name, char *description, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalate_on_warning, int escalate_on_unknown, int escalate_on_critical, int escalate_on_recovery) { + serviceescalation *new_serviceescalation = NULL; + int result = OK; + + /* make sure we have the data we need */ + if((host_name == NULL || !strcmp(host_name, "")) || (description == NULL || !strcmp(description, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service escalation host name or description is NULL\n"); + return NULL; + } + +#ifdef TEST + printf("NEW SVC ESCALATION: %s/%s = %d/%d/%.3f\n", host_name, description, first_notification, last_notification, notification_interval); +#endif + + /* allocate memory for a new service escalation entry */ + if((new_serviceescalation = calloc(1, sizeof(serviceescalation))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_serviceescalation->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + if((new_serviceescalation->description = (char *)strdup(description)) == NULL) + result = ERROR; + if(escalation_period) { + if((new_serviceescalation->escalation_period = (char *)strdup(escalation_period)) == NULL) + result = ERROR; + } + + new_serviceescalation->first_notification = first_notification; + new_serviceescalation->last_notification = last_notification; + new_serviceescalation->notification_interval = (notification_interval <= 0) ? 0 : notification_interval; + new_serviceescalation->escalate_on_recovery = (escalate_on_recovery > 0) ? TRUE : FALSE; + new_serviceescalation->escalate_on_warning = (escalate_on_warning > 0) ? TRUE : FALSE; + new_serviceescalation->escalate_on_unknown = (escalate_on_unknown > 0) ? TRUE : FALSE; + new_serviceescalation->escalate_on_critical = (escalate_on_critical > 0) ? TRUE : FALSE; + + /* add new serviceescalation to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[SERVICEESCALATION_SKIPLIST], (void *)new_serviceescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add escalation for service '%s' on host '%s' to skiplist\n", description, host_name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_serviceescalation->host_name); + my_free(new_serviceescalation->description); + my_free(new_serviceescalation->escalation_period); + my_free(new_serviceescalation); + return NULL; + } + + /* service escalations are sorted alphabetically, so add new items to tail of list */ + if(serviceescalation_list == NULL) { + serviceescalation_list = new_serviceescalation; + serviceescalation_list_tail = serviceescalation_list; + } + else { + serviceescalation_list_tail->next = new_serviceescalation; + serviceescalation_list_tail = new_serviceescalation; + } + + return new_serviceescalation; + } + + + +/* adds a contact group to a service escalation */ +contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *se, char *group_name) { + contactgroupsmember *new_contactgroupsmember = NULL; + int result = OK; + + /* bail out if we weren't given the data we need */ + if(se == NULL || (group_name == NULL || !strcmp(group_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service escalation or contactgroup name is NULL\n"); + return NULL; + } + + /* allocate memory for the contactgroups member */ + if((new_contactgroupsmember = (contactgroupsmember *)calloc(1, sizeof(contactgroupsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_contactgroupsmember->group_name = (char *)strdup(group_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_contactgroupsmember->group_name); + my_free(new_contactgroupsmember); + return NULL; + } + + /* add this contactgroup to the service escalation */ + new_contactgroupsmember->next = se->contact_groups; + se->contact_groups = new_contactgroupsmember; + + return new_contactgroupsmember; + } + + + +/* adds a contact to a service escalation */ +contactsmember *add_contact_to_serviceescalation(serviceescalation *se, char *contact_name) { + + return add_contact_to_object(&se->contacts, contact_name); + } + + + +/* adds a service dependency definition */ +servicedependency *add_service_dependency(char *dependent_host_name, char *dependent_service_description, char *host_name, char *service_description, int dependency_type, int inherits_parent, int fail_on_ok, int fail_on_warning, int fail_on_unknown, int fail_on_critical, int fail_on_pending, char *dependency_period) { + servicedependency *new_servicedependency = NULL; + int result = OK; + + /* make sure we have what we need */ + if((host_name == NULL || !strcmp(host_name, "")) || (service_description == NULL || !strcmp(service_description, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL master service description/host name in service dependency definition\n"); + return NULL; + } + if((dependent_host_name == NULL || !strcmp(dependent_host_name, "")) || (dependent_service_description == NULL || !strcmp(dependent_service_description, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL dependent service description/host name in service dependency definition\n"); + return NULL; + } + + /* allocate memory for a new service dependency entry */ + if((new_servicedependency = (servicedependency *)calloc(1, sizeof(servicedependency))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_servicedependency->dependent_host_name = (char *)strdup(dependent_host_name)) == NULL) + result = ERROR; + if((new_servicedependency->dependent_service_description = (char *)strdup(dependent_service_description)) == NULL) + result = ERROR; + if((new_servicedependency->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + if((new_servicedependency->service_description = (char *)strdup(service_description)) == NULL) + result = ERROR; + if(dependency_period) { + if((new_servicedependency->dependency_period = (char *)strdup(dependency_period)) == NULL) + result = ERROR; + } + + new_servicedependency->dependency_type = (dependency_type == EXECUTION_DEPENDENCY) ? EXECUTION_DEPENDENCY : NOTIFICATION_DEPENDENCY; + new_servicedependency->inherits_parent = (inherits_parent > 0) ? TRUE : FALSE; + new_servicedependency->fail_on_ok = (fail_on_ok == 1) ? TRUE : FALSE; + new_servicedependency->fail_on_warning = (fail_on_warning == 1) ? TRUE : FALSE; + new_servicedependency->fail_on_unknown = (fail_on_unknown == 1) ? TRUE : FALSE; + new_servicedependency->fail_on_critical = (fail_on_critical == 1) ? TRUE : FALSE; + new_servicedependency->fail_on_pending = (fail_on_pending == 1) ? TRUE : FALSE; +#ifdef NSCORE + new_servicedependency->circular_path_checked = FALSE; + new_servicedependency->contains_circular_path = FALSE; +#endif + + /* add new service dependency to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[SERVICEDEPENDENCY_SKIPLIST], (void *)new_servicedependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service dependency to skiplist\n"); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_servicedependency->host_name); + my_free(new_servicedependency->service_description); + my_free(new_servicedependency->dependent_host_name); + my_free(new_servicedependency->dependent_service_description); + my_free(new_servicedependency); + return NULL; + } + + /* service dependencies are sorted alphabetically, so add new items to tail of list */ + if(servicedependency_list == NULL) { + servicedependency_list = new_servicedependency; + servicedependency_list_tail = servicedependency_list; + } + else { + servicedependency_list_tail->next = new_servicedependency; + servicedependency_list_tail = new_servicedependency; + } + + return new_servicedependency; + } + + +/* adds a host dependency definition */ +hostdependency *add_host_dependency(char *dependent_host_name, char *host_name, int dependency_type, int inherits_parent, int fail_on_up, int fail_on_down, int fail_on_unreachable, int fail_on_pending, char *dependency_period) { + hostdependency *new_hostdependency = NULL; + int result = OK; + + /* make sure we have what we need */ + if((dependent_host_name == NULL || !strcmp(dependent_host_name, "")) || (host_name == NULL || !strcmp(host_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL host name in host dependency definition\n"); + return NULL; + } + + /* allocate memory for a new host dependency entry */ + if((new_hostdependency = (hostdependency *)calloc(1, sizeof(hostdependency))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_hostdependency->dependent_host_name = (char *)strdup(dependent_host_name)) == NULL) + result = ERROR; + if((new_hostdependency->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + if(dependency_period) { + if((new_hostdependency->dependency_period = (char *)strdup(dependency_period)) == NULL) + result = ERROR; + } + + new_hostdependency->dependency_type = (dependency_type == EXECUTION_DEPENDENCY) ? EXECUTION_DEPENDENCY : NOTIFICATION_DEPENDENCY; + new_hostdependency->inherits_parent = (inherits_parent > 0) ? TRUE : FALSE; + new_hostdependency->fail_on_up = (fail_on_up == 1) ? TRUE : FALSE; + new_hostdependency->fail_on_down = (fail_on_down == 1) ? TRUE : FALSE; + new_hostdependency->fail_on_unreachable = (fail_on_unreachable == 1) ? TRUE : FALSE; + new_hostdependency->fail_on_pending = (fail_on_pending == 1) ? TRUE : FALSE; +#ifdef NSCORE + new_hostdependency->circular_path_checked = FALSE; + new_hostdependency->contains_circular_path = FALSE; +#endif + + /* add new host dependency to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[HOSTDEPENDENCY_SKIPLIST], (void *)new_hostdependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host dependency to skiplist\n"); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_hostdependency->host_name); + my_free(new_hostdependency->dependent_host_name); + my_free(new_hostdependency); + return NULL; + } + + /* host dependencies are sorted alphabetically, so add new items to tail of list */ + if(hostdependency_list == NULL) { + hostdependency_list = new_hostdependency; + hostdependency_list_tail = hostdependency_list; + } + else { + hostdependency_list_tail->next = new_hostdependency; + hostdependency_list_tail = new_hostdependency; + } + + return new_hostdependency; + } + + + +/* add a new host escalation to the list in memory */ +hostescalation *add_hostescalation(char *host_name, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalate_on_down, int escalate_on_unreachable, int escalate_on_recovery) { + hostescalation *new_hostescalation = NULL; + int result = OK; + + /* make sure we have the data we need */ + if(host_name == NULL || !strcmp(host_name, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host escalation host name is NULL\n"); + return NULL; + } + +#ifdef TEST + printf("NEW HST ESCALATION: %s = %d/%d/%.3f\n", host_name, first_notification, last_notification, notification_interval); +#endif + + /* allocate memory for a new host escalation entry */ + if((new_hostescalation = calloc(1, sizeof(hostescalation))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_hostescalation->host_name = (char *)strdup(host_name)) == NULL) + result = ERROR; + if(escalation_period) { + if((new_hostescalation->escalation_period = (char *)strdup(escalation_period)) == NULL) + result = ERROR; + } + + new_hostescalation->first_notification = first_notification; + new_hostescalation->last_notification = last_notification; + new_hostescalation->notification_interval = (notification_interval <= 0) ? 0 : notification_interval; + new_hostescalation->escalate_on_recovery = (escalate_on_recovery > 0) ? TRUE : FALSE; + new_hostescalation->escalate_on_down = (escalate_on_down > 0) ? TRUE : FALSE; + new_hostescalation->escalate_on_unreachable = (escalate_on_unreachable > 0) ? TRUE : FALSE; + + /* add new hostescalation to skiplist */ + if(result == OK) { + result = skiplist_insert(object_skiplists[HOSTESCALATION_SKIPLIST], (void *)new_hostescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add hostescalation '%s' to skiplist\n", host_name); + result = ERROR; + break; + } + } + + /* handle errors */ + if(result == ERROR) { + my_free(new_hostescalation->host_name); + my_free(new_hostescalation->escalation_period); + my_free(new_hostescalation); + return NULL; + } + + /* host escalations are sorted alphabetically, so add new items to tail of list */ + if(hostescalation_list == NULL) { + hostescalation_list = new_hostescalation; + hostescalation_list_tail = hostescalation_list; + } + else { + hostescalation_list_tail->next = new_hostescalation; + hostescalation_list_tail = new_hostescalation; + } + + return new_hostescalation; + } + + + +/* adds a contact group to a host escalation */ +contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *he, char *group_name) { + contactgroupsmember *new_contactgroupsmember = NULL; + int result = OK; + + /* bail out if we weren't given the data we need */ + if(he == NULL || (group_name == NULL || !strcmp(group_name, ""))) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host escalation or contactgroup name is NULL\n"); + return NULL; + } + + /* allocate memory for the contactgroups member */ + if((new_contactgroupsmember = (contactgroupsmember *)calloc(1, sizeof(contactgroupsmember))) == NULL) + return NULL; + + /* duplicate vars */ + if((new_contactgroupsmember->group_name = (char *)strdup(group_name)) == NULL) + result = ERROR; + + /* handle errors */ + if(result == ERROR) { + my_free(new_contactgroupsmember->group_name); + my_free(new_contactgroupsmember); + return NULL; + } + + /* add this contactgroup to the host escalation */ + new_contactgroupsmember->next = he->contact_groups; + he->contact_groups = new_contactgroupsmember; + + return new_contactgroupsmember; + } + + + +/* adds a contact to a host escalation */ +contactsmember *add_contact_to_hostescalation(hostescalation *he, char *contact_name) { + + return add_contact_to_object(&he->contacts, contact_name); + } + + + +/* adds a contact to an object */ +contactsmember *add_contact_to_object(contactsmember **object_ptr, char *contactname) { + contactsmember *new_contactsmember = NULL; + + /* make sure we have the data we need */ + if(object_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact object is NULL\n"); + return NULL; + } + + if(contactname == NULL || !strcmp(contactname, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact name is NULL\n"); + return NULL; + } + + /* allocate memory for a new member */ + if((new_contactsmember = malloc(sizeof(contactsmember))) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for contact\n"); + return NULL; + } + if((new_contactsmember->contact_name = (char *)strdup(contactname)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for contact name\n"); + my_free(new_contactsmember); + return NULL; + } + + /* set initial values */ +#ifdef NSCORE + new_contactsmember->contact_ptr = NULL; +#endif + + /* add the new contact to the head of the contact list */ + new_contactsmember->next = *object_ptr; + *object_ptr = new_contactsmember; + + return new_contactsmember; + } + + + +/* adds a custom variable to an object */ +customvariablesmember *add_custom_variable_to_object(customvariablesmember **object_ptr, char *varname, char *varvalue) { + customvariablesmember *new_customvariablesmember = NULL; + + /* make sure we have the data we need */ + if(object_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Custom variable object is NULL\n"); + return NULL; + } + + if(varname == NULL || !strcmp(varname, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Custom variable name is NULL\n"); + return NULL; + } + + /* allocate memory for a new member */ + if((new_customvariablesmember = malloc(sizeof(customvariablesmember))) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for custom variable\n"); + return NULL; + } + if((new_customvariablesmember->variable_name = (char *)strdup(varname)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for custom variable name\n"); + my_free(new_customvariablesmember); + return NULL; + } + if(varvalue) { + if((new_customvariablesmember->variable_value = (char *)strdup(varvalue)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for custom variable value\n"); + my_free(new_customvariablesmember->variable_name); + my_free(new_customvariablesmember); + return NULL; + } + } + else + new_customvariablesmember->variable_value = NULL; + + /* set initial values */ + new_customvariablesmember->has_been_modified = FALSE; + + /* add the new member to the head of the member list */ + new_customvariablesmember->next = *object_ptr; + *object_ptr = new_customvariablesmember; + + return new_customvariablesmember; + } + + + + +/******************************************************************/ +/******************** OBJECT SEARCH FUNCTIONS *********************/ +/******************************************************************/ + +/* given a timeperiod name and a starting point, find a timeperiod from the list in memory */ +timeperiod * find_timeperiod(char *name) { + timeperiod temp_timeperiod; + + if(name == NULL) + return NULL; + + temp_timeperiod.name = name; + + return skiplist_find_first(object_skiplists[TIMEPERIOD_SKIPLIST], &temp_timeperiod, NULL); + } + + +/* given a host name, find it in the list in memory */ +host * find_host(char *name) { + host temp_host; + + if(name == NULL) + return NULL; + + temp_host.name = name; + + return skiplist_find_first(object_skiplists[HOST_SKIPLIST], &temp_host, NULL); + } + + +/* find a hostgroup from the list in memory */ +hostgroup * find_hostgroup(char *name) { + hostgroup temp_hostgroup; + + if(name == NULL) + return NULL; + + temp_hostgroup.group_name = name; + + return skiplist_find_first(object_skiplists[HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL); + } + + +/* find a servicegroup from the list in memory */ +servicegroup * find_servicegroup(char *name) { + servicegroup temp_servicegroup; + + if(name == NULL) + return NULL; + + temp_servicegroup.group_name = name; + + return skiplist_find_first(object_skiplists[SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL); + } + + +/* find a contact from the list in memory */ +contact * find_contact(char *name) { + contact temp_contact; + + if(name == NULL) + return NULL; + + temp_contact.name = name; + + return skiplist_find_first(object_skiplists[CONTACT_SKIPLIST], &temp_contact, NULL); + } + + +/* find a contact group from the list in memory */ +contactgroup * find_contactgroup(char *name) { + contactgroup temp_contactgroup; + + if(name == NULL) + return NULL; + + temp_contactgroup.group_name = name; + + return skiplist_find_first(object_skiplists[CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL); + } + + +/* given a command name, find a command from the list in memory */ +command * find_command(char *name) { + command temp_command; + + if(name == NULL) + return NULL; + + temp_command.name = name; + + return skiplist_find_first(object_skiplists[COMMAND_SKIPLIST], &temp_command, NULL); + } + + +/* given a host/service name, find the service in the list in memory */ +service * find_service(char *host_name, char *svc_desc) { + service temp_service; + + if(host_name == NULL || svc_desc == NULL) + return NULL; + + temp_service.host_name = host_name; + temp_service.description = svc_desc; + + return skiplist_find_first(object_skiplists[SERVICE_SKIPLIST], &temp_service, NULL); + } + + + + +/******************************************************************/ +/******************* OBJECT TRAVERSAL FUNCTIONS *******************/ +/******************************************************************/ + +hostescalation *get_first_hostescalation_by_host(char *host_name, void **ptr) { + hostescalation temp_hostescalation; + + if(host_name == NULL) + return NULL; + + temp_hostescalation.host_name = host_name; + + return skiplist_find_first(object_skiplists[HOSTESCALATION_SKIPLIST], &temp_hostescalation, ptr); + } + + +hostescalation *get_next_hostescalation_by_host(char *host_name, void **ptr) { + hostescalation temp_hostescalation; + + if(host_name == NULL) + return NULL; + + temp_hostescalation.host_name = host_name; + + return skiplist_find_next(object_skiplists[HOSTESCALATION_SKIPLIST], &temp_hostescalation, ptr); + } + + +serviceescalation *get_first_serviceescalation_by_service(char *host_name, char *svc_description, void **ptr) { + serviceescalation temp_serviceescalation; + + if(host_name == NULL || svc_description == NULL) + return NULL; + + temp_serviceescalation.host_name = host_name; + temp_serviceescalation.description = svc_description; + + return skiplist_find_first(object_skiplists[SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, ptr); + } + + +serviceescalation *get_next_serviceescalation_by_service(char *host_name, char *svc_description, void **ptr) { + serviceescalation temp_serviceescalation; + + if(host_name == NULL || svc_description == NULL) + return NULL; + + temp_serviceescalation.host_name = host_name; + temp_serviceescalation.description = svc_description; + + return skiplist_find_next(object_skiplists[SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, ptr); + } + + +hostdependency *get_first_hostdependency_by_dependent_host(char *host_name, void **ptr) { + hostdependency temp_hostdependency; + + if(host_name == NULL) + return NULL; + + temp_hostdependency.dependent_host_name = host_name; + + return skiplist_find_first(object_skiplists[HOSTDEPENDENCY_SKIPLIST], &temp_hostdependency, ptr); + } + + +hostdependency *get_next_hostdependency_by_dependent_host(char *host_name, void **ptr) { + hostdependency temp_hostdependency; + + if(host_name == NULL || ptr == NULL) + return NULL; + + temp_hostdependency.dependent_host_name = host_name; + + return skiplist_find_next(object_skiplists[HOSTDEPENDENCY_SKIPLIST], &temp_hostdependency, ptr); + } + + +servicedependency *get_first_servicedependency_by_dependent_service(char *host_name, char *svc_description, void **ptr) { + servicedependency temp_servicedependency; + + if(host_name == NULL || svc_description == NULL) + return NULL; + + temp_servicedependency.dependent_host_name = host_name; + temp_servicedependency.dependent_service_description = svc_description; + + return skiplist_find_first(object_skiplists[SERVICEDEPENDENCY_SKIPLIST], &temp_servicedependency, ptr); + } + + +servicedependency *get_next_servicedependency_by_dependent_service(char *host_name, char *svc_description, void **ptr) { + servicedependency temp_servicedependency; + + if(host_name == NULL || svc_description == NULL || ptr == NULL) + return NULL; + + temp_servicedependency.dependent_host_name = host_name; + temp_servicedependency.dependent_service_description = svc_description; + + return skiplist_find_next(object_skiplists[SERVICEDEPENDENCY_SKIPLIST], &temp_servicedependency, ptr); + + return NULL; + } + + +#ifdef NSCORE +/* adds a object to a list of objects */ +int add_object_to_objectlist(objectlist **list, void *object_ptr) { + objectlist *temp_item = NULL; + objectlist *new_item = NULL; + + if(list == NULL || object_ptr == NULL) + return ERROR; + + /* skip this object if its already in the list */ + for(temp_item = *list; temp_item; temp_item = temp_item->next) { + if(temp_item->object_ptr == object_ptr) + break; + } + if(temp_item) + return OK; + + /* allocate memory for a new list item */ + if((new_item = (objectlist *)malloc(sizeof(objectlist))) == NULL) + return ERROR; + + /* initialize vars */ + new_item->object_ptr = object_ptr; + + /* add new item to head of list */ + new_item->next = *list; + *list = new_item; + + return OK; + } + + + +/* frees memory allocated to a temporary object list */ +int free_objectlist(objectlist **temp_list) { + objectlist *this_objectlist = NULL; + objectlist *next_objectlist = NULL; + + if(temp_list == NULL) + return ERROR; + + /* free memory allocated to object list */ + for(this_objectlist = *temp_list; this_objectlist != NULL; this_objectlist = next_objectlist) { + next_objectlist = this_objectlist->next; + my_free(this_objectlist); + } + + *temp_list = NULL; + + return OK; + } +#endif + + + +/******************************************************************/ +/********************* OBJECT QUERY FUNCTIONS *********************/ +/******************************************************************/ + +/* determines whether or not a specific host is an immediate child of another host */ +int is_host_immediate_child_of_host(host *parent_host, host *child_host) { + hostsmember *temp_hostsmember = NULL; + + /* not enough data */ + if(child_host == NULL) + return FALSE; + + /* root/top-level hosts */ + if(parent_host == NULL) { + if(child_host->parent_hosts == NULL) + return TRUE; + } + + /* mid-level/bottom hosts */ + else { + + for(temp_hostsmember = child_host->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { +#ifdef NSCORE + if(temp_hostsmember->host_ptr == parent_host) + return TRUE; +#else + if(!strcmp(temp_hostsmember->host_name, parent_host->name)) + return TRUE; +#endif + } + } + + return FALSE; + } + + +/* determines whether or not a specific host is an immediate parent of another host */ +int is_host_immediate_parent_of_host(host *child_host, host *parent_host) { + + if(is_host_immediate_child_of_host(parent_host, child_host) == TRUE) + return TRUE; + + return FALSE; + } + + +/* returns a count of the immediate children for a given host */ +/* NOTE: This function is only used by the CGIS */ +int number_of_immediate_child_hosts(host *hst) { + int children = 0; + host *temp_host = NULL; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_host_immediate_child_of_host(hst, temp_host) == TRUE) + children++; + } + + return children; + } + + +/* returns a count of the total children for a given host */ +/* NOTE: This function is only used by the CGIS */ +int number_of_total_child_hosts(host *hst) { + int children = 0; + host *temp_host = NULL; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_host_immediate_child_of_host(hst, temp_host) == TRUE) + children += number_of_total_child_hosts(temp_host) + 1; + } + + return children; + } + + +/* get the number of immediate parent hosts for a given host */ +/* NOTE: This function is only used by the CGIS */ +int number_of_immediate_parent_hosts(host *hst) { + int parents = 0; + host *temp_host = NULL; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_host_immediate_parent_of_host(hst, temp_host) == TRUE) { + parents++; + } + } + + return parents; + } + + +/* get the total number of parent hosts for a given host */ +/* NOTE: This function is only used by the CGIS */ +int number_of_total_parent_hosts(host *hst) { + int parents = 0; + host *temp_host = NULL; + + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + if(is_host_immediate_parent_of_host(hst, temp_host) == TRUE) { + parents += number_of_total_parent_hosts(temp_host) + 1; + } + } + + return parents; + } + + +/* tests whether a host is a member of a particular hostgroup */ +/* NOTE: This function is only used by the CGIS */ +int is_host_member_of_hostgroup(hostgroup *group, host *hst) { + hostsmember *temp_hostsmember = NULL; + + if(group == NULL || hst == NULL) + return FALSE; + + for(temp_hostsmember = group->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) { +#ifdef NSCORE + if(temp_hostsmember->host_ptr == hst) + return TRUE; +#else + if(!strcmp(temp_hostsmember->host_name, hst->name)) + return TRUE; +#endif + } + + return FALSE; + } + + +/* tests whether a host is a member of a particular servicegroup */ +/* NOTE: This function is only used by the CGIS */ +int is_host_member_of_servicegroup(servicegroup *group, host *hst) { + servicesmember *temp_servicesmember = NULL; + + if(group == NULL || hst == NULL) + return FALSE; + + for(temp_servicesmember = group->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { +#ifdef NSCORE + if(temp_servicesmember->service_ptr != NULL && temp_servicesmember->service_ptr->host_ptr == hst) + return TRUE; +#else + if(!strcmp(temp_servicesmember->host_name, hst->name)) + return TRUE; +#endif + } + + return FALSE; + } + + +/* tests whether a service is a member of a particular servicegroup */ +/* NOTE: This function is only used by the CGIS */ +int is_service_member_of_servicegroup(servicegroup *group, service *svc) { + servicesmember *temp_servicesmember = NULL; + + if(group == NULL || svc == NULL) + return FALSE; + + for(temp_servicesmember = group->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) { +#ifdef NSCORE + if(temp_servicesmember->service_ptr == svc) + return TRUE; +#else + if(!strcmp(temp_servicesmember->host_name, svc->host_name) && !strcmp(temp_servicesmember->service_description, svc->description)) + return TRUE; +#endif + } + + return FALSE; + } + + +/* + * tests whether a contact is a member of a particular contactgroup. + * The mk-livestatus eventbroker module uses this, so it must hang + * around until 4.0 to prevent api breakage. + * The cgi's stopped using it quite long ago though, so we need only + * compile it if we're building the core + */ +int is_contact_member_of_contactgroup(contactgroup *group, contact *cntct) { + contactsmember *member; + contact *temp_contact = NULL; + + if(!group || !cntct) + return FALSE; + + /* search all contacts in this contact group */ + for(member = group->members; member; member = member->next) { +#ifdef NSCORE + temp_contact = member->contact_ptr; +#else + temp_contact = find_contact(member->contact_name); +#endif + if(temp_contact == NULL) + continue; + if(temp_contact == cntct) + return TRUE; + } + + return FALSE; + } + +/* tests whether a contact is a contact for a particular host */ +int is_contact_for_host(host *hst, contact *cntct) { + contactsmember *temp_contactsmember = NULL; + contact *temp_contact = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + contactgroup *temp_contactgroup = NULL; + + if(hst == NULL || cntct == NULL) { + return FALSE; + } + + /* search all individual contacts of this host */ + for(temp_contactsmember = hst->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { +#ifdef NSCORE + temp_contact = temp_contactsmember->contact_ptr; +#else + temp_contact = find_contact(temp_contactsmember->contact_name); +#endif + if(temp_contact == NULL) + continue; + if(temp_contact == cntct) + return TRUE; + } + + /* search all contactgroups of this host */ + for(temp_contactgroupsmember = hst->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { +#ifdef NSCORE + temp_contactgroup = temp_contactgroupsmember->group_ptr; +#else + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); +#endif + if(temp_contactgroup == NULL) + continue; + if(is_contact_member_of_contactgroup(temp_contactgroup, cntct)) + return TRUE; + } + + return FALSE; + } + + + +/* tests whether or not a contact is an escalated contact for a particular host */ +int is_escalated_contact_for_host(host *hst, contact *cntct) { + contactsmember *temp_contactsmember = NULL; + contact *temp_contact = NULL; + hostescalation *temp_hostescalation = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + contactgroup *temp_contactgroup = NULL; + void *ptr = NULL; + + + /* search all host escalations */ + for(temp_hostescalation = get_first_hostescalation_by_host(hst->name, &ptr); temp_hostescalation != NULL; temp_hostescalation = get_next_hostescalation_by_host(hst->name, &ptr)) { + + /* search all contacts of this host escalation */ + for(temp_contactsmember = temp_hostescalation->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { +#ifdef NSCORE + temp_contact = temp_contactsmember->contact_ptr; +#else + temp_contact = find_contact(temp_contactsmember->contact_name); +#endif + if(temp_contact == NULL) + continue; + if(temp_contact == cntct) + return TRUE; + } + + /* search all contactgroups of this host escalation */ + for(temp_contactgroupsmember = temp_hostescalation->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { +#ifdef NSCORE + temp_contactgroup = temp_contactgroupsmember->group_ptr; +#else + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); +#endif + if(temp_contactgroup == NULL) + continue; + if(is_contact_member_of_contactgroup(temp_contactgroup, cntct)) + return TRUE; + + } + } + + return FALSE; + } + + +/* tests whether a contact is a contact for a particular service */ +int is_contact_for_service(service *svc, contact *cntct) { + contactsmember *temp_contactsmember = NULL; + contact *temp_contact = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + contactgroup *temp_contactgroup = NULL; + + if(svc == NULL || cntct == NULL) + return FALSE; + + /* search all individual contacts of this service */ + for(temp_contactsmember = svc->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { +#ifdef NSCORE + temp_contact = temp_contactsmember->contact_ptr; +#else + temp_contact = find_contact(temp_contactsmember->contact_name); +#endif + + if(temp_contact == cntct) + return TRUE; + } + + /* search all contactgroups of this service */ + for(temp_contactgroupsmember = svc->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { +#ifdef NSCORE + temp_contactgroup = temp_contactgroupsmember->group_ptr; +#else + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); +#endif + if(temp_contactgroup == NULL) + continue; + if(is_contact_member_of_contactgroup(temp_contactgroup, cntct)) + return TRUE; + + } + + return FALSE; + } + + + +/* tests whether or not a contact is an escalated contact for a particular service */ +int is_escalated_contact_for_service(service *svc, contact *cntct) { + serviceescalation *temp_serviceescalation = NULL; + contactsmember *temp_contactsmember = NULL; + contact *temp_contact = NULL; + contactgroupsmember *temp_contactgroupsmember = NULL; + contactgroup *temp_contactgroup = NULL; + void *ptr = NULL; + + /* search all the service escalations */ + for(temp_serviceescalation = get_first_serviceescalation_by_service(svc->host_name, svc->description, &ptr); temp_serviceescalation != NULL; temp_serviceescalation = get_next_serviceescalation_by_service(svc->host_name, svc->description, &ptr)) { + + /* search all contacts of this service escalation */ + for(temp_contactsmember = temp_serviceescalation->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { +#ifdef NSCORE + temp_contact = temp_contactsmember->contact_ptr; +#else + temp_contact = find_contact(temp_contactsmember->contact_name); +#endif + if(temp_contact == NULL) + continue; + if(temp_contact == cntct) + return TRUE; + } + + /* search all contactgroups of this service escalation */ + for(temp_contactgroupsmember = temp_serviceescalation->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) { +#ifdef NSCORE + temp_contactgroup = temp_contactgroupsmember->group_ptr; +#else + temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name); +#endif + if(temp_contactgroup == NULL) + continue; + if(is_contact_member_of_contactgroup(temp_contactgroup, cntct)) + return TRUE; + } + } + + return FALSE; + } + + +#ifdef NSCORE + +/* checks to see if there exists a circular dependency for a service */ +int check_for_circular_servicedependency_path(servicedependency *root_dep, servicedependency *dep, int dependency_type) { + servicedependency *temp_sd = NULL; + + if(root_dep == NULL || dep == NULL) + return FALSE; + + /* this is not the proper dependency type */ + if(root_dep->dependency_type != dependency_type || dep->dependency_type != dependency_type) + return FALSE; + + /* don't go into a loop, don't bother checking anymore if we know this dependency already has a loop */ + if(root_dep->contains_circular_path == TRUE) + return TRUE; + + /* dependency has already been checked - there is a path somewhere, but it may not be for this particular dep... */ + /* this should speed up detection for some loops */ + if(dep->circular_path_checked == TRUE) + return FALSE; + + /* set the check flag so we don't get into an infinite loop */ + dep->circular_path_checked = TRUE; + + /* is this service dependent on the root service? */ + if(dep != root_dep) { + if(root_dep->dependent_service_ptr == dep->master_service_ptr) { + root_dep->contains_circular_path = TRUE; + dep->contains_circular_path = TRUE; + return TRUE; + } + } + + /* notification dependencies are ok at this point as long as they don't inherit */ + if(dependency_type == NOTIFICATION_DEPENDENCY && dep->inherits_parent == FALSE) + return FALSE; + + /* check all parent dependencies */ + for(temp_sd = servicedependency_list; temp_sd != NULL; temp_sd = temp_sd->next) { + + /* only check parent dependencies */ + if(dep->master_service_ptr != temp_sd->dependent_service_ptr) + continue; + + if(check_for_circular_servicedependency_path(root_dep, temp_sd, dependency_type) == TRUE) + return TRUE; + } + + return FALSE; + } + + +/* checks to see if there exists a circular dependency for a host */ +int check_for_circular_hostdependency_path(hostdependency *root_dep, hostdependency *dep, int dependency_type) { + hostdependency *temp_hd = NULL; + + if(root_dep == NULL || dep == NULL) + return FALSE; + + /* this is not the proper dependency type */ + if(root_dep->dependency_type != dependency_type || dep->dependency_type != dependency_type) + return FALSE; + + /* don't go into a loop, don't bother checking anymore if we know this dependency already has a loop */ + if(root_dep->contains_circular_path == TRUE) + return TRUE; + + /* dependency has already been checked - there is a path somewhere, but it may not be for this particular dep... */ + /* this should speed up detection for some loops */ + if(dep->circular_path_checked == TRUE) + return FALSE; + + /* set the check flag so we don't get into an infinite loop */ + dep->circular_path_checked = TRUE; + + /* is this host dependent on the root host? */ + if(dep != root_dep) { + if(root_dep->dependent_host_ptr == dep->master_host_ptr) { + root_dep->contains_circular_path = TRUE; + dep->contains_circular_path = TRUE; + return TRUE; + } + } + + /* notification dependencies are ok at this point as long as they don't inherit */ + if(dependency_type == NOTIFICATION_DEPENDENCY && dep->inherits_parent == FALSE) + return FALSE; + + /* check all parent dependencies */ + for(temp_hd = hostdependency_list; temp_hd != NULL; temp_hd = temp_hd->next) { + + /* only check parent dependencies */ + if(dep->master_host_ptr != temp_hd->dependent_host_ptr) + continue; + + if(check_for_circular_hostdependency_path(root_dep, temp_hd, dependency_type) == TRUE) + return TRUE; + } + + return FALSE; + } + +#endif + + + + +/******************************************************************/ +/******************* OBJECT DELETION FUNCTIONS ********************/ +/******************************************************************/ + + +/* free all allocated memory for objects */ +int free_object_data(void) { + timeperiod *this_timeperiod = NULL; + timeperiod *next_timeperiod = NULL; + daterange *this_daterange = NULL; + daterange *next_daterange = NULL; + timerange *this_timerange = NULL; + timerange *next_timerange = NULL; + timeperiodexclusion *this_timeperiodexclusion = NULL; + timeperiodexclusion *next_timeperiodexclusion = NULL; + host *this_host = NULL; + host *next_host = NULL; + hostsmember *this_hostsmember = NULL; + hostsmember *next_hostsmember = NULL; + hostgroup *this_hostgroup = NULL; + hostgroup *next_hostgroup = NULL; + servicegroup *this_servicegroup = NULL; + servicegroup *next_servicegroup = NULL; + servicesmember *this_servicesmember = NULL; + servicesmember *next_servicesmember = NULL; + contact *this_contact = NULL; + contact *next_contact = NULL; + contactgroup *this_contactgroup = NULL; + contactgroup *next_contactgroup = NULL; + contactsmember *this_contactsmember = NULL; + contactsmember *next_contactsmember = NULL; + contactgroupsmember *this_contactgroupsmember = NULL; + contactgroupsmember *next_contactgroupsmember = NULL; + customvariablesmember *this_customvariablesmember = NULL; + customvariablesmember *next_customvariablesmember = NULL; + service *this_service = NULL; + service *next_service = NULL; + command *this_command = NULL; + command *next_command = NULL; + commandsmember *this_commandsmember = NULL; + commandsmember *next_commandsmember = NULL; + serviceescalation *this_serviceescalation = NULL; + serviceescalation *next_serviceescalation = NULL; + servicedependency *this_servicedependency = NULL; + servicedependency *next_servicedependency = NULL; + hostdependency *this_hostdependency = NULL; + hostdependency *next_hostdependency = NULL; + hostescalation *this_hostescalation = NULL; + hostescalation *next_hostescalation = NULL; + register int x = 0; + register int i = 0; + + + /**** free memory for the timeperiod list ****/ + this_timeperiod = timeperiod_list; + while(this_timeperiod != NULL) { + + /* free the exception time ranges contained in this timeperiod */ + for(x = 0; x < DATERANGE_TYPES; x++) { + + for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = next_daterange) { + next_daterange = this_daterange->next; + for(this_timerange = this_daterange->times; this_timerange != NULL; this_timerange = next_timerange) { + next_timerange = this_timerange->next; + my_free(this_timerange); + } + my_free(this_daterange); + } + } + + /* free the day time ranges contained in this timeperiod */ + for(x = 0; x < 7; x++) { + + for(this_timerange = this_timeperiod->days[x]; this_timerange != NULL; this_timerange = next_timerange) { + next_timerange = this_timerange->next; + my_free(this_timerange); + } + } + + /* free exclusions */ + for(this_timeperiodexclusion = this_timeperiod->exclusions; this_timeperiodexclusion != NULL; this_timeperiodexclusion = next_timeperiodexclusion) { + next_timeperiodexclusion = this_timeperiodexclusion->next; + my_free(this_timeperiodexclusion->timeperiod_name); + my_free(this_timeperiodexclusion); + } + + next_timeperiod = this_timeperiod->next; + my_free(this_timeperiod->name); + my_free(this_timeperiod->alias); + my_free(this_timeperiod); + this_timeperiod = next_timeperiod; + } + + /* reset pointers */ + timeperiod_list = NULL; + + + /**** free memory for the host list ****/ + this_host = host_list; + while(this_host != NULL) { + + next_host = this_host->next; + + /* free memory for parent hosts */ + this_hostsmember = this_host->parent_hosts; + while(this_hostsmember != NULL) { + next_hostsmember = this_hostsmember->next; + my_free(this_hostsmember->host_name); + my_free(this_hostsmember); + this_hostsmember = next_hostsmember; + } + + /* free memory for child host links */ + this_hostsmember = this_host->child_hosts; + while(this_hostsmember != NULL) { + next_hostsmember = this_hostsmember->next; + my_free(this_hostsmember->host_name); + my_free(this_hostsmember); + this_hostsmember = next_hostsmember; + } + + /* free memory for service links */ + this_servicesmember = this_host->services; + while(this_servicesmember != NULL) { + next_servicesmember = this_servicesmember->next; + my_free(this_servicesmember->host_name); + my_free(this_servicesmember->service_description); + my_free(this_servicesmember); + this_servicesmember = next_servicesmember; + } + + /* free memory for contact groups */ + this_contactgroupsmember = this_host->contact_groups; + while(this_contactgroupsmember != NULL) { + next_contactgroupsmember = this_contactgroupsmember->next; + my_free(this_contactgroupsmember->group_name); + my_free(this_contactgroupsmember); + this_contactgroupsmember = next_contactgroupsmember; + } + + /* free memory for contacts */ + this_contactsmember = this_host->contacts; + while(this_contactsmember != NULL) { + next_contactsmember = this_contactsmember->next; + my_free(this_contactsmember->contact_name); + my_free(this_contactsmember); + this_contactsmember = next_contactsmember; + } + + /* free memory for custom variables */ + this_customvariablesmember = this_host->custom_variables; + while(this_customvariablesmember != NULL) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + this_customvariablesmember = next_customvariablesmember; + } + + my_free(this_host->name); + my_free(this_host->display_name); + my_free(this_host->alias); + my_free(this_host->address); +#ifdef NSCORE + my_free(this_host->plugin_output); + my_free(this_host->long_plugin_output); + my_free(this_host->perf_data); + + free_objectlist(&this_host->hostgroups_ptr); +#endif + my_free(this_host->check_period); + my_free(this_host->host_check_command); + my_free(this_host->event_handler); + my_free(this_host->failure_prediction_options); + my_free(this_host->notification_period); + my_free(this_host->notes); + my_free(this_host->notes_url); + my_free(this_host->action_url); + my_free(this_host->icon_image); + my_free(this_host->icon_image_alt); + my_free(this_host->vrml_image); + my_free(this_host->statusmap_image); + my_free(this_host); + this_host = next_host; + } + + /* reset pointers */ + host_list = NULL; + + + /**** free memory for the host group list ****/ + this_hostgroup = hostgroup_list; + while(this_hostgroup != NULL) { + + /* free memory for the group members */ + this_hostsmember = this_hostgroup->members; + while(this_hostsmember != NULL) { + next_hostsmember = this_hostsmember->next; + my_free(this_hostsmember->host_name); + my_free(this_hostsmember); + this_hostsmember = next_hostsmember; + } + + next_hostgroup = this_hostgroup->next; + my_free(this_hostgroup->group_name); + my_free(this_hostgroup->alias); + my_free(this_hostgroup->notes); + my_free(this_hostgroup->notes_url); + my_free(this_hostgroup->action_url); + my_free(this_hostgroup); + this_hostgroup = next_hostgroup; + } + + /* reset pointers */ + hostgroup_list = NULL; + + + /**** free memory for the service group list ****/ + this_servicegroup = servicegroup_list; + while(this_servicegroup != NULL) { + + /* free memory for the group members */ + this_servicesmember = this_servicegroup->members; + while(this_servicesmember != NULL) { + next_servicesmember = this_servicesmember->next; + my_free(this_servicesmember->host_name); + my_free(this_servicesmember->service_description); + my_free(this_servicesmember); + this_servicesmember = next_servicesmember; + } + + next_servicegroup = this_servicegroup->next; + my_free(this_servicegroup->group_name); + my_free(this_servicegroup->alias); + my_free(this_servicegroup->notes); + my_free(this_servicegroup->notes_url); + my_free(this_servicegroup->action_url); + my_free(this_servicegroup); + this_servicegroup = next_servicegroup; + } + + /* reset pointers */ + servicegroup_list = NULL; + + + /**** free memory for the contact list ****/ + this_contact = contact_list; + while(this_contact != NULL) { + + /* free memory for the host notification commands */ + this_commandsmember = this_contact->host_notification_commands; + while(this_commandsmember != NULL) { + next_commandsmember = this_commandsmember->next; + if(this_commandsmember->command != NULL) + my_free(this_commandsmember->command); + my_free(this_commandsmember); + this_commandsmember = next_commandsmember; + } + + /* free memory for the service notification commands */ + this_commandsmember = this_contact->service_notification_commands; + while(this_commandsmember != NULL) { + next_commandsmember = this_commandsmember->next; + if(this_commandsmember->command != NULL) + my_free(this_commandsmember->command); + my_free(this_commandsmember); + this_commandsmember = next_commandsmember; + } + + /* free memory for custom variables */ + this_customvariablesmember = this_contact->custom_variables; + while(this_customvariablesmember != NULL) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + this_customvariablesmember = next_customvariablesmember; + } + + next_contact = this_contact->next; + my_free(this_contact->name); + my_free(this_contact->alias); + my_free(this_contact->email); + my_free(this_contact->pager); + for(i = 0; i < MAX_CONTACT_ADDRESSES; i++) + my_free(this_contact->address[i]); + my_free(this_contact->host_notification_period); + my_free(this_contact->service_notification_period); + +#ifdef NSCORE + free_objectlist(&this_contact->contactgroups_ptr); +#endif + + my_free(this_contact); + this_contact = next_contact; + } + + /* reset pointers */ + contact_list = NULL; + + + /**** free memory for the contact group list ****/ + this_contactgroup = contactgroup_list; + while(this_contactgroup != NULL) { + + /* free memory for the group members */ + this_contactsmember = this_contactgroup->members; + while(this_contactsmember != NULL) { + next_contactsmember = this_contactsmember->next; + my_free(this_contactsmember->contact_name); + my_free(this_contactsmember); + this_contactsmember = next_contactsmember; + } + + next_contactgroup = this_contactgroup->next; + my_free(this_contactgroup->group_name); + my_free(this_contactgroup->alias); + my_free(this_contactgroup); + this_contactgroup = next_contactgroup; + } + + /* reset pointers */ + contactgroup_list = NULL; + + + /**** free memory for the service list ****/ + this_service = service_list; + while(this_service != NULL) { + + next_service = this_service->next; + + /* free memory for contact groups */ + this_contactgroupsmember = this_service->contact_groups; + while(this_contactgroupsmember != NULL) { + next_contactgroupsmember = this_contactgroupsmember->next; + my_free(this_contactgroupsmember->group_name); + my_free(this_contactgroupsmember); + this_contactgroupsmember = next_contactgroupsmember; + } + + /* free memory for contacts */ + this_contactsmember = this_service->contacts; + while(this_contactsmember != NULL) { + next_contactsmember = this_contactsmember->next; + my_free(this_contactsmember->contact_name); + my_free(this_contactsmember); + this_contactsmember = next_contactsmember; + } + + /* free memory for custom variables */ + this_customvariablesmember = this_service->custom_variables; + while(this_customvariablesmember != NULL) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + this_customvariablesmember = next_customvariablesmember; + } + + my_free(this_service->host_name); + my_free(this_service->description); + my_free(this_service->display_name); + my_free(this_service->service_check_command); +#ifdef NSCORE + my_free(this_service->plugin_output); + my_free(this_service->long_plugin_output); + my_free(this_service->perf_data); + + my_free(this_service->event_handler_args); + my_free(this_service->check_command_args); + + free_objectlist(&this_service->servicegroups_ptr); +#endif + my_free(this_service->notification_period); + my_free(this_service->check_period); + my_free(this_service->event_handler); + my_free(this_service->failure_prediction_options); + my_free(this_service->notes); + my_free(this_service->notes_url); + my_free(this_service->action_url); + my_free(this_service->icon_image); + my_free(this_service->icon_image_alt); + my_free(this_service); + this_service = next_service; + } + + /* reset pointers */ + service_list = NULL; + + + /**** free memory for the command list ****/ + this_command = command_list; + while(this_command != NULL) { + next_command = this_command->next; + my_free(this_command->name); + my_free(this_command->command_line); + my_free(this_command); + this_command = next_command; + } + + /* reset pointers */ + command_list = NULL; + + + /**** free memory for the service escalation list ****/ + this_serviceescalation = serviceescalation_list; + while(this_serviceescalation != NULL) { + + /* free memory for the contact group members */ + this_contactgroupsmember = this_serviceescalation->contact_groups; + while(this_contactgroupsmember != NULL) { + next_contactgroupsmember = this_contactgroupsmember->next; + my_free(this_contactgroupsmember->group_name); + my_free(this_contactgroupsmember); + this_contactgroupsmember = next_contactgroupsmember; + } + + /* free memory for contacts */ + this_contactsmember = this_serviceescalation->contacts; + while(this_contactsmember != NULL) { + next_contactsmember = this_contactsmember->next; + my_free(this_contactsmember->contact_name); + my_free(this_contactsmember); + this_contactsmember = next_contactsmember; + } + + next_serviceescalation = this_serviceescalation->next; + my_free(this_serviceescalation->host_name); + my_free(this_serviceescalation->description); + my_free(this_serviceescalation->escalation_period); + my_free(this_serviceescalation); + this_serviceescalation = next_serviceescalation; + } + + /* reset pointers */ + serviceescalation_list = NULL; + + + /**** free memory for the service dependency list ****/ + this_servicedependency = servicedependency_list; + while(this_servicedependency != NULL) { + next_servicedependency = this_servicedependency->next; + my_free(this_servicedependency->dependency_period); + my_free(this_servicedependency->dependent_host_name); + my_free(this_servicedependency->dependent_service_description); + my_free(this_servicedependency->host_name); + my_free(this_servicedependency->service_description); + my_free(this_servicedependency); + this_servicedependency = next_servicedependency; + } + + /* reset pointers */ + servicedependency_list = NULL; + + + /**** free memory for the host dependency list ****/ + this_hostdependency = hostdependency_list; + while(this_hostdependency != NULL) { + next_hostdependency = this_hostdependency->next; + my_free(this_hostdependency->dependency_period); + my_free(this_hostdependency->dependent_host_name); + my_free(this_hostdependency->host_name); + my_free(this_hostdependency); + this_hostdependency = next_hostdependency; + } + + /* reset pointers */ + hostdependency_list = NULL; + + + /**** free memory for the host escalation list ****/ + this_hostescalation = hostescalation_list; + while(this_hostescalation != NULL) { + + /* free memory for the contact group members */ + this_contactgroupsmember = this_hostescalation->contact_groups; + while(this_contactgroupsmember != NULL) { + next_contactgroupsmember = this_contactgroupsmember->next; + my_free(this_contactgroupsmember->group_name); + my_free(this_contactgroupsmember); + this_contactgroupsmember = next_contactgroupsmember; + } + + /* free memory for contacts */ + this_contactsmember = this_hostescalation->contacts; + while(this_contactsmember != NULL) { + next_contactsmember = this_contactsmember->next; + my_free(this_contactsmember->contact_name); + my_free(this_contactsmember); + this_contactsmember = next_contactsmember; + } + + next_hostescalation = this_hostescalation->next; + my_free(this_hostescalation->host_name); + my_free(this_hostescalation->escalation_period); + my_free(this_hostescalation); + this_hostescalation = next_hostescalation; + } + + /* reset pointers */ + hostescalation_list = NULL; + + /* free object skiplists */ + free_object_skiplists(); + + return OK; + } + diff --git a/common/shared.c b/common/shared.c new file mode 100644 index 0000000..2e61d80 --- /dev/null +++ b/common/shared.c @@ -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; + } diff --git a/common/skiplist.c b/common/skiplist.c new file mode 100644 index 0000000..02bfaf3 --- /dev/null +++ b/common/skiplist.c @@ -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; + } + + + diff --git a/common/snprintf.c b/common/snprintf.c new file mode 100644 index 0000000..d7018eb --- /dev/null +++ b/common/snprintf.c @@ -0,0 +1,1459 @@ +/* + * NOTE: If you change this file, please merge it into rsync, samba, etc. + */ + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE + * + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 + * actually print args for %g and %e + * + * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 + * Since includes.h isn't included here, VA_COPY has to be defined here. I don't + * see any include file that is guaranteed to be here, so I'm defining it + * locally. Fixes AIX and Solaris builds. + * + * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 + * put the ifdef for HAVE_VA_COPY in one place rather than in lots of + * functions + * + * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 + * Fix usage of va_list passed as an arg. Use __va_copy before using it + * when it exists. + * + * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 + * Fix incorrect zpadlen handling in fmtfp. + * Thanks to Ollie Oldham for spotting it. + * few mods to make it easier to compile the tests. + * addedd the "Ollie" test to the floating point ones. + * + * Martin Pool (mbp@samba.org) April 2003 + * Remove NO_CONFIG_H so that the test case can be built within a source + * tree with less trouble. + * Remove unnecessary SAFE_FREE() definition. + * + * Martin Pool (mbp@samba.org) May 2003 + * Put in a prototype for dummy_snprintf() to quiet compiler warnings. + * + * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even + * if the C library has some snprintf functions already. + * + * Darren Tucker (dtucker@zip.com.au) 2005 + * Fix bug allowing read overruns of the source string with "%.*s" + * Usually harmless unless the read runs outside the process' allocation + * (eg if your malloc does guard pages) in which case it will segfault. + * From OpenSSH. Also added test for same. + * + * Simo Sorce (idra@samba.org) Jan 2006 + * + * Add support for position independent parameters + * fix fmtstr now it conforms to sprintf wrt min.max + * + **************************************************************/ + +#ifndef NO_CONFIG_H +/* 02/28/2006 EG changed path to config.h to match Nagios distro */ +#include "../include/config.h" +#else +#define NULL 0 +#endif + +#ifdef TEST_SNPRINTF /* need math library headers for testing */ + +/* In test mode, we pretend that this system doesn't have any snprintf + * functions, regardless of what config.h says. */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +# undef HAVE_C99_VSNPRINTF +# undef HAVE_ASPRINTF +# undef HAVE_VASPRINTF +# include +#endif /* TEST_SNPRINTF */ + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif +#ifdef HAVE_CTYPE_H +#include +#endif +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) +/* only include stdio.h if we are not re-defining snprintf or vsnprintf */ +#include +/* make the compiler happy with an empty file */ +void dummy_snprintf(void); +void dummy_snprintf(void) {} +#endif /* HAVE_SNPRINTF, etc */ + +#ifdef HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif + +#ifdef HAVE_LONG_LONG +#define LLONG long long +#else +#define LLONG long +#endif + +#ifndef VA_COPY +#ifdef HAVE_VA_COPY +#define VA_COPY(dest, src) va_copy(dest, src) +#else +#ifdef HAVE___VA_COPY +#define VA_COPY(dest, src) __va_copy(dest, src) +#else +#define VA_COPY(dest, src) (dest) = (src) +#endif +#endif + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_CHAR 1 +#define DP_C_SHORT 2 +#define DP_C_LONG 3 +#define DP_C_LDOUBLE 4 +#define DP_C_LLONG 5 + +/* Chunk types */ +#define CNK_FMT_STR 0 +#define CNK_INT 1 +#define CNK_OCTAL 2 +#define CNK_UINT 3 +#define CNK_HEX 4 +#define CNK_FLOAT 5 +#define CNK_CHAR 6 +#define CNK_STRING 7 +#define CNK_PTR 8 +#define CNK_NUM 9 +#define CNK_PRCNT 10 + +#define char_to_int(p) ((p)- '0') +#ifndef MAX +#define MAX(p,q) (((p) >= (q)) ? (p) : (q)) +#endif + +/* yes this really must be a ||. Don't muck with this (tridge) */ +#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) + +struct pr_chunk { + int type; /* chunk type */ + int num; /* parameter number */ + int min; + int max; + int flags; + int cflags; + int start; + int len; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + void *pnum; + struct pr_chunk *min_star; + struct pr_chunk *max_star; + struct pr_chunk *next; + }; + +struct pr_chunk_x { + struct pr_chunk **chunks; + int num; + }; + +static size_t dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags); +static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); +static struct pr_chunk *new_chunk(void); +static int add_cnk_list_entry(struct pr_chunk_x **list, + int max_num, struct pr_chunk *chunk); + +static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { + char ch; + int state; + int pflag; + int pnum; + int pfirst; + size_t currlen; + va_list args; + const char *base; + struct pr_chunk *chunks = NULL; + struct pr_chunk *cnk = NULL; + struct pr_chunk_x *clist = NULL; + int max_pos; + size_t ret = -1; + + VA_COPY(args, args_in); + + state = DP_S_DEFAULT; + pfirst = 1; + pflag = 0; + pnum = 0; + + max_pos = 0; + base = format; + ch = *format++; + + /* retrieve the string structure as chunks */ + while(state != DP_S_DONE) { + if(ch == '\0') + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + + if(cnk) { + cnk->next = new_chunk(); + cnk = cnk->next; + } + else { + cnk = new_chunk(); + } + if(!cnk) goto done; + if(!chunks) chunks = cnk; + + if(ch == '%') { + state = DP_S_FLAGS; + ch = *format++; + } + else { + cnk->type = CNK_FMT_STR; + cnk->start = format - base - 1; + while((ch != '\0') && (ch != '%')) ch = *format++; + cnk->len = format - base - cnk->start - 1; + } + break; + case DP_S_FLAGS: + switch(ch) { + case '-': + cnk->flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + cnk->flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + cnk->flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + cnk->flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + cnk->flags |= DP_F_ZERO; + ch = *format++; + break; + case 'I': + /* internationalization not supported yet */ + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if(isdigit((unsigned char)ch)) { + cnk->min = 10 * cnk->min + char_to_int(ch); + ch = *format++; + } + else if(ch == '$') { + if(!pfirst && !pflag) { + /* parameters must be all positioned or none */ + goto done; + } + if(pfirst) { + pfirst = 0; + pflag = 1; + } + if(cnk->min == 0) /* what ?? */ + goto done; + cnk->num = cnk->min; + cnk->min = 0; + ch = *format++; + } + else if(ch == '*') { + if(pfirst) pfirst = 0; + cnk->min_star = new_chunk(); + if(!cnk->min_star) /* out of memory :-( */ + goto done; + cnk->min_star->type = CNK_INT; + if(pflag) { + int num; + ch = *format++; + if(!isdigit((unsigned char)ch)) { + /* parameters must be all positioned or none */ + goto done; + } + for(num = 0; isdigit((unsigned char)ch); ch = *format++) { + num = 10 * num + char_to_int(ch); + } + cnk->min_star->num = num; + if(ch != '$') /* what ?? */ + goto done; + } + else { + cnk->min_star->num = ++pnum; + } + max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star); + if(max_pos == 0) /* out of memory :-( */ + goto done; + ch = *format++; + state = DP_S_DOT; + } + else { + if(pfirst) pfirst = 0; + state = DP_S_DOT; + } + break; + case DP_S_DOT: + if(ch == '.') { + state = DP_S_MAX; + ch = *format++; + } + else { + state = DP_S_MOD; + } + break; + case DP_S_MAX: + if(isdigit((unsigned char)ch)) { + if(cnk->max < 0) + cnk->max = 0; + cnk->max = 10 * cnk->max + char_to_int(ch); + ch = *format++; + } + else if(ch == '$') { + if(!pfirst && !pflag) { + /* parameters must be all positioned or none */ + goto done; + } + if(cnk->max <= 0) /* what ?? */ + goto done; + cnk->num = cnk->max; + cnk->max = -1; + ch = *format++; + } + else if(ch == '*') { + cnk->max_star = new_chunk(); + if(!cnk->max_star) /* out of memory :-( */ + goto done; + cnk->max_star->type = CNK_INT; + if(pflag) { + int num; + ch = *format++; + if(!isdigit((unsigned char)ch)) { + /* parameters must be all positioned or none */ + goto done; + } + for(num = 0; isdigit((unsigned char)ch); ch = *format++) { + num = 10 * num + char_to_int(ch); + } + cnk->max_star->num = num; + if(ch != '$') /* what ?? */ + goto done; + } + else { + cnk->max_star->num = ++pnum; + } + max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star); + if(max_pos == 0) /* out of memory :-( */ + goto done; + + ch = *format++; + state = DP_S_MOD; + } + else { + state = DP_S_MOD; + } + break; + case DP_S_MOD: + switch(ch) { + case 'h': + cnk->cflags = DP_C_SHORT; + ch = *format++; + if(ch == 'h') { + cnk->cflags = DP_C_CHAR; + ch = *format++; + } + break; + case 'l': + cnk->cflags = DP_C_LONG; + ch = *format++; + if(ch == 'l') { /* It's a long long */ + cnk->cflags = DP_C_LLONG; + ch = *format++; + } + break; + case 'L': + cnk->cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + if(cnk->num == 0) cnk->num = ++pnum; + max_pos = add_cnk_list_entry(&clist, max_pos, cnk); + if(max_pos == 0) /* out of memory :-( */ + goto done; + + switch(ch) { + case 'd': + case 'i': + cnk->type = CNK_INT; + break; + case 'o': + cnk->type = CNK_OCTAL; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'u': + cnk->type = CNK_UINT; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'X': + cnk->flags |= DP_F_UP; + case 'x': + cnk->type = CNK_HEX; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'A': + /* hex float not supported yet */ + case 'E': + case 'G': + case 'F': + cnk->flags |= DP_F_UP; + case 'a': + /* hex float not supported yet */ + case 'e': + case 'f': + case 'g': + cnk->type = CNK_FLOAT; + break; + case 'c': + cnk->type = CNK_CHAR; + break; + case 's': + cnk->type = CNK_STRING; + break; + case 'p': + cnk->type = CNK_PTR; + break; + case 'n': + cnk->type = CNK_NUM; + break; + case '%': + cnk->type = CNK_PRCNT; + break; + default: + /* Unknown, bail out*/ + goto done; + } + ch = *format++; + state = DP_S_DEFAULT; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + + /* retieve the format arguments */ + for(pnum = 0; pnum < max_pos; pnum++) { + int i; + + if(clist[pnum].num == 0) { + /* ignoring a parameter should not be permitted + * all parameters must be matched at least once + * BUT seem some system ignore this rule ... + * at least my glibc based system does --SSS + */ +#ifdef DEBUG_SNPRINTF + printf("parameter at position %d not used\n", pnum + 1); +#endif + /* eat the parameter */ + va_arg(args, int); + continue; + } + for(i = 1; i < clist[pnum].num; i++) { + if(clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) { + /* nooo noo no! + * all the references to a parameter + * must be of the same type + */ + goto done; + } + } + cnk = clist[pnum].chunks[0]; + switch(cnk->type) { + case CNK_INT: + if(cnk->cflags == DP_C_SHORT) + cnk->value = va_arg(args, int); + else if(cnk->cflags == DP_C_LONG) + cnk->value = va_arg(args, long int); + else if(cnk->cflags == DP_C_LLONG) + cnk->value = va_arg(args, LLONG); + else + cnk->value = va_arg(args, int); + + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_OCTAL: + case CNK_UINT: + case CNK_HEX: + if(cnk->cflags == DP_C_SHORT) + cnk->value = va_arg(args, unsigned int); + else if(cnk->cflags == DP_C_LONG) + cnk->value = (long)va_arg(args, unsigned long int); + else if(cnk->cflags == DP_C_LLONG) + cnk->value = (LLONG)va_arg(args, unsigned LLONG); + else + cnk->value = (long)va_arg(args, unsigned int); + + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_FLOAT: + if(cnk->cflags == DP_C_LDOUBLE) + cnk->fvalue = va_arg(args, LDOUBLE); + else + cnk->fvalue = va_arg(args, double); + + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->fvalue = cnk->fvalue; + } + break; + + case CNK_CHAR: + cnk->value = va_arg(args, int); + + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_STRING: + cnk->strvalue = va_arg(args, char *); + if(!cnk->strvalue) cnk->strvalue = "(NULL)"; + + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->strvalue = cnk->strvalue; + } + break; + + case CNK_PTR: + cnk->strvalue = va_arg(args, void *); + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->strvalue = cnk->strvalue; + } + break; + + case CNK_NUM: + if(cnk->cflags == DP_C_CHAR) + cnk->pnum = va_arg(args, char *); + else if(cnk->cflags == DP_C_SHORT) + cnk->pnum = va_arg(args, short int *); + else if(cnk->cflags == DP_C_LONG) + cnk->pnum = va_arg(args, long int *); + else if(cnk->cflags == DP_C_LLONG) + cnk->pnum = va_arg(args, LLONG *); + else + cnk->pnum = va_arg(args, int *); + + for(i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->pnum = cnk->pnum; + } + break; + + case CNK_PRCNT: + break; + + default: + /* what ?? */ + goto done; + } + } + /* print out the actual string from chunks */ + currlen = 0; + cnk = chunks; + while(cnk) { + int len, min, max; + + if(cnk->min_star) min = cnk->min_star->value; + else min = cnk->min; + if(cnk->max_star) max = cnk->max_star->value; + else max = cnk->max; + + switch(cnk->type) { + + case CNK_FMT_STR: + if(maxlen != 0 && maxlen > currlen) { + if(maxlen > (currlen + cnk->len)) len = cnk->len; + else len = maxlen - currlen; + + memcpy(&(buffer[currlen]), &(base[cnk->start]), len); + } + currlen += cnk->len; + + break; + + case CNK_INT: + case CNK_UINT: + fmtint(buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags); + break; + + case CNK_OCTAL: + fmtint(buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags); + break; + + case CNK_HEX: + fmtint(buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags); + break; + + case CNK_FLOAT: + fmtfp(buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags); + break; + + case CNK_CHAR: + dopr_outch(buffer, &currlen, maxlen, cnk->value); + break; + + case CNK_STRING: + if(max == -1) { + max = strlen(cnk->strvalue); + } + fmtstr(buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max); + break; + + case CNK_PTR: + fmtint(buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags); + break; + + case CNK_NUM: + if(cnk->cflags == DP_C_CHAR) + *((char *)(cnk->pnum)) = (char)currlen; + else if(cnk->cflags == DP_C_SHORT) + *((short int *)(cnk->pnum)) = (short int)currlen; + else if(cnk->cflags == DP_C_LONG) + *((long int *)(cnk->pnum)) = (long int)currlen; + else if(cnk->cflags == DP_C_LLONG) + *((LLONG *)(cnk->pnum)) = (LLONG)currlen; + else + *((int *)(cnk->pnum)) = (int)currlen; + break; + + case CNK_PRCNT: + dopr_outch(buffer, &currlen, maxlen, '%'); + break; + + default: + /* what ?? */ + goto done; + } + cnk = cnk->next; + } + if(maxlen != 0) { + if(currlen < maxlen - 1) + buffer[currlen] = '\0'; + else if(maxlen > 0) + buffer[maxlen - 1] = '\0'; + } + ret = currlen; + +done: + while(chunks) { + cnk = chunks->next; + free(chunks); + chunks = cnk; + } + if(clist) { + for(pnum = 0; pnum < max_pos; pnum++) { + if(clist[pnum].chunks) free(clist[pnum].chunks); + } + free(clist); + } + return ret; + } + +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) { + int padlen, strln; /* amount to pad */ + int cnt = 0; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if(value == 0) { + value = ""; + } + + for(strln = 0; strln < max && value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if(padlen < 0) + padlen = 0; + if(flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while(padlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + } + while(*value && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, *value++); + ++cnt; + } + while(padlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + } + } + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) { + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if(max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) { + if(value < 0) { + signvalue = '-'; + uvalue = -value; + } + else { + if(flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if(flags & DP_F_SPACE) + signvalue = ' '; + } + } + + if(flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base); + } + while(uvalue && (place < 20)); + if(place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); + if(zpadlen < 0) zpadlen = 0; + if(spadlen < 0) spadlen = 0; + if(flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if(flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place); +#endif + + /* Spaces */ + while(spadlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if(signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if(zpadlen > 0) { + while(zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while(place > 0) + dopr_outch(buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while(spadlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++spadlen; + } + } + +static LDOUBLE abs_val(LDOUBLE value) { + LDOUBLE result = value; + + if(value < 0) + result = -value; + + return result; + } + +static LDOUBLE POW10(int exp) { + LDOUBLE result = 1; + + while(exp) { + result *= 10; + exp--; + } + + return result; + } + +static LLONG ROUND(LDOUBLE value) { + LLONG intpart; + + intpart = (LLONG)value; + value = value - intpart; + if(value >= 0.5) intpart++; + + return intpart; + } + +/* a replacement for modf that doesn't need the math library. Should + be portable, but slow */ +static double my_modf(double x0, double *iptr) { + int i; + long l; + double x = x0; + double f = 1.0; + + for(i = 0; i < 100; i++) { + l = (long)x; + if(l <= (x + 1) && l >= (x - 1)) break; + x *= 0.1; + f *= 10.0; + } + + if(i == 100) { + /* yikes! the number is beyond what we can handle. What do we do? */ + (*iptr) = 0; + return 0; + } + + if(i != 0) { + double i2; + double ret; + + ret = my_modf(x0 - l * f, &i2); + (*iptr) = l * f + i2; + return ret; + } + + (*iptr) = l; + return x - (*iptr); + } + + +static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) { + int signvalue = 0; + double ufvalue; + char iconvert[311]; + char fconvert[311]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + int idx; + double intpart; + double fracpart; + double temp; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if(max < 0) + max = 6; + + ufvalue = abs_val(fvalue); + + if(fvalue < 0) { + signvalue = '-'; + } + else { + if(flags & DP_F_PLUS) { /* Do a sign (+/i) */ + signvalue = '+'; + } + else { + if(flags & DP_F_SPACE) + signvalue = ' '; + } + } + +#if 0 + if(flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + +#if 0 + if(max == 0) ufvalue += 0.5; /* if max = 0 we must round */ +#endif + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if(max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + + temp = ufvalue; + my_modf(temp, &intpart); + + fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); + + if(fracpart >= POW10(max)) { + intpart++; + fracpart -= POW10(max); + } + + + /* Convert integer part */ + do { + temp = intpart * 0.1; + my_modf(temp, &intpart); + idx = (int)((temp - intpart + 0.05) * 10.0); + /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ + /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ + iconvert[iplace++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef")[idx]; + } + while(intpart && (iplace < 311)); + if(iplace == 311) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + if(fracpart) { + do { + temp = fracpart * 0.1; + my_modf(temp, &fracpart); + idx = (int)((temp - fracpart + 0.05) * 10.0); + /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ + /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ + fconvert[fplace++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef")[idx]; + } + while(fracpart && (fplace < 311)); + if(fplace == 311) fplace--; + } + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if(zpadlen < 0) zpadlen = 0; + if(padlen < 0) + padlen = 0; + if(flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if((flags & DP_F_ZERO) && (padlen > 0)) { + if(signvalue) { + dopr_outch(buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while(padlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --padlen; + } + } + while(padlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + } + if(signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + while(iplace > 0) + dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + +#ifdef DEBUG_SNPRINTF + printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); +#endif + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if(max > 0) { + dopr_outch(buffer, currlen, maxlen, '.'); + + while(zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while(fplace > 0) + dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + } + + while(padlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + } + } + +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { + if(*currlen < maxlen) { + buffer[(*currlen)] = c; + } + (*currlen)++; + } + +static struct pr_chunk *new_chunk(void) { + struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk)); + + if(!new_c) + return NULL; + + new_c->type = 0; + new_c->num = 0; + new_c->min = 0; + new_c->min_star = NULL; + new_c->max = -1; + new_c->max_star = NULL; + new_c->flags = 0; + new_c->cflags = 0; + new_c->start = 0; + new_c->len = 0; + new_c->value = 0; + new_c->fvalue = 0; + new_c->strvalue = NULL; + new_c->pnum = NULL; + new_c->next = NULL; + + return new_c; + } + +static int add_cnk_list_entry(struct pr_chunk_x **list, + int max_num, struct pr_chunk *chunk) { + struct pr_chunk_x *l; + struct pr_chunk **c; + int max; + int cnum; + int i, pos; + + if(chunk->num > max_num) { + max = chunk->num; + + if(*list == NULL) { + l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max); + pos = 0; + } + else { + l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max); + pos = max_num; + } + if(l == NULL) { + for(i = 0; i < max; i++) { + if((*list)[i].chunks) free((*list)[i].chunks); + } + return 0; + } + for(i = pos; i < max; i++) { + l[i].chunks = NULL; + l[i].num = 0; + } + } + else { + l = *list; + max = max_num; + } + + i = chunk->num - 1; + cnum = l[i].num + 1; + if(l[i].chunks == NULL) { + c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); + } + else { + c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum); + } + if(c == NULL) { + for(i = 0; i < max; i++) { + if(l[i].chunks) free(l[i].chunks); + } + return 0; + } + c[l[i].num] = chunk; + l[i].chunks = c; + l[i].num = cnum; + + *list = l; + return max; + } + +int smb_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { + return dopr(str, count, fmt, args); + } +#define vsnprintf smb_vsnprintf +#endif + +/* yes this really must be a ||. Don't muck with this (tridge) + * + * The logic for these two is that we need our own definition if the + * OS *either* has no definition of *sprintf, or if it does have one + * that doesn't work properly according to the autoconf test. + */ +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) +int smb_snprintf(char *str, size_t count, const char *fmt, ...) { + size_t ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(str, count, fmt, ap); + va_end(ap); + return ret; + } +#define snprintf smb_snprintf +#endif + +#endif + +#ifndef HAVE_VASPRINTF +int vasprintf(char **ptr, const char *format, va_list ap) { + int ret; + va_list ap2; + + VA_COPY(ap2, ap); + + ret = vsnprintf(NULL, 0, format, ap2); + if(ret <= 0) return ret; + + (*ptr) = (char *)malloc(ret + 1); + if(!*ptr) return -1; + + VA_COPY(ap2, ap); + + ret = vsnprintf(*ptr, ret + 1, format, ap2); + + return ret; + } +#endif + + +#ifndef HAVE_ASPRINTF +int asprintf(char **ptr, const char *format, ...) { + va_list ap; + int ret; + + *ptr = NULL; + va_start(ap, format); + ret = vasprintf(ptr, format, ap); + va_end(ap); + + return ret; + } +#endif + +#ifdef TEST_SNPRINTF + +int sprintf(char *str, const char *fmt, ...); + +int main(void) { + char buf1[1024]; + char buf2[1024]; + char *buf3; + char *fp_fmt[] = { + "%1.1f", + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + "%.0f", + "%f", + "%-8.8f", + "%-9.9f", + NULL + }; + double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 5.030201, 0.00205, + /* END LIST */ 0 + }; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 1234567890}; + char *str_fmt[] = { + "%10.5s", + "%-10.5s", + "%5.10s", + "%-5.10s", + "%10.1s", + "%0.10s", + "%10.0s", + "%1.10s", + "%s", + "%.1s", + "%.10s", + "%10s", + NULL + }; + char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; + int x, y; + int fail = 0; + int num = 0; + int l1, l2; + + printf("Testing snprintf format codes against system sprintf...\n"); + + for(x = 0; fp_fmt[x] ; x++) { + for(y = 0; fp_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]); + l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); + sprintf(buf2, fp_fmt[x], fp_nums[y]); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + fp_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + + for(x = 0; int_fmt[x] ; x++) { + for(y = 0; int_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]); + l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); + sprintf(buf2, int_fmt[x], int_nums[y]); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + int_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + + for(x = 0; str_fmt[x] ; x++) { + for(y = 0; str_vals[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]); + l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); + sprintf(buf2, str_fmt[x], str_vals[y]); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + str_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + +#define BUFSZ 2048 + + buf1[0] = buf2[0] = '\0'; + if((buf3 = malloc(BUFSZ)) == NULL) { + fail++; + } + else { + num++; + memset(buf3, 'a', BUFSZ); + snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); + buf1[1023] = '\0'; + if(strcmp(buf1, "a") != 0) { + printf("length limit buf1 '%s' expected 'a'\n", buf1); + fail++; + } + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); + l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); + fail++; + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); + l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); + fail++; + } +#if 0 + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890); + l2 = sprintf(buf2, "%lld", (LLONG)1234567890); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%lld", l1, buf1, l2, buf2); + fail++; + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123); + l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123); + buf1[1023] = buf1[1023] = '\0'; + if(strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%Lf", l1, buf1, l2, buf2); + fail++; + } +#endif + printf("%d tests failed out of %d.\n", fail, num); + + printf("seeing how many digits we support\n"); + { + double v0 = 0.12345678901234567890123456789012345678901; + for(x = 0; x < 100; x++) { + double p = pow(10, x); + double r = v0 * p; + snprintf(buf1, sizeof(buf1), "%1.1f", r); + sprintf(buf2, "%1.1f", r); + if(strcmp(buf1, buf2)) { + printf("we seem to support %d digits\n", x - 1); + break; + } + } + } + + return 0; + } +#endif /* TEST_SNPRINTF */ diff --git a/common/statusdata.c b/common/statusdata.c new file mode 100644 index 0000000..87e2c7c --- /dev/null +++ b/common/statusdata.c @@ -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 + diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..2b03b48 --- /dev/null +++ b/config.guess @@ -0,0 +1,1510 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-12-08' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[3456]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..4b8cc7b --- /dev/null +++ b/config.sub @@ -0,0 +1,1619 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-12-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..e285f0c --- /dev/null +++ b/configure @@ -0,0 +1,8860 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="base/nagios.c" +ac_default_prefix=/usr/local/nagios +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subdirs_all="$ac_subdirs_all tap" +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA INSTALL build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT SET_MAKE STRIP CPP EGREP SNPRINTF_O SOCKETLIBS THREADLIBS nagios_user nagios_grp INSTALL_OPTS command_user command_grp COMMAND_OPTS MAIL_PROG HTTPD_CONF CHECKRESULTDIR TMPDIR init_dir lockfile XSDC XSDH XCDC XCDH XRDC XRDH XODC XODH XPDC XPDH XDDC XDDH htmurl cgiurl BROKER_LDFLAGS BROKERLIBS MOD_CFLAGS MOD_LDFLAGS BROKER_O BROKER_H nagios_name nagiostats_name PATH_TO_TRACEROUTE PACKDIR VERSION subdirs USE_LIBTAP CGIEXTRAS GDLIBS PERLLIBS PERLDIR PERLXSI_O BASEEXTRALIBS INITDIR INSTALLPERLSTUFF USE_EVENTBROKER PERL LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] +--disable-statusmap=disables compilation of statusmap CGI +--disable-statuswrl=disables compilation of statuswrl (VRML) CGI +--enable-nanosleep enables use of nanosleep (instead of sleep) in event timing +--enable-event-broker enables integration of event broker routines +--enable-embedded-perl will enable embedded Perl interpreter +--enable-cygwin enables building under the CYGWIN environment + --enable-libtap Enable built-in libtap for unit-testing (default: + no). + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-nagios-user= + sets user name to run nagios + --with-nagios-group= + sets group name to run nagios + --with-command-user= + sets user name for command access + --with-command-group= + sets group name for command access +--with-mail= sets path to equivalent program to mail +--with-httpd-conf= sets path to Apache conf.d directory +--with-checkresult-dir= sets path to check results spool directory +--with-temp-dir= sets path to temp directory +--with-init-dir= sets directory to place init script into +--with-lockfile= sets path and file name for lock file +--with-gd-lib=DIR sets location of the gd library +--with-gd-inc=DIR sets location of the gd include files +--with-cgiurl= sets URL for cgi programs (do not use a trailing slash) +--with-htmurl= sets URL for public html +--with-perlcache turns on cacheing of internally compiled Perl scripts + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + ac_config_headers="$ac_config_headers include/config.h include/snprintf.h" + + + +PKG_NAME=nagios +PKG_VERSION="3.5.1" +PKG_HOME_URL="http://www.nagios.org/" +PKG_REL_DATE="08-30-2013" + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $STRIP in + [\\/]* | ?:[\\/]*) + ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_STRIP" && ac_cv_path_STRIP="true" + ;; +esac +fi +STRIP=$ac_cv_path_STRIP + +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_sys_wait_h=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +for ac_header in 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 +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 +echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 +if test "${ac_cv_struct_tm+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm *tp; tp->tm_sec; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_struct_tm=time.h +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_struct_tm=sys/time.h +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 +echo "${ECHO_T}$ac_cv_struct_tm" >&6 +if test $ac_cv_struct_tm = sys/time.h; then + +cat >>confdefs.h <<\_ACEOF +#define TM_IN_SYS_TIME 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for struct tm.tm_zone" >&5 +echo $ECHO_N "checking for struct tm.tm_zone... $ECHO_C" >&6 +if test "${ac_cv_member_struct_tm_tm_zone+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include <$ac_cv_struct_tm> + + +int +main () +{ +static struct tm ac_aggr; +if (ac_aggr.tm_zone) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_tm_tm_zone=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include <$ac_cv_struct_tm> + + +int +main () +{ +static struct tm ac_aggr; +if (sizeof ac_aggr.tm_zone) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_tm_tm_zone=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_tm_tm_zone=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_tm_tm_zone" >&5 +echo "${ECHO_T}$ac_cv_member_struct_tm_tm_zone" >&6 +if test $ac_cv_member_struct_tm_tm_zone = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_TM_TM_ZONE 1 +_ACEOF + + +fi + +if test "$ac_cv_member_struct_tm_tm_zone" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TM_ZONE 1 +_ACEOF + +else + echo "$as_me:$LINENO: checking for tzname" >&5 +echo $ECHO_N "checking for tzname... $ECHO_C" >&6 +if test "${ac_cv_var_tzname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#ifndef tzname /* For SGI. */ +extern char *tzname[]; /* RS6000 and others reject char **tzname. */ +#endif + +int +main () +{ +atoi(*tzname); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_var_tzname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_var_tzname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_var_tzname" >&5 +echo "${ECHO_T}$ac_cv_var_tzname" >&6 + if test $ac_cv_var_tzname = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TZNAME 1 +_ACEOF + + fi +fi + +echo "$as_me:$LINENO: checking for mode_t" >&5 +echo $ECHO_N "checking for mode_t... $ECHO_C" >&6 +if test "${ac_cv_type_mode_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((mode_t *) 0) + return 0; +if (sizeof (mode_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_mode_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_mode_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 +echo "${ECHO_T}$ac_cv_type_mode_t" >&6 +if test $ac_cv_type_mode_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((pid_t *) 0) + return 0; +if (sizeof (pid_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_pid_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6 +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + +echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_signal=int +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6 +if test $ac_cv_type_uid_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define uid_t int +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define gid_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking type of array argument to getgroups" >&5 +echo $ECHO_N "checking type of array argument to getgroups... $ECHO_C" >&6 +if test "${ac_cv_type_getgroups+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_type_getgroups=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Thanks to Mike Rendell for this test. */ +#include +#define NGID 256 +#undef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + +int +main () +{ + gid_t gidset[NGID]; + int i, n; + union { gid_t gval; long lval; } val; + + val.lval = -1; + for (i = 0; i < NGID; i++) + gidset[i] = val.gval; + n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1, + gidset); + /* Exit non-zero if getgroups seems to require an array of ints. This + happens when gid_t is short but getgroups modifies an array of ints. */ + exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_getgroups=gid_t +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_type_getgroups=int +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +if test $ac_cv_type_getgroups = cross; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then + ac_cv_type_getgroups=gid_t +else + ac_cv_type_getgroups=int +fi +rm -f conftest* + +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_type_getgroups" >&5 +echo "${ECHO_T}$ac_cv_type_getgroups" >&6 + +cat >>confdefs.h <<_ACEOF +#define GETGROUPS_T $ac_cv_type_getgroups +_ACEOF + + + + +echo "$as_me:$LINENO: checking for va_copy" >&5 +echo $ECHO_N "checking for va_copy... $ECHO_C" >&6 +if test "${ac_cv_HAVE_VA_COPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +va_list ap1,ap2; +int +main () +{ +va_copy(ap1,ap2); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_HAVE_VA_COPY=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_HAVE_VA_COPY=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_HAVE_VA_COPY" >&5 +echo "${ECHO_T}$ac_cv_HAVE_VA_COPY" >&6 +if test x"$ac_cv_HAVE_VA_COPY" = x"yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_VA_COPY 1 +_ACEOF + +else + echo "$as_me:$LINENO: checking for __va_copy" >&5 +echo $ECHO_N "checking for __va_copy... $ECHO_C" >&6 +if test "${ac_cv_HAVE___VA_COPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + va_list ap1,ap2; +int +main () +{ +__va_copy(ap1,ap2); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_HAVE___VA_COPY=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_HAVE___VA_COPY=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_HAVE___VA_COPY" >&5 +echo "${ECHO_T}$ac_cv_HAVE___VA_COPY" >&6 + if test x"$ac_cv_HAVE___VA_COPY" = x"yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE___VA_COPY 1 +_ACEOF + + fi +fi + +echo "$as_me:$LINENO: checking for vsnprintf" >&5 +echo $ECHO_N "checking for vsnprintf... $ECHO_C" >&6 +if test "${ac_cv_func_vsnprintf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define vsnprintf to an innocuous variant, in case declares vsnprintf. + For example, HP-UX 11i declares gettimeofday. */ +#define vsnprintf innocuous_vsnprintf + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char vsnprintf (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef vsnprintf + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vsnprintf (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_vsnprintf) || defined (__stub___vsnprintf) +choke me +#else +char (*f) () = vsnprintf; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != vsnprintf; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_vsnprintf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_vsnprintf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_vsnprintf" >&5 +echo "${ECHO_T}$ac_cv_func_vsnprintf" >&6 +if test $ac_cv_func_vsnprintf = yes; then + : +else + SNPRINTF_O=../common/snprintf.o +fi + +echo "$as_me:$LINENO: checking for snprintf" >&5 +echo $ECHO_N "checking for snprintf... $ECHO_C" >&6 +if test "${ac_cv_func_snprintf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define snprintf to an innocuous variant, in case declares snprintf. + For example, HP-UX 11i declares gettimeofday. */ +#define snprintf innocuous_snprintf + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char snprintf (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef snprintf + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char snprintf (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_snprintf) || defined (__stub___snprintf) +choke me +#else +char (*f) () = snprintf; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != snprintf; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_snprintf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_snprintf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_snprintf" >&5 +echo "${ECHO_T}$ac_cv_func_snprintf" >&6 +if test $ac_cv_func_snprintf = yes; then + : +else + SNPRINTF_O=../common/snprintf.o +fi + +echo "$as_me:$LINENO: checking for asprintf" >&5 +echo $ECHO_N "checking for asprintf... $ECHO_C" >&6 +if test "${ac_cv_func_asprintf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define asprintf to an innocuous variant, in case declares asprintf. + For example, HP-UX 11i declares gettimeofday. */ +#define asprintf innocuous_asprintf + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char asprintf (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef asprintf + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char asprintf (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_asprintf) || defined (__stub___asprintf) +choke me +#else +char (*f) () = asprintf; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != asprintf; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_asprintf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_asprintf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_asprintf" >&5 +echo "${ECHO_T}$ac_cv_func_asprintf" >&6 +if test $ac_cv_func_asprintf = yes; then + : +else + SNPRINTF_O=../common/snprintf.o +fi + +echo "$as_me:$LINENO: checking for vasprintf" >&5 +echo $ECHO_N "checking for vasprintf... $ECHO_C" >&6 +if test "${ac_cv_func_vasprintf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define vasprintf to an innocuous variant, in case declares vasprintf. + For example, HP-UX 11i declares gettimeofday. */ +#define vasprintf innocuous_vasprintf + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char vasprintf (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef vasprintf + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vasprintf (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_vasprintf) || defined (__stub___vasprintf) +choke me +#else +char (*f) () = vasprintf; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != vasprintf; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_vasprintf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_vasprintf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_vasprintf" >&5 +echo "${ECHO_T}$ac_cv_func_vasprintf" >&6 +if test $ac_cv_func_vasprintf = yes; then + : +else + SNPRINTF_O=../common/snprintf.o +fi + + +echo "$as_me:$LINENO: checking for C99 vsnprintf" >&5 +echo $ECHO_N "checking for C99 vsnprintf... $ECHO_C" >&6 +if test "${ac_cv_HAVE_C99_VSNPRINTF+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_HAVE_C99_VSNPRINTF=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +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"); } + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_HAVE_C99_VSNPRINTF=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_HAVE_C99_VSNPRINTF=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_HAVE_C99_VSNPRINTF" >&5 +echo "${ECHO_T}$ac_cv_HAVE_C99_VSNPRINTF" >&6 +if test x"$ac_cv_HAVE_C99_VSNPRINTF" = x"yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_C99_VSNPRINTF 1 +_ACEOF + +fi + + + + +echo "$as_me:$LINENO: checking for library containing getservbyname" >&5 +echo $ECHO_N "checking for library containing getservbyname... $ECHO_C" >&6 +if test "${ac_cv_search_getservbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_getservbyname=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getservbyname (); +int +main () +{ +getservbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_getservbyname="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_getservbyname" = no; then + for ac_lib in nsl; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getservbyname (); +int +main () +{ +getservbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_getservbyname="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_getservbyname" >&5 +echo "${ECHO_T}$ac_cv_search_getservbyname" >&6 +if test "$ac_cv_search_getservbyname" != no; then + test "$ac_cv_search_getservbyname" = "none required" || LIBS="$ac_cv_search_getservbyname $LIBS" + if test "$ac_cv_search_getservbyname" != "none required"; then + SOCKETLIBS="$SOCKETLIBS -lnsl" + fi +fi + +echo "$as_me:$LINENO: checking for library containing connect" >&5 +echo $ECHO_N "checking for library containing connect... $ECHO_C" >&6 +if test "${ac_cv_search_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_connect=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +int +main () +{ +connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_connect="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_connect" = no; then + for ac_lib in socket; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +int +main () +{ +connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_connect="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_connect" >&5 +echo "${ECHO_T}$ac_cv_search_connect" >&6 +if test "$ac_cv_search_connect" != no; then + test "$ac_cv_search_connect" = "none required" || LIBS="$ac_cv_search_connect $LIBS" + if test "$ac_cv_search_connect" != "none required"; then + SOCKETLIBS="$SOCKETLIBS -lsocket" + fi +fi + + + + + + + + +for ac_func in initgroups setenv strdup strstr strtoul unsetenv +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +echo "$as_me:$LINENO: checking for type of socket size" >&5 +echo $ECHO_N "checking for type of socket size... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +int a = send(1, (const void *) 0, (size_t) 0, (int) 0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define SOCKET_SIZE_TYPE size_t +_ACEOF + echo "$as_me:$LINENO: result: size_t" >&5 +echo "${ECHO_T}size_t" >&6 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +cat >>confdefs.h <<\_ACEOF +#define SOCKET_SIZE_TYPE int +_ACEOF + echo "$as_me:$LINENO: result: int" >&5 +echo "${ECHO_T}int" >&6 +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + +THREADLIBS="" +have_pthreads="no" + + + +echo "$as_me:$LINENO: checking for pthread_create in -lcma" >&5 +echo $ECHO_N "checking for pthread_create in -lcma... $ECHO_C" >&6 +if test "${ac_cv_lib_cma_pthread_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcma $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main () +{ +pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_cma_pthread_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_cma_pthread_create=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_cma_pthread_create" >&5 +echo "${ECHO_T}$ac_cv_lib_cma_pthread_create" >&6 +if test $ac_cv_lib_cma_pthread_create = yes; then + THREADLIBS="$THREADLIBS -lpthread" +fi + +if test $ac_cv_lib_cma_pthread_create = yes; then + have_pthreads="yes" +fi + +echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 +echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main () +{ +pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread_pthread_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread_pthread_create=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6 +if test $ac_cv_lib_pthread_pthread_create = yes; then + THREADLIBS="$THREADLIBS -lpthread" +fi + +if test $ac_cv_lib_pthread_pthread_create = yes; then + have_pthreads="yes" +else + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_mutex_init (); +int +main () +{ +pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread_pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread_pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 +if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then + THREADLIBS="$THREADLIBS -lpthread" +fi + + if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then + have_pthreads="yes" + fi +fi + +if test $have_pthreads = "no"; then + echo "$as_me:$LINENO: checking for pthread_create in -lpthreads" >&5 +echo $ECHO_N "checking for pthread_create in -lpthreads... $ECHO_C" >&6 +if test "${ac_cv_lib_pthreads_pthread_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthreads $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main () +{ +pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthreads_pthread_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthreads_pthread_create=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_create" >&5 +echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_create" >&6 +if test $ac_cv_lib_pthreads_pthread_create = yes; then + THREADLIBS="$THREADLIBS -lpthreads" +fi + + if test $ac_cv_lib_pthreads_pthread_create = yes; then + have_pthreads="yes" + fi +fi + +if test $have_pthreads = "no"; then + + echo "$as_me:$LINENO: checking for pthread_create in -llthread" >&5 +echo $ECHO_N "checking for pthread_create in -llthread... $ECHO_C" >&6 +if test "${ac_cv_lib_lthread_pthread_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llthread -L/usr/local/lib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main () +{ +pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_lthread_pthread_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_lthread_pthread_create=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_lthread_pthread_create" >&5 +echo "${ECHO_T}$ac_cv_lib_lthread_pthread_create" >&6 +if test $ac_cv_lib_lthread_pthread_create = yes; then + + CFLAGS="-D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -I/usr/include $CFLAGS" + THREADLIBS="-L/usr/local/lib -llthread -llgcc_r" + +else + + echo "$as_me:$LINENO: checking if we need -pthread for threads" >&5 +echo $ECHO_N "checking if we need -pthread for threads... $ECHO_C" >&6 + if test "${ac_ldflag_pthread+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="-pthread $LDFLAGS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + char pthread_create(); + +int +main () +{ +pthread_create(); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "ac_ldflag_pthread=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "ac_ldflag_pthread=no" + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext, + THREADLIBS="$ac_save_LDFLAGS" + +fi + + if eval "test \"`echo $ac_ldflag_pthread`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +fi + + +fi + + + +echo "$as_me:$LINENO: checking for library containing nanosleep" >&5 +echo $ECHO_N "checking for library containing nanosleep... $ECHO_C" >&6 +if test "${ac_cv_search_nanosleep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_nanosleep=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char nanosleep (); +int +main () +{ +nanosleep (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_nanosleep="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_nanosleep" = no; then + for ac_lib in rt posix4; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char nanosleep (); +int +main () +{ +nanosleep (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_nanosleep="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_nanosleep" >&5 +echo "${ECHO_T}$ac_cv_search_nanosleep" >&6 +if test "$ac_cv_search_nanosleep" != no; then + test "$ac_cv_search_nanosleep" = "none required" || LIBS="$ac_cv_search_nanosleep $LIBS" + +else + + echo "Error: nanosleep() needed for timing operations." + exit 1 + +fi + + + +# Check whether --with-nagios_user or --without-nagios_user was given. +if test "${with_nagios_user+set}" = set; then + withval="$with_nagios_user" + nagios_user=$withval +else + nagios_user=nagios +fi; + +# Check whether --with-nagios_group or --without-nagios_group was given. +if test "${with_nagios_group+set}" = set; then + withval="$with_nagios_group" + nagios_grp=$withval +else + nagios_grp=nagios +fi; + + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_NAGIOS_USER "$nagios_user" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_NAGIOS_GROUP "$nagios_grp" +_ACEOF + +INSTALL_OPTS="-o $nagios_user -g $nagios_grp" + + + +# Check whether --with-command_user or --without-command_user was given. +if test "${with_command_user+set}" = set; then + withval="$with_command_user" + command_user=$withval +else + command_user=$nagios_user +fi; + +# Check whether --with-command_group or --without-command_group was given. +if test "${with_command_group+set}" = set; then + withval="$with_command_group" + command_grp=$withval +else + command_grp=$nagios_grp +fi; + + +COMMAND_OPTS="-o $command_user -g $command_grp" + + +MAIL_PROG=no + +# Check whether --with-mail or --without-mail was given. +if test "${with_mail+set}" = set; then + withval="$with_mail" + MAIL_PROG=$withval +else + MAIL_PROG=no +fi; +if test x$MAIL_PROG = xno; then + # Extract the first word of "mail", so it can be a program name with args. +set dummy mail; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_MAIL_PROG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAIL_PROG in + [\\/]* | ?:[\\/]*) + ac_cv_path_MAIL_PROG="$MAIL_PROG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MAIL_PROG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +MAIL_PROG=$ac_cv_path_MAIL_PROG + +if test -n "$MAIL_PROG"; then + echo "$as_me:$LINENO: result: $MAIL_PROG" >&5 +echo "${ECHO_T}$MAIL_PROG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test x$MAIL_PROG = x; then + MAIL_PROG="/bin/mail" +fi + + +HTTP_CONF=no + +# Check whether --with-httpd_conf or --without-httpd_conf was given. +if test "${with_httpd_conf+set}" = set; then + withval="$with_httpd_conf" + HTTPD_CONF=$withval +else + HTTPD_CONF=no +fi; +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 + + +CHECKRESULTDIR=no + +# Check whether --with-checkresult-dir or --without-checkresult-dir was given. +if test "${with_checkresult_dir+set}" = set; then + withval="$with_checkresult_dir" + CHECKRESULTDIR=$withval +else + CHECKRESULTDIR=no +fi; +if test x$CHECKRESULTDIR = xno; then + CHECKRESULTDIR="$localstatedir/spool/checkresults" +fi + + +TMPDIR=no + +# Check whether --with-temp-dir or --without-temp-dir was given. +if test "${with_temp_dir+set}" = set; then + withval="$with_temp_dir" + TMPDIR=$withval +else + TMPDIR=no +fi; +if test x$TMPDIR = xno; then + TMPDIR="/tmp" +fi + + +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 + + +# Check whether --with-init_dir or --without-init_dir was given. +if test "${with_init_dir+set}" = set; then + withval="$with_init_dir" + init_dir=$withval +fi; + + + +# Check whether --with-lockfile or --without-lockfile was given. +if test "${with_lockfile+set}" = set; then + withval="$with_lockfile" + lockfile=$withval +else + lockfile=$localstatedir/nagios.lock +fi; + + + + +XSDTYPE=default +XCDTYPE=default +XRDTYPE=default +XODTYPE=template +XPDTYPE=default +XDDTYPE=default + +XSDCOMMENT= +XCDCOMMENT= +XRDCOMMENT= +XODCOMMENT= +XPDCOMMENT= +XDDCOMMENT= + +USE_MYSQL=no +USE_PGSQL=no + + +cat >>confdefs.h <<_ACEOF +#define USE_XSDDEFAULT +_ACEOF + +XSDC="xsddefault.c" +XSDH="xsddefault.h" +XSDCOMMENT="Default (text file)" +echo "We'll use default routines (in xdata/xsddefault.*) for status data I/O..." + + + + + +cat >>confdefs.h <<_ACEOF +#define USE_XCDDEFAULT +_ACEOF + +XCDC="xcddefault.c" +XCDH="xcddefault.h" +XCDCOMMENT="Default (text file)" +echo "We'll use default routines (in xdata/xcddefault.*) for comment data I/O..." + + + + + +cat >>confdefs.h <<_ACEOF +#define USE_XRDDEFAULT +_ACEOF + +XRDC="xrddefault.c" +XRDH="xrddefault.h" +XRDCOMMENT="Default (text file)" +echo "We'll use default routines (in xdata/xrddefault.*) for retention data I/O..." + + + + + +cat >>confdefs.h <<_ACEOF +#define USE_XODTEMPLATE +_ACEOF + +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..." + + + + + + +cat >>confdefs.h <<_ACEOF +#define USE_XPDDEFAULT +_ACEOF + +XPDC="xpddefault.c" +XPDH="xpddefault.h" +XPDCOMMENT="Default (external commands)" +echo "We'll use default routines (in xdata/xpddefault.*) for performance data I/O..." + + + + + +cat >>confdefs.h <<_ACEOF +#define USE_XDDDEFAULT +_ACEOF + +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..." + + + + + +# Check whether --with-gd-lib or --without-gd-lib was given. +if test "${with_gd_lib+set}" = set; then + withval="$with_gd_lib" + + LDFLAGS="${LDFLAGS} -L${withval}" + LD_RUN_PATH="${withval}${LD_RUN_PATH:+:}${LD_RUN_PATH}" + +fi; + +# Check whether --with-gd-inc or --without-gd-inc was given. +if test "${with_gd_inc+set}" = set; then + withval="$with_gd_inc" + + CFLAGS="${CFLAGS} -I${withval}" + +fi; + + +TRYGD=yep + +TRYSTATUSMAP=yep +# Check whether --enable-statusmap or --disable-statusmap was given. +if test "${enable_statusmap+set}" = set; then + enableval="$enable_statusmap" + TRYSTATUSMAP=nope +fi; + + +TRYSTATUSWRL=yep +# Check whether --enable-statuswrl or --disable-statuswrl was given. +if test "${enable_statuswrl+set}" = set; then + enableval="$enable_statuswrl" + TRYSTATUSWRL=nope +fi; + +if test x$TRYSTATUSWRL = xyep; then + +cat >>confdefs.h <<_ACEOF +#define USE_STATUSWRL +_ACEOF + + CGIEXTRAS="$CGIEXTRAS statuswrl.cgi" +fi + + + + + + +if test x$TRYGD = xyep; then + + echo "$as_me:$LINENO: checking for main in -liconv" >&5 +echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6 +if test "${ac_cv_lib_iconv_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-liconv $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_iconv_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_iconv_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5 +echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6 +if test $ac_cv_lib_iconv_main = yes; then + ICONV=-liconv +fi + + + + echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 1)" >&5 +echo $ECHO_N "checking for gdImagePng in -lgd (order 1)... $ECHO_C" >&6 + ac_lib_var=`echo gd'_'gdImagePng'_'1 | sed 'y%./+-%__p_%'` + if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_LIBS="$LIBS" + LIBS="-lgd -lttf -lpng -ljpeg -lz -lm $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + /* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gdImagePng(); + +int +main () +{ +gdImagePng() + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi + if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + + GDLIBFOUND=yep + GDLIBS="-lgd -lttf -lpng -ljpeg -lz -lm" + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + : + fi + + + if test x$GDLIBFOUND = x; then + echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 2)" >&5 +echo $ECHO_N "checking for gdImagePng in -lgd (order 2)... $ECHO_C" >&6 + ac_lib_var=`echo gd'_'gdImagePng'_'2 | sed 'y%./+-%__p_%'` + if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_LIBS="$LIBS" + LIBS="-lgd $ICONV -lpng -ljpeg -lz -lm $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + /* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gdImagePng(); + +int +main () +{ +gdImagePng() + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi + if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + + GDLIBFOUND=yep + GDLIBS="-lgd $ICONV -lpng -ljpeg -lz -lm" + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + : + fi + + fi + + if test x$GDLIBFOUND = x; then + echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 3)" >&5 +echo $ECHO_N "checking for gdImagePng in -lgd (order 3)... $ECHO_C" >&6 + ac_lib_var=`echo gd'_'gdImagePng'_'3 | sed 'y%./+-%__p_%'` + if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_LIBS="$LIBS" + LIBS="-lgd $ICONV -lz -lm -lpng $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + /* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gdImagePng(); + +int +main () +{ +gdImagePng() + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi + if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + + GDLIBFOUND=yep + GDLIBS="-lgd $ICONV -lz -lm -lpng" + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + : + fi + + fi + + if test x$GDLIBFOUND = x; then + echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 4)" >&5 +echo $ECHO_N "checking for gdImagePng in -lgd (order 4)... $ECHO_C" >&6 + ac_lib_var=`echo gd'_'gdImagePng'_'4 | sed 'y%./+-%__p_%'` + if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_LIBS="$LIBS" + LIBS="-lgd $ICONV -lpng -lz -lm $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + /* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gdImagePng(); + +int +main () +{ +gdImagePng() + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi + if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + + GDLIBFOUND=yep + GDLIBS="-lgd $ICONV -lpng -lz -lm" + + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + : + fi + + fi + + 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 "" + + else + echo "GD library was found!" + if test x$TRYSTATUSMAP = xyep; then + +cat >>confdefs.h <<_ACEOF +#define USE_STATUSMAP +_ACEOF + + CGIEXTRAS="$CGIEXTRAS statusmap.cgi" + echo "$as_me:$LINENO: checking for gdImageCreateTrueColor in -lgd" >&5 +echo $ECHO_N "checking for gdImageCreateTrueColor in -lgd... $ECHO_C" >&6 +if test "${ac_cv_lib_gd_gdImageCreateTrueColor+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgd $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gdImageCreateTrueColor (); +int +main () +{ +gdImageCreateTrueColor (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_gd_gdImageCreateTrueColor=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_gd_gdImageCreateTrueColor=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_gd_gdImageCreateTrueColor" >&5 +echo "${ECHO_T}$ac_cv_lib_gd_gdImageCreateTrueColor" >&6 +if test $ac_cv_lib_gd_gdImageCreateTrueColor = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GDIMAGECREATETRUECOLOR 1 +_ACEOF + +fi + + fi + + +cat >>confdefs.h <<_ACEOF +#define USE_TRENDS +_ACEOF + + CGIEXTRAS="$CGIEXTRAS trends.cgi" + + +cat >>confdefs.h <<_ACEOF +#define USE_HISTOGRAM +_ACEOF + + CGIEXTRAS="$CGIEXTRAS histogram.cgi" + fi +fi + + +# Check whether --with-cgiurl or --without-cgiurl was given. +if test "${with_cgiurl+set}" = set; then + withval="$with_cgiurl" + cgiurl=$withval +else + cgiurl=/nagios/cgi-bin +fi; + +# Check whether --with-htmurl or --without-htmurl was given. +if test "${with_htmurl+set}" = set; then + withval="$with_htmurl" + htmurl=$withval +else + htmurl=/nagios +fi; + + + +USE_NANOSLEEP=yes +# Check whether --enable-nanosleep or --disable-nanosleep was given. +if test "${enable_nanosleep+set}" = set; then + enableval="$enable_nanosleep" + USE_NANOSLEEP=$enableval +else + USE_NANOSLEEP=yes +fi; +if test x$USE_NANOSLEEP = xyes; then + +cat >>confdefs.h <<_ACEOF +#define USE_NANOSLEEP +_ACEOF + +fi + +USE_EVENTBROKER=yes +# Check whether --enable-event-broker or --disable-event-broker was given. +if test "${enable_event_broker+set}" = set; then + enableval="$enable_event_broker" + USE_EVENTBROKER=$enableval +else + USE_EVENTBROKER=yes +fi; + +BROKER_LDFLAGS="" +BROKERLIBS=""; +some_dl_found="no"; +if test x$USE_EVENTBROKER = xyes; then + + if test "${ac_cv_header_ltdl_h+set}" = set; then + echo "$as_me:$LINENO: checking for ltdl.h" >&5 +echo $ECHO_N "checking for ltdl.h... $ECHO_C" >&6 +if test "${ac_cv_header_ltdl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_ltdl_h" >&5 +echo "${ECHO_T}$ac_cv_header_ltdl_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking ltdl.h usability" >&5 +echo $ECHO_N "checking ltdl.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking ltdl.h presence" >&5 +echo $ECHO_N "checking ltdl.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: ltdl.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: ltdl.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: ltdl.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: ltdl.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: ltdl.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: ltdl.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: ltdl.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: ltdl.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: ltdl.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: ltdl.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: ltdl.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: ltdl.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: ltdl.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: ltdl.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for ltdl.h" >&5 +echo $ECHO_N "checking for ltdl.h... $ECHO_C" >&6 +if test "${ac_cv_header_ltdl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_ltdl_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_ltdl_h" >&5 +echo "${ECHO_T}$ac_cv_header_ltdl_h" >&6 + +fi +if test $ac_cv_header_ltdl_h = yes; then + + echo "$as_me:$LINENO: checking for lt_dlinit in -lltdl" >&5 +echo $ECHO_N "checking for lt_dlinit in -lltdl... $ECHO_C" >&6 +if test "${ac_cv_lib_ltdl_lt_dlinit+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lltdl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char lt_dlinit (); +int +main () +{ +lt_dlinit (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ltdl_lt_dlinit=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_ltdl_lt_dlinit=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ltdl_lt_dlinit" >&5 +echo "${ECHO_T}$ac_cv_lib_ltdl_lt_dlinit" >&6 +if test $ac_cv_lib_ltdl_lt_dlinit = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LTDL_H +_ACEOF + + some_dl_found="yes" + BROKERLIBS="$BROKERLIBS -lltdl" + +fi + + +fi + + + if test "x$some_dl_found" != xyes; then + if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo "$as_me:$LINENO: checking for dlfcn.h" >&5 +echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 +if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 +echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 +echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 +echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for dlfcn.h" >&5 +echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 +if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_dlfcn_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 +echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 + +fi +if test $ac_cv_header_dlfcn_h = yes; then + + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DLFCN_H +_ACEOF + + some_dl_found="yes" + BROKERLIBS="$BROKERLIBS -ldl" + +fi + + +fi + + + fi + + # 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. + echo "$as_me:$LINENO: checking for extra flags needed to export symbols" >&5 +echo $ECHO_N "checking for extra flags needed to export symbols... $ECHO_C" >&6 + 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 + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-export-dynamic" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + LDFLAGS=-Wl,-Bexport + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-Bexport" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_ldflags" + ;; + esac + + + test "x$BROKER_LDFLAGS" != x && echo "$as_me:$LINENO: result: $BROKER_LDFLAGS" >&5 +echo "${ECHO_T}$BROKER_LDFLAGS" >&6 + + + echo "$as_me:$LINENO: checking for linker flags for loadable modules" >&5 +echo $ECHO_N "checking for linker flags for loadable modules... $ECHO_C" >&6 + 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 + echo "$as_me:$LINENO: result: $MOD_LDFLAGS" >&5 +echo "${ECHO_T}$MOD_LDFLAGS" >&6 + + + + + +cat >>confdefs.h <<_ACEOF +#define USE_EVENT_BROKER +_ACEOF + + BROKER_O="broker.o nebmods.o" + + BROKER_H="../include/broker.h ../include/nebmods.h ../include/nebmodules.h ../include/nebcallbacks.h ../include/neberrors.h" + +fi + + +USEPERL=no; +INSTALLPERLSTUFF=no; +# Check whether --enable-embedded-perl or --disable-embedded-perl was given. +if test "${enable_embedded_perl+set}" = set; then + enableval="$enable_embedded_perl" + + USEPERL=$enableval + + +else + USEPERL=no +fi; + +PERLCACHE=yes; + +# Check whether --with-perlcache or --without-perlcache was given. +if test "${with_perlcache+set}" = set; then + withval="$with_perlcache" + + PERLCACHE=$withval + + +else + + +cat >>confdefs.h <<\_ACEOF +#define DO_CLEAN "1" +_ACEOF + + PERLCACHE=yes; + +fi; + +if test x$USEPERL = xyes; then + + +cat >>confdefs.h <<_ACEOF +#define EMBEDDEDPERL +_ACEOF + + 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..." + + if test x$PERLCACHE = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define DO_CLEAN "0" +_ACEOF + + PERLCACHE=yes; + echo "Internally compiled Perl scripts will be cached..." + else + +cat >>confdefs.h <<\_ACEOF +#define DO_CLEAN "1" +_ACEOF + + echo "Internally compiled Perl scripts will NOT be cached..." + fi +fi + +if test x$USEPERL = xyes; then + if (perl -e 'use Config;exit -1 unless ($Config{'usethreads'});'); then + echo "Using threaded perl" + +cat >>confdefs.h <<_ACEOF +#define THREADEDPERL +_ACEOF + + fi +fi + + +nagios_name=nagios +nagiostats_name=nagiostats +cygwin=no +# Check whether --enable-cygwin or --disable-cygwin was given. +if test "${enable_cygwin+set}" = set; then + enableval="$enable_cygwin" + + cygwin=$enableval + +fi; +if test x$cygwin = xyes; then + CFLAGS="${CFLAGS} -DCYGWIN" + nagios_name=nagios.exe; + nagiostats_name=nagiostats.exe; +fi + + + + + +# Extract the first word of "traceroute", so it can be a program name with args. +set dummy traceroute; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PATH_TO_TRACEROUTE+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PATH_TO_TRACEROUTE in + [\\/]* | ?:[\\/]*) + ac_cv_path_PATH_TO_TRACEROUTE="$PATH_TO_TRACEROUTE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PATH_TO_TRACEROUTE="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +PATH_TO_TRACEROUTE=$ac_cv_path_PATH_TO_TRACEROUTE + +if test -n "$PATH_TO_TRACEROUTE"; then + echo "$as_me:$LINENO: result: $PATH_TO_TRACEROUTE" >&5 +echo "${ECHO_T}$PATH_TO_TRACEROUTE" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + +cat >>confdefs.h <<_ACEOF +#define TRACEROUTE_COMMAND "$PATH_TO_TRACEROUTE" +_ACEOF + + + + +VERSION=$PKG_VERSION +PACKDIR=`pwd`/pkg + + + +echo "$as_me:$LINENO: checking for type va_list" >&5 +echo $ECHO_N "checking for type va_list... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +#include +#include +#include +#else +#include +#include +#include +#endif +int +main () +{ +va_list args; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +cat >>confdefs.h <<\_ACEOF +#define NEED_VA_LIST +_ACEOF + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +# Check whether --enable-libtap or --disable-libtap was given. +if test "${enable_libtap+set}" = set; then + enableval="$enable_libtap" + enable_libtap=$enableval +else + enable_libtap=no +fi; +#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 + + +subdirs="$subdirs tap" + + USE_LIBTAP=yes +else + USE_LIBTAP=no +fi + + + + + + + + + + + + + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +PERL=$ac_cv_path_PERL + +if test -n "$PERL"; then + echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + + ac_config_files="$ac_config_files Makefile subst pkginfo base/Makefile common/Makefile contrib/Makefile cgi/Makefile html/Makefile module/Makefile xdata/Makefile daemon-init t/Makefile t-tap/Makefile" + + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "subst" ) CONFIG_FILES="$CONFIG_FILES subst" ;; + "pkginfo" ) CONFIG_FILES="$CONFIG_FILES pkginfo" ;; + "base/Makefile" ) CONFIG_FILES="$CONFIG_FILES base/Makefile" ;; + "common/Makefile" ) CONFIG_FILES="$CONFIG_FILES common/Makefile" ;; + "contrib/Makefile" ) CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; + "cgi/Makefile" ) CONFIG_FILES="$CONFIG_FILES cgi/Makefile" ;; + "html/Makefile" ) CONFIG_FILES="$CONFIG_FILES html/Makefile" ;; + "module/Makefile" ) CONFIG_FILES="$CONFIG_FILES module/Makefile" ;; + "xdata/Makefile" ) CONFIG_FILES="$CONFIG_FILES xdata/Makefile" ;; + "daemon-init" ) CONFIG_FILES="$CONFIG_FILES daemon-init" ;; + "t/Makefile" ) CONFIG_FILES="$CONFIG_FILES t/Makefile" ;; + "t-tap/Makefile" ) CONFIG_FILES="$CONFIG_FILES t-tap/Makefile" ;; + "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; + "include/snprintf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/snprintf.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@INSTALL@,$INSTALL,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@STRIP@,$STRIP,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@SNPRINTF_O@,$SNPRINTF_O,;t t +s,@SOCKETLIBS@,$SOCKETLIBS,;t t +s,@THREADLIBS@,$THREADLIBS,;t t +s,@nagios_user@,$nagios_user,;t t +s,@nagios_grp@,$nagios_grp,;t t +s,@INSTALL_OPTS@,$INSTALL_OPTS,;t t +s,@command_user@,$command_user,;t t +s,@command_grp@,$command_grp,;t t +s,@COMMAND_OPTS@,$COMMAND_OPTS,;t t +s,@MAIL_PROG@,$MAIL_PROG,;t t +s,@HTTPD_CONF@,$HTTPD_CONF,;t t +s,@CHECKRESULTDIR@,$CHECKRESULTDIR,;t t +s,@TMPDIR@,$TMPDIR,;t t +s,@init_dir@,$init_dir,;t t +s,@lockfile@,$lockfile,;t t +s,@XSDC@,$XSDC,;t t +s,@XSDH@,$XSDH,;t t +s,@XCDC@,$XCDC,;t t +s,@XCDH@,$XCDH,;t t +s,@XRDC@,$XRDC,;t t +s,@XRDH@,$XRDH,;t t +s,@XODC@,$XODC,;t t +s,@XODH@,$XODH,;t t +s,@XPDC@,$XPDC,;t t +s,@XPDH@,$XPDH,;t t +s,@XDDC@,$XDDC,;t t +s,@XDDH@,$XDDH,;t t +s,@htmurl@,$htmurl,;t t +s,@cgiurl@,$cgiurl,;t t +s,@BROKER_LDFLAGS@,$BROKER_LDFLAGS,;t t +s,@BROKERLIBS@,$BROKERLIBS,;t t +s,@MOD_CFLAGS@,$MOD_CFLAGS,;t t +s,@MOD_LDFLAGS@,$MOD_LDFLAGS,;t t +s,@BROKER_O@,$BROKER_O,;t t +s,@BROKER_H@,$BROKER_H,;t t +s,@nagios_name@,$nagios_name,;t t +s,@nagiostats_name@,$nagiostats_name,;t t +s,@PATH_TO_TRACEROUTE@,$PATH_TO_TRACEROUTE,;t t +s,@PACKDIR@,$PACKDIR,;t t +s,@VERSION@,$VERSION,;t t +s,@subdirs@,$subdirs,;t t +s,@USE_LIBTAP@,$USE_LIBTAP,;t t +s,@CGIEXTRAS@,$CGIEXTRAS,;t t +s,@GDLIBS@,$GDLIBS,;t t +s,@PERLLIBS@,$PERLLIBS,;t t +s,@PERLDIR@,$PERLDIR,;t t +s,@PERLXSI_O@,$PERLXSI_O,;t t +s,@BASEEXTRALIBS@,$BASEEXTRALIBS,;t t +s,@INITDIR@,$INITDIR,;t t +s,@INSTALLPERLSTUFF@,$INSTALLPERLSTUFF,;t t +s,@USE_EVENTBROKER@,$USE_EVENTBROKER,;t t +s,@PERL@,$PERL,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d $srcdir/$ac_dir || continue + + { echo "$as_me:$LINENO: configuring in $ac_dir" >&5 +echo "$as_me: configuring in $ac_dir" >&6;} + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + cd $ac_dir + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'" + elif test -f $ac_srcdir/configure; then + ac_sub_configure="$SHELL '$ac_srcdir/configure'" + elif test -f $ac_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5 +echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file=$ac_top_builddir$cache_file ;; + esac + + { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval $ac_sub_configure $ac_sub_configure_args \ + --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir || + { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 +echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} + { (exit 1); exit 1; }; } + fi + + cd $ac_popdir + done +fi + + + +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 + + + + +echo "" +echo "" +echo "$as_me:$LINENO: result: *** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:" >&5 +echo "${ECHO_T}*** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:" >&6 + +echo "" +echo " General Options:" +echo " -------------------------" + +echo "$as_me:$LINENO: result: Nagios executable: $nagios_name" >&5 +echo "${ECHO_T} Nagios executable: $nagios_name" >&6 +echo "$as_me:$LINENO: result: Nagios user/group: $nagios_user,$nagios_grp" >&5 +echo "${ECHO_T} Nagios user/group: $nagios_user,$nagios_grp" >&6 +echo "$as_me:$LINENO: result: Command user/group: $command_user,$command_grp" >&5 +echo "${ECHO_T} Command user/group: $command_user,$command_grp" >&6 +if test x$USEPERL = xyes; then +if test x$PERLCACHE = xyes; then +echo "$as_me:$LINENO: result: Embedded Perl: yes, with caching" >&5 +echo "${ECHO_T} Embedded Perl: yes, with caching" >&6 +else +echo "$as_me:$LINENO: result: Embedded Perl: yes, without caching" >&5 +echo "${ECHO_T} Embedded Perl: yes, without caching" >&6 +fi +else +echo "$as_me:$LINENO: result: Embedded Perl: no" >&5 +echo "${ECHO_T} Embedded Perl: no" >&6 +fi +if test x$USE_EVENTBROKER = xyes; then +echo "$as_me:$LINENO: result: Event Broker: yes" >&5 +echo "${ECHO_T} Event Broker: yes" >&6 +else +echo "$as_me:$LINENO: result: Event Broker: no" >&5 +echo "${ECHO_T} Event Broker: no" >&6 +fi +echo "$as_me:$LINENO: result: Install \${prefix}: $prefix" >&5 +echo "${ECHO_T} Install \${prefix}: $prefix" >&6 +echo "$as_me:$LINENO: result: Lock file: $lockfile" >&5 +echo "${ECHO_T} Lock file: $lockfile" >&6 +echo "$as_me:$LINENO: result: Check result directory: $CHECKRESULTDIR" >&5 +echo "${ECHO_T} Check result directory: $CHECKRESULTDIR" >&6 +echo "$as_me:$LINENO: result: Init directory: $init_dir" >&5 +echo "${ECHO_T} Init directory: $init_dir" >&6 +echo "$as_me:$LINENO: result: Apache conf.d directory: $HTTPD_CONF" >&5 +echo "${ECHO_T} Apache conf.d directory: $HTTPD_CONF" >&6 +echo "$as_me:$LINENO: result: Mail program: $MAIL_PROG" >&5 +echo "${ECHO_T} Mail program: $MAIL_PROG" >&6 +echo "$as_me:$LINENO: result: Host OS: $host_os" >&5 +echo "${ECHO_T} Host OS: $host_os" >&6 + +echo "" +echo " Web Interface Options:" +echo " ------------------------" + +echo "$as_me:$LINENO: result: HTML URL: http://localhost$htmurl/" >&5 +echo "${ECHO_T} HTML URL: http://localhost$htmurl/" >&6 +echo "$as_me:$LINENO: result: CGI URL: http://localhost$cgiurl/" >&5 +echo "${ECHO_T} CGI URL: http://localhost$cgiurl/" >&6 +echo "$as_me:$LINENO: result: Traceroute (used by WAP): $PATH_TO_TRACEROUTE" >&5 +echo "${ECHO_T} Traceroute (used by WAP): $PATH_TO_TRACEROUTE" >&6 + + + + +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 "" + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..b575b02 --- /dev/null +++ b/configure.in @@ -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 +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 + 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 +#include +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 +#include +#include +], +[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 +dnl FreeBSD -pthread check - Jonathan McDowell +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=],[sets user name to run nagios]),nagios_user=$withval,nagios_user=nagios) +AC_ARG_WITH(nagios_group,AC_HELP_STRING([--with-nagios-group=],[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=],[sets user name for command access]),command_user=$withval,command_user=$nagios_user) +AC_ARG_WITH(command_group,AC_HELP_STRING([--with-command-group=],[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= 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= 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= 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= 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= 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= 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= sets URL for cgi programs (do not use a trailing slash),cgiurl=$withval,cgiurl=/nagios/cgi-bin) +AC_ARG_WITH(htmurl,--with-htmurl= 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 +#include +#include +#else +#include +#include +#include +#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 "" + diff --git a/contrib/.gitignore b/contrib/.gitignore new file mode 100644 index 0000000..4f1e93a --- /dev/null +++ b/contrib/.gitignore @@ -0,0 +1,2 @@ +perlxsi.c +Makefile diff --git a/contrib/Makefile.in b/contrib/Makefile.in new file mode 100644 index 0000000..addf145 --- /dev/null +++ b/contrib/Makefile.in @@ -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 $@ diff --git a/contrib/README b/contrib/README new file mode 100644 index 0000000..fac2630 --- /dev/null +++ b/contrib/README @@ -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. + + + + + + diff --git a/contrib/convertcfg.c b/contrib/convertcfg.c new file mode 100644 index 0000000..15bf22b --- /dev/null +++ b/contrib/convertcfg.c @@ -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 +#include +#include + +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 \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; + } + + diff --git a/contrib/daemonchk.c b/contrib/daemonchk.c new file mode 100644 index 0000000..78716e5 --- /dev/null +++ b/contrib/daemonchk.c @@ -0,0 +1,277 @@ +#include "config.h" +#include "common.h" +#include "locations.h" +#include "cgiutils.h" +#include "getcgi.h" +#ifdef HAVE_GETOPT_H +#include +#endif +#include + +#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("\n\nNagios Daemon Status\n\n"); + printf("\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); + } diff --git a/contrib/epn_nagios.h b/contrib/epn_nagios.h new file mode 100644 index 0000000..fea7cad --- /dev/null +++ b/contrib/epn_nagios.h @@ -0,0 +1,26 @@ +/******** BEGIN EMBEDDED PERL INTERPRETER DECLARATIONS ********/ + +#include +#include + +#include +#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 ********/ diff --git a/contrib/eventhandlers/disable_active_service_checks b/contrib/eventhandlers/disable_active_service_checks new file mode 100755 index 0000000..c01f2be --- /dev/null +++ b/contrib/eventhandlers/disable_active_service_checks @@ -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` + diff --git a/contrib/eventhandlers/disable_notifications b/contrib/eventhandlers/disable_notifications new file mode 100755 index 0000000..a92bb7a --- /dev/null +++ b/contrib/eventhandlers/disable_notifications @@ -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` + diff --git a/contrib/eventhandlers/distributed-monitoring/obsessive_svc_handler b/contrib/eventhandlers/distributed-monitoring/obsessive_svc_handler new file mode 100755 index 0000000..ece9e99 --- /dev/null +++ b/contrib/eventhandlers/distributed-monitoring/obsessive_svc_handler @@ -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" + diff --git a/contrib/eventhandlers/distributed-monitoring/submit_check_result_via_nsca b/contrib/eventhandlers/distributed-monitoring/submit_check_result_via_nsca new file mode 100755 index 0000000..f990cc4 --- /dev/null +++ b/contrib/eventhandlers/distributed-monitoring/submit_check_result_via_nsca @@ -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 + diff --git a/contrib/eventhandlers/enable_active_service_checks b/contrib/eventhandlers/enable_active_service_checks new file mode 100755 index 0000000..423c8d9 --- /dev/null +++ b/contrib/eventhandlers/enable_active_service_checks @@ -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` + diff --git a/contrib/eventhandlers/enable_notifications b/contrib/eventhandlers/enable_notifications new file mode 100755 index 0000000..0d3f13d --- /dev/null +++ b/contrib/eventhandlers/enable_notifications @@ -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` + + + + diff --git a/contrib/eventhandlers/redundancy-scenario1/handle-master-host-event b/contrib/eventhandlers/redundancy-scenario1/handle-master-host-event new file mode 100755 index 0000000..713c9c1 --- /dev/null +++ b/contrib/eventhandlers/redundancy-scenario1/handle-master-host-event @@ -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 + diff --git a/contrib/eventhandlers/redundancy-scenario1/handle-master-proc-event b/contrib/eventhandlers/redundancy-scenario1/handle-master-proc-event new file mode 100755 index 0000000..50672b3 --- /dev/null +++ b/contrib/eventhandlers/redundancy-scenario1/handle-master-proc-event @@ -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 + + diff --git a/contrib/eventhandlers/submit_check_result b/contrib/eventhandlers/submit_check_result new file mode 100755 index 0000000..5d89f31 --- /dev/null +++ b/contrib/eventhandlers/submit_check_result @@ -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` diff --git a/contrib/exfoliation/images/NagiosEnterprises-whitebg-112x46.png b/contrib/exfoliation/images/NagiosEnterprises-whitebg-112x46.png new file mode 100644 index 0000000..0775aba Binary files /dev/null and b/contrib/exfoliation/images/NagiosEnterprises-whitebg-112x46.png differ diff --git a/contrib/exfoliation/images/ack.gif b/contrib/exfoliation/images/ack.gif new file mode 100644 index 0000000..de77567 Binary files /dev/null and b/contrib/exfoliation/images/ack.gif differ diff --git a/contrib/exfoliation/images/action-graph.gif b/contrib/exfoliation/images/action-graph.gif new file mode 100644 index 0000000..068082a Binary files /dev/null and b/contrib/exfoliation/images/action-graph.gif differ diff --git a/contrib/exfoliation/images/action-nagios.gif b/contrib/exfoliation/images/action-nagios.gif new file mode 100644 index 0000000..3028728 Binary files /dev/null and b/contrib/exfoliation/images/action-nagios.gif differ diff --git a/contrib/exfoliation/images/action-orig.gif b/contrib/exfoliation/images/action-orig.gif new file mode 100644 index 0000000..4e516b6 Binary files /dev/null and b/contrib/exfoliation/images/action-orig.gif differ diff --git a/contrib/exfoliation/images/action.gif b/contrib/exfoliation/images/action.gif new file mode 100644 index 0000000..068082a Binary files /dev/null and b/contrib/exfoliation/images/action.gif differ diff --git a/contrib/exfoliation/images/command.png b/contrib/exfoliation/images/command.png new file mode 100644 index 0000000..649ad8c Binary files /dev/null and b/contrib/exfoliation/images/command.png differ diff --git a/contrib/exfoliation/images/comment.gif b/contrib/exfoliation/images/comment.gif new file mode 100644 index 0000000..133954c Binary files /dev/null and b/contrib/exfoliation/images/comment.gif differ diff --git a/contrib/exfoliation/images/contexthelp1.gif b/contrib/exfoliation/images/contexthelp1.gif new file mode 100644 index 0000000..1cacaa6 Binary files /dev/null and b/contrib/exfoliation/images/contexthelp1.gif differ diff --git a/contrib/exfoliation/images/contexthelp2.gif b/contrib/exfoliation/images/contexthelp2.gif new file mode 100644 index 0000000..1cacaa6 Binary files /dev/null and b/contrib/exfoliation/images/contexthelp2.gif differ diff --git a/contrib/exfoliation/images/critical.png b/contrib/exfoliation/images/critical.png new file mode 100644 index 0000000..04224b8 Binary files /dev/null and b/contrib/exfoliation/images/critical.png differ diff --git a/contrib/exfoliation/images/delay.gif b/contrib/exfoliation/images/delay.gif new file mode 100644 index 0000000..5c2b408 Binary files /dev/null and b/contrib/exfoliation/images/delay.gif differ diff --git a/contrib/exfoliation/images/delete.gif b/contrib/exfoliation/images/delete.gif new file mode 100644 index 0000000..91c28f4 Binary files /dev/null and b/contrib/exfoliation/images/delete.gif differ diff --git a/contrib/exfoliation/images/detail.gif b/contrib/exfoliation/images/detail.gif new file mode 100644 index 0000000..31dfb03 Binary files /dev/null and b/contrib/exfoliation/images/detail.gif differ diff --git a/contrib/exfoliation/images/disabled.gif b/contrib/exfoliation/images/disabled.gif new file mode 100644 index 0000000..282f562 Binary files /dev/null and b/contrib/exfoliation/images/disabled.gif differ diff --git a/contrib/exfoliation/images/down.gif b/contrib/exfoliation/images/down.gif new file mode 100644 index 0000000..a93e2ad Binary files /dev/null and b/contrib/exfoliation/images/down.gif differ diff --git a/contrib/exfoliation/images/downtime.gif b/contrib/exfoliation/images/downtime.gif new file mode 100644 index 0000000..c241c79 Binary files /dev/null and b/contrib/exfoliation/images/downtime.gif differ diff --git a/contrib/exfoliation/images/empty.gif b/contrib/exfoliation/images/empty.gif new file mode 100644 index 0000000..3a09af5 Binary files /dev/null and b/contrib/exfoliation/images/empty.gif differ diff --git a/contrib/exfoliation/images/enabled.gif b/contrib/exfoliation/images/enabled.gif new file mode 100644 index 0000000..c755d4b Binary files /dev/null and b/contrib/exfoliation/images/enabled.gif differ diff --git a/contrib/exfoliation/images/extinfo.gif b/contrib/exfoliation/images/extinfo.gif new file mode 100644 index 0000000..107f078 Binary files /dev/null and b/contrib/exfoliation/images/extinfo.gif differ diff --git a/contrib/exfoliation/images/favicon.ico b/contrib/exfoliation/images/favicon.ico new file mode 100644 index 0000000..b85849b Binary files /dev/null and b/contrib/exfoliation/images/favicon.ico differ diff --git a/contrib/exfoliation/images/flapping.gif b/contrib/exfoliation/images/flapping.gif new file mode 100644 index 0000000..acbc3ab Binary files /dev/null and b/contrib/exfoliation/images/flapping.gif differ diff --git a/contrib/exfoliation/images/graph.gif b/contrib/exfoliation/images/graph.gif new file mode 100644 index 0000000..068082a Binary files /dev/null and b/contrib/exfoliation/images/graph.gif differ diff --git a/contrib/exfoliation/images/greendot.gif b/contrib/exfoliation/images/greendot.gif new file mode 100644 index 0000000..4f9cfa1 Binary files /dev/null and b/contrib/exfoliation/images/greendot.gif differ diff --git a/contrib/exfoliation/images/histogram.png b/contrib/exfoliation/images/histogram.png new file mode 100644 index 0000000..5064c3a Binary files /dev/null and b/contrib/exfoliation/images/histogram.png differ diff --git a/contrib/exfoliation/images/history.gif b/contrib/exfoliation/images/history.gif new file mode 100644 index 0000000..4208a24 Binary files /dev/null and b/contrib/exfoliation/images/history.gif differ diff --git a/contrib/exfoliation/images/hostevent.gif b/contrib/exfoliation/images/hostevent.gif new file mode 100644 index 0000000..5135711 Binary files /dev/null and b/contrib/exfoliation/images/hostevent.gif differ diff --git a/contrib/exfoliation/images/info.png b/contrib/exfoliation/images/info.png new file mode 100644 index 0000000..211a1ca Binary files /dev/null and b/contrib/exfoliation/images/info.png differ diff --git a/contrib/exfoliation/images/left.gif b/contrib/exfoliation/images/left.gif new file mode 100644 index 0000000..1138d14 Binary files /dev/null and b/contrib/exfoliation/images/left.gif differ diff --git a/contrib/exfoliation/images/logofullsize.png b/contrib/exfoliation/images/logofullsize.png new file mode 100644 index 0000000..44cb2dc Binary files /dev/null and b/contrib/exfoliation/images/logofullsize.png differ diff --git a/contrib/exfoliation/images/logos/aix.gd2 b/contrib/exfoliation/images/logos/aix.gd2 new file mode 100644 index 0000000..8d5ea9e Binary files /dev/null and b/contrib/exfoliation/images/logos/aix.gd2 differ diff --git a/contrib/exfoliation/images/logos/aix.gif b/contrib/exfoliation/images/logos/aix.gif new file mode 100644 index 0000000..0d6adc8 Binary files /dev/null and b/contrib/exfoliation/images/logos/aix.gif differ diff --git a/contrib/exfoliation/images/logos/aix.jpg b/contrib/exfoliation/images/logos/aix.jpg new file mode 100644 index 0000000..25e7896 Binary files /dev/null and b/contrib/exfoliation/images/logos/aix.jpg differ diff --git a/contrib/exfoliation/images/logos/aix.png b/contrib/exfoliation/images/logos/aix.png new file mode 100644 index 0000000..ea842ca Binary files /dev/null and b/contrib/exfoliation/images/logos/aix.png differ diff --git a/contrib/exfoliation/images/logos/amiga.gd2 b/contrib/exfoliation/images/logos/amiga.gd2 new file mode 100644 index 0000000..3437e64 Binary files /dev/null and b/contrib/exfoliation/images/logos/amiga.gd2 differ diff --git a/contrib/exfoliation/images/logos/amiga.gif b/contrib/exfoliation/images/logos/amiga.gif new file mode 100644 index 0000000..91f1447 Binary files /dev/null and b/contrib/exfoliation/images/logos/amiga.gif differ diff --git a/contrib/exfoliation/images/logos/amiga.jpg b/contrib/exfoliation/images/logos/amiga.jpg new file mode 100644 index 0000000..d157178 Binary files /dev/null and b/contrib/exfoliation/images/logos/amiga.jpg differ diff --git a/contrib/exfoliation/images/logos/amiga.png b/contrib/exfoliation/images/logos/amiga.png new file mode 100644 index 0000000..b8ddd10 Binary files /dev/null and b/contrib/exfoliation/images/logos/amiga.png differ diff --git a/contrib/exfoliation/images/logos/apple.gd2 b/contrib/exfoliation/images/logos/apple.gd2 new file mode 100644 index 0000000..855b095 Binary files /dev/null and b/contrib/exfoliation/images/logos/apple.gd2 differ diff --git a/contrib/exfoliation/images/logos/apple.gif b/contrib/exfoliation/images/logos/apple.gif new file mode 100644 index 0000000..15d77f0 Binary files /dev/null and b/contrib/exfoliation/images/logos/apple.gif differ diff --git a/contrib/exfoliation/images/logos/apple.jpg b/contrib/exfoliation/images/logos/apple.jpg new file mode 100644 index 0000000..0c29620 Binary files /dev/null and b/contrib/exfoliation/images/logos/apple.jpg differ diff --git a/contrib/exfoliation/images/logos/apple.png b/contrib/exfoliation/images/logos/apple.png new file mode 100644 index 0000000..fe1e738 Binary files /dev/null and b/contrib/exfoliation/images/logos/apple.png differ diff --git a/contrib/exfoliation/images/logos/beos.gd2 b/contrib/exfoliation/images/logos/beos.gd2 new file mode 100644 index 0000000..53ad28d Binary files /dev/null and b/contrib/exfoliation/images/logos/beos.gd2 differ diff --git a/contrib/exfoliation/images/logos/beos.gif b/contrib/exfoliation/images/logos/beos.gif new file mode 100644 index 0000000..51946ab Binary files /dev/null and b/contrib/exfoliation/images/logos/beos.gif differ diff --git a/contrib/exfoliation/images/logos/beos.jpg b/contrib/exfoliation/images/logos/beos.jpg new file mode 100644 index 0000000..f959475 Binary files /dev/null and b/contrib/exfoliation/images/logos/beos.jpg differ diff --git a/contrib/exfoliation/images/logos/beos.png b/contrib/exfoliation/images/logos/beos.png new file mode 100644 index 0000000..33d408a Binary files /dev/null and b/contrib/exfoliation/images/logos/beos.png differ diff --git a/contrib/exfoliation/images/logos/bluetooth.png b/contrib/exfoliation/images/logos/bluetooth.png new file mode 100644 index 0000000..72444e1 Binary files /dev/null and b/contrib/exfoliation/images/logos/bluetooth.png differ diff --git a/contrib/exfoliation/images/logos/caldera.gd2 b/contrib/exfoliation/images/logos/caldera.gd2 new file mode 100644 index 0000000..d15b948 Binary files /dev/null and b/contrib/exfoliation/images/logos/caldera.gd2 differ diff --git a/contrib/exfoliation/images/logos/caldera.gif b/contrib/exfoliation/images/logos/caldera.gif new file mode 100644 index 0000000..5ee8de8 Binary files /dev/null and b/contrib/exfoliation/images/logos/caldera.gif differ diff --git a/contrib/exfoliation/images/logos/caldera.jpg b/contrib/exfoliation/images/logos/caldera.jpg new file mode 100644 index 0000000..657ba94 Binary files /dev/null and b/contrib/exfoliation/images/logos/caldera.jpg differ diff --git a/contrib/exfoliation/images/logos/caldera.png b/contrib/exfoliation/images/logos/caldera.png new file mode 100644 index 0000000..daf6607 Binary files /dev/null and b/contrib/exfoliation/images/logos/caldera.png differ diff --git a/contrib/exfoliation/images/logos/cat1900.gd2 b/contrib/exfoliation/images/logos/cat1900.gd2 new file mode 100644 index 0000000..b5bf060 Binary files /dev/null and b/contrib/exfoliation/images/logos/cat1900.gd2 differ diff --git a/contrib/exfoliation/images/logos/cat2900.gd2 b/contrib/exfoliation/images/logos/cat2900.gd2 new file mode 100644 index 0000000..486fced Binary files /dev/null and b/contrib/exfoliation/images/logos/cat2900.gd2 differ diff --git a/contrib/exfoliation/images/logos/cat5000.gd2 b/contrib/exfoliation/images/logos/cat5000.gd2 new file mode 100644 index 0000000..f8fe467 Binary files /dev/null and b/contrib/exfoliation/images/logos/cat5000.gd2 differ diff --git a/contrib/exfoliation/images/logos/database.gd2 b/contrib/exfoliation/images/logos/database.gd2 new file mode 100644 index 0000000..6d4ed60 Binary files /dev/null and b/contrib/exfoliation/images/logos/database.gd2 differ diff --git a/contrib/exfoliation/images/logos/database.gif b/contrib/exfoliation/images/logos/database.gif new file mode 100644 index 0000000..0fc93f5 Binary files /dev/null and b/contrib/exfoliation/images/logos/database.gif differ diff --git a/contrib/exfoliation/images/logos/debian.gd2 b/contrib/exfoliation/images/logos/debian.gd2 new file mode 100644 index 0000000..5623411 Binary files /dev/null and b/contrib/exfoliation/images/logos/debian.gd2 differ diff --git a/contrib/exfoliation/images/logos/debian.gif b/contrib/exfoliation/images/logos/debian.gif new file mode 100644 index 0000000..495839b Binary files /dev/null and b/contrib/exfoliation/images/logos/debian.gif differ diff --git a/contrib/exfoliation/images/logos/debian.jpg b/contrib/exfoliation/images/logos/debian.jpg new file mode 100644 index 0000000..776b3fb Binary files /dev/null and b/contrib/exfoliation/images/logos/debian.jpg differ diff --git a/contrib/exfoliation/images/logos/debian.png b/contrib/exfoliation/images/logos/debian.png new file mode 100644 index 0000000..a30cee9 Binary files /dev/null and b/contrib/exfoliation/images/logos/debian.png differ diff --git a/contrib/exfoliation/images/logos/desktop-server.gd2 b/contrib/exfoliation/images/logos/desktop-server.gd2 new file mode 100644 index 0000000..2dbbea1 Binary files /dev/null and b/contrib/exfoliation/images/logos/desktop-server.gd2 differ diff --git a/contrib/exfoliation/images/logos/desktop-server.gif b/contrib/exfoliation/images/logos/desktop-server.gif new file mode 100644 index 0000000..745c99e Binary files /dev/null and b/contrib/exfoliation/images/logos/desktop-server.gif differ diff --git a/contrib/exfoliation/images/logos/ethernet_card.png b/contrib/exfoliation/images/logos/ethernet_card.png new file mode 100644 index 0000000..2c3e963 Binary files /dev/null and b/contrib/exfoliation/images/logos/ethernet_card.png differ diff --git a/contrib/exfoliation/images/logos/fax.gd2 b/contrib/exfoliation/images/logos/fax.gd2 new file mode 100644 index 0000000..c210bfc Binary files /dev/null and b/contrib/exfoliation/images/logos/fax.gd2 differ diff --git a/contrib/exfoliation/images/logos/fax.gif b/contrib/exfoliation/images/logos/fax.gif new file mode 100644 index 0000000..fc0b0c2 Binary files /dev/null and b/contrib/exfoliation/images/logos/fax.gif differ diff --git a/contrib/exfoliation/images/logos/firewall.gd2 b/contrib/exfoliation/images/logos/firewall.gd2 new file mode 100644 index 0000000..f683764 Binary files /dev/null and b/contrib/exfoliation/images/logos/firewall.gd2 differ diff --git a/contrib/exfoliation/images/logos/firewall.gif b/contrib/exfoliation/images/logos/firewall.gif new file mode 100644 index 0000000..06ac7bc Binary files /dev/null and b/contrib/exfoliation/images/logos/firewall.gif differ diff --git a/contrib/exfoliation/images/logos/freebsd40.gd2 b/contrib/exfoliation/images/logos/freebsd40.gd2 new file mode 100644 index 0000000..f0ae01b Binary files /dev/null and b/contrib/exfoliation/images/logos/freebsd40.gd2 differ diff --git a/contrib/exfoliation/images/logos/freebsd40.gif b/contrib/exfoliation/images/logos/freebsd40.gif new file mode 100644 index 0000000..0d02cd8 Binary files /dev/null and b/contrib/exfoliation/images/logos/freebsd40.gif differ diff --git a/contrib/exfoliation/images/logos/freebsd40.jpg b/contrib/exfoliation/images/logos/freebsd40.jpg new file mode 100644 index 0000000..8050d29 Binary files /dev/null and b/contrib/exfoliation/images/logos/freebsd40.jpg differ diff --git a/contrib/exfoliation/images/logos/freebsd40.png b/contrib/exfoliation/images/logos/freebsd40.png new file mode 100644 index 0000000..e26825d Binary files /dev/null and b/contrib/exfoliation/images/logos/freebsd40.png differ diff --git a/contrib/exfoliation/images/logos/globe.png b/contrib/exfoliation/images/logos/globe.png new file mode 100644 index 0000000..343fd69 Binary files /dev/null and b/contrib/exfoliation/images/logos/globe.png differ diff --git a/contrib/exfoliation/images/logos/graph.gif b/contrib/exfoliation/images/logos/graph.gif new file mode 100644 index 0000000..068082a Binary files /dev/null and b/contrib/exfoliation/images/logos/graph.gif differ diff --git a/contrib/exfoliation/images/logos/hp-printer40.gd2 b/contrib/exfoliation/images/logos/hp-printer40.gd2 new file mode 100644 index 0000000..5471403 Binary files /dev/null and b/contrib/exfoliation/images/logos/hp-printer40.gd2 differ diff --git a/contrib/exfoliation/images/logos/hp-printer40.gif b/contrib/exfoliation/images/logos/hp-printer40.gif new file mode 100644 index 0000000..f817c36 Binary files /dev/null and b/contrib/exfoliation/images/logos/hp-printer40.gif differ diff --git a/contrib/exfoliation/images/logos/hp-printer40.jpg b/contrib/exfoliation/images/logos/hp-printer40.jpg new file mode 100644 index 0000000..2439cf1 Binary files /dev/null and b/contrib/exfoliation/images/logos/hp-printer40.jpg differ diff --git a/contrib/exfoliation/images/logos/hp-printer40.png b/contrib/exfoliation/images/logos/hp-printer40.png new file mode 100644 index 0000000..f1db051 Binary files /dev/null and b/contrib/exfoliation/images/logos/hp-printer40.png differ diff --git a/contrib/exfoliation/images/logos/hpux.gd2 b/contrib/exfoliation/images/logos/hpux.gd2 new file mode 100644 index 0000000..50c0320 Binary files /dev/null and b/contrib/exfoliation/images/logos/hpux.gd2 differ diff --git a/contrib/exfoliation/images/logos/hpux.gif b/contrib/exfoliation/images/logos/hpux.gif new file mode 100644 index 0000000..37de528 Binary files /dev/null and b/contrib/exfoliation/images/logos/hpux.gif differ diff --git a/contrib/exfoliation/images/logos/hpux.jpg b/contrib/exfoliation/images/logos/hpux.jpg new file mode 100644 index 0000000..5ecdbe7 Binary files /dev/null and b/contrib/exfoliation/images/logos/hpux.jpg differ diff --git a/contrib/exfoliation/images/logos/hpux.png b/contrib/exfoliation/images/logos/hpux.png new file mode 100644 index 0000000..57fc27b Binary files /dev/null and b/contrib/exfoliation/images/logos/hpux.png differ diff --git a/contrib/exfoliation/images/logos/hub.gd2 b/contrib/exfoliation/images/logos/hub.gd2 new file mode 100644 index 0000000..41b2c50 Binary files /dev/null and b/contrib/exfoliation/images/logos/hub.gd2 differ diff --git a/contrib/exfoliation/images/logos/hub.gif b/contrib/exfoliation/images/logos/hub.gif new file mode 100644 index 0000000..e2bcd30 Binary files /dev/null and b/contrib/exfoliation/images/logos/hub.gif differ diff --git a/contrib/exfoliation/images/logos/internet.gd2 b/contrib/exfoliation/images/logos/internet.gd2 new file mode 100644 index 0000000..303dae5 Binary files /dev/null and b/contrib/exfoliation/images/logos/internet.gd2 differ diff --git a/contrib/exfoliation/images/logos/internet.gif b/contrib/exfoliation/images/logos/internet.gif new file mode 100644 index 0000000..6d7b52f Binary files /dev/null and b/contrib/exfoliation/images/logos/internet.gif differ diff --git a/contrib/exfoliation/images/logos/internet_device.png b/contrib/exfoliation/images/logos/internet_device.png new file mode 100644 index 0000000..4a8d6eb Binary files /dev/null and b/contrib/exfoliation/images/logos/internet_device.png differ diff --git a/contrib/exfoliation/images/logos/ip-pbx.gd2 b/contrib/exfoliation/images/logos/ip-pbx.gd2 new file mode 100644 index 0000000..7496a24 Binary files /dev/null and b/contrib/exfoliation/images/logos/ip-pbx.gd2 differ diff --git a/contrib/exfoliation/images/logos/ip-pbx.gif b/contrib/exfoliation/images/logos/ip-pbx.gif new file mode 100644 index 0000000..3ee689a Binary files /dev/null and b/contrib/exfoliation/images/logos/ip-pbx.gif differ diff --git a/contrib/exfoliation/images/logos/irix.gd2 b/contrib/exfoliation/images/logos/irix.gd2 new file mode 100644 index 0000000..b7250d8 Binary files /dev/null and b/contrib/exfoliation/images/logos/irix.gd2 differ diff --git a/contrib/exfoliation/images/logos/irix.gif b/contrib/exfoliation/images/logos/irix.gif new file mode 100644 index 0000000..8149f22 Binary files /dev/null and b/contrib/exfoliation/images/logos/irix.gif differ diff --git a/contrib/exfoliation/images/logos/irix.jpg b/contrib/exfoliation/images/logos/irix.jpg new file mode 100644 index 0000000..c09a40f Binary files /dev/null and b/contrib/exfoliation/images/logos/irix.jpg differ diff --git a/contrib/exfoliation/images/logos/irix.png b/contrib/exfoliation/images/logos/irix.png new file mode 100644 index 0000000..e42070c Binary files /dev/null and b/contrib/exfoliation/images/logos/irix.png differ diff --git a/contrib/exfoliation/images/logos/linux40.gd2 b/contrib/exfoliation/images/logos/linux40.gd2 new file mode 100644 index 0000000..ccd2bd4 Binary files /dev/null and b/contrib/exfoliation/images/logos/linux40.gd2 differ diff --git a/contrib/exfoliation/images/logos/linux40.gif b/contrib/exfoliation/images/logos/linux40.gif new file mode 100644 index 0000000..560dda4 Binary files /dev/null and b/contrib/exfoliation/images/logos/linux40.gif differ diff --git a/contrib/exfoliation/images/logos/linux40.jpg b/contrib/exfoliation/images/logos/linux40.jpg new file mode 100644 index 0000000..48a46ab Binary files /dev/null and b/contrib/exfoliation/images/logos/linux40.jpg differ diff --git a/contrib/exfoliation/images/logos/linux40.png b/contrib/exfoliation/images/logos/linux40.png new file mode 100644 index 0000000..55d6764 Binary files /dev/null and b/contrib/exfoliation/images/logos/linux40.png differ diff --git a/contrib/exfoliation/images/logos/logo.gd2 b/contrib/exfoliation/images/logos/logo.gd2 new file mode 100644 index 0000000..6272395 Binary files /dev/null and b/contrib/exfoliation/images/logos/logo.gd2 differ diff --git a/contrib/exfoliation/images/logos/mac40.gd2 b/contrib/exfoliation/images/logos/mac40.gd2 new file mode 100644 index 0000000..82699fa Binary files /dev/null and b/contrib/exfoliation/images/logos/mac40.gd2 differ diff --git a/contrib/exfoliation/images/logos/mac40.gif b/contrib/exfoliation/images/logos/mac40.gif new file mode 100644 index 0000000..6fdea58 Binary files /dev/null and b/contrib/exfoliation/images/logos/mac40.gif differ diff --git a/contrib/exfoliation/images/logos/mac40.jpg b/contrib/exfoliation/images/logos/mac40.jpg new file mode 100644 index 0000000..b4e8913 Binary files /dev/null and b/contrib/exfoliation/images/logos/mac40.jpg differ diff --git a/contrib/exfoliation/images/logos/mac40.png b/contrib/exfoliation/images/logos/mac40.png new file mode 100644 index 0000000..47968ae Binary files /dev/null and b/contrib/exfoliation/images/logos/mac40.png differ diff --git a/contrib/exfoliation/images/logos/mainframe.gd2 b/contrib/exfoliation/images/logos/mainframe.gd2 new file mode 100644 index 0000000..f1f435d Binary files /dev/null and b/contrib/exfoliation/images/logos/mainframe.gd2 differ diff --git a/contrib/exfoliation/images/logos/mainframe.gif b/contrib/exfoliation/images/logos/mainframe.gif new file mode 100644 index 0000000..489335f Binary files /dev/null and b/contrib/exfoliation/images/logos/mainframe.gif differ diff --git a/contrib/exfoliation/images/logos/mandrake.gd2 b/contrib/exfoliation/images/logos/mandrake.gd2 new file mode 100644 index 0000000..75712ed Binary files /dev/null and b/contrib/exfoliation/images/logos/mandrake.gd2 differ diff --git a/contrib/exfoliation/images/logos/mandrake.gif b/contrib/exfoliation/images/logos/mandrake.gif new file mode 100644 index 0000000..65758c0 Binary files /dev/null and b/contrib/exfoliation/images/logos/mandrake.gif differ diff --git a/contrib/exfoliation/images/logos/mandrake.jpg b/contrib/exfoliation/images/logos/mandrake.jpg new file mode 100644 index 0000000..d2ec629 Binary files /dev/null and b/contrib/exfoliation/images/logos/mandrake.jpg differ diff --git a/contrib/exfoliation/images/logos/mandrake.png b/contrib/exfoliation/images/logos/mandrake.png new file mode 100644 index 0000000..b6a90b0 Binary files /dev/null and b/contrib/exfoliation/images/logos/mandrake.png differ diff --git a/contrib/exfoliation/images/logos/monitor.png b/contrib/exfoliation/images/logos/monitor.png new file mode 100644 index 0000000..6b94a70 Binary files /dev/null and b/contrib/exfoliation/images/logos/monitor.png differ diff --git a/contrib/exfoliation/images/logos/nagios.gd2 b/contrib/exfoliation/images/logos/nagios.gd2 new file mode 100644 index 0000000..bb6dd5a Binary files /dev/null and b/contrib/exfoliation/images/logos/nagios.gd2 differ diff --git a/contrib/exfoliation/images/logos/nagios.gif b/contrib/exfoliation/images/logos/nagios.gif new file mode 100644 index 0000000..5ffa8f4 Binary files /dev/null and b/contrib/exfoliation/images/logos/nagios.gif differ diff --git a/contrib/exfoliation/images/logos/nagiosvrml.png b/contrib/exfoliation/images/logos/nagiosvrml.png new file mode 100644 index 0000000..36fcb56 Binary files /dev/null and b/contrib/exfoliation/images/logos/nagiosvrml.png differ diff --git a/contrib/exfoliation/images/logos/next.gd2 b/contrib/exfoliation/images/logos/next.gd2 new file mode 100644 index 0000000..4adc643 Binary files /dev/null and b/contrib/exfoliation/images/logos/next.gd2 differ diff --git a/contrib/exfoliation/images/logos/next.gif b/contrib/exfoliation/images/logos/next.gif new file mode 100644 index 0000000..fd05a2c Binary files /dev/null and b/contrib/exfoliation/images/logos/next.gif differ diff --git a/contrib/exfoliation/images/logos/next.jpg b/contrib/exfoliation/images/logos/next.jpg new file mode 100644 index 0000000..3517cf7 Binary files /dev/null and b/contrib/exfoliation/images/logos/next.jpg differ diff --git a/contrib/exfoliation/images/logos/next.png b/contrib/exfoliation/images/logos/next.png new file mode 100644 index 0000000..fdd0c2d Binary files /dev/null and b/contrib/exfoliation/images/logos/next.png differ diff --git a/contrib/exfoliation/images/logos/ng-switch40.gd2 b/contrib/exfoliation/images/logos/ng-switch40.gd2 new file mode 100644 index 0000000..69b6152 Binary files /dev/null and b/contrib/exfoliation/images/logos/ng-switch40.gd2 differ diff --git a/contrib/exfoliation/images/logos/ng-switch40.gif b/contrib/exfoliation/images/logos/ng-switch40.gif new file mode 100644 index 0000000..c1a1f42 Binary files /dev/null and b/contrib/exfoliation/images/logos/ng-switch40.gif differ diff --git a/contrib/exfoliation/images/logos/ng-switch40.jpg b/contrib/exfoliation/images/logos/ng-switch40.jpg new file mode 100644 index 0000000..e50d870 Binary files /dev/null and b/contrib/exfoliation/images/logos/ng-switch40.jpg differ diff --git a/contrib/exfoliation/images/logos/ng-switch40.png b/contrib/exfoliation/images/logos/ng-switch40.png new file mode 100644 index 0000000..f7ca364 Binary files /dev/null and b/contrib/exfoliation/images/logos/ng-switch40.png differ diff --git a/contrib/exfoliation/images/logos/notebook.gd2 b/contrib/exfoliation/images/logos/notebook.gd2 new file mode 100644 index 0000000..43e8bc7 Binary files /dev/null and b/contrib/exfoliation/images/logos/notebook.gd2 differ diff --git a/contrib/exfoliation/images/logos/notebook.gif b/contrib/exfoliation/images/logos/notebook.gif new file mode 100644 index 0000000..b24f95d Binary files /dev/null and b/contrib/exfoliation/images/logos/notebook.gif differ diff --git a/contrib/exfoliation/images/logos/novell40.gd2 b/contrib/exfoliation/images/logos/novell40.gd2 new file mode 100644 index 0000000..db24d4e Binary files /dev/null and b/contrib/exfoliation/images/logos/novell40.gd2 differ diff --git a/contrib/exfoliation/images/logos/novell40.gif b/contrib/exfoliation/images/logos/novell40.gif new file mode 100644 index 0000000..48a2098 Binary files /dev/null and b/contrib/exfoliation/images/logos/novell40.gif differ diff --git a/contrib/exfoliation/images/logos/novell40.jpg b/contrib/exfoliation/images/logos/novell40.jpg new file mode 100644 index 0000000..b85baab Binary files /dev/null and b/contrib/exfoliation/images/logos/novell40.jpg differ diff --git a/contrib/exfoliation/images/logos/novell40.png b/contrib/exfoliation/images/logos/novell40.png new file mode 100644 index 0000000..596d1a0 Binary files /dev/null and b/contrib/exfoliation/images/logos/novell40.png differ diff --git a/contrib/exfoliation/images/logos/openbsd.gd2 b/contrib/exfoliation/images/logos/openbsd.gd2 new file mode 100644 index 0000000..d96c055 Binary files /dev/null and b/contrib/exfoliation/images/logos/openbsd.gd2 differ diff --git a/contrib/exfoliation/images/logos/openbsd.gif b/contrib/exfoliation/images/logos/openbsd.gif new file mode 100644 index 0000000..8ac7786 Binary files /dev/null and b/contrib/exfoliation/images/logos/openbsd.gif differ diff --git a/contrib/exfoliation/images/logos/openbsd.jpg b/contrib/exfoliation/images/logos/openbsd.jpg new file mode 100644 index 0000000..1d78e44 Binary files /dev/null and b/contrib/exfoliation/images/logos/openbsd.jpg differ diff --git a/contrib/exfoliation/images/logos/openbsd.png b/contrib/exfoliation/images/logos/openbsd.png new file mode 100644 index 0000000..1e05979 Binary files /dev/null and b/contrib/exfoliation/images/logos/openbsd.png differ diff --git a/contrib/exfoliation/images/logos/printer.gd2 b/contrib/exfoliation/images/logos/printer.gd2 new file mode 100644 index 0000000..bca0a94 Binary files /dev/null and b/contrib/exfoliation/images/logos/printer.gd2 differ diff --git a/contrib/exfoliation/images/logos/printer.gif b/contrib/exfoliation/images/logos/printer.gif new file mode 100644 index 0000000..ef0f228 Binary files /dev/null and b/contrib/exfoliation/images/logos/printer.gif differ diff --git a/contrib/exfoliation/images/logos/rack-server.gd2 b/contrib/exfoliation/images/logos/rack-server.gd2 new file mode 100644 index 0000000..e61686b Binary files /dev/null and b/contrib/exfoliation/images/logos/rack-server.gd2 differ diff --git a/contrib/exfoliation/images/logos/rack-server.gif b/contrib/exfoliation/images/logos/rack-server.gif new file mode 100644 index 0000000..482b1e0 Binary files /dev/null and b/contrib/exfoliation/images/logos/rack-server.gif differ diff --git a/contrib/exfoliation/images/logos/redhat.gd2 b/contrib/exfoliation/images/logos/redhat.gd2 new file mode 100644 index 0000000..db5e897 Binary files /dev/null and b/contrib/exfoliation/images/logos/redhat.gd2 differ diff --git a/contrib/exfoliation/images/logos/redhat.gif b/contrib/exfoliation/images/logos/redhat.gif new file mode 100644 index 0000000..48b7b7f Binary files /dev/null and b/contrib/exfoliation/images/logos/redhat.gif differ diff --git a/contrib/exfoliation/images/logos/redhat.jpg b/contrib/exfoliation/images/logos/redhat.jpg new file mode 100644 index 0000000..002f1fc Binary files /dev/null and b/contrib/exfoliation/images/logos/redhat.jpg differ diff --git a/contrib/exfoliation/images/logos/redhat.png b/contrib/exfoliation/images/logos/redhat.png new file mode 100644 index 0000000..6cafd9d Binary files /dev/null and b/contrib/exfoliation/images/logos/redhat.png differ diff --git a/contrib/exfoliation/images/logos/router.gd2 b/contrib/exfoliation/images/logos/router.gd2 new file mode 100644 index 0000000..7025897 Binary files /dev/null and b/contrib/exfoliation/images/logos/router.gd2 differ diff --git a/contrib/exfoliation/images/logos/router.gif b/contrib/exfoliation/images/logos/router.gif new file mode 100644 index 0000000..f928c27 Binary files /dev/null and b/contrib/exfoliation/images/logos/router.gif differ diff --git a/contrib/exfoliation/images/logos/router40.gd2 b/contrib/exfoliation/images/logos/router40.gd2 new file mode 100644 index 0000000..3c4f4b5 Binary files /dev/null and b/contrib/exfoliation/images/logos/router40.gd2 differ diff --git a/contrib/exfoliation/images/logos/router40.gif b/contrib/exfoliation/images/logos/router40.gif new file mode 100644 index 0000000..d90ec19 Binary files /dev/null and b/contrib/exfoliation/images/logos/router40.gif differ diff --git a/contrib/exfoliation/images/logos/router40.jpg b/contrib/exfoliation/images/logos/router40.jpg new file mode 100644 index 0000000..eb9a81d Binary files /dev/null and b/contrib/exfoliation/images/logos/router40.jpg differ diff --git a/contrib/exfoliation/images/logos/router40.png b/contrib/exfoliation/images/logos/router40.png new file mode 100644 index 0000000..64bc554 Binary files /dev/null and b/contrib/exfoliation/images/logos/router40.png differ diff --git a/contrib/exfoliation/images/logos/san.gd2 b/contrib/exfoliation/images/logos/san.gd2 new file mode 100644 index 0000000..e3ae764 Binary files /dev/null and b/contrib/exfoliation/images/logos/san.gd2 differ diff --git a/contrib/exfoliation/images/logos/san.gif b/contrib/exfoliation/images/logos/san.gif new file mode 100644 index 0000000..e6c2b29 Binary files /dev/null and b/contrib/exfoliation/images/logos/san.gif differ diff --git a/contrib/exfoliation/images/logos/satellite.png b/contrib/exfoliation/images/logos/satellite.png new file mode 100644 index 0000000..ac6a364 Binary files /dev/null and b/contrib/exfoliation/images/logos/satellite.png differ diff --git a/contrib/exfoliation/images/logos/server.png b/contrib/exfoliation/images/logos/server.png new file mode 100644 index 0000000..cecc6a5 Binary files /dev/null and b/contrib/exfoliation/images/logos/server.png differ diff --git a/contrib/exfoliation/images/logos/signal.png b/contrib/exfoliation/images/logos/signal.png new file mode 100644 index 0000000..cea3d28 Binary files /dev/null and b/contrib/exfoliation/images/logos/signal.png differ diff --git a/contrib/exfoliation/images/logos/slackware.gd2 b/contrib/exfoliation/images/logos/slackware.gd2 new file mode 100644 index 0000000..127e957 Binary files /dev/null and b/contrib/exfoliation/images/logos/slackware.gd2 differ diff --git a/contrib/exfoliation/images/logos/slackware.gif b/contrib/exfoliation/images/logos/slackware.gif new file mode 100644 index 0000000..2d89123 Binary files /dev/null and b/contrib/exfoliation/images/logos/slackware.gif differ diff --git a/contrib/exfoliation/images/logos/slackware.jpg b/contrib/exfoliation/images/logos/slackware.jpg new file mode 100644 index 0000000..381d069 Binary files /dev/null and b/contrib/exfoliation/images/logos/slackware.jpg differ diff --git a/contrib/exfoliation/images/logos/slackware.png b/contrib/exfoliation/images/logos/slackware.png new file mode 100644 index 0000000..c5cfec9 Binary files /dev/null and b/contrib/exfoliation/images/logos/slackware.png differ diff --git a/contrib/exfoliation/images/logos/stampede.gd2 b/contrib/exfoliation/images/logos/stampede.gd2 new file mode 100644 index 0000000..42f3724 Binary files /dev/null and b/contrib/exfoliation/images/logos/stampede.gd2 differ diff --git a/contrib/exfoliation/images/logos/stampede.gif b/contrib/exfoliation/images/logos/stampede.gif new file mode 100644 index 0000000..0fec7cd Binary files /dev/null and b/contrib/exfoliation/images/logos/stampede.gif differ diff --git a/contrib/exfoliation/images/logos/stampede.jpg b/contrib/exfoliation/images/logos/stampede.jpg new file mode 100644 index 0000000..520b75c Binary files /dev/null and b/contrib/exfoliation/images/logos/stampede.jpg differ diff --git a/contrib/exfoliation/images/logos/stampede.png b/contrib/exfoliation/images/logos/stampede.png new file mode 100644 index 0000000..668e170 Binary files /dev/null and b/contrib/exfoliation/images/logos/stampede.png differ diff --git a/contrib/exfoliation/images/logos/station.gd2 b/contrib/exfoliation/images/logos/station.gd2 new file mode 100644 index 0000000..2225ed7 Binary files /dev/null and b/contrib/exfoliation/images/logos/station.gd2 differ diff --git a/contrib/exfoliation/images/logos/storm.gd2 b/contrib/exfoliation/images/logos/storm.gd2 new file mode 100644 index 0000000..e73cb51 Binary files /dev/null and b/contrib/exfoliation/images/logos/storm.gd2 differ diff --git a/contrib/exfoliation/images/logos/storm.gif b/contrib/exfoliation/images/logos/storm.gif new file mode 100644 index 0000000..683a7ef Binary files /dev/null and b/contrib/exfoliation/images/logos/storm.gif differ diff --git a/contrib/exfoliation/images/logos/storm.jpg b/contrib/exfoliation/images/logos/storm.jpg new file mode 100644 index 0000000..6cce938 Binary files /dev/null and b/contrib/exfoliation/images/logos/storm.jpg differ diff --git a/contrib/exfoliation/images/logos/storm.png b/contrib/exfoliation/images/logos/storm.png new file mode 100644 index 0000000..9e9b762 Binary files /dev/null and b/contrib/exfoliation/images/logos/storm.png differ diff --git a/contrib/exfoliation/images/logos/sun40.gd2 b/contrib/exfoliation/images/logos/sun40.gd2 new file mode 100644 index 0000000..3c46f70 Binary files /dev/null and b/contrib/exfoliation/images/logos/sun40.gd2 differ diff --git a/contrib/exfoliation/images/logos/sun40.gif b/contrib/exfoliation/images/logos/sun40.gif new file mode 100644 index 0000000..1727767 Binary files /dev/null and b/contrib/exfoliation/images/logos/sun40.gif differ diff --git a/contrib/exfoliation/images/logos/sun40.jpg b/contrib/exfoliation/images/logos/sun40.jpg new file mode 100644 index 0000000..eab9f4d Binary files /dev/null and b/contrib/exfoliation/images/logos/sun40.jpg differ diff --git a/contrib/exfoliation/images/logos/sun40.png b/contrib/exfoliation/images/logos/sun40.png new file mode 100644 index 0000000..9961753 Binary files /dev/null and b/contrib/exfoliation/images/logos/sun40.png differ diff --git a/contrib/exfoliation/images/logos/sunlogo.gd2 b/contrib/exfoliation/images/logos/sunlogo.gd2 new file mode 100644 index 0000000..0cabbcc Binary files /dev/null and b/contrib/exfoliation/images/logos/sunlogo.gd2 differ diff --git a/contrib/exfoliation/images/logos/sunlogo.gif b/contrib/exfoliation/images/logos/sunlogo.gif new file mode 100644 index 0000000..a035f10 Binary files /dev/null and b/contrib/exfoliation/images/logos/sunlogo.gif differ diff --git a/contrib/exfoliation/images/logos/sunlogo.jpg b/contrib/exfoliation/images/logos/sunlogo.jpg new file mode 100644 index 0000000..d278721 Binary files /dev/null and b/contrib/exfoliation/images/logos/sunlogo.jpg differ diff --git a/contrib/exfoliation/images/logos/sunlogo.png b/contrib/exfoliation/images/logos/sunlogo.png new file mode 100644 index 0000000..7b84f6f Binary files /dev/null and b/contrib/exfoliation/images/logos/sunlogo.png differ diff --git a/contrib/exfoliation/images/logos/switch.gd2 b/contrib/exfoliation/images/logos/switch.gd2 new file mode 100644 index 0000000..af1d0f0 Binary files /dev/null and b/contrib/exfoliation/images/logos/switch.gd2 differ diff --git a/contrib/exfoliation/images/logos/switch.gif b/contrib/exfoliation/images/logos/switch.gif new file mode 100644 index 0000000..27c6527 Binary files /dev/null and b/contrib/exfoliation/images/logos/switch.gif differ diff --git a/contrib/exfoliation/images/logos/switch40.gd2 b/contrib/exfoliation/images/logos/switch40.gd2 new file mode 100644 index 0000000..811609e Binary files /dev/null and b/contrib/exfoliation/images/logos/switch40.gd2 differ diff --git a/contrib/exfoliation/images/logos/switch40.gif b/contrib/exfoliation/images/logos/switch40.gif new file mode 100644 index 0000000..1ef629c Binary files /dev/null and b/contrib/exfoliation/images/logos/switch40.gif differ diff --git a/contrib/exfoliation/images/logos/switch40.jpg b/contrib/exfoliation/images/logos/switch40.jpg new file mode 100644 index 0000000..daae168 Binary files /dev/null and b/contrib/exfoliation/images/logos/switch40.jpg differ diff --git a/contrib/exfoliation/images/logos/switch40.png b/contrib/exfoliation/images/logos/switch40.png new file mode 100644 index 0000000..6f5b2cb Binary files /dev/null and b/contrib/exfoliation/images/logos/switch40.png differ diff --git a/contrib/exfoliation/images/logos/thin-client.gd2 b/contrib/exfoliation/images/logos/thin-client.gd2 new file mode 100644 index 0000000..6d60a46 Binary files /dev/null and b/contrib/exfoliation/images/logos/thin-client.gd2 differ diff --git a/contrib/exfoliation/images/logos/thin-client.gif b/contrib/exfoliation/images/logos/thin-client.gif new file mode 100644 index 0000000..43935e1 Binary files /dev/null and b/contrib/exfoliation/images/logos/thin-client.gif differ diff --git a/contrib/exfoliation/images/logos/turbolinux.gd2 b/contrib/exfoliation/images/logos/turbolinux.gd2 new file mode 100644 index 0000000..f46f602 Binary files /dev/null and b/contrib/exfoliation/images/logos/turbolinux.gd2 differ diff --git a/contrib/exfoliation/images/logos/turbolinux.gif b/contrib/exfoliation/images/logos/turbolinux.gif new file mode 100644 index 0000000..de5ccfb Binary files /dev/null and b/contrib/exfoliation/images/logos/turbolinux.gif differ diff --git a/contrib/exfoliation/images/logos/turbolinux.jpg b/contrib/exfoliation/images/logos/turbolinux.jpg new file mode 100644 index 0000000..bb1f75c Binary files /dev/null and b/contrib/exfoliation/images/logos/turbolinux.jpg differ diff --git a/contrib/exfoliation/images/logos/turbolinux.png b/contrib/exfoliation/images/logos/turbolinux.png new file mode 100644 index 0000000..0ef6289 Binary files /dev/null and b/contrib/exfoliation/images/logos/turbolinux.png differ diff --git a/contrib/exfoliation/images/logos/ultrapenguin.gd2 b/contrib/exfoliation/images/logos/ultrapenguin.gd2 new file mode 100644 index 0000000..3db9012 Binary files /dev/null and b/contrib/exfoliation/images/logos/ultrapenguin.gd2 differ diff --git a/contrib/exfoliation/images/logos/ultrapenguin.gif b/contrib/exfoliation/images/logos/ultrapenguin.gif new file mode 100644 index 0000000..f33dd17 Binary files /dev/null and b/contrib/exfoliation/images/logos/ultrapenguin.gif differ diff --git a/contrib/exfoliation/images/logos/ultrapenguin.jpg b/contrib/exfoliation/images/logos/ultrapenguin.jpg new file mode 100644 index 0000000..a3d6b5b Binary files /dev/null and b/contrib/exfoliation/images/logos/ultrapenguin.jpg differ diff --git a/contrib/exfoliation/images/logos/ultrapenguin.png b/contrib/exfoliation/images/logos/ultrapenguin.png new file mode 100644 index 0000000..76a9cc8 Binary files /dev/null and b/contrib/exfoliation/images/logos/ultrapenguin.png differ diff --git a/contrib/exfoliation/images/logos/unicos.gd2 b/contrib/exfoliation/images/logos/unicos.gd2 new file mode 100644 index 0000000..cc6f44b Binary files /dev/null and b/contrib/exfoliation/images/logos/unicos.gd2 differ diff --git a/contrib/exfoliation/images/logos/unicos.gif b/contrib/exfoliation/images/logos/unicos.gif new file mode 100644 index 0000000..054de27 Binary files /dev/null and b/contrib/exfoliation/images/logos/unicos.gif differ diff --git a/contrib/exfoliation/images/logos/unicos.jpg b/contrib/exfoliation/images/logos/unicos.jpg new file mode 100644 index 0000000..4c196f9 Binary files /dev/null and b/contrib/exfoliation/images/logos/unicos.jpg differ diff --git a/contrib/exfoliation/images/logos/unicos.png b/contrib/exfoliation/images/logos/unicos.png new file mode 100644 index 0000000..8efe4ea Binary files /dev/null and b/contrib/exfoliation/images/logos/unicos.png differ diff --git a/contrib/exfoliation/images/logos/unknown.gd2 b/contrib/exfoliation/images/logos/unknown.gd2 new file mode 100644 index 0000000..4d4bba9 Binary files /dev/null and b/contrib/exfoliation/images/logos/unknown.gd2 differ diff --git a/contrib/exfoliation/images/logos/unknown.gif b/contrib/exfoliation/images/logos/unknown.gif new file mode 100644 index 0000000..8aac3f9 Binary files /dev/null and b/contrib/exfoliation/images/logos/unknown.gif differ diff --git a/contrib/exfoliation/images/logos/webcamera.png b/contrib/exfoliation/images/logos/webcamera.png new file mode 100644 index 0000000..673c48c Binary files /dev/null and b/contrib/exfoliation/images/logos/webcamera.png differ diff --git a/contrib/exfoliation/images/logos/wifi.gd2 b/contrib/exfoliation/images/logos/wifi.gd2 new file mode 100644 index 0000000..62912eb Binary files /dev/null and b/contrib/exfoliation/images/logos/wifi.gd2 differ diff --git a/contrib/exfoliation/images/logos/wifi.gif b/contrib/exfoliation/images/logos/wifi.gif new file mode 100644 index 0000000..e7d12ff Binary files /dev/null and b/contrib/exfoliation/images/logos/wifi.gif differ diff --git a/contrib/exfoliation/images/logos/wifi_modem.png b/contrib/exfoliation/images/logos/wifi_modem.png new file mode 100644 index 0000000..29a4499 Binary files /dev/null and b/contrib/exfoliation/images/logos/wifi_modem.png differ diff --git a/contrib/exfoliation/images/logos/win40.gd2 b/contrib/exfoliation/images/logos/win40.gd2 new file mode 100644 index 0000000..2225ed7 Binary files /dev/null and b/contrib/exfoliation/images/logos/win40.gd2 differ diff --git a/contrib/exfoliation/images/logos/win40.gif b/contrib/exfoliation/images/logos/win40.gif new file mode 100644 index 0000000..05803bc Binary files /dev/null and b/contrib/exfoliation/images/logos/win40.gif differ diff --git a/contrib/exfoliation/images/logos/win40.jpg b/contrib/exfoliation/images/logos/win40.jpg new file mode 100644 index 0000000..905d557 Binary files /dev/null and b/contrib/exfoliation/images/logos/win40.jpg differ diff --git a/contrib/exfoliation/images/logos/win40.png b/contrib/exfoliation/images/logos/win40.png new file mode 100644 index 0000000..cd34eaf Binary files /dev/null and b/contrib/exfoliation/images/logos/win40.png differ diff --git a/contrib/exfoliation/images/logos/workstation.gd2 b/contrib/exfoliation/images/logos/workstation.gd2 new file mode 100644 index 0000000..f43ad49 Binary files /dev/null and b/contrib/exfoliation/images/logos/workstation.gd2 differ diff --git a/contrib/exfoliation/images/logos/workstation.gif b/contrib/exfoliation/images/logos/workstation.gif new file mode 100644 index 0000000..9a967cc Binary files /dev/null and b/contrib/exfoliation/images/logos/workstation.gif differ diff --git a/contrib/exfoliation/images/logos/workstation.png b/contrib/exfoliation/images/logos/workstation.png new file mode 100644 index 0000000..b3f087b Binary files /dev/null and b/contrib/exfoliation/images/logos/workstation.png differ diff --git a/contrib/exfoliation/images/logos/workstation_locked.png b/contrib/exfoliation/images/logos/workstation_locked.png new file mode 100644 index 0000000..8028a42 Binary files /dev/null and b/contrib/exfoliation/images/logos/workstation_locked.png differ diff --git a/contrib/exfoliation/images/logos/yellowdog.gd2 b/contrib/exfoliation/images/logos/yellowdog.gd2 new file mode 100644 index 0000000..d6a2ecb Binary files /dev/null and b/contrib/exfoliation/images/logos/yellowdog.gd2 differ diff --git a/contrib/exfoliation/images/logos/yellowdog.gif b/contrib/exfoliation/images/logos/yellowdog.gif new file mode 100644 index 0000000..cb5e640 Binary files /dev/null and b/contrib/exfoliation/images/logos/yellowdog.gif differ diff --git a/contrib/exfoliation/images/logos/yellowdog.jpg b/contrib/exfoliation/images/logos/yellowdog.jpg new file mode 100644 index 0000000..777a908 Binary files /dev/null and b/contrib/exfoliation/images/logos/yellowdog.jpg differ diff --git a/contrib/exfoliation/images/logos/yellowdog.png b/contrib/exfoliation/images/logos/yellowdog.png new file mode 100644 index 0000000..336322e Binary files /dev/null and b/contrib/exfoliation/images/logos/yellowdog.png differ diff --git a/contrib/exfoliation/images/logrotate.png b/contrib/exfoliation/images/logrotate.png new file mode 100644 index 0000000..a8398d9 Binary files /dev/null and b/contrib/exfoliation/images/logrotate.png differ diff --git a/contrib/exfoliation/images/ndisabled.gif b/contrib/exfoliation/images/ndisabled.gif new file mode 100644 index 0000000..a262301 Binary files /dev/null and b/contrib/exfoliation/images/ndisabled.gif differ diff --git a/contrib/exfoliation/images/noack.gif b/contrib/exfoliation/images/noack.gif new file mode 100644 index 0000000..4b557a5 Binary files /dev/null and b/contrib/exfoliation/images/noack.gif differ diff --git a/contrib/exfoliation/images/notes.gif b/contrib/exfoliation/images/notes.gif new file mode 100644 index 0000000..0f6d43e Binary files /dev/null and b/contrib/exfoliation/images/notes.gif differ diff --git a/contrib/exfoliation/images/notify.gif b/contrib/exfoliation/images/notify.gif new file mode 100644 index 0000000..f5a2a34 Binary files /dev/null and b/contrib/exfoliation/images/notify.gif differ diff --git a/contrib/exfoliation/images/orangedot.gif b/contrib/exfoliation/images/orangedot.gif new file mode 100644 index 0000000..c52e970 Binary files /dev/null and b/contrib/exfoliation/images/orangedot.gif differ diff --git a/contrib/exfoliation/images/passiveonly.gif b/contrib/exfoliation/images/passiveonly.gif new file mode 100644 index 0000000..867818c Binary files /dev/null and b/contrib/exfoliation/images/passiveonly.gif differ diff --git a/contrib/exfoliation/images/recovery.png b/contrib/exfoliation/images/recovery.png new file mode 100644 index 0000000..e9552cf Binary files /dev/null and b/contrib/exfoliation/images/recovery.png differ diff --git a/contrib/exfoliation/images/redundancy.png b/contrib/exfoliation/images/redundancy.png new file mode 100644 index 0000000..e04bf71 Binary files /dev/null and b/contrib/exfoliation/images/redundancy.png differ diff --git a/contrib/exfoliation/images/restart.gif b/contrib/exfoliation/images/restart.gif new file mode 100644 index 0000000..2bd465a Binary files /dev/null and b/contrib/exfoliation/images/restart.gif differ diff --git a/contrib/exfoliation/images/right.gif b/contrib/exfoliation/images/right.gif new file mode 100644 index 0000000..435ae6c Binary files /dev/null and b/contrib/exfoliation/images/right.gif differ diff --git a/contrib/exfoliation/images/sblogo.png b/contrib/exfoliation/images/sblogo.png new file mode 100644 index 0000000..383f34f Binary files /dev/null and b/contrib/exfoliation/images/sblogo.png differ diff --git a/contrib/exfoliation/images/serviceevent.gif b/contrib/exfoliation/images/serviceevent.gif new file mode 100644 index 0000000..b9dca15 Binary files /dev/null and b/contrib/exfoliation/images/serviceevent.gif differ diff --git a/contrib/exfoliation/images/sflogo.png b/contrib/exfoliation/images/sflogo.png new file mode 100644 index 0000000..142a6f9 Binary files /dev/null and b/contrib/exfoliation/images/sflogo.png differ diff --git a/contrib/exfoliation/images/splunk1.gif b/contrib/exfoliation/images/splunk1.gif new file mode 100644 index 0000000..1ccad05 Binary files /dev/null and b/contrib/exfoliation/images/splunk1.gif differ diff --git a/contrib/exfoliation/images/splunk2.gif b/contrib/exfoliation/images/splunk2.gif new file mode 100644 index 0000000..91eb417 Binary files /dev/null and b/contrib/exfoliation/images/splunk2.gif differ diff --git a/contrib/exfoliation/images/start.gif b/contrib/exfoliation/images/start.gif new file mode 100644 index 0000000..c5c9c41 Binary files /dev/null and b/contrib/exfoliation/images/start.gif differ diff --git a/contrib/exfoliation/images/status.gif b/contrib/exfoliation/images/status.gif new file mode 100644 index 0000000..cb14431 Binary files /dev/null and b/contrib/exfoliation/images/status.gif differ diff --git a/contrib/exfoliation/images/status2.gif b/contrib/exfoliation/images/status2.gif new file mode 100644 index 0000000..6785758 Binary files /dev/null and b/contrib/exfoliation/images/status2.gif differ diff --git a/contrib/exfoliation/images/status3.gif b/contrib/exfoliation/images/status3.gif new file mode 100644 index 0000000..e78a22c Binary files /dev/null and b/contrib/exfoliation/images/status3.gif differ diff --git a/contrib/exfoliation/images/status4.gif b/contrib/exfoliation/images/status4.gif new file mode 100644 index 0000000..cfc433e Binary files /dev/null and b/contrib/exfoliation/images/status4.gif differ diff --git a/contrib/exfoliation/images/stop.gif b/contrib/exfoliation/images/stop.gif new file mode 100644 index 0000000..50d8192 Binary files /dev/null and b/contrib/exfoliation/images/stop.gif differ diff --git a/contrib/exfoliation/images/tacdisabled.jpg b/contrib/exfoliation/images/tacdisabled.jpg new file mode 100644 index 0000000..bb2248e Binary files /dev/null and b/contrib/exfoliation/images/tacdisabled.jpg differ diff --git a/contrib/exfoliation/images/tacdisabled.png b/contrib/exfoliation/images/tacdisabled.png new file mode 100644 index 0000000..de076cd Binary files /dev/null and b/contrib/exfoliation/images/tacdisabled.png differ diff --git a/contrib/exfoliation/images/tacenabled.jpg b/contrib/exfoliation/images/tacenabled.jpg new file mode 100644 index 0000000..191ce44 Binary files /dev/null and b/contrib/exfoliation/images/tacenabled.jpg differ diff --git a/contrib/exfoliation/images/tacenabled.png b/contrib/exfoliation/images/tacenabled.png new file mode 100644 index 0000000..9048b9b Binary files /dev/null and b/contrib/exfoliation/images/tacenabled.png differ diff --git a/contrib/exfoliation/images/thermcrit.png b/contrib/exfoliation/images/thermcrit.png new file mode 100644 index 0000000..6a3150d Binary files /dev/null and b/contrib/exfoliation/images/thermcrit.png differ diff --git a/contrib/exfoliation/images/thermok.png b/contrib/exfoliation/images/thermok.png new file mode 100644 index 0000000..3e3659a Binary files /dev/null and b/contrib/exfoliation/images/thermok.png differ diff --git a/contrib/exfoliation/images/thermwarn.png b/contrib/exfoliation/images/thermwarn.png new file mode 100644 index 0000000..0f5252b Binary files /dev/null and b/contrib/exfoliation/images/thermwarn.png differ diff --git a/contrib/exfoliation/images/trends.gif b/contrib/exfoliation/images/trends.gif new file mode 100644 index 0000000..41967c1 Binary files /dev/null and b/contrib/exfoliation/images/trends.gif differ diff --git a/contrib/exfoliation/images/trendshost.png b/contrib/exfoliation/images/trendshost.png new file mode 100644 index 0000000..408d85b Binary files /dev/null and b/contrib/exfoliation/images/trendshost.png differ diff --git a/contrib/exfoliation/images/trendssvc.png b/contrib/exfoliation/images/trendssvc.png new file mode 100644 index 0000000..4c7c50f Binary files /dev/null and b/contrib/exfoliation/images/trendssvc.png differ diff --git a/contrib/exfoliation/images/unknown.png b/contrib/exfoliation/images/unknown.png new file mode 100644 index 0000000..bc8c252 Binary files /dev/null and b/contrib/exfoliation/images/unknown.png differ diff --git a/contrib/exfoliation/images/up.gif b/contrib/exfoliation/images/up.gif new file mode 100644 index 0000000..3dec330 Binary files /dev/null and b/contrib/exfoliation/images/up.gif differ diff --git a/contrib/exfoliation/images/warning.png b/contrib/exfoliation/images/warning.png new file mode 100644 index 0000000..2ac9472 Binary files /dev/null and b/contrib/exfoliation/images/warning.png differ diff --git a/contrib/exfoliation/images/weblogo1.png b/contrib/exfoliation/images/weblogo1.png new file mode 100644 index 0000000..78605a4 Binary files /dev/null and b/contrib/exfoliation/images/weblogo1.png differ diff --git a/contrib/exfoliation/images/zoom1.gif b/contrib/exfoliation/images/zoom1.gif new file mode 100644 index 0000000..4f9cfa1 Binary files /dev/null and b/contrib/exfoliation/images/zoom1.gif differ diff --git a/contrib/exfoliation/images/zoom2.gif b/contrib/exfoliation/images/zoom2.gif new file mode 100644 index 0000000..c52e970 Binary files /dev/null and b/contrib/exfoliation/images/zoom2.gif differ diff --git a/contrib/exfoliation/readme.txt b/contrib/exfoliation/readme.txt new file mode 100644 index 0000000..fa9ae54 --- /dev/null +++ b/contrib/exfoliation/readme.txt @@ -0,0 +1,92 @@ +exfoliation - a skin for nagios +Copyright (c) 2009-2010 Matthew Wall, all rights reserved + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +To use this skin, replace the stock 'images' and 'stylesheets' folders with +those from this tarball. For example: + + cd /opt/nagios/share + tar xvfz exfoliation.tgz + +On debian/unbuntu installations you might have to modify side.html to include +the common.css stylesheet by adding a line like this in the head section: + + + +This skin has been tested with Nagios 3.2.0, 3.2.1, 3.2.2, 3.2.3 + +Revision History: + +0.7 25dec10 + - minor cleanup to statusmap mouseover matrix (nagios bugs still remain) + - added instructions for installations with side.html rather than side.php + - added .NavBarTitle, .NavBarItem, and .NavBarSearchItem for side.html in + ubuntu/debian installations (thanks to michael berman) + - passiveonly is now simply a question mark + - fix jpg versions of tacenabled and tacdisabled + - punt the globe + - added crude service and event handler icons + +0.6 16oct10 + - change enabled/disabled images to x-mark and check-mark + - new trends icon closer to what trends actually does + - reduce size of left and right arrow icons + +0.5 12feb10 + - changed unreachable from red to orange (to parallel unknown) + - right-justify filter names + - eliminate more redundant css + - use blue to indicate 'problem' (nod to vautour) + - use purple to indicate indeterminate state + - make font sizing more consistent in host/service tables + - make font sizing more consistent in data/log/queue tables + - another round of cleanup on the icons + - include nagios base images (in the images/logos directory) + +0.4 29jan10 + - lighten the 'dark' color in even/odd listings + - fix even/odd background colors across pages + - put border on cells that i missed (notifications, status) + note: the cgi emits class tags where it should not, so in a few + places we end up with borders where there should be none. + - include the basic image set in images/logos + - tone down heading text color in data tables + - underline data table headings instead of background color + - more cleanup of tactical layout and stylesheet + - fixed queue enabled/disabled border in extinfo listings + +0.3 30dec09 + - consolidate colors + - refactor style sheets for easier editing + - eliminate (some) redundant stylesheet entries + +0.2 27dec09 + - added images for log activity + - added images for enabled/disabled + - replace images on tactical page + +0.1 27dec09 + - initial rework of color scheme + - eliminate extraneous borders + + + +TODO: + - fixes that require changes to CGI/PHP/HTML: + for extinfo - nested tables with 'command' class + for controls (state versus action) + for host summary - nested td with class + for host listing - statusPENDING should be statusHOSTPENDING + for service summary - nested td with class + to eliminate 'view status' and 'view ... status' redundancy + 'host status totals' -> 'host totals' + 'service status totals' -> 'service totals' + 'current network status' -> 'status' + histogram.cgi contains 'calss' instead of 'class' + inconsistent table definitions - some use padding/spacing + remove hard-coded tags + remove hard-coded center tags + - tone down the neon green/red in the trend graphs diff --git a/contrib/exfoliation/stylesheets/avail.css b/contrib/exfoliation/stylesheets/avail.css new file mode 100644 index 0000000..b1ad0bf --- /dev/null +++ b/contrib/exfoliation/stylesheets/avail.css @@ -0,0 +1,35 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.avail { } + +.data { font-size: 9pt; } + +.hostUP { background-color: #cce8cc; padding: 0 4 0 4; } +.hostDOWN { background-color: #ffdddd; padding: 0 4 0 4; } +.hostUNREACHABLE { background-color: #ffddaa; padding: 0 4 0 4; } + +.serviceOK { background-color: #cce8cc; padding: 0 4 0 4; } +.serviceWARNING { background-color: #feffc1; padding: 0 4 0 4; } +.serviceUNKNOWN { background-color: #ffddaa; padding: 0 4 0 4; } +.serviceCRITICAL { background-color: #ffdddd; padding: 0 4 0 4; } + +table.logEntries { font-size: 9pt; padding: 5 0 0 0; } +th.logEntries { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +.logEntriesOdd { background-color: #e7e7e7; padding: 0 4 0 4; } +.logEntriesEven { background-color: #f4f2f2; padding: 0 4 0 4; } + +.logEntriesOK { background-color: #cce8cc; padding: 0 4 0 4; } +.logEntriesUNKNOWN { background-color: #ffddaa; padding: 0 4 0 4; } +.logEntriesWARNING { background-color: #feffc1; padding: 0 4 0 4; } +.logEntriesCRITICAL { background-color: #ffdddd; padding: 0 4 0 4; } +.logEntriesUP { background-color: #cce8cc; padding: 0 4 0 4; } +.logEntriesDOWN { background-color: #ffdddd; padding: 0 4 0 4; } +.logEntriesUNREACHABLE { background-color: #ffddaa; padding: 0 4 0 4; } +.logEntriesINDETERMINATE { background-color: #ddccff; padding: 0 4 0 4; } + +.infoMessage { font-size: 9pt; } diff --git a/contrib/exfoliation/stylesheets/checksanity.css b/contrib/exfoliation/stylesheets/checksanity.css new file mode 100644 index 0000000..49922d1 --- /dev/null +++ b/contrib/exfoliation/stylesheets/checksanity.css @@ -0,0 +1,27 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.extinfo { } + +.Title { font-size: 12pt; text-align: center; font-weight: bold; } +.SectionTitle { font-size: 12pt; text-align: center; font-weight: bold; } + +.DynamicData { font-size: 10pt; padding: 2; } +.StaticData { font-size: 10pt; padding: 2; } +.TableHeader { font-size: 10pt; background-color: #d0d0d0; font-weight: bold; } + +.Item { font-size: 10pt; background-color: #f4f2f2; font-weight: bold; } +.DataSource { font-size: 10pt; background-color: #f4f2f2; } +.Number { font-size: 10pt; background-color: #f4f2f2; } + +.Value { font-size: 10pt; background-color: #f4f2f2; font-weight: bold; } +.ValueOk { font-size: 10pt; background-color: #88d066; font-weight: bold; } +.ValueError { font-size: 10pt; background-color: #f88888; font-weight: bold; } + + + + diff --git a/contrib/exfoliation/stylesheets/cmd.css b/contrib/exfoliation/stylesheets/cmd.css new file mode 100644 index 0000000..f8698f7 --- /dev/null +++ b/contrib/exfoliation/stylesheets/cmd.css @@ -0,0 +1,14 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.cmd { } + +.cmdType { font-size: 12pt; font-weight: bold; color: #aa0000; padding-bottom: 40; } +.commandDescription { font-size: 8pt; background-color: #f4f2f2; border: 1px solid #d0d0d0; margin: 4 0 0 0; padding: 4 4 4 4; } +.descriptionTitle { font-size: 10pt; font-weight: bold; } +.infoMessage { font-size: 8pt; background-color: #efefaa; border: 1px solid #777777; margin: 40 20% 0 20%; padding: 5 5 5 5; } +.optBox { font-size: 9pt; padding: 5 5 5 5; } diff --git a/contrib/exfoliation/stylesheets/common.css b/contrib/exfoliation/stylesheets/common.css new file mode 100644 index 0000000..6d8e1aa --- /dev/null +++ b/contrib/exfoliation/stylesheets/common.css @@ -0,0 +1,370 @@ +/* exfoliation: a nagios makeover */ +/* version: 0.7 */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +/* thanks to jacob.laack for nagiosneat */ +/* thanks to nagios authors for a solid base */ + +/* these are reference colors for the color scheme: + + color dark light border + OK: green 88d066 cce8cc 777777 + WARNING: yellow ffff00 feffc1 777777 + CRITICAL: red f88888 ffdddd 777777 + PENDING: grey acacac fefefe 777777 + UNKNOWN: orange ffbb55 ffddaa 777777 + UNREACHABLE: orange ffbb55 ffddaa 777777 +INDETERMINATE: purple ddccff 777777 + PROBLEMS: blue aaccff 777777 + + ACK: aaaaaa + CUSTOM: 778899 + + important: blue 99aacc 777777 +not important: blue aaccff 777777 + + table header: d0d0d0 + odd rows: e7e7e7 + even rows: f4f2f2 + + titles: 12pt + body: 10pt + table headings: 9pt + controls: 9pt + data in tables: 8pt or 9pt +*/ + +body { + margin: 0em; + margin: 0.8em 0.8em 2em 0.8em; + color: black; + background-color: white; + font-family: arial, verdana, serif; + font-weight: normal; + font-size: 10pt; +} + +table { + border: none; + margin: 0; +} + +th, td { + border: none; + padding: 0 2px 0 2px; +} + +form { + margin: 0; + padding: 0; +} + + +a img { + border: none; +} +a { + text-decoration: none; + color: #40529b; +} +a:hover { + text-decoration: underline; + color: #3f5bcd; +} +a:active { + color: #496aef; +} +a:visited { + color: #2c3763; +} + + +div.navbarlogo { + margin: 0 0 10px 0; +} +div.navsection { + margin: 5px 0 10px 0; +} +div.navsectiontitle { + font-size: 9pt; + font-weight: bold; + padding: 2px; + background-color: #efefef; + border:1px solid #dddddd; +} +div.navsectionlinks { + margin: 3px 0 0 0; +} + +ul.navsectionlinks { + margin: 0; + padding: 0; + list-style: none; +} +ul.navsectionlinks li { } +ul.navsectionlinks li a { + font-weight: bold; + font-size: 9pt; + text-decoration: none; + padding: 0 0 0 15px; + /* background: transparent url(../images/greendot.gif) no-repeat scroll 0 0; */ + +} +ul.navsectionlinks li ul { + margin: 0px; + padding: 0 0 0 30px; + list-style: none; +} +ul.navsectionlinks li ul li { } +ul.navsectionlinks li a:hover { +/* background: transparent url(../images/orangedot.gif) no-repeat scroll 0 0; */ +color: #8391cd; +} +ul.navsectionlinks li ul li a { + background: none; + padding: 0; + font-weight: normal; +} +ul.navsectionlinks li ul li a:hover { + background: none; +} +ul.navsectionlinks li ul li ul { + margin: 0px; + padding: 0 0 0 15px; + list-style: none; +} + + +.navbarsearch { + margin: 5px 0 0 0; +} +.navbarsearch fieldset { + border: none; +} + +.navbarsearch fieldset legend { + font-size: 8pt; +} +.navbarsearch input{ + font-size: 9pt; +} + + +#splashpage{ + text-align: center; +} +#mainbrandsplash{ + font-size: 12pt; + font-weight: bold; + margin: 0 0 35px 0; +} +#maincopy{ + margin: 0 0 15px 0; +} +#currentversioninfo{ + font-size: 12pt; +} +#currentversioninfo .product{ + font-size: 14pt; + font-weight: bold; +} +#currentversioninfo .version{ + font-size: 14pt; + font-weight: bold; +} +#currentversioninfo .releasedate{ + font-size: 11pt; + margin: 5px 0 0 0; +} +#currentversioninfo .checkforupdates{ + font-size: 11pt; + font-weight: bold; +} +#currentversioninfo .whatsnew{ + font-size: 11pt; + font-weight: bold; + margin: 50px 0 0 0; +} +#updateversioninfo{ + margin: 15px auto 35px auto; + width: 400px; +} +.updatechecksdisabled{ + background-color: #FF9F9F; + border: 1px solid red; + padding: 10px; +} +.updatechecksdisabled div.warningmessage{ + font-weight: bold; +} +#updateversioninfo div.submessage{ + clear: left; +} +.updateavailable{ + background-color: #9FD4FF; + border: 1px solid blue; + padding: 10px; +} +.updateavailable div.updatemessage{ + font-size: 12pt; + font-weight: bold; +} + +#splashpage #mainfooter{ + /*margin: 100px 0 0 0;*/ + clear: both; + font-size: 8pt; + padding-top: 35px; +} +#splashpage #mainfooter .disclaimer{ + /*width: 80%;*/ + margin: auto; +} +#splashpage #mainfooter .logos{ + margin: 15px 0 0 0; +} + + + + + + +table.infoBox { width: 100%; } +td.infoBox { font-size: 8pt; padding: 0 0 1em 0; white-space: nowrap; } +div.infoBoxTitle { font-size: 10pt; font-weight: bold; } +div.infoBoxBadProcStatus { font-size: 8pt; font-weight: bold; color: red; } + +.linkBox { font-size: 8pt; padding: 1; } +table.linkBox td { white-space: nowrap; } + +.filter { font-size: 8pt; padding: 1; } +.filterTitle { font-size: 9pt; font-weight: bold; } +.filterName { font-size: 8pt; text-align: right; font-weight: bold; } +.filterValue { font-size: 8pt; } + +.errorDescription { font-size: 10pt; text-align: center; font-weight: bold; } +.errorMessage { font-size: 10pt; text-align: center; font-weight: bold; color: red; } +.warningMessage { font-size: 10pt; text-align: center; font-weight: bold; color: red; } + +.statusTitle { text-align: center; font-weight: bold; font-size: 12pt; white-space: nowrap; } +.statusSort { font-size: 8pt; } + +table.data { padding: 0; } +th.data { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +.dataOdd { font-size: 8pt; background-color: #e7e7e7; padding: 0 4 0 4; } +.dataEven { font-size: 8pt; background-color: #f4f2f2; padding: 0 4 0 4; } +.dataTitle { font-size: 12pt; text-align: center; font-weight: bold; } +.dataSubTitle { font-size: 10pt; text-align: center; font-weight: bold; } + +.optBox { font-size: 9pt; white-space: nowrap; padding: 2 0 0 0; } +.optBoxTitle { font-size: 10pt; font-weight: bold; text-align: center; } +.optBoxRequiredItem { font-size: 9pt; text-align: right; padding: 0 5 0 5; color: red; } +.optBoxItem { font-size: 9pt; text-align: right; padding: 0 5 0 5; } +.optBoxValue { font-size: 9pt; } + +.optionBoxTitle { font-size: 10pt; text-align: center; font-weight: bold; } +.optionBox { font-size: 10pt; padding: 2; } + +.navBoxTitle { font-size: 10pt; font-weight: bold; white-space: nowrap; } +.navBoxItem { font-size: 8pt; } +.navBoxDate { font-size: 8pt; white-space: nowrap; } +.navBoxFile { font-size: 8pt; text-align: center; } + +.helpfulHint { font-size: 8pt; font-style: italic; text-align: center; } + +.logEntries { font-size: 8pt; white-space: nowrap; } + +.dateTimeBreak { font-size: 9pt; font-weight: bold; } + +.reportRange { font-size: 10pt; white-space: nowrap; } +.reportDuration { font-size: 8pt; white-space: nowrap; } +.reportTime { font-size: 8pt; white-space: nowrap; text-align: right; font-style: italic; } + +.reportSelectTitle { font-size: 12pt; text-align: center; font-weight: bold; } +.reportSelectSubTitle { font-size: 9pt; text-align: right; } +.reportSelectItem { font-size: 9pt; } +.reportSelectTip { font-size: 8pt; font-style: italic; } + +.dateSelectTitle { font-size: 12pt; text-align: center; font-weight: bold; } +.dateSelectSubTitle { font-size: 9pt; text-align: right; } +.dateSelectItem { font-size: 9pt; } + +.popupText { font-size: 8pt; background-color: #eeeeaa; border: 1px solid #777777; padding: 10 10 10 10; } + +.hostImportantProblem { font-size: 8pt; background-color: #88aadd; border: 1px solid #aaaaaa; padding: 0 5 0 5; } +.hostUnimportantProblem { font-size: 8pt; background-color: #aaccff; border: 1px solid #888888; padding: 0 5 0 5; } + +.serviceImportantProblem { font-size: 8pt; background-color: #88aadd; border: 1px solid #aaaaaa; padding: 0 5 0 5; } +.serviceUnimportantProblem { font-size: 8pt; background-color: #aaccff; border: 1px solid #888888; padding: 0 5 0 5; } + +.outageImportantProblem { font-size: 8pt; background-color: #88aadd; border: 1px solid #aaaaaa; padding: 0 5 0 5; } +.outageUnimportantProblem { font-size: 8pt; background-color: #aaccff; border: 1px solid #888888; padding: 0 5 0 5; } + + +/* Some nagios configurations have side.html rather than side.php and define */ +/* a slightly different set of nav elements. */ +.NavBarTitle { + font-size: 9pt; + font-weight: bold; + margin: 5px 0 10px 0; + padding: 2px; + background-color: #efefef; + border:v1px solid #dddddd; +} + +.NavBarItem { + font-size: 9pt; + font-weight: bold; + list-style: none; + text-decoration: none; + margin: 0; + padding: 0 0 0 0; +} + +.NavBarSearchItem { + font-size: 9pt; +} + + + +#splashboxes { + /*border: 1px solid blue;*/ + margin: auto; + width: 90%; + } +.splashbox{ + padding: 5px; + margin: 5px 5px 5px; + border: 1px solid #AAAAAA; + float: left; + text-align: left; + height: 140px; + } +.splashbox h2{ + margin: 0px; + font-size: 12pt; + } +.splashbox ul{ + margin: 0; + padding: 5px 5px 5px 15px; + } +.splashbox ul li{ + clear: both; + } +#splashbox1 { + width: 250px; + } +#splashbox2 { + width: 500px; + } +#splashbox3 { + width: 250px; + clear: both; + } +#splashbox4 { + width: 500px; + } \ No newline at end of file diff --git a/contrib/exfoliation/stylesheets/config.css b/contrib/exfoliation/stylesheets/config.css new file mode 100644 index 0000000..558d4fa --- /dev/null +++ b/contrib/exfoliation/stylesheets/config.css @@ -0,0 +1,11 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.config { } + +.reportSelectSubTitle { font-size: 9pt; text-align: left; } +.reportSelectItem { font-size: 9pt; } diff --git a/contrib/exfoliation/stylesheets/extinfo.css b/contrib/exfoliation/stylesheets/extinfo.css new file mode 100644 index 0000000..4c81320 --- /dev/null +++ b/contrib/exfoliation/stylesheets/extinfo.css @@ -0,0 +1,84 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.extinfo { } + +.perfTypeTitle { font-size: 10pt; text-align: right; font-weight: bold; } + +.stateInfoPanel { font-size: 9pt; } +.stateStatisticsPanel { } +.stateInfoTable1 { background-color: #f4f2f2; border: 1px solid #d0d0d0; } +.stateInfoTable2 { background-color: #f4f2f2; border: 1px solid #d0d0d0; } + +.dataVar { font-size: 9pt; font-weight: bold; } +.dataVal { font-size: 9pt; } + +/* FIXME: override the defaults until php/html is fixed */ +/* .data { font-size: 10pt; font-weight: bold; } */ +div.data { font-size: 10pt; font-weight: normal; } +.dataTitle { font-size: 10pt; font-weight: bold; padding-bottom: 5; } + +.commandTitle { font-size: 10pt; text-align: center; font-weight: bold; padding-bottom: 5; } +TABLE.command { background-color: #f4f2f2; border: 1px solid #d0d0d0; } +.command { font-size: 9pt; } +.commandPanel { } +.commentPanel { } + +.commentTitle { font-size: 10pt; text-align: center; font-weight: bold; } +DIV.commentNav { font-size: 10pt; text-align: center; } +A.commentNav { font-size: 10pt; } + +TABLE.comment { font-size: 10pt; background-color: white; padding: 2; } +TH.comment { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +.commentOdd { font-size: 9pt; background-color: #e7e7e7; } +.commentEven { font-size: 9pt; background-color: #f4f2f2; } +DIV.comment,A.comment { font-size: 10pt; background-color: white; text-align: center; } + +.downtimeTitle { font-size: 12pt; text-align: center; font-weight: bold; } +DIV.downtimeNav { font-size: 10pt; text-align: center; } +A.downtimeNav { font-size: 10pt; } + +TABLE.downtime { font-size: 10pt; background-color: white; padding: 2; } +TH.downtime { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +.downtimeOdd { font-size: 9pt; background-color: #e7e7e7; } +.downtimeEven { font-size: 9pt; background-color: #f4f2f2; } + +.notflapping { background-color: #88d066; border: 1px solid #777777; font-weight: bold; float: left; } +.flapping { background-color: #f88888; border: 1px solid #777777; font-weight: bold; float: left; } +.notificationsENABLED { background-color: #88d066; border: 1px solid #777777; font-weight: bold; } +.notificationsDISABLED { background-color: #f88888; border: 1px solid #777777; font-weight: bold; } +.checksENABLED { background-color: #88d066; border: 1px solid #777777; font-weight: bold; } +.checksDISABLED { background-color: #f88888; border: 1px solid #777777; font-weight: bold; } +.eventhandlersENABLED { background-color: #88d066; border: 1px solid #777777; font-weight: bold; } +.eventhandlersDISABLED { background-color: #f88888; border: 1px solid #777777; font-weight: bold; } +.flapdetectionENABLED { background-color: #88d066; border: 1px solid #777777; font-weight: bold; } +.flapdetectionDISABLED { background-color: #f88888; border: 1px solid #777777; font-weight: bold; } +.downtimeACTIVE { background-color: #f88888; border: 1px solid #777777; font-weight: bold; float: left; } +.downtimeINACTIVE { background-color: #88d066; border: 1px solid #777777; font-weight: bold; float: left; } +.processOK { background-color: #88d066; border: 1px solid #777777; font-weight: bold; } +.processUNKNOWN { background-color: #ffbb55; border: 1px solid #777777; font-weight: bold; } +.processWARNING { background-color: #ffff00; border: 1px solid #777777; font-weight: bold; } +.processCRITICAL { background-color: #f88888; border: 1px solid #777777; font-weight: bold; } +.modeACTIVE { background-color: #88d066; border: 1px solid #777777; font-weight: bold; } +.modeSTANDBY { background-color: #ffff00; border: 1px solid #777777; font-weight: bold; } + +.hostUP { background-color: #88d066; border: 1px solid #777777; font-weight: bold; float: left; } +.hostDOWN { background-color: #f88888; border: 1px solid #777777; font-weight: bold; float: left; } +.hostUNREACHABLE { background-color: #f88888; border: 1px solid #777777; font-weight: bold; float: left; } + +.serviceOK { background-color: #88d066; border: 1px solid #777777; font-weight: bold; float: left; } +.serviceWARNING { background-color: #ffff00; border: 1px solid #777777; font-weight: bold; float: left; } +.serviceUNKNOWN { background-color: #ffbb55; border: 1px solid #777777; font-weight: bold; float: left; } +.serviceCRITICAL { background-color: #f88888; border: 1px solid #777777; font-weight: bold; float: left; } + +.queueTitle { font-size: 12pt; text-align: center; font-weight: bold; } +TABLE.queue { font-size: 9pt; padding: 0; } +TH.queue { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +.queueOdd { font-size: 9pt; background-color: #e7e7e7; padding: 0 4 0 4; } +.queueEven { font-size: 9pt; background-color: #f4f2f2; padding: 0 4 0 4; } +.queueENABLED { font-size: 9pt; background-color: #88d066; border: 1px solid #777777; padding: 0 4 0 4; } +.queueDISABLED { font-size: 9pt; background-color: #f88888; border: 1px solid #777777; padding: 0 4 0 4; } diff --git a/contrib/exfoliation/stylesheets/histogram.css b/contrib/exfoliation/stylesheets/histogram.css new file mode 100644 index 0000000..9b147f6 --- /dev/null +++ b/contrib/exfoliation/stylesheets/histogram.css @@ -0,0 +1,10 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.histogram { } + +.helpfulHints { font-size: 10pt; font-style: italic; text-align: center; } diff --git a/contrib/exfoliation/stylesheets/history.css b/contrib/exfoliation/stylesheets/history.css new file mode 100644 index 0000000..ed8dba3 --- /dev/null +++ b/contrib/exfoliation/stylesheets/history.css @@ -0,0 +1,8 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.history { } diff --git a/contrib/exfoliation/stylesheets/ministatus.css b/contrib/exfoliation/stylesheets/ministatus.css new file mode 100644 index 0000000..040c8ac --- /dev/null +++ b/contrib/exfoliation/stylesheets/ministatus.css @@ -0,0 +1,64 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.status { } + +TABLE.status { font-size: 9pt; padding: 2; } +TH.status { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +DIV.status { font-size: 10pt; text-align: center; } +.statusOdd { font-size: 9pt; background-color: #e7e7e7; } +.statusEven { font-size: 9pt; background-color: #f4f2f2; } + +.statusPENDING { font-size: 9pt; background-color: #acacac; } +.statusOK { font-size: 9pt; background-color: #88d066; } +.statusRECOVERY { font-size: 9pt; background-color: #88d066; } +.statusUNKNOWN { font-size: 9pt; background-color: #ffbb55; } +.statusWARNING { font-size: 9pt; background-color: #ffff00; } +.statusCRITICAL { font-size: 9pt; background-color: #f88888; } + +.statusHOSTPENDING { font-size: 9pt; background-color: #acacac; } +.statusHOSTUP { font-size: 9pt; background-color: #88d066; } +.statusHOSTDOWN { font-size: 9pt; background-color: #f88888; } +.statusHOSTUNREACHABLE { font-size: 9pt; background-color: #ffbb55; } + +.statusBGUNKNOWN { font-size: 9pt; background-color: #ffddaa; } +.statusBGWARNING { font-size: 9pt; background-color: #feffc1; } +.statusBGCRITICAL { font-size: 9pt; background-color: #ffdddd; } +.statusBGDOWN { font-size: 9pt; background-color: #ffdddd; } +.statusBGUNREACHABLE { font-size: 9pt; background-color: #ffbb55; } + +DIV.serviceTotals { font-size: 10pt; text-align: center; font-weight: bold; } +TABLE.serviceTotals { font-size: 10pt; font-weight: bold; } +TH.serviceTotals,A.serviceTotals { font-size: 9pt; } +TD.serviceTotals { font-size: 9pt; text-align: center; background-color: #e0e0e0; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsOK { font-size: 9pt; text-align: center; background-color: #88d066; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsWARNING { font-size: 9pt; text-align: center; background-color: #ffff00; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsUNKNOWN { font-size: 9pt; text-align: center; background-color: #ffbb55; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsCRITICAL { font-size: 9pt; text-align: center; background-color: #f88888; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsPENDING { font-size: 9pt; text-align: center; background-color: #acacac; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsPROBLEMS { font-size: 9pt; text-align: center; background-color: #aaccff; border: 1px solid #777777; padding: 2 4 2 4; } + + +DIV.hostTotals { font-size: 10pt; text-align: center; font-weight: bold; } +TABLE.hostTotals { font-size: 10pt; font-weight: bold; } +TH.hostTotals,A.hostTotals { font-size: 9pt; } +TD.hostTotals { font-size: 9pt; text-align: center; background-color: #e4e4e4; } +.hostTotalsUP { font-size: 9pt; text-align: center; background-color: #88d066; } +.hostTotalsDOWN { font-size: 9pt; text-align: center; background-color: #f88888; } +.hostTotalsUNREACHABLE { font-size: 9pt; text-align: center; background-color: #ffbb55; } +.hostTotalsPENDING { font-size: 9pt; text-align: center; background-color: #acacac; } +.hostTotalsPROBLEMS { font-size: 9pt; text-align: center; background-color: #aaccff; } + +.miniStatusPENDING { font-size: 9pt; background-color: #acacac; text-align: center; } +.miniStatusOK { font-size: 9pt; background-color: #66ffee; text-align: center; } +.miniStatusUNKNOWN { font-size: 9pt; background-color: #ffbb55; text-align: center; } +.miniStatusWARNING { font-size: 9pt; background-color: #ffff00; text-align: center; } +.miniStatusCRITICAL { font-size: 9pt; background-color: #f88888; text-align: center; } + +.miniStatusUP { font-size: 9pt; background-color: #66ffee; text-align: center; } +.miniStatusDOWN { font-size: 9pt; background-color: #f88888; text-align: center; } +.miniStatusUNREACHABLE { font-size: 9pt; background-color: #ffbb55; text-align: center; } diff --git a/contrib/exfoliation/stylesheets/notifications.css b/contrib/exfoliation/stylesheets/notifications.css new file mode 100644 index 0000000..1138025 --- /dev/null +++ b/contrib/exfoliation/stylesheets/notifications.css @@ -0,0 +1,29 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.notifications { } + +TABLE.notifications { padding: 0; margin: 0; } +TH.notifications { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +.notificationsOdd { font-size: 8pt; background-color: #e7e7e7; padding: 0 4 0 4; } +.notificationsEven { font-size: 8pt; background-color: #f4f2f2; padding: 0 4 0 4; } + +/* these are dark colors */ +.notificationsOK { background-color: #88d066; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsUNKNOWN { background-color: #ffbb55; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsWARNING { background-color: #ffff00; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsCRITICAL { background-color: #f88888; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsACKNOWLEDGEMENT { background-color: #aaaaaa; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsCUSTOM { background-color: #778899; border: 1px solid #777777; padding: 0 4 0 4; } + +/* these are dark colors */ +.notificationsHOSTUP { background-color: #88d066; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsHOSTDOWN { background-color: #f88888; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsHOSTUNREACHABLE { background-color: #ffbb55; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsHOSTACKNOWLEDGEMENT { background-color: #aaaaaa; border: 1px solid #777777; padding: 0 4 0 4; } +.notificationsHOSTCUSTOM { background-color: #778899; border: 1px solid #777777; padding: 0 4 0 4; } + diff --git a/contrib/exfoliation/stylesheets/outages.css b/contrib/exfoliation/stylesheets/outages.css new file mode 100644 index 0000000..10db27d --- /dev/null +++ b/contrib/exfoliation/stylesheets/outages.css @@ -0,0 +1,15 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.outages { } + +.itemTotalsTitle { font-size: 8pt; text-align: center; } + +.hostUP { background-color: #88d066; font-weight: bold; } +.hostDOWN { background-color: #f88888; font-weight: bold; } +.hostUNREACHABLE { background-color: #ffbb55; font-weight: bold; } + diff --git a/contrib/exfoliation/stylesheets/showlog.css b/contrib/exfoliation/stylesheets/showlog.css new file mode 100644 index 0000000..ccbd242 --- /dev/null +++ b/contrib/exfoliation/stylesheets/showlog.css @@ -0,0 +1,8 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.showlog { } diff --git a/contrib/exfoliation/stylesheets/status.css b/contrib/exfoliation/stylesheets/status.css new file mode 100644 index 0000000..51f1e48 --- /dev/null +++ b/contrib/exfoliation/stylesheets/status.css @@ -0,0 +1,88 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.status { } + +.itemTotalsTitle { font-size: 8pt; font-style: italic; clear:both;} + +table.status { font-size: 9pt; padding: 0 0 10 0; } +th.status { font-size: 9pt; text-align: left; padding: 0 3px 0 3px; border-bottom: 1px solid #777777; color: #333333; } +div.status { font-size: 10pt; text-align: center; } +.statusOdd { font-size: 8pt; background-color: #e7e7e7; line-height: 150%; padding: 0 4 0 4; } +.statusEven { font-size: 8pt; background-color: #f4f2f2; line-height: 150%; padding: 0 4 0 4; } + +.statusPENDING { font-size: 8pt; background-color: #acacac; border: 1px solid #777777; padding: 0 5 0 5; } +.statusOK { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; padding: 0 5 0 5; } +.statusRECOVERY { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; padding: 0 5 0 5; } +.statusUNKNOWN { font-size: 8pt; background-color: #ffbb55; border: 1px solid #777777; padding: 0 5 0 5; } +.statusWARNING { font-size: 8pt; background-color: #ffff00; border: 1px solid #777777; padding: 0 5 0 5; } +.statusCRITICAL { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; padding: 0 5 0 5; } + +.statusHOSTPENDING { font-size: 8pt; background-color: #acacac; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTUP { font-size: 8pt; background-color: #cce8cc; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTDOWN { font-size: 8pt; background-color: #ffdddd; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTDOWNACK { font-size: 8pt; background-color: #ffdddd; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTDOWNSCHED { font-size: 8pt; background-color: #ffdddd; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTUNREACHABLE { font-size: 8pt; background-color: #ffddaa; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTUNREACHABLEACK { font-size: 8pt; background-color: #ffddaa; line-height: 150%; padding: 0 4 0 4; } +.statusHOSTUNREACHABLESCHED { font-size: 8pt; background-color: #ffddaa; line-height: 150%; padding: 0 4 0 4; } + +.statusBGUNKNOWN { font-size: 8pt; background-color: #ffddaa; } +.statusBGUNKNOWNACK { font-size: 8pt; background-color: #ffddaa; } +.statusBGUNKNOWNSCHED { font-size: 8pt; background-color: #ffddaa; } +.statusBGWARNING { font-size: 8pt; background-color: #feffc1; } +.statusBGWARNINGACK { font-size: 8pt; background-color: #feffc1; } +.statusBGWARNINGSCHED { font-size: 8pt; background-color: #feffc1; } +.statusBGCRITICAL { font-size: 8pt; background-color: #ffdddd; } +.statusBGCRITICALACK { font-size: 8pt; background-color: #ffdddd; } +.statusBGCRITICALSCHED { font-size: 8pt; background-color: #ffdddd; } +.statusBGDOWN { font-size: 8pt; background-color: #ffdddd; } +.statusBGDOWNACK { font-size: 8pt; background-color: #ffdddd; } +.statusBGDOWNSCHED { font-size: 8pt; background-color: #ffdddd; } +.statusBGUNREACHABLE { font-size: 8pt; background-color: #ffddaa; } +.statusBGUNREACHABLEACK { font-size: 8pt; background-color: #ffddaa; } +.statusBGUNREACHABLESCHED { font-size: 8pt; background-color: #ffddaa; } + +div.serviceTotals { font-size: 10pt; text-align: center; font-weight: bold; } +table.serviceTotals { font-size: 10pt; font-weight: bold; } +th.serviceTotals,a.serviceTotals { font-size: 8pt; } +td.serviceTotals { font-size: 8pt; text-align: center; background-color: #e0e0e0; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsOK { font-size: 8pt; text-align: center; background-color: #88d066; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsWARNING { font-size: 8pt; text-align: center; background-color: #ffff00; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsUNKNOWN { font-size: 8pt; text-align: center; background-color: #ffbb55; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsCRITICAL { font-size: 8pt; text-align: center; background-color: #f88888; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsPENDING { font-size: 8pt; text-align: center; background-color: #acacac; border: 1px solid #777777; padding: 2 4 2 4; } +.serviceTotalsPROBLEMS { font-size: 8pt; text-align: center; background-color: #aaccff; border: 1px solid #777777; padding: 2 4 2 4; } + +div.hostTotals { font-size: 10pt; text-align: center; font-weight: bold; } +table.hostTotals { font-size: 10pt; font-weight: bold; } +th.hostTotals,a.hostTotals { font-size: 8pt; } +td.hostTotals { font-size: 8pt; text-align: center; background-color: #e0e0e0; border: 1px solid #777777; padding: 2 4 2 4; } +.hostTotalsUP { font-size: 8pt; text-align: center; background-color: #88d066; border: 1px solid #777777; padding: 2 4 2 4; } +.hostTotalsDOWN { font-size: 8pt; text-align: center; background-color: #f88888; border: 1px solid #777777; padding: 2 4 2 4; } +.hostTotalsUNREACHABLE { font-size: 8pt; text-align: center; background-color: #ffbb55; border: 1px solid #777777; padding: 2 4 2 4; } +.hostTotalsPENDING { font-size: 8pt; text-align: center; background-color: #acacac; border: 1px solid #777777; padding: 2 4 2 4; } +.hostTotalsPROBLEMS { font-size: 8pt; text-align: center; background-color: #aaccff; border: 1px solid #777777; padding: 2 4 2 4; } + +.miniStatusPENDING { font-size: 8pt; text-align: center; background-color: #acacac; border: 1px solid #777777; padding: 0 5 0 5; } +.miniStatusOK { font-size: 8pt; text-align: center; background-color: #88d066; border: 1px solid #777777; padding: 0 5 0 5; } +.miniStatusUNKNOWN { font-size: 8pt; text-align: center; background-color: #ffbb55; border: 1px solid #777777; padding: 0 5 0 5; } +.miniStatusWARNING { font-size: 8pt; text-align: center; background-color: #ffff00; border: 1px solid #777777; padding: 0 5 0 5; } +.miniStatusCRITICAL { font-size: 8pt; text-align: center; background-color: #f88888; border: 1px solid #777777; padding: 0 5 0 5; } + +.miniStatusUP { font-size: 8pt; text-align: center; background-color: #88d066; border: 1px solid #777777; padding: 0 5 0 5; } +.miniStatusDOWN { font-size: 8pt; text-align: center; background-color: #f88888; border: 1px solid #777777; padding: 0 5 0 5; } +.miniStatusUNREACHABLE { font-size: 8pt; text-align: center; background-color: #ffbb55; border: 1px solid #777777; padding: 0 5 0 5; } + +/* page number styles, added 2/01/2012 -MG */ +#top_page_numbers { float:right;} +#result_limit { display:inline;} +.pagenumber { display: block; float:left; border: 1px solid #AAAAAA; padding: 0 2px 0 2px; margin: 1px;text-align:center; height:15px; } +a.pagenumber:hover { background-color: #EFEFEF;text-decoration:none;} +.current_page { color: #AAA; } +#inner_numbers { clear:right;} +#pagelimit,#bottom_page_numbers { font-size:8pt;} diff --git a/contrib/exfoliation/stylesheets/statusmap.css b/contrib/exfoliation/stylesheets/statusmap.css new file mode 100644 index 0000000..d41888f --- /dev/null +++ b/contrib/exfoliation/stylesheets/statusmap.css @@ -0,0 +1,14 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.statusmap { } + +.imageInfo { font-size: 8pt; font-weight: bold; text-align: center; } + +.zoomTitle { font-size: 8pt; font-weight: bold; } + +.popupText { font-size: 8pt; background-color: #eeeeaa; border: 1px solid #777777; padding: 0 5 0 5; } diff --git a/contrib/exfoliation/stylesheets/summary.css b/contrib/exfoliation/stylesheets/summary.css new file mode 100644 index 0000000..f6a9f32 --- /dev/null +++ b/contrib/exfoliation/stylesheets/summary.css @@ -0,0 +1,30 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.summary { } + +/* override to match filter table style */ +.optBoxItem { font-size: 8pt; font-weight: bold; } +.optBoxValue { font-size: 8pt; } + +/* override to match query info style */ +.dataSubTitle { font-size: 8pt; text-align: center; font-weight: normal; } + +/* override so we get a bit of whitespace */ +table.data { padding-top: 15; } + +.reportDataOdd { font-size: 9pt; background-color: #e7e7e7; padding: 0 4 0 4; } +.reportDataEven { font-size: 9pt; background-color: #f4f2f2; padding: 0 4 0 4; } + +.hostUP { font-size: 9pt; background-color: #88d066; border: 1px solid #777777; padding: 0 4 0 4; } +.hostDOWN { font-size: 9pt; background-color: #f88888; border: 1px solid #777777; padding: 0 4 0 4; } +.hostUNREACHABLE { font-size: 9pt; background-color: #ffbb55; border: 1px solid #777777; padding: 0 4 0 4; } + +.serviceOK { font-size: 9pt; background-color: #88d066; border: 1px solid #777777; padding: 0 4 0 4; } +.serviceWARNING { font-size: 9pt; background-color: #ffff00; border: 1px solid #777777; padding: 0 4 0 4; } +.serviceUNKNOWN { font-size: 9pt; background-color: #ffbb55; border: 1px solid #777777; padding: 0 4 0 4; } +.serviceCRITICAL { font-size: 9pt; background-color: #f88888; border: 1px solid #777777; padding: 0 4 0 4; } diff --git a/contrib/exfoliation/stylesheets/tac.css b/contrib/exfoliation/stylesheets/tac.css new file mode 100644 index 0000000..a5ed1e5 --- /dev/null +++ b/contrib/exfoliation/stylesheets/tac.css @@ -0,0 +1,75 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.tac { font-size: 10pt; } + +.title { font-weight: bold; } +.titleItem { font-size: 8pt; font-weight: bold; } + +td.perfTitle { font-size: 10pt; font-weight: bold; background-color: #d0d0d0; border: 1px solid #aaaaaa; } +.perfBox { background-color: #eeeeee; border: 1px solid #cccccc; } +.perfItem { font-size: 8pt; font-weight: bold; } +.perfValue { font-size: 8pt; } + +.healthTitle { font-weight: bold; font-size: 10pt; background-color: #d0d0d0; border: 1px solid #aaaaaa; } +.healthBox { } +.healthItem { font-size: 10pt; font-weight: bold; } +.healthBar { background-color: grey; padding: 2 4 2 4; } + +.outageTitle { font-weight: bold; background-color: #d0d0d0; border: 1px solid #aaaaaa; } +.outageHeader { font-weight: bold; border-bottom: 1px solid #aaaaaa; } + +.hostTitle { font-weight: bold; background-color: #d0d0d0; border: 1px solid #aaaaaa; } +td.hostHeader { font-weight: bold; border-bottom: 1px solid #aaaaaa; } + +.serviceTitle { font-weight: bold; background-color: #d0d0d0; border: 1px solid #aaaaaa; } +td.serviceHeader { font-weight: bold; border-bottom: 1px solid #aaaaaa; } + +.featureTitle { font-weight: bold; background-color: #d0d0d0; border: 1px solid #aaaaaa; } +td.featureHeader { font-weight: bold; border-bottom: 1px solid #aaaaaa; } + +.featureEnabled { text-align: center; background-color: #ccffcc; } +.featureDisabled { text-align: center; background-color: #ffcccc; } + +.featureEnabledFlapDetection { text-align: center; font-weight: bold; } +.featureDisabledFlapDetection { text-align: center; font-weight: bold; } +.featureItemEnabledServiceFlapDetection { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledServiceFlapDetection { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemEnabledHostFlapDetection { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledHostFlapDetection { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemServicesNotFlapping { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemServicesFlapping { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemHostsNotFlapping { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemHostsFlapping { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } + +.featureEnabledNotifications { text-align: center; font-weight: bold; } +.featureDisabledNotifications { text-align: center; font-weight: bold; } +.featureItemEnabledServiceNotifications { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledServiceNotifications { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemEnabledHostNotifications { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledHostNotifications { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } + +.featureEnabledHandlers { text-align: center; font-weight: bold; } +.featureDisabledHandlers { text-align: center; font-weight: bold; } +.featureItemEnabledServiceHandlers { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledServiceHandlers { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemEnabledHostHandlers { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledHostHandlers { font-size: 8pt; background-color: #f88888; } + +.featureEnabledActiveChecks { text-align: center; font-weight: bold; } +.featureDisabledActiveChecks { text-align: center; font-weight: bold; } +.featureItemEnabledActiveServiceChecks { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledActiveServiceChecks { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemEnabledActiveHostChecks { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledActiveHostChecks { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } + +.featureEnabledPassiveChecks { text-align: center; font-weight: bold; } +.featureDisabledPassiveChecks { text-align: center; font-weight: bold; } +.featureItemEnabledPassiveServiceChecks { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledPassiveServiceChecks { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } +.featureItemEnabledPassiveHostChecks { font-size: 8pt; background-color: #88d066; border: 1px solid #777777; } +.featureItemDisabledPassiveHostChecks { font-size: 8pt; background-color: #f88888; border: 1px solid #777777; } diff --git a/contrib/exfoliation/stylesheets/trends.css b/contrib/exfoliation/stylesheets/trends.css new file mode 100644 index 0000000..6ca9d8b --- /dev/null +++ b/contrib/exfoliation/stylesheets/trends.css @@ -0,0 +1,8 @@ +/* exfoliation: a nagios makeover */ +/* Copyright 2010 Matthew Wall, all rights reserved */ +/* */ +/* Permission to use, copy, modify, and distribute this software for any */ +/* purpose with or without fee is hereby granted, provided that the above */ +/* copyright notice and this permission notice appear in all copies. */ + +.trends { } diff --git a/contrib/mini_epn.c b/contrib/mini_epn.c new file mode 100644 index 0000000..83c5cb3 --- /dev/null +++ b/contrib/mini_epn.c @@ -0,0 +1,122 @@ +/* + mini_epn.c + +*/ + +#include +#include +#include "epn_nagios.h" + +#define MAX_INPUT_CHARS 1024 + +static PerlInterpreter *my_perl = NULL; + +int main(int argc, char **argv, char **env) { + + /* + #ifdef aTHX + dTHX; + #endif + */ + + char *embedding[] = { "", "p1.pl" }; + char *plugin_output ; + char fname[MAX_INPUT_CHARS]; + char *args[] = {"", "0", "", "", NULL }; + char command_line[MAX_INPUT_CHARS]; + int exitstatus; + int pclose_result; + + if((my_perl = perl_alloc()) == NULL) { + printf("%s\n", "Error: Could not allocate memory for embedded Perl interpreter!"); + exit(1); + } + perl_construct(my_perl); + exitstatus = perl_parse(my_perl, xs_init, 2, embedding, NULL); + if(!exitstatus) { + + exitstatus = perl_run(my_perl); + + while(printf("Enter file name: ") && fgets(command_line, MAX_INPUT_CHARS - 1, stdin)) { + SV *plugin_hndlr_cr; + STRLEN n_a; + int count = 0 ; + + dSP; + + command_line[strlen(command_line) - 1] = '\0'; + + strncpy(fname, command_line, strcspn(command_line, " ")); + fname[strcspn(command_line, " ")] = '\x0'; + args[0] = fname ; + args[3] = command_line + strlen(fname) + 1 ; + + args[2] = ""; + + /* call our perl interpreter to compile and optionally cache the command */ + + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(sv_2mortal(newSVpv(args[2], 0))); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + count = call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL); + + SPAGAIN; + + /* check return status */ + if(SvTRUE(ERRSV)) { + (void) POPs; + + pclose_result = -2; + printf("embedded perl ran %s with error %s\n", fname, SvPVX(ERRSV)); + continue; + } + else { + plugin_hndlr_cr = newSVsv(POPs); + + PUTBACK; + FREETMPS; + LEAVE; + } + + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(plugin_hndlr_cr); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + count = perl_call_pv("Embed::Persistent::run_package", G_EVAL | G_ARRAY); + + SPAGAIN; + + plugin_output = POPpx ; + pclose_result = POPi ; + + printf("embedded perl plugin return code and output was: %d & '%s'\n", pclose_result, plugin_output); + + PUTBACK; + FREETMPS; + LEAVE; + + } + + } + + + PL_perl_destruct_level = 0; + perl_destruct(my_perl); + perl_free(my_perl); + exit(exitstatus); + } diff --git a/contrib/new_mini_epn.c b/contrib/new_mini_epn.c new file mode 100644 index 0000000..51a8f49 --- /dev/null +++ b/contrib/new_mini_epn.c @@ -0,0 +1,255 @@ +/* + new_mini_epn.c + +*/ + +#include +#include +#include "epn_nagios.h" + +/* + * DO_CLEAN must be a pointer to a char string + */ + +#define DO_CLEAN "0" + +static PerlInterpreter *my_perl = NULL; + +/* + * <=== Align Right + * 56 spaces from left margin + * Do N O T use T A B S in #define code. + * + * Indent level == 4 spaces + */ + +#define DO_READLINE \ + "$_ = defined($term) " \ + " ? $term->readline($prompt) " \ + " : do { " \ + " print $prompt; " \ + " chomp($_ = <>); " \ + " $_; " \ + " }; " \ + "die qq(That's all folks.\\n) " \ + " unless $_ && ! /^\\s*$/ ; " \ + "$_; " + +#define INIT_TERM_READLINE \ + "use vars qw($term $prompt $OUT); " \ + \ + "eval { require Term::ReadLine; }; " \ + "unless ($@) { " \ + " $term = new Term::ReadLine 'new_mini_epn'; " \ + "} else { " \ + " warn qq(Install Term::ReadLine for arrow key access to history, filename completion etc.); " \ + "} " \ + \ + "$OUT = $term->OUT " \ + " if defined($term); " \ + "$prompt = 'plugin command line: '; " + +void run_plugin(char *command_line) { + +#ifdef aTHX + dTHX; +#endif + + SV *plugin_hndlr_cr ; + STRLEN n_a ; + int count = 0 ; + int pclose_result; + char *plugin_output; + char fname[128]; + char *args[] = {"", "", "", "", NULL }; + + dSP; + + strncpy(fname, command_line, strcspn(command_line, " ")); + fname[strcspn(command_line, " ")] = '\0'; + + /* + * Arguments passsed to Perl sub Embed::Persistent::run_package + */ + + /* + * filename containing plugin + */ + args[0] = fname ; + /* + * Do _not_ cache the compiled plugin + */ + args[1] = DO_CLEAN ; + /* + * pointer to plugin arguments + */ + + args[3] = command_line + strlen(fname) + 1 ; + + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(sv_2mortal(newSVpv(args[2], 0))); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL); + + SPAGAIN ; + + if(SvTRUE(ERRSV)) { + (void) POPs; + + printf("embedded perl compiled plugin %s with error: %s - skipping plugin\n", fname, SvPVX(ERRSV)); + return; + } + else { + plugin_hndlr_cr = newSVsv(POPs); + + PUTBACK ; + FREETMPS ; + LEAVE ; + } + /* + * Push the arguments to Embed::Persistent::run_package onto + * the Perl stack. + */ + ENTER; + SAVETMPS; + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSVpv(args[0], 0))); + XPUSHs(sv_2mortal(newSVpv(args[1], 0))); + XPUSHs(plugin_hndlr_cr); + XPUSHs(sv_2mortal(newSVpv(args[3], 0))); + + PUTBACK; + + count = call_pv("Embed::Persistent::run_package", G_ARRAY); + + SPAGAIN; + + plugin_output = POPpx ; + pclose_result = POPi ; + + printf("embedded perl plugin return code and output was: %d & %s\n", pclose_result, plugin_output) ; + + PUTBACK; + FREETMPS; + LEAVE; + + return ; + + } + +SV * my_eval_pv(char *pv) { + + SV* result; + + /* + * eval_pv(..., TRUE) means die if Perl traps an error + */ + result = eval_pv(pv, TRUE) ; + return result ; + } + +char * get_command_line(void) { + + /* debug + * printf("%s\n", INIT_TERM_READLINE) ; + */ + SV *cmd_line ; + char *command_line ; + + cmd_line = my_eval_pv(DO_READLINE) ; + command_line = SvPVX(cmd_line) ; + /* command_line = SvPV(cmd_line, n_a) ; */ + return command_line ; + } + +void init_term_readline(void) { + (void) my_eval_pv(INIT_TERM_READLINE) ; + } + +void init_embedded_perl(void) { + char *embedding[] = { "", "p1.pl" }; + /* embedding takes the place of argv[] ($argv[0] is the program name. + * - which is not given to Perl). + * Note that the number of args (ie the number of elements in embedding + * [argc] is the third argument of perl_parse(). + */ + int exitstatus; + char buffer[132]; + + if((my_perl = perl_alloc()) == NULL) { + snprintf(buffer, sizeof(buffer), "Error: Could not allocate memory for embedded Perl interpreter!\n"); + buffer[sizeof(buffer) - 1] = '\x0'; + printf("%s\n", buffer); + exit(1); + } + + perl_construct(my_perl); + exitstatus = perl_parse(my_perl, xs_init, 2, embedding, NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + /* Why is perl_run() necessary ? + * It is needed if the code parsed by perl_parse() has + * any runtime semantics (eg code that gets eval'd, + * behaviour that depends on constants etc). + */ + exitstatus = perl_run(my_perl); + + if(exitstatus) { + printf("%s\n", "perl_run() failed."); + exit(1); + } + } + +void deinit_embedded_perl(void) { + + PL_perl_destruct_level = 0; + perl_destruct(my_perl); + perl_free(my_perl); + } + + +int main(int argc, char **argv, char **env) { + + init_embedded_perl(); + /* Calls Perl to load and construct a new + * Term::ReadLine object. + */ + + init_term_readline(); + + while(1) { + /* + * get_command_line calls Perl to get a scalar from stdin + */ + + /* Perl Term::ReadLine::readline() method chomps the "\n" + * from the end of the input. + */ + char *cmd, *end; + /* Allow any length command line */ + cmd = (get_command_line()) ; + + // Trim leading whitespace + while(isspace(*cmd)) cmd++; + + // Trim trailing whitespace + end = cmd + strlen(cmd) - 1; + while(end > cmd && isspace(*end)) end--; + + // Write new null terminator + *(end + 1) = 0; + + run_plugin(cmd) ; + } + + deinit_embedded_perl(); + } + diff --git a/contrib/p1.pl b/contrib/p1.pl new file mode 100644 index 0000000..27a734c --- /dev/null +++ b/contrib/p1.pl @@ -0,0 +1,851 @@ + package Embed::Persistent; + +# $Id$ + +# $Log$ +# Revision 1.5 2005-01-18 13:52:15+11 anwsmh +# 1 Set log level back to RETICENT and log file name to a placeholder for dist. +# +# Revision 1.4 2005-01-18 13:26:12+11 anwsmh +# 1 Major changes for Perl >= 5.6 +# 1.1 tieing STDERR to ErrorTrap caused a SEGV in libperl because of +# misuse of the open statement. +# 1.2 STDERR is now aliased to the handle associated with a log file +# opened if logging is enabled. +# + + +# p1.pl for Nagios 2.0 + +# Only major changes are that STDOUT is redirected to a scalar +# by means of a tied filehandle so that it can be returned to Nagios +# without the need for a syscall to read() +# + +use strict ; +use vars '%Cache' ; +use Text::ParseWords qw(parse_line) ; + +use constant RETICENT => 1 ; +use constant GARRULOUS => 0 ; +use constant DEBUG => 0 ; + +use constant EPN_STDERR_LOG => '/Path/to/embedded/Perl/Nagios/Logfile' ; + +use constant TEXT_RETICENT => <<'RETICENT' ; + +package OutputTrap; + +# +# Methods for use by tied STDOUT in embedded PERL module. +# +# Simply ties STDOUT to a scalar and emulates serial semantics. +# + +sub TIEHANDLE { + my ($class) = @_; + my $me ; + bless \$me, $class; +} + +sub PRINT { + my $self = shift; + $$self .= join("",@_); +} + +sub PRINTF { + my $self = shift; + my $fmt = shift; + $$self .= sprintf($fmt,@_); +} + +sub READLINE { + my $self = shift; + # Perl code other than plugins may print nothing; in this case return "(No output!)\n". + return(defined $$self ? $$self : "(No output!)\n"); +} + +sub CLOSE { + my $self = shift; +} + +package Embed::Persistent; + +sub valid_package_name { + my($string) = @_; + $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; + # second pass only for words starting with a digit + $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; + + # Dress it up as a real package name + $string =~ s|/|::|g; + return "Embed::" . $string; + } + +# Perl 5.005_03 only traps warnings for errors classed by perldiag +# as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). +# Therefore treat all warnings as fatal. + +sub throw_exception { + my $warn = shift ; + return if $warn =~ /^Subroutine CORE::GLOBAL::exit redefined/ ; + die $warn ; +} + +sub eval_file { + my $filename = shift; + my $delete = shift; + + my $pn = substr($filename, rindex($filename,"/")+1); + my $package = valid_package_name($pn); + my $mtime = -M $filename ; + if ( defined $Cache{$package}{mtime} && + $Cache{$package}{mtime} <= $mtime) { + # we have compiled this subroutine already, + # it has not been updated on disk, nothing left to do + } + else { + local *FH; + # FIXME - error handling + open FH, $filename or die "'$filename' $!"; + local($/) = undef; + my $sub = ; + close FH; + # cater for routines that expect to get args without progname + # and for those using @ARGV + $sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub) ; + + # cater for scripts that have embedded EOF symbols (__END__) + $sub =~ s/__END__/\;}\n__END__/; + + # wrap the code into a subroutine inside our unique package + my $eval = qq{ + package main; + use subs 'CORE::GLOBAL::exit'; + sub CORE::GLOBAL::exit { die "ExitTrap: \$_[0] ($package)"; } + package $package; sub hndlr { $sub } + }; + $Cache{$package}{plugin_error} = 0 ; + # suppress warning display. + local $SIG{__WARN__} = \&throw_exception ; + { + # hide our variables within this block + my ($filename, $mtime, $package, $sub); + eval $eval; + } + # $@ is set for any warning and error. This guarantees that the plugin will not be run. + if ($@) { + # Log eval'd text of plugin. + # Correct the line number of the error by removing the lines added (the subroutine prologue) by Embed::eval_file. + my $i = 1 ; + $eval =~ s/^/sprintf('%10d ', $i++)/meg ; + $Cache{$package}{plugin_error} = $@ ; + $Cache{$package}{mtime} = $mtime unless $delete; + # If the compilation fails, leave nothing behind that may affect subsequent compilations. + die; + + } + + #cache it unless we're cleaning out each time + $Cache{$package}{mtime} = $mtime unless $delete; + + } +} + +sub run_package { + my $filename = shift; + my $delete = shift; + my $tmpfname = shift; + my $ar = shift; + my $pn = substr($filename, rindex($filename,"/")+1); + my $package = valid_package_name($pn); + my $res = 3; + + tie (*STDOUT, 'OutputTrap'); + + my @a = &parse_line('\s+', 0, $ar) ; + + if ( $Cache{$package}{plugin_error} ) { + untie *STDOUT; + # return unknown + return (3, '**ePN' . " '$pn' " . $Cache{$package}{plugin_error} . "\n") ; + } + + local $SIG{__WARN__} = \&throw_exception ; + eval { $package->hndlr(@a); }; + + if ($@) { + if ($@ =~ /^ExitTrap: /) { + # For normal plugin exit the ExitTrap string is set by the + # redefined CORE::GLOBAL::exit sub calling die to return a string =~ /^ExitTrap: -?\d+ $package/ + # However, there is only _one_ exit sub so the last plugin to be compiled sets _its_ + # package name. + $res = 0; + } else { + # get return code (which may be negative) + if ($@ =~ /^ExitTrap: (-?\d+)/) { + $res = $1; + } else { + # run time error/abnormal plugin termination; exit was not called in plugin + # return unknown + $res = 3; + + chomp $@ ; + # correct line number reported by eval for the prologue added by eval_file + $@ =~ s/(\d+)\.$/($1 - 8)/e ; + print STDOUT '**ePN', " '$pn' ", $@, "\n" ; + # Don't run it again until the plugin is recompiled (clearing $Cache{$package}{plugin_error}) + # Note that the plugin should be handle any run time errors (such as timeouts) + # that may occur in service checking. + + # FIXME - doesn't work under both 5.005 and 5.8.0. The cached value of plugin error is reset somehow. + # $Cache{$package}{plugin_error} = $@ ; + } + } + } + # !! + my $plugin_output = ; + untie *STDOUT; + return ($res, $plugin_output) ; +} + +1; + +RETICENT + +use constant TEXT_GARRULOUS => <<'GARRULOUS' ; + +BEGIN { + open STDERRLOG, '>> ' . EPN_STDERR_LOG + or die "Can't open '" . EPN_STDERR_LOG . " for append: $!" ; +} + +package OutputTrap; + +# +# Methods for use by tied STDOUT in embedded PERL module. +# +# Simply ties STDOUT to a scalar and emulates serial semantics. +# + +sub TIEHANDLE { + my ($class) = @_; + my $me ; + bless \$me, $class; +} + +sub PRINT { + my $self = shift; + $$self .= join("",@_); +} + +sub PRINTF { + my $self = shift; + my $fmt = shift; + $$self .= sprintf($fmt,@_); +} + +sub READLINE { + my $self = shift; + # Perl code other than plugins may print nothing; in this case return "(No output!)\n". + return(defined $$self ? $$self : "(No output!)\n"); +} + +sub CLOSE { + my $self = shift; +} + +package Embed::Persistent; + +sub valid_package_name { + my($string) = @_; + $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; + # second pass only for words starting with a digit + $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; + + # Dress it up as a real package name + $string =~ s|/|::|g; + return "Embed::" . $string; + } + +# Perl 5.005_03 only traps warnings for errors classed by perldiag +# as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). +# Therefore treat all warnings as fatal. + +sub throw_exception { + my $warn = shift ; + return if $warn =~ /^Subroutine CORE::GLOBAL::exit redefined/ ; + die $warn ; +} + +sub eval_file { + my $filename = shift; + my $delete = shift; + + *STDERR = *STDERRLOG ; + + my $pn = substr($filename, rindex($filename,"/")+1); + my $package = valid_package_name($pn); + my $mtime = -M $filename ; + if ( defined $Cache{$package}{mtime} && + $Cache{$package}{mtime} <= $mtime) { + # we have compiled this subroutine already, + # it has not been updated on disk, nothing left to do + } + else { + local *FH; + # FIXME - error handling + open FH, $filename or die "'$filename' $!"; + local($/) = undef; + my $sub = ; + close FH; + # cater for routines that expect to get args without progname + # and for those using @ARGV + $sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub) ; + + # cater for scripts that have embedded EOF symbols (__END__) + $sub =~ s/__END__/\;}\n__END__/; + + # wrap the code into a subroutine inside our unique package + my $eval = qq{ + package main; + use subs 'CORE::GLOBAL::exit'; + sub CORE::GLOBAL::exit { die "ExitTrap: \$_[0] ($package)"; } + package $package; sub hndlr { $sub } + }; + $Cache{$package}{plugin_error} = 0 ; + # suppress warning display. + local $SIG{__WARN__} = \&throw_exception ; + { + # hide our variables within this block + my ($filename, $mtime, $package, $sub); + eval $eval; + } + # $@ is set for any warning and error. This guarantees that the plugin will not be run. + if ($@) { + # Log eval'd text of plugin. + # Correct the line number of the error by removing the lines added (the subroutine prologue) by Embed::eval_file. + my $i = 1 ; + $eval =~ s/^/sprintf('%10d ', $i++)/meg ; + print STDERR '[', time(), ']', qq( **ePN '$pn' error '$@' in text "\n$eval"\n) ; + $Cache{$package}{plugin_error} = $@ ; + $Cache{$package}{mtime} = $mtime unless $delete; + # If the compilation fails, leave nothing behind that may affect subsequent compilations. + die; + + } + + #cache it unless we're cleaning out each time + $Cache{$package}{mtime} = $mtime unless $delete; + + } +} + +sub run_package { + my $filename = shift; + my $delete = shift; + my $tmpfname = shift; + my $ar = shift; + my $pn = substr($filename, rindex($filename,"/")+1); + my $package = valid_package_name($pn); + my $res = 3; + + tie (*STDOUT, 'OutputTrap'); + + my @a = &parse_line('\s+', 0, $ar) ; + + if ( $Cache{$package}{plugin_error} ) { + untie *STDOUT; + # return unknown + return (3, '**ePN' . " '$pn' " . $Cache{$package}{plugin_error} . "\n") ; + } + + local $SIG{__WARN__} = \&throw_exception ; + eval { $package->hndlr(@a); }; + + if ($@) { + if ($@ =~ /^ExitTrap: /) { + # For normal plugin exit the ExitTrap string is set by the + # redefined CORE::GLOBAL::exit sub calling die to return a string =~ /^ExitTrap: -?\d+ $package/ + # However, there is only _one_ exit sub so the last plugin to be compiled sets _its_ + # package name. + $res = 0; + } else { + # get return code (which may be negative) + if ($@ =~ /^ExitTrap: (-?\d+)/) { + $res = $1; + } else { + # run time error/abnormal plugin termination; exit was not called in plugin + # return unknown + $res = 3; + + chomp $@ ; + # correct line number reported by eval for the prologue added by eval_file + $@ =~ s/(\d+)\.$/($1 - 8)/e ; + print STDOUT '**ePN', " '$pn' ", $@, "\n" ; + # Don't run it again until the plugin is recompiled (clearing $Cache{$package}{plugin_error}) + # Note that the plugin should be handle any run time errors (such as timeouts) + # that may occur in service checking. + + # FIXME - doesn't work under both 5.005 and 5.8.0. The cached value of plugin error is reset somehow. + # $Cache{$package}{plugin_error} = $@ ; + } + } + } + # !! + my $plugin_output = ; + untie *STDOUT; + return ($res, $plugin_output) ; +} + +1; + +GARRULOUS + +use constant TEXT_DEBUG => <<'DEBUG' ; + +BEGIN { + open STDERRLOG, '>> ' . EPN_STDERR_LOG + or die "Can't open '" . EPN_STDERR_LOG . " for append: $!" ; +} + +package OutputTrap; + +# +# Methods for use by tied STDOUT in embedded PERL module. +# +# Simply ties STDOUT to a scalar and emulates serial semantics. +# + +sub TIEHANDLE { + my ($class) = @_; + my $me ; + bless \$me, $class; +} + +sub PRINT { + my $self = shift; + $$self .= join("",@_); +} + +sub PRINTF { + my $self = shift; + my $fmt = shift; + $$self .= sprintf($fmt,@_); +} + +sub READLINE { + my $self = shift; + # Perl code other than plugins may print nothing; in this case return "(No output!)\n". + return(defined $$self ? $$self : "(No output!)\n"); +} + +sub CLOSE { + my $self = shift; +} + +package Embed::Persistent; + +sub valid_package_name { + my($string) = @_; + $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; + # second pass only for words starting with a digit + $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; + + # Dress it up as a real package name + $string =~ s|/|::|g; + return "Embed::" . $string; + } + +# Perl 5.005_03 only traps warnings for errors classed by perldiag +# as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). +# Therefore treat all warnings as fatal. + +sub throw_exception { + my $warn = shift ; + return if $warn =~ /^Subroutine CORE::GLOBAL::exit redefined/ ; + print STDERR " ... throw_exception: calling die $warn\n" ; + die $warn ; +} + +sub eval_file { + my $filename = shift; + my $delete = shift; + + *STDERR = *STDERRLOG ; + + my $pn = substr($filename, rindex($filename,"/")+1); + my $package = valid_package_name($pn); + my $mtime = -M $filename ; + if ( defined $Cache{$package}{mtime} && + $Cache{$package}{mtime} <= $mtime) { + # we have compiled this subroutine already, + # it has not been updated on disk, nothing left to do + print STDERR "(I) \$mtime: $mtime, \$Cache{$package}{mtime}: '$Cache{$package}{mtime}' - already compiled $package->hndlr.\n"; + } + else { + print STDERR "(I) \$mtime: $mtime, \$Cache{$package}{mtime}: '$Cache{$package}{mtime}' - Compiling or recompiling \$filename: $filename.\n" ; + local *FH; + # FIXME - error handling + open FH, $filename or die "'$filename' $!"; + local($/) = undef; + my $sub = ; + close FH; + # cater for routines that expect to get args without progname + # and for those using @ARGV + $sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub) ; + + # cater for scripts that have embedded EOF symbols (__END__) + $sub =~ s/__END__/\;}\n__END__/; + + # wrap the code into a subroutine inside our unique package + my $eval = qq{ + package main; + use subs 'CORE::GLOBAL::exit'; + sub CORE::GLOBAL::exit { die "ExitTrap: \$_[0] ($package)"; } + package $package; sub hndlr { $sub } + }; + $Cache{$package}{plugin_error} = 0 ; + # suppress warning display. + local $SIG{__WARN__} = \&throw_exception ; + { + # hide our variables within this block + my ($filename, $mtime, $package, $sub); + eval $eval; + } + # $@ is set for any warning and error. This guarantees that the plugin will not be run. + if ($@) { + # Log eval'd text of plugin. + # Correct the line number of the error by removing the lines added (the subroutine prologue) by Embed::eval_file. + # $@ =~ s/line (\d+)\.\n/'line ' . ($1 - 8) . ".\n"/ge ; + my $i = 1 ; + $eval =~ s/^/sprintf('%10d ', $i++)/meg ; + print STDERR '[', time(), ']', qq( **ePN '$pn' error '$@' in text "\n$eval"\n) ; + $Cache{$package}{plugin_error} = $@ ; + $Cache{$package}{mtime} = $mtime unless $delete; + # If the compilation fails, leave nothing behind that may affect subsequent compilations. + die; + + } + + #cache it unless we're cleaning out each time + $Cache{$package}{mtime} = $mtime unless $delete; + + } +} + +sub run_package { + my $filename = shift; + my $delete = shift; + my $tmpfname = shift; + my $ar = shift; + my $pn = substr($filename, rindex($filename,"/")+1); + my $package = valid_package_name($pn); + my $res = 3; + + use Data::Dumper ; + print STDERR Data::Dumper->Dump([\%Cache], [qw(%Cache)]) ; + + tie (*STDOUT, 'OutputTrap'); + + my @a = &parse_line('\s+', 0, $ar) ; + + if ( $Cache{$package}{plugin_error} ) { + untie *STDOUT; + # return unknown + print STDERR " ... eval failed in eval_file, run_package returning (3, **ePN '$pn' '$Cache{$package}{plugin_error}'\\n)\n" ; + return (3, '**ePN' . " '$pn' " . $Cache{$package}{plugin_error} . "\n") ; + } + + local $SIG{__WARN__} = \&throw_exception ; + eval { $package->hndlr(@a); }; + + if ($@) { + if ($@ =~ /^ExitTrap: /) { + # For normal plugin exit the ExitTrap string is set by the + # redefined CORE::GLOBAL::exit sub calling die to return a string =~ /^ExitTrap: -?\d+ $package/ + # However, there is only _one_ exit sub so the last plugin to be compiled sets _its_ + # package name. + $res = 0; + } else { + # get return code (which may be negative) + if ($@ =~ /^ExitTrap: (-?\d+)/) { + $res = $1; + } else { + # run time error/abnormal plugin termination; exit was not called in plugin + # return unknown + $res = 3; + + chomp $@ ; + # correct line number reported by eval for the prologue added by eval_file + $@ =~ s/(\d+)\.$/($1 - 8)/e ; + print STDOUT '**ePN', " '$pn' ", $@, "\n" ; + # Don't run it again until the plugin is recompiled (clearing $Cache{$package}{plugin_error}) + # Note that the plugin should be handle any run time errors (such as timeouts) + # that may occur in service checking. + + # FIXME - doesn't work under both 5.005 and 5.8.0. The cached value of plugin error is reset somehow. + # $Cache{$package}{plugin_error} = $@ ; + } + } + } + # !! + my $plugin_output = ; + untie *STDOUT; + print STDERR " ... run_package returning ('$res', '$plugin_output')\n" ; + return ($res, $plugin_output) ; +} + +1; + +DEBUG + +SWITCH: { + eval TEXT_RETICENT, last SWITCH if RETICENT ; + eval TEXT_GARRULOUS, last SWITCH if GARRULOUS ; + eval TEXT_DEBUG, last SWITCH if DEBUG ; + die "Please set one of (use constant statements) RETICENT, GARRULOUS or DEBUG in code.\n" ; +} + +1 ; + +=head1 NAME + +p1.pl - Perl program to provide Perl code persistence for the Nagios project (http://www.Nagios.Org). + +This program attempts to provide a mod_perl like facility for Nagios. + +=head1 SYNOPSIS + +Edit the text to set the values of (the 'use constant' statements) the log path, B, and any one +(only) of the boolean log level flags B, B, and B. The default is to set RETICENT, and +to use S</var/epn_stderr.log> as the log path. + +The log level flags determine the amount and type of messages logged in the log path. + +The RETICENT log level results in similar behaviour to former versions of p1.pl. +In particular, the log file EPN_STDERR_LOG will B be opened. + +=head1 DESCRIPTION + +Nagios is a program to monitor service availability; it does this by scheduling 'plugins' - discrete programs +that check a service and output a line of text describing the service state intended for +those responsible for the service and exit with a coded value to relay the same information to Nagios. + +Plugins, like CGIs, can be coded in Perl. The persistence framework embeds a Perl interpreter in Nagios to + +=over 4 + +=item * reduce the time taken for the Perl compile and execute cycle. + +=item * eliminate the need for the shell to fork and exec Perl. + +=item * eliminate the need for Nagios to fork a process (with popen) to run the Perl code. + +=item * eliminate reloading of frequently used modules. + +=back + +and all the good things mentioned in the B man page under 'Maintaining a persistent interpreter'. + +Plugin syntax errors (possibly introduced when the plugin is transformed by the persistence framework) and run-time +errors are logged depending on the log level flags. + +Regardless of the log level, plugin run-time and syntax errors, are returned to Nagios as the 'plugin output'. These messages +appear in the Nagios log like S<**ePN 'check_test' Global symbol "$status" requires explicit package name at (eval 54) line 15.> + +=over 4 + +=item * GARRULOUS + +=over 8 + +=item 1 opens an extra output stream in the path given by the value of EPN_STDERR_LOG. + +=item 2 logs a listing of plugin errors, followed by a dump of the plugin source - as transformed by +the persistence framework - each time the plugin source file modification time stamp is changed (either +by correcting the syntax error or touching the file). + +=back + +An example of such a listing is + + [1074760243] **ePN 'check_test' error 'Global symbol "$status" requires explicit package name at (eval 54) line 15. ' in text " + 1 + 2 package main; + 3 use subs 'CORE::GLOBAL::exit'; + 4 sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] (Embed::check_5ftest)"; } + 5 package Embed::check_5ftest; sub hndlr { + 6 shift(@_); + 7 @ARGV=@_; + 8 local $^W=1; + 9 #!/usr/bin/perl -w + 10 + 11 # This plugin always does what it is told. + 12 + 13 use strict ; + 14 + 15 $status = shift @ARGV ; + 16 # my $status = shift @ARGV ; + 17 $status ||= 'fail' ; + 18 + 19 my $invert = 1 ; + 20 + 21 $status = lc($status) ; + 22 + 23 $status = ( ( $invert and $status eq 'ok' ) ? 'fail' : + 24 ( $invert and $status eq 'fail' ) ? 'ok' : + 25 $status ) ; + 26 + 27 $status eq 'ok' and do { + 28 print "Ok. Got a \"$status\". Expecting \"OK\".\n" ; + 29 exit 0 ; + 30 } ; + 31 + 32 $status eq 'fail' and do { + 33 print "Failed. Got a \"$status\". Expecting \"FAIL\".\n" ; + 34 exit 2 ; + 35 } ; + 36 + 37 # print "Mmmm. Looks like I got an "$status\" when expecting an \"ok\" or \"fail\".\n" ; + 38 print "Mmmm. Looks like I got an \"$status\" when expecting an \"ok\" or \"fail\".\n" ; + 39 exit 3 ; + 40 } + 41 " + +Note that the plugin text (lines 9 to 39 inclusive) has been transformed by the persistence frame work to +E<10>1 override the exit sub in package main + +E<10>2 create a new package from the plugin file name, here Embed::check_5ftest + +E<10>3 wrap the plugin in a subroutine named hndlr within the new package + +E<10>4 handle the argument list the same way as for a method call, restoring @ARGV from the remaining +arguments + +E<10>5 Setting the warning level to trap all warnings (note that the -w option to Perl is no +longer significant because the shebang line is not fed to exec()). + +=item * DEBUG + +This setting is intended only for hacking this code. In addition to the garrulous messages + +=over 8 + +=item 1 enter, leave messages + +=item 2 dump of %Cache data structure + +=back + +=item * RETICENT + +This is the default verbosity level and recommended for production use. One line only of compile or run +time errors is reported in the Nagios log. There are no other output streams. + +=back + +=head1 SUBROUTINES + +Unless otherwise stated, all subroutines take two (2) arguments :- + +=over 4 + +=item 1 plugin_filename - string (called from C) or scalar(called from Perl): the path to the plugin. + +=item 2 DO_CLEAN - boolean: set if plugin is not to be cached. Defaults to 0. + +Setting this flag means that the plugin is compiled each time it is executed. Nagios B sets this flag when the +Nagios is compiled with the configure setting --with-perlcache. + +=back + +=over 4 + +=item Embed::Persistent::eval_file( plugin_filename, DO_CLEAN ) + +E<10> +Returns nothing. + + +eval_file() transforms the plugin to a subroutine in a package, compiles the string containing the +transformed plugin, caches the plugin file modification time (to avoid recompiling it), and caches +any errors returned by the compilation. + +If the plugin has been modified or has not been compiled before, the plugin is transformed to a subroutine in a new package by + +creating a package name from the plugin file name (C) + +turning off subroutine redefinition warnings (C) + +overriding CORE::GLOBAL::exit from within package main (C) +This allows the plugin to call exit without taking down the persistence framework. + +prepending the plugin text with code to let the plugin function as a subroutine. This code sets up +the plugin argument vector (@ARGV) from the subroutine arguments and turns on warnings. +(C<$sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub)>). + +writing the plugin as the subroutine named 'hndlr' in the new package (C) + + +The plugin compilation, performed by C, caches C<$@> if the transformed plugin has syntax errors. + + +=item Embed::Persistent::run_package( plugin_filename, DO_CLEAN, '', plugin_argument_string ) + +E<10> +Returns (plugin_return_code, plugin_output) + +run_package() + +=back + +=head1 BUGS + +This framework does nothing to prevent the memory leaks mentioned in B, relying on operator intervention. + +Probably the best way of doing so is by periodically scheduling + +=over 4 + +=item 1 A check of the memory used by the Nagios process (by running for example the standard Nagios plugin check_vsz) + +=item 2 Restarting Nagios with the (supplied with Nagios) startup script (restart command). + + +=back + +If you do periodocally restart Nagios, make sure that + +=over 4 + +=item 1 plugins all set the PATH environment variable if they need other system binaries (otherwise, if the +init script is excec'd by cron, the PATH will be reset and the plugins will fail - but only when reatsrted by cron). + +=item 2 that the group owning the Nagios command pipe is the same as the Nagios group (otherwise, the restarted +Nagios will not be able to read from the command pipe). + +=back + +Nagios installations using the persistence framework must monitor the memory use of the Nagios process and stop/start it when +the usage is exorbidant (eg, for a site with 400 services on 200 hosts and custom Perl plugins used for about 10% of the +service checks, the Nagios process uses ~80 MB after 20-30 days runningi with Perl 5.005 [Memory usage is +B greater with recent Perls]. It is usually stopped and started at this point). + +Note that a HUP signal is B sufficient to deallocate the Perl memory; the Nagios process must be stopped and started. + + +=head1 AUTHOR + +Originally by Stephen Davies. + +Now maintained by Stanley Hopcroft who retains responsibility for the 'bad bits'. + +=head1 COPYRIGHT + +Copyright (c) 2004 Stanley Hopcroft. All rights reserved. +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/contrib/traceroute.cgi b/contrib/traceroute.cgi new file mode 100644 index 0000000..0ba34f5 --- /dev/null +++ b/contrib/traceroute.cgi @@ -0,0 +1,201 @@ +#!/usr/bin/perl +# +# (c)2004 Andreas Wassatsch +# released under GPLv2 +# +# based on traceroute.cgi of Ian Cass Knowledge Matters Ltd +# (c)1999 Ian Cass Knowledge Matters Ltd +# +# This script should be put in your Nagios cgi-bin directory +# (usually /usr/local/nagios/sbin) +# +# It will perform a traceroute from your Nagios box to +# the machine that the check_ping plugin is pinging, +# output includes links to host status and status map +# for hosts known to Nagios +# +# This software is provided as-is, without any express or implied +# warranty. In no event will the author be held liable for any mental +# or physical damages arising from the use of this script. +# +# Legal note: +# Nagios is a registered trademark of Ethan Galstad. +# +use strict; +use File::Basename; +use POSIX qw(strftime); + +# Global Settings +#---------------- +$| = 1; +my($nagios) = "/usr/local/nagios"; +my($urlbase) = "/nagios"; +my($refresh) = 30; +my($self) = basename($0); +my($traceroute) = "/usr/sbin/traceroute -m 20 -q 1"; + +# Generate HTTP header +#--------------------- +my($mdate)=`date +"%a, %d %b %Y %H:%M:%S %Z"`; +print "Cache-Control: no-store\n"; +print "Pragma: no-cache\n"; +print "Last-Modified: $mdate"; +print "Expires: Thu, 01 Jan 1970 00:00:00 GMT\n"; +print "Content-type: text/html\n\n"; + +# accept either traceroute/foo or traceroute?foo; default to REMOTE_ADDR +# if nothing else is specified +#----------------------------------------------------------------------- +my($addr) = $ENV{PATH_INFO} || $ENV{QUERY_STRING} || $ENV{REMOTE_ADDR}; +$addr =~ tr/+/ /; +$addr =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; +$addr =~ s,^addr=,,; +$addr =~ s/[^A-Za-z0-9\.-]//g; # for security + + +# HTML Head with META Refresh info / stylesheet +#---------------------------------------------- +print "\n"; +print "\n\ntraceroute to host $addr\n"; +print "\n"; +print "\n"; +print "\n\n"; + +# Info Box +#--------- +print ""; +print ""; +print "
    "; +print "
    traceroute
    "; +print "Genereated by $self
    "; +print "Last Updated: $mdate
    "; +print "Updated every $refresh seconds
    "; +print "Nagios® - www.nagios.org
    "; +print "Logged in as $ENV{'REMOTE_USER'}
    "; +print "
    "; + +print "

    "; +print "Traceroute to Host $addr

    \n"; + +print "\n"; + +# read in nagios hosts +#--------------------- +my(@cfg); +my($entry); +my($bla); +my($host); +my(@hostlist); +open(HOSTS, "$nagios/etc/hosts.cfg"); + @cfg = grep {!/#/ && /host_name/} ; +close(HOSTS); + +foreach $entry (@cfg) { + $entry =~ s/^\s+//; + ($bla, $host) = split(/\s+/,$entry); + push @hostlist,$host; +} + +# open traceroute pipe +#--------------------- +my($i)=0; +open(TRACEROUTE, "$traceroute $addr |" ) || + die "
    couldn't open pipe to traceroute! $!
    "; + +my(@arr); +my($class); +my($known_host); +while () { + chomp; + s/\&/\&/g; + s/\"; + print "
    "; + print ""; + print ""; + print ""; + print "\n"; + + } else { + + # class for odd/even lines + #------------------------- + if ($i/2 == int($i/2)) { + $class="statusEven"; + } else { + $class="statusOdd"; + } + + # parse traceroute lines + #----------------------- + s/^\s//g; + (@arr) = split(/\s+/, $_, 4); + if (grep(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,$arr[1])) { + $arr[3] = $arr[2] ." ". $arr[3]; + $arr[2] = $arr[1]; + $arr[1] = "-"; + } + $arr[2] =~ s/\(//; + $arr[2] =~ s/\)//; + + # check if host is known to nagios + #--------------------------------- + $known_host = 0; + foreach $host (@hostlist) { + if ($host eq $arr[1]) { + $known_host++; + } + } + + # print table row + #---------------- + print ""; + print "\n"; # hop + + print "\n"; # ip + print "\n"; # rtt + print "\n"; + } + + $i++; +} +close(TRACEROUTE) || die "couldn't close pipe to traceroute! $!"; + +print "
    HopHostIPRound Trip Time
    $arr[0]"; + print "\n"; + print "\n"; + } else { + print "$arr[1]\n"; + } + + print "
    \n"; + + if ($known_host) { + print ""; + print "$arr[1]\n"; + if ($known_host) { + print ""; + print "\n"; + } + print "
    \n"; # host + + print "
    $arr[2]$arr[3]
    \n"; + + +# footer +#------- +print " 

     

    "; +print "$self by Andreas Wassatsch"; +print "\n"; + +# end +#---- +exit 0; + + diff --git a/daemon-init.in b/daemon-init.in new file mode 100644 index 0000000..98f35e5 --- /dev/null +++ b/daemon-init.in @@ -0,0 +1,236 @@ +#!/bin/sh +# +# chkconfig: 345 99 01 +# description: Nagios network monitor +# +# File : nagios +# +# Author : Jorge Sanchez Aymar (jsanchez@lanchile.cl) +# +# Changelog : +# +# 1999-07-09 Karl DeBisschop +# - setup for autoconf +# - add reload function +# 1999-08-06 Ethan Galstad +# - Added configuration info for use with RedHat's chkconfig tool +# per Fran Boon's suggestion +# 1999-08-13 Jim Popovitch +# - added variable for nagios/var directory +# - cd into nagios/var directory before creating tmp files on startup +# 1999-08-16 Ethan Galstad +# - Added test for rc.d directory as suggested by Karl DeBisschop +# 2000-07-23 Karl DeBisschop +# - Clean out redhat macros and other dependencies +# 2003-01-11 Ethan Galstad +# - Updated su syntax (Gary Miller) +# +# Description: Starts and stops the Nagios monitor +# used to provide network services status. +# + +# Load any extra environment variables for Nagios and its plugins +if test -f /etc/sysconfig/nagios; then + . /etc/sysconfig/nagios +fi + +status_nagios () +{ + + if test -x $NagiosCGI/daemonchk.cgi; then + if $NagiosCGI/daemonchk.cgi -l $NagiosRunFile; then + return 0 + else + return 1 + fi + else + if ps -p $NagiosPID > /dev/null 2>&1; then + return 0 + else + return 1 + fi + fi + + return 1 +} + + +printstatus_nagios() +{ + + if status_nagios $1 $2; then + echo "nagios (pid $NagiosPID) is running..." + else + echo "nagios is not running" + fi +} + + +killproc_nagios () +{ + + kill $2 $NagiosPID + +} + + +pid_nagios () +{ + + if test ! -f $NagiosRunFile; then + echo "No lock file found in $NagiosRunFile" + exit 1 + fi + + NagiosPID=`head -n 1 $NagiosRunFile` +} + + +# Source function library +# Solaris doesn't have an rc.d directory, so do a test first +if [ -f /etc/rc.d/init.d/functions ]; then + . /etc/rc.d/init.d/functions +elif [ -f /etc/init.d/functions ]; then + . /etc/init.d/functions +fi + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +NagiosBin=@bindir@/nagios +NagiosCfgFile=@sysconfdir@/nagios.cfg +NagiosStatusFile=@localstatedir@/status.dat +NagiosRetentionFile=@localstatedir@/retention.dat +NagiosCommandFile=@localstatedir@/rw/nagios.cmd +NagiosVarDir=@localstatedir@ +NagiosRunFile=@lockfile@ +NagiosLockDir=/var/lock/subsys +NagiosLockFile=nagios +NagiosCGIDir=@sbindir@ +NagiosUser=@nagios_user@ +NagiosGroup=@nagios_grp@ + + +# Check that nagios exists. +if [ ! -f $NagiosBin ]; then + echo "Executable file $NagiosBin not found. Exiting." + exit 1 +fi + +# Check that nagios.cfg exists. +if [ ! -f $NagiosCfgFile ]; then + echo "Configuration file $NagiosCfgFile not found. Exiting." + exit 1 +fi + +# See how we were called. +case "$1" in + + start) + echo -n "Starting nagios:" + $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; + if [ $? -eq 0 ]; then + su - $NagiosUser -c "touch $NagiosVarDir/nagios.log $NagiosRetentionFile" + rm -f $NagiosCommandFile + touch $NagiosRunFile + chown $NagiosUser:$NagiosGroup $NagiosRunFile + $NagiosBin -d $NagiosCfgFile + if [ -d $NagiosLockDir ]; then touch $NagiosLockDir/$NagiosLockFile; fi + echo " done." + exit 0 + else + echo "CONFIG ERROR! Start aborted. Check your Nagios configuration." + exit 1 + fi + ;; + + stop) + echo -n "Stopping nagios: " + + pid_nagios + killproc_nagios nagios + + # now we have to wait for nagios to exit and remove its + # own NagiosRunFile, otherwise a following "start" could + # happen, and then the exiting nagios will remove the + # new NagiosRunFile, allowing multiple nagios daemons + # to (sooner or later) run - John Sellens + #echo -n 'Waiting for nagios to exit .' + for i in 1 2 3 4 5 6 7 8 9 10 ; do + if status_nagios > /dev/null; then + echo -n '.' + sleep 1 + else + break + fi + done + if status_nagios > /dev/null; then + echo '' + echo 'Warning - nagios did not exit in a timely manner' + else + echo 'done.' + fi + + rm -f $NagiosStatusFile $NagiosRunFile $NagiosLockDir/$NagiosLockFile $NagiosCommandFile + ;; + + status) + pid_nagios + printstatus_nagios nagios + ;; + + checkconfig) + printf "Running configuration check..." + $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; + if [ $? -eq 0 ]; then + echo " OK." + else + echo " CONFIG ERROR! Check your Nagios configuration." + exit 1 + fi + ;; + + restart) + printf "Running configuration check..." + $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; + if [ $? -eq 0 ]; then + echo "done." + $0 stop + $0 start + else + echo " CONFIG ERROR! Restart aborted. Check your Nagios configuration." + exit 1 + fi + ;; + + reload|force-reload) + printf "Running configuration check..." + $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; + if [ $? -eq 0 ]; then + echo "done." + if test ! -f $NagiosRunFile; then + $0 start + else + pid_nagios + if status_nagios > /dev/null; then + printf "Reloading nagios configuration..." + killproc_nagios nagios -HUP + echo "done" + else + $0 stop + $0 start + fi + fi + else + echo " CONFIG ERROR! Reload aborted. Check your Nagios configuration." + exit 1 + fi + ;; + + *) + echo "Usage: nagios {start|stop|restart|reload|force-reload|status|checkconfig}" + exit 1 + ;; + +esac + +# End of this script diff --git a/functions b/functions new file mode 100755 index 0000000..0e7dc7b --- /dev/null +++ b/functions @@ -0,0 +1,319 @@ +#!/bin/sh +# +# functions This file contains functions to be used by most or all +# shell scripts in the /etc/init.d directory. +# +# Version: @(#) /etc/init.d/functions 1.01 26-Oct-1993 +# +# Author: Miquel van Smoorenburg, +# Hacked by: Greg Galloway and Marc Ewing +# Karl DeBisschop (19991018 for solaris) +# + +# First set up a default search path. +PATH=/opt/gnu/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin +export PATH + +# Get a sane screen width +[ -z "$COLUMNS" ] && COLUMNS=80 + +# Read in our configuration +if [ -z "$BOOTUP" ]; then + if [ -f /etc/sysconfig/init ]; then + . /etc/sysconfig/init + else + # This all seem confusing? Look in /etc/sysconfig/init, + # or in /usr/doc/initscripts-*/sysconfig.txt + BOOTUP=color + RES_COL=20 + MOVE_TO_COL="printf \033[300C\033[%dD ${RES_COL}" + SETCOLOR_SUCCESS='printf \033[1;%dm 32' + SETCOLOR_FAILURE='printf \033[1;%dm 31' + SETCOLOR_WARNING='printf \033[1;%dm 33' + SETCOLOR_NORMAL='printf \033[0;%dm 39' + LOGLEVEL=1 + fi +fi + +if [ "$BOOTUP" != "verbose" ]; then + INITLOG_CMD="initlog -q -c" +else + INITLOG_CMD="initlog -q -c" +fi + +#if which initlog | egrep "^no initlog" >/dev/null 2&1; then +# INITLOG_CMD="" +#fi + +#if which initlog | egrep "^no pidof" >/dev/null 2>&1; then +# IN_INITLOG="not found" +#else +# IN_INITLOG= +#fi + +# A function to start a program. +daemon() { + # Test syntax. + gotbase= + case $1 in + '') echo '$0: Usage: daemon [+/-nicelevel] {program}' + return 1;; + --check) + shift + base=$1 + gotbase="yes" + shift + nicelevel=0 + ;; + + -*|+*) nicelevel=$1 + shift;; + *) nicelevel=0;; + esac + + # Save basename. + [ -z $gotbase ] && base=`basename $1` + + # See if it's already running. + pid=`pidofproc $base` + [ -n "$pid" ] && ps -p $pid >/dev/null 2>&1 && return + + # make sure it doesn't core dump anywhere; while this could mask + # problems with the daemon, it also closes some security problems + ulimit -c 0 + + # Echo daemon + [ "$BOOTUP" = "verbose" ] && printf " $base" + + # And start it up. + nice -n $nicelevel $INITLOG_CMD "$*" && success "$base startup" || failure "$base startup" +} + +# A function to stop a program. +killproc() { + # Test syntax. + if [ $# = 0 ]; then + echo "Usage: killproc {program} [signal]" + return 1 + fi + + notset=0 + # check for second arg to be kill level + if [ "$2" != "" ] ; then + killlevel=$2 + else + notset=1 + killlevel="-9" + fi + + # Save basename. + base=`basename $1` + + # Find pid. + pid=`pidofproc $base` + + # Kill it. + if [ "$pid" != "" ] ; then + [ $BOOTUP = "verbose" ] && printf "$base " + if [ "$notset" = "1" ] ; then + if ps -p $pid>/dev/null 2>&1; then + # TERM first, then KILL if not dead + kill -TERM $pid + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 3 + if ps -p $pid >/dev/null 2>&1 ; then + kill -KILL $pid + fi + fi + fi + fi + ps -p $pid >/dev/null 2>&1 && failure "$base shutdown" || success "$base shutdown" + # use specified level only + else + if ps -p $pid >/dev/null 2>&1; then + kill $killlevel $pid && success "$base $killlevel" || failure "$base $killlevel" + fi + fi + else + failure "$base shutdown" + fi + + # Remove pid file if any. + if [ "$notset" = "1" ]; then + rm -f /var/run/$base.pid + fi +} + +# A function to find the pid of a program. +pidofproc() { + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: pidofproc {program}" + return 1 + fi + + # First try "/var/run/*.pid" files + if [ -f /var/run/$1.pid ] ; then + pid=`head -1 /var/run/$1.pid` + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + fi + + # Next try "pidof" +# if which pidof | egrep -v "^no pidof" >/dev/null 2>&1; then +# pid=`pidof $1` +# if [ "$pid" != "" ] ; then +# echo $pid +# return 0 +# fi +# fi + + # Finally try to extract it from ps + pid=`ps -eo pid,ppid,fname | egrep -v $$ | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $3) || (("(" prog ")") == $3) || (("[" prog "]") == $3) || ((prog ":") == $3)) { print $1 ; exit 0 } }' $1` + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + + return 2 +} + +status() { + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: status {program}" + return 1 + fi + + base=`basename $1` + pid=`pidofproc $base` + if [ "$pid" != "" ] ; then + echo "$1 (pid $pid) is running..." + return 0 + fi + + # Next try "/var/run/*.pid" files + if [ -f /var/run/$1.pid ] ; then + pid=`head -1 /var/run/$1.pid` + if [ "$pid" != "" ] ; then + echo "$1 dead but pid file exists" + return 1 + fi + fi + + # See if /var/lock/subsys/$1 exists + if [ -f /var/lock/subsys/$1 ]; then + echo "$1 dead but subsys locked" + return 2 + fi + echo "$1 is stopped" + return 3 +} + +echo_success() { + [ "$BOOTUP" = "color" ] && $MOVE_TO_COL + printf "[ " + [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS + printf "OK" + [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL + printf " ]" + return 0 +} + +echo_failure() { + [ "$BOOTUP" = "color" ] && $MOVE_TO_COL + printf "[" + [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE + printf "FAILED" + [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL + printf "]" + return 1 +} + +echo_passed() { + [ "$BOOTUP" = "color" ] && $MOVE_TO_COL + printf "[" + [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING + printf "PASSED" + [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL + printf "]" + return 1 +} + +# Log that something succeeded +success() { + if [ -z "$IN_INITLOG" ]; then +# initlog -n $0 -s "$1" -e 1 + logger -t $0 "Success: $1" + else + logger -t $0 "Success: $1" +# echo "-n $0 -s \"$1\" -e 1" >&21 + fi + [ "$BOOTUP" != "verbose" ] && echo_success + return 0 +} + +# Log that something failed +failure() { + rc=$? + if [ -z "$IN_INITLOG" ]; then + logger -t $0 "Failure: $1" +# initlog -n $0 -s "$1" -e 2 + else + logger -t $0 "Failure: $1" +# echo "-n $0 -s \"$1\" -e 2" >&21 + fi + [ "$BOOTUP" != "verbose" ] && echo_failure + return $rc +} + +# Log that something passed, but may have had errors. Useful for fsck +passed() { + rc=$? + if [ -z "$IN_INITLOG" ]; then + logger -t $0 "Success: $1" +# initlog -n $0 -s "$1" -e 1 + else + logger -t $0 "Success: $1" +# echo "-n $0 -s \"$1\" -e 1" >&21 + fi + [ "$BOOTUP" != "verbose" ] && echo_passed + return $rc +} + +# Run some action. Log its output. +action() { + STRING=$1 + printf "$STRING " + shift + $INITLOG_CMD "$*" && success "$STRING" || failure "$STRING" + rc=$? + echo + return $rc +} + +# Confirm whether we really want to run this service +confirm() { + printf "Start service $1 (Y)es/(N)o/(C)ontinue? [Y] " + read answer + case $answer in + y|Y|"") + return 0 + ;; + c|C) + return 2 + ;; + n|N) + return 1 + ;; + *) + confirm $1 + return $? + ;; + esac +} diff --git a/html/.gitignore b/html/.gitignore new file mode 100644 index 0000000..6f3eb0c --- /dev/null +++ b/html/.gitignore @@ -0,0 +1,4 @@ +Makefile +index.html +side.html +config.inc.php diff --git a/html/Makefile.in b/html/Makefile.in new file mode 100644 index 0000000..a977e35 --- /dev/null +++ b/html/Makefile.in @@ -0,0 +1,92 @@ +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ +LDFLAGS=@LDFLAGS@ @LIBS@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +LOGDIR=@localstatedir@ +CFGDIR=@sysconfdir@ +BINDIR=@bindir@ +CGIDIR=@sbindir@ +HTMLDIR=@datadir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +COMMAND_OPTS=@COMMAND_OPTS@ + +CP=@CP@ + +all html: + +clean: + rm -f *.cfg *.sub core + rm -f *~ + rm -f images/*.jbf + rm -f images/logos/*.jbf + rm -f contexthelp/*~ + rm -f docs/*~ + rm -f docs/images/*.jbf + rm -f stylesheets/*~ + rm -f js/*~ + +distclean: clean + rm -f Makefile config.inc.php + +devclean: distclean + +install: + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR) + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/media + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/stylesheets + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/contexthelp + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/docs + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/docs/images + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/js + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/images + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/images/logos + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/includes + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/includes/rss + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/includes/rss/extlib + $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/ssi + $(INSTALL) -m 664 $(INSTALL_OPTS) robots.txt $(DESTDIR)$(HTMLDIR) +# $(INSTALL) -m 664 $(INSTALL_OPTS) docs/robots.txt $(DESTDIR)$(HTMLDIR)/docs +# Remove old HTML files (PHP files are used now) + rm -f $(DESTDIR)$(HTMLDIR)/index.html + rm -f $(DESTDIR)$(HTMLDIR)/main.html + rm -f $(DESTDIR)$(HTMLDIR)/side.html + for file in *.php; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR); done +# for file in media/*.wav; \ +# do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/media; done + for file in stylesheets/*.css; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/stylesheets; done + for file in contexthelp/*.html; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/contexthelp; done + for file in js/*.js; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/js; done +# for file in docs/*.html; \ +# do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/docs; done +# for file in docs/images/*.*; \ +# do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/docs/images; done + for file in images/*.gif; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done + for file in images/*.jpg; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done + for file in images/*.png; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done + for file in images/*.ico; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done + for file in images/logos/*.*; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images/logos; done + for file in includes/*.*; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/includes; done + for file in includes/rss/*.*; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/includes/rss; done + for file in includes/rss/extlib/*.*; \ + do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/includes/rss/extlib; done + +install-unstripped: + $(MAKE) install + + + + diff --git a/html/config.inc.php.in b/html/config.inc.php.in new file mode 100644 index 0000000..77a64d0 --- /dev/null +++ b/html/config.inc.php.in @@ -0,0 +1,20 @@ + diff --git a/html/contexthelp/A1.html b/html/contexthelp/A1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/A2.html b/html/contexthelp/A2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/A3.html b/html/contexthelp/A3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/A4.html b/html/contexthelp/A4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/A5.html b/html/contexthelp/A5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/A6.html b/html/contexthelp/A6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/A7.html b/html/contexthelp/A7.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/A7.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/B1.html b/html/contexthelp/B1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/B1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/C1.html b/html/contexthelp/C1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/C1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/D1.html b/html/contexthelp/D1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/D1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/E1.html b/html/contexthelp/E1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/E1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/F1.html b/html/contexthelp/F1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/F1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/G1.html b/html/contexthelp/G1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/G1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/G2.html b/html/contexthelp/G2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/G2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/G3.html b/html/contexthelp/G3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/G3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/G4.html b/html/contexthelp/G4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/G4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/G5.html b/html/contexthelp/G5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/G5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/G6.html b/html/contexthelp/G6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/G6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H1.html b/html/contexthelp/H1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H2.html b/html/contexthelp/H2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H3.html b/html/contexthelp/H3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H4.html b/html/contexthelp/H4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H5.html b/html/contexthelp/H5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H6.html b/html/contexthelp/H6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H7.html b/html/contexthelp/H7.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H7.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/H8.html b/html/contexthelp/H8.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/H8.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I1.html b/html/contexthelp/I1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I2.html b/html/contexthelp/I2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I3.html b/html/contexthelp/I3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I4.html b/html/contexthelp/I4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I5.html b/html/contexthelp/I5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I6.html b/html/contexthelp/I6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I7.html b/html/contexthelp/I7.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I7.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I8.html b/html/contexthelp/I8.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I8.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/I9.html b/html/contexthelp/I9.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/I9.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/J1.html b/html/contexthelp/J1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/J1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/K1.html b/html/contexthelp/K1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/K1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L1.html b/html/contexthelp/L1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L10.html b/html/contexthelp/L10.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L10.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L11.html b/html/contexthelp/L11.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L11.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L12.html b/html/contexthelp/L12.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L12.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L13.html b/html/contexthelp/L13.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L13.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L2.html b/html/contexthelp/L2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L3.html b/html/contexthelp/L3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L4.html b/html/contexthelp/L4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L5.html b/html/contexthelp/L5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L6.html b/html/contexthelp/L6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L7.html b/html/contexthelp/L7.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L7.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L8.html b/html/contexthelp/L8.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L8.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/L9.html b/html/contexthelp/L9.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/L9.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/M1.html b/html/contexthelp/M1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/M1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/M2.html b/html/contexthelp/M2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/M2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/M3.html b/html/contexthelp/M3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/M3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/M4.html b/html/contexthelp/M4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/M4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/M5.html b/html/contexthelp/M5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/M5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/M6.html b/html/contexthelp/M6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/M6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N1.html b/html/contexthelp/N1.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N1.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N2.html b/html/contexthelp/N2.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N2.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N3.html b/html/contexthelp/N3.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N3.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N4.html b/html/contexthelp/N4.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N4.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N5.html b/html/contexthelp/N5.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N5.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N6.html b/html/contexthelp/N6.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N6.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/contexthelp/N7.html b/html/contexthelp/N7.html new file mode 100644 index 0000000..e40ba28 --- /dev/null +++ b/html/contexthelp/N7.html @@ -0,0 +1,33 @@ + + + + +Context-Sensitive Help Unavailable + + + + + + + +

    +Context-Sensitive Help Unavailable +

    + +

    +Context-sensitive help is not yet available. +

    + +

    +For more information, please visit the main Nagios website at http://www.nagios.org. +

    + + + diff --git a/html/docs/index.html b/html/docs/index.html new file mode 100644 index 0000000..4d12a47 --- /dev/null +++ b/html/docs/index.html @@ -0,0 +1,97 @@ + + + + + + + + + + +Nagios Core Documentation + + + + + + + + + + + + + +
    + +Nagios + +
    + + + +

    + +The Nagios Core Documentation Has Moved! + +

    + + + +

    + +Documentation for Nagios Core can now be found online at http://go.nagios.com/nagioscore/docs/ + +

    + + + +



    + + + +

    + +Nagios, Nagios Core, NRPE, NSCA, and the Nagios logo are trademarks, servicemarks, registered servicemarks or registered trademarks of Nagios Enterprises. All other trademarks, servicemarks, registered trademarks, and registered servicemarks mentioned herein may be the property of their respective owner(s). The information contained herein is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. + +

    + + + + + + \ No newline at end of file diff --git a/html/images/Nagios-clearbg.png b/html/images/Nagios-clearbg.png new file mode 100755 index 0000000..fa3af36 Binary files /dev/null and b/html/images/Nagios-clearbg.png differ diff --git a/html/images/NagiosEnterprises-whitebg-112x46.png b/html/images/NagiosEnterprises-whitebg-112x46.png new file mode 100644 index 0000000..0775aba Binary files /dev/null and b/html/images/NagiosEnterprises-whitebg-112x46.png differ diff --git a/html/images/ack.gif b/html/images/ack.gif new file mode 100644 index 0000000..6b5a7cf Binary files /dev/null and b/html/images/ack.gif differ diff --git a/html/images/action.gif b/html/images/action.gif new file mode 100644 index 0000000..5a1d5d7 Binary files /dev/null and b/html/images/action.gif differ diff --git a/html/images/b_first2.png b/html/images/b_first2.png new file mode 100644 index 0000000..02bf87d Binary files /dev/null and b/html/images/b_first2.png differ diff --git a/html/images/b_last2.png b/html/images/b_last2.png new file mode 100755 index 0000000..7909238 Binary files /dev/null and b/html/images/b_last2.png differ diff --git a/html/images/b_next2.png b/html/images/b_next2.png new file mode 100644 index 0000000..d110815 Binary files /dev/null and b/html/images/b_next2.png differ diff --git a/html/images/b_prev2.png b/html/images/b_prev2.png new file mode 100644 index 0000000..aef82ec Binary files /dev/null and b/html/images/b_prev2.png differ diff --git a/html/images/command.png b/html/images/command.png new file mode 100644 index 0000000..f3c02a0 Binary files /dev/null and b/html/images/command.png differ diff --git a/html/images/comment.gif b/html/images/comment.gif new file mode 100644 index 0000000..7822c66 Binary files /dev/null and b/html/images/comment.gif differ diff --git a/html/images/contexthelp1.gif b/html/images/contexthelp1.gif new file mode 100644 index 0000000..aaf48ff Binary files /dev/null and b/html/images/contexthelp1.gif differ diff --git a/html/images/contexthelp2.gif b/html/images/contexthelp2.gif new file mode 100644 index 0000000..7712f15 Binary files /dev/null and b/html/images/contexthelp2.gif differ diff --git a/html/images/critical.png b/html/images/critical.png new file mode 100644 index 0000000..3b91871 Binary files /dev/null and b/html/images/critical.png differ diff --git a/html/images/delay.gif b/html/images/delay.gif new file mode 100644 index 0000000..00f3cda Binary files /dev/null and b/html/images/delay.gif differ diff --git a/html/images/delete.gif b/html/images/delete.gif new file mode 100644 index 0000000..9bec553 Binary files /dev/null and b/html/images/delete.gif differ diff --git a/html/images/detail.gif b/html/images/detail.gif new file mode 100644 index 0000000..f04baaa Binary files /dev/null and b/html/images/detail.gif differ diff --git a/html/images/disabled.gif b/html/images/disabled.gif new file mode 100644 index 0000000..fd0e750 Binary files /dev/null and b/html/images/disabled.gif differ diff --git a/html/images/down.gif b/html/images/down.gif new file mode 100644 index 0000000..a93e2ad Binary files /dev/null and b/html/images/down.gif differ diff --git a/html/images/downtime.gif b/html/images/downtime.gif new file mode 100644 index 0000000..dde07ef Binary files /dev/null and b/html/images/downtime.gif differ diff --git a/html/images/empty.gif b/html/images/empty.gif new file mode 100644 index 0000000..3a09af5 Binary files /dev/null and b/html/images/empty.gif differ diff --git a/html/images/enabled.gif b/html/images/enabled.gif new file mode 100644 index 0000000..1a87c78 Binary files /dev/null and b/html/images/enabled.gif differ diff --git a/html/images/extinfo.gif b/html/images/extinfo.gif new file mode 100644 index 0000000..bab5beb Binary files /dev/null and b/html/images/extinfo.gif differ diff --git a/html/images/favicon.ico b/html/images/favicon.ico new file mode 100644 index 0000000..b85849b Binary files /dev/null and b/html/images/favicon.ico differ diff --git a/html/images/flapping.gif b/html/images/flapping.gif new file mode 100644 index 0000000..5d6c74d Binary files /dev/null and b/html/images/flapping.gif differ diff --git a/html/images/globe-support-150x150.png b/html/images/globe-support-150x150.png new file mode 100644 index 0000000..d9677bb Binary files /dev/null and b/html/images/globe-support-150x150.png differ diff --git a/html/images/greendot.gif b/html/images/greendot.gif new file mode 100644 index 0000000..54977a2 Binary files /dev/null and b/html/images/greendot.gif differ diff --git a/html/images/histogram.png b/html/images/histogram.png new file mode 100644 index 0000000..fa207b5 Binary files /dev/null and b/html/images/histogram.png differ diff --git a/html/images/history.gif b/html/images/history.gif new file mode 100644 index 0000000..2d2071f Binary files /dev/null and b/html/images/history.gif differ diff --git a/html/images/hostevent.gif b/html/images/hostevent.gif new file mode 100644 index 0000000..dbd216a Binary files /dev/null and b/html/images/hostevent.gif differ diff --git a/html/images/info.png b/html/images/info.png new file mode 100644 index 0000000..f890891 Binary files /dev/null and b/html/images/info.png differ diff --git a/html/images/left.gif b/html/images/left.gif new file mode 100644 index 0000000..1b40680 Binary files /dev/null and b/html/images/left.gif differ diff --git a/html/images/logofullsize.png b/html/images/logofullsize.png new file mode 100644 index 0000000..44cb2dc Binary files /dev/null and b/html/images/logofullsize.png differ diff --git a/html/images/logos/nagios.gd2 b/html/images/logos/nagios.gd2 new file mode 100644 index 0000000..3cfe346 Binary files /dev/null and b/html/images/logos/nagios.gd2 differ diff --git a/html/images/logos/nagios.gif b/html/images/logos/nagios.gif new file mode 100644 index 0000000..aa2750f Binary files /dev/null and b/html/images/logos/nagios.gif differ diff --git a/html/images/logos/nagiosvrml.png b/html/images/logos/nagiosvrml.png new file mode 100644 index 0000000..36fcb56 Binary files /dev/null and b/html/images/logos/nagiosvrml.png differ diff --git a/html/images/logos/unknown.gd2 b/html/images/logos/unknown.gd2 new file mode 100644 index 0000000..4d4bba9 Binary files /dev/null and b/html/images/logos/unknown.gd2 differ diff --git a/html/images/logos/unknown.gif b/html/images/logos/unknown.gif new file mode 100644 index 0000000..8aac3f9 Binary files /dev/null and b/html/images/logos/unknown.gif differ diff --git a/html/images/logrotate.png b/html/images/logrotate.png new file mode 100644 index 0000000..b6cbbb4 Binary files /dev/null and b/html/images/logrotate.png differ diff --git a/html/images/ndisabled.gif b/html/images/ndisabled.gif new file mode 100644 index 0000000..9fda31a Binary files /dev/null and b/html/images/ndisabled.gif differ diff --git a/html/images/noack.gif b/html/images/noack.gif new file mode 100644 index 0000000..c8b9281 Binary files /dev/null and b/html/images/noack.gif differ diff --git a/html/images/notes.gif b/html/images/notes.gif new file mode 100644 index 0000000..5f832ef Binary files /dev/null and b/html/images/notes.gif differ diff --git a/html/images/notify.gif b/html/images/notify.gif new file mode 100644 index 0000000..17f0b0b Binary files /dev/null and b/html/images/notify.gif differ diff --git a/html/images/orangedot.gif b/html/images/orangedot.gif new file mode 100644 index 0000000..03d32f1 Binary files /dev/null and b/html/images/orangedot.gif differ diff --git a/html/images/passiveonly.gif b/html/images/passiveonly.gif new file mode 100644 index 0000000..1cad3d9 Binary files /dev/null and b/html/images/passiveonly.gif differ diff --git a/html/images/recovery.png b/html/images/recovery.png new file mode 100644 index 0000000..5bf4d39 Binary files /dev/null and b/html/images/recovery.png differ diff --git a/html/images/redudancy.png b/html/images/redudancy.png new file mode 100644 index 0000000..61dd9b0 Binary files /dev/null and b/html/images/redudancy.png differ diff --git a/html/images/redundancy.png b/html/images/redundancy.png new file mode 100644 index 0000000..e04bf71 Binary files /dev/null and b/html/images/redundancy.png differ diff --git a/html/images/restart.gif b/html/images/restart.gif new file mode 100644 index 0000000..417643b Binary files /dev/null and b/html/images/restart.gif differ diff --git a/html/images/right.gif b/html/images/right.gif new file mode 100644 index 0000000..dc4a3b3 Binary files /dev/null and b/html/images/right.gif differ diff --git a/html/images/sblogo.png b/html/images/sblogo.png new file mode 100644 index 0000000..336260a Binary files /dev/null and b/html/images/sblogo.png differ diff --git a/html/images/serviceevent.gif b/html/images/serviceevent.gif new file mode 100644 index 0000000..dbd216a Binary files /dev/null and b/html/images/serviceevent.gif differ diff --git a/html/images/sflogo.png b/html/images/sflogo.png new file mode 100644 index 0000000..142a6f9 Binary files /dev/null and b/html/images/sflogo.png differ diff --git a/html/images/splunk1.gif b/html/images/splunk1.gif new file mode 100644 index 0000000..1ccad05 Binary files /dev/null and b/html/images/splunk1.gif differ diff --git a/html/images/splunk2.gif b/html/images/splunk2.gif new file mode 100644 index 0000000..91eb417 Binary files /dev/null and b/html/images/splunk2.gif differ diff --git a/html/images/start.gif b/html/images/start.gif new file mode 100644 index 0000000..4120069 Binary files /dev/null and b/html/images/start.gif differ diff --git a/html/images/status.gif b/html/images/status.gif new file mode 100644 index 0000000..1c52387 Binary files /dev/null and b/html/images/status.gif differ diff --git a/html/images/status2.gif b/html/images/status2.gif new file mode 100644 index 0000000..e1e8add Binary files /dev/null and b/html/images/status2.gif differ diff --git a/html/images/status3.gif b/html/images/status3.gif new file mode 100644 index 0000000..251a070 Binary files /dev/null and b/html/images/status3.gif differ diff --git a/html/images/status4.gif b/html/images/status4.gif new file mode 100644 index 0000000..f8983f5 Binary files /dev/null and b/html/images/status4.gif differ diff --git a/html/images/stop.gif b/html/images/stop.gif new file mode 100644 index 0000000..3baf628 Binary files /dev/null and b/html/images/stop.gif differ diff --git a/html/images/tacdisabled.jpg b/html/images/tacdisabled.jpg new file mode 100644 index 0000000..c6d87b6 Binary files /dev/null and b/html/images/tacdisabled.jpg differ diff --git a/html/images/tacdisabled.png b/html/images/tacdisabled.png new file mode 100644 index 0000000..e7ceeca Binary files /dev/null and b/html/images/tacdisabled.png differ diff --git a/html/images/tacenabled.jpg b/html/images/tacenabled.jpg new file mode 100644 index 0000000..6c11ffc Binary files /dev/null and b/html/images/tacenabled.jpg differ diff --git a/html/images/tacenabled.png b/html/images/tacenabled.png new file mode 100644 index 0000000..c4bcb27 Binary files /dev/null and b/html/images/tacenabled.png differ diff --git a/html/images/thermcrit.png b/html/images/thermcrit.png new file mode 100644 index 0000000..6a3150d Binary files /dev/null and b/html/images/thermcrit.png differ diff --git a/html/images/thermok.png b/html/images/thermok.png new file mode 100644 index 0000000..3e3659a Binary files /dev/null and b/html/images/thermok.png differ diff --git a/html/images/thermwarn.png b/html/images/thermwarn.png new file mode 100644 index 0000000..0f5252b Binary files /dev/null and b/html/images/thermwarn.png differ diff --git a/html/images/trends.gif b/html/images/trends.gif new file mode 100644 index 0000000..29943d2 Binary files /dev/null and b/html/images/trends.gif differ diff --git a/html/images/trendshost.png b/html/images/trendshost.png new file mode 100644 index 0000000..b305526 Binary files /dev/null and b/html/images/trendshost.png differ diff --git a/html/images/trendssvc.png b/html/images/trendssvc.png new file mode 100644 index 0000000..80be2f6 Binary files /dev/null and b/html/images/trendssvc.png differ diff --git a/html/images/unknown.png b/html/images/unknown.png new file mode 100644 index 0000000..fec1ea9 Binary files /dev/null and b/html/images/unknown.png differ diff --git a/html/images/up.gif b/html/images/up.gif new file mode 100644 index 0000000..3dec330 Binary files /dev/null and b/html/images/up.gif differ diff --git a/html/images/warning.png b/html/images/warning.png new file mode 100644 index 0000000..36e3d8c Binary files /dev/null and b/html/images/warning.png differ diff --git a/html/images/weblogo1.png b/html/images/weblogo1.png new file mode 100644 index 0000000..78605a4 Binary files /dev/null and b/html/images/weblogo1.png differ diff --git a/html/images/zoom1.gif b/html/images/zoom1.gif new file mode 100644 index 0000000..2297773 Binary files /dev/null and b/html/images/zoom1.gif differ diff --git a/html/images/zoom2.gif b/html/images/zoom2.gif new file mode 100644 index 0000000..f4f2143 Binary files /dev/null and b/html/images/zoom2.gif differ diff --git a/html/includes/rss/AUTHORS b/html/includes/rss/AUTHORS new file mode 100644 index 0000000..7d7f3f5 --- /dev/null +++ b/html/includes/rss/AUTHORS @@ -0,0 +1 @@ +kellan diff --git a/html/includes/rss/CHANGES b/html/includes/rss/CHANGES new file mode 100644 index 0000000..3346f2b --- /dev/null +++ b/html/includes/rss/CHANGES @@ -0,0 +1,41 @@ +Version 0.72 +----------- + - fix security exploit: http://www.sec-consult.com/216.html + +Version 0.7 +----------- + - support for input and output charset encoding + based on the work in FoF, uses iconv or mbstring if available + - + +Version 0.6 +----------- + - basic support for Atom syndication format + including support for Atom content constructs + - fixed support for private feeds (HTTP Auth and SSL) + (thanks to silverorange.com for providing test feeds) + - support for some broken webservers + +Version 0.52 +----------- + - support GZIP content negoiation + - PHP 4.3.2 support + +Version 0.4 +----------- + - improved error handling, better access for script authors + - included example scripts of working with MagpieRSS + - new Smarty plugin for RSS date parsing + +Version 0.3 +----------- + - added support for conditional gets (Last-Modified, ETag) + - now use Snoopy to handle fetching RSS files + +Version 0.2 +----------- + - MAJOR CLEAN UP + - removed kludgy $options array in favour of constants + - phased out returning arrays + - added better error handling + - re-worked comments diff --git a/html/includes/rss/ChangeLog b/html/includes/rss/ChangeLog new file mode 100644 index 0000000..62fa4f5 --- /dev/null +++ b/html/includes/rss/ChangeLog @@ -0,0 +1,405 @@ +2005-10-28 14:11 kellan + + * extlib/Snoopy.class.inc: a better solution + +2005-10-28 11:51 kellan + + * extlib/Snoopy.class.inc: fix arbtriary code execution + vulnerability when using curl+ssl + + http://www.sec-consult.com/216.html + +2005-03-08 10:46 kellan + + * rss_parse.inc: fix bug w/ atom and date normalization + +2005-02-09 14:59 kellan + + * rss_fetch.inc: fix stale cache bug + +2005-01-28 02:27 kellan + + * rss_parse.inc: support php w/o array_change_case + +2005-01-23 20:02 kellan + + * rss_fetch.inc: fix cache bug introduced by charset encoding + +2005-01-12 09:14 kellan + + * rss_cache.inc, rss_fetch.inc: more sanity checks for when things + go wrong + +2004-12-12 13:44 kellan + + * INSTALL, rss_cache.inc, rss_utils.inc: detab + +2004-11-23 20:15 kellan + + * rss_parse.inc: fix calling iconv instead of mb_convert_encoding + +2004-11-22 02:11 kellan + + * CHANGES, ChangeLog, rss_parse.inc, scripts/magpie_debug.php: last + bit of tidying + +2004-11-22 01:45 kellan + + * rss_fetch.inc: detab, bump version + +2004-11-22 01:43 kellan + + * rss_parse.inc: was filtering too much + +2004-11-22 00:03 kellan + + * rss_fetch.inc, rss_parse.inc: cache on $url . $output_encoding + otherwise we can get munged output + +2004-11-21 23:52 kellan + + * rss_parse.inc: add WARNING + +2004-11-21 23:45 kellan + + * rss_parse.inc: don't set ERROR on notice or warning (rss_fetch + dies on parse errors) + +2004-11-21 23:44 kellan + + * rss_fetch.inc: add encoding defines (fix timeout error reporting) + +2004-11-21 20:21 kellan + + * rss_parse.inc: incorporate steve's patch + +2004-11-21 19:26 kellan + + * rss_parse.inc: remove old debugging functions, totally + arbitrarily. might break stuff. can't really explain why i'm + doing this. + +2004-10-28 15:52 kellan + + * rss_parse.inc: fixed '=' instead of '==' + +2004-10-26 00:48 kellan + + * rss_parse.inc: chance epoch to timestamp to conform w/ php naming + conventions + +2004-06-15 12:00 kellan + + * rss_parse.inc: [no log message] + +2004-04-26 14:16 kellan + + * rss_fetch.inc: bump version + +2004-04-26 12:36 kellan + + * rss_parse.inc: fix field doubling + +2004-04-24 17:47 kellan + + * CHANGES, ChangeLog: updated + +2004-04-24 17:35 kellan + + * rss_fetch.inc: bumped version + +2004-04-24 16:52 kellan + + * rss_parse.inc: support arbitrary atom content constructs + + some refactoring + +2004-04-24 16:15 kellan + + * rss_parse.inc: support summary content contstruct. add normalize + function + +2004-03-27 16:29 kellan + + * extlib/Snoopy.class.inc: accept self-signed certs + +2004-03-27 12:53 kellan + + * extlib/Snoopy.class.inc: fixed SSL support * set status * set + error on bad curl + + (also ripped out big chunks of dead weight (submit_form) which + were getting in my way + +2004-01-25 02:25 kellan + + * rss_parse.inc: make RSS 1.0's rdf:about available + +2004-01-25 02:07 kellan + + * rss_parse.inc: clean up text, and line formats. add support item + rdf:about + +2004-01-24 23:40 kellan + + * CHANGES, ChangeLog: update changes + +2004-01-24 23:37 kellan + + * rss_fetch.inc: updated version + +2004-01-24 23:35 kellan + + * rss_parse.inc: whitespace + +2004-01-24 23:23 kellan + + * extlib/Snoopy.class.inc: support badly formatted http headers + +2004-01-24 23:20 kellan + + * rss_parse.inc: added alpha atom parsing support + +2003-06-25 22:34 kellan + + * extlib/Snoopy.class.inc: fixed fread 4.3.2 compatibility problems + +2003-06-13 11:31 kellan + + * rss_fetch.inc: reset cache on 304 + +2003-06-12 21:37 kellan + + * rss_cache.inc, rss_fetch.inc, rss_parse.inc, rss_utils.inc: + bumped up version numbers + +2003-06-12 21:32 kellan + + * htdocs/index.html: updated news + +2003-06-12 21:27 kellan + + * NEWS: a manual blog :) + +2003-06-12 21:22 kellan + + * htdocs/index.html: fully qualified img + +2003-06-12 21:20 kellan + + * htdocs/index.html: clean up. added badge. + +2003-06-12 21:04 kellan + + * rss_utils.inc: clean up regex + +2003-06-12 21:02 kellan + + * rss_cache.inc: suppress some warnings + +2003-05-30 20:44 kellan + + * extlib/Snoopy.class.inc: more comments, cleaned up notice + +2003-05-30 15:14 kellan + + * extlib/Snoopy.class.inc: don't advertise gzip support if the user + hasn't built php with gzinflate support + +2003-05-12 22:32 kellan + + * ChangeLog: changes + +2003-05-12 22:11 kellan + + * htdocs/index.html: announce 0.5 + +2003-05-12 21:42 kellan + + * htdocs/index.html: change + +2003-05-12 21:39 kellan + + * rss_fetch.inc: use gzip + +2003-05-12 21:37 kellan + + * extlib/Snoopy.class.inc: added support gzip encoded content + negoiation + +2003-05-12 21:32 kellan + + * rss_cache.inc, rss_fetch.inc, rss_parse.inc, rss_utils.inc: fixed + typoes + +2003-04-26 21:44 kellan + + * rss_parse.inc: fix minor typo + +2003-04-18 08:19 kellan + + * htdocs/cookbook.html: updated cookbook to show more code for + limiting items + +2003-03-03 16:02 kellan + + * rss_parse.inc, scripts/magpie_slashbox.php: committed (or + adpated) patch from Nicola (www.technick.com) to quell 'Undefined + Indexes' notices + +2003-03-03 15:59 kellan + + * rss_fetch.inc: commited patch from nicola (www.technick.com) to + quell 'undefined indexes' notices. + + * Magpie now automatically includes its version in the + user-agent, & whether cacheing is turned on. + +2003-02-12 01:22 kellan + + * CHANGES, ChangeLog: ChangeLog now auto-generated by cvs2cl + +2003-02-12 00:21 kellan + + * rss_fetch.inc: better errors, hopefully stomped on pesky notices + +2003-02-12 00:19 kellan + + * rss_parse.inc: check to see is xml is supported, if not die + + also throw better xml errors + +2003-02-12 00:18 kellan + + * rss_cache.inc: hopefully cleared up some notices that were being + thrown into the log + + fixed a debug statement that was being called as an error + +2003-02-12 00:15 kellan + + * scripts/: magpie_simple.php, magpie_slashbox.php: moved + magpie_simple to magpie_slashbox, and replaced it with a simpler + demo. + +2003-02-12 00:02 kellan + + * INSTALL, README, TROUBLESHOOTING: Improved documentation. Better + install instructions. + + TROUBLESHOOTING cover common installation and usage problems + +2003-01-22 14:40 kellan + + * htdocs/cookbook.html: added cookbook.html + +2003-01-21 23:47 kellan + + * cookbook: a magpie cookbook + +2003-01-20 10:09 kellan + + * ChangeLog: updated + +2003-01-20 09:23 kellan + + * scripts/simple_smarty.php: minor clean up + +2003-01-20 09:15 kellan + + * scripts/README: added smarty url + +2003-01-20 09:14 kellan + + * magpie_simple.php, htdocs/index.html, scripts/README, + scripts/magpie_debug.php, scripts/magpie_simple.php, + scripts/simple_smarty.php, + scripts/smarty_plugin/modifier.rss_date_parse.php, + scripts/templates/simple.smarty: Added scripts directory for + examples on how to use MagpieRSS + + magpie_simple - is a simple example magpie_debug - spew all the + information from a parsed RSS feed simple_smary - example of + using magpie with Smarty template system + smarty_plugin/modifier.rss_date_parse.php - support file for the + smarty demo templates/simple.smary - template for the smarty demo + +2003-01-20 09:11 kellan + + * rss_fetch.inc, rss_parse.inc: changes to error handling to give + script authors more access to magpie's errors. + + added method magpie_error() to retrieve global MAGPIE_ERROR + variable for when fetch_rss() returns false + +2002-10-26 19:02 kellan + + * htdocs/index.html: putting the website under source control + +2002-10-26 18:43 kellan + + * AUTHORS, ChangeLog, INSTALL, README: some documentation to make + it all look official :) + +2002-10-25 23:04 kellan + + * magpie_simple.php: quxx + +2002-10-25 23:04 kellan + + * rss_parse.inc: added support for textinput and image + +2002-10-25 19:23 kellan + + * magpie_simple.php, rss_cache.inc, rss_fetch.inc, rss_parse.inc, + rss_utils.inc: switched to using Snoopy for fetching remote RSS + files. + + added support for conditional gets + +2002-10-25 19:22 kellan + + * rss_cache.inc, rss_fetch.inc, rss_parse.inc, rss_utils.inc: + Change comment style to slavishly imitate the phpinsider style + found in Smarty and Snoopy :) + +2002-10-25 19:18 kellan + + * extlib/Snoopy.class.inc: added Snoopy in order to support + conditional gets + +2002-10-23 23:19 kellan + + * magpie_simple.php, rss_cache.inc, rss_fetch.inc, rss_parse.inc: + MAJOR CLEANUP! + + * rss_fetch got rid of the options array, replaced it with a more + PHP-like solution of using defines. constants are setup, with + defaults, in the function init() + + got rid of the idiom of passing back an array, its was awkward to + deal with in PHP, and unusual (and consquently confusing to + people). now i return true/false values, and try to setup error + string where appropiate (rss_cache has the most complete example + of this) + + change the logic for interacting with the cache + + * rss_cache major re-working of how error are handled. tried to + make the code more resillient. the cache is now much more aware + of MAX_AGE, where before this was being driven out of rss_fetch + (which was silly) + + * rss_parse properly handles xml parse errors. used to sail + along blithely unaware. + +2002-09-11 11:11 kellan + + * rss_cache.inc, rss_parse.inc, magpie_simple.php, rss_fetch.inc, + rss_utils.inc: Initial revision + +2002-09-11 11:11 kellan + + * rss_cache.inc, rss_parse.inc, magpie_simple.php, rss_fetch.inc, + rss_utils.inc: initial import + diff --git a/html/includes/rss/INSTALL b/html/includes/rss/INSTALL new file mode 100644 index 0000000..640833d --- /dev/null +++ b/html/includes/rss/INSTALL @@ -0,0 +1,143 @@ +REQUIREMENTS + + MapieRSS requires a recent PHP 4+ (developed with 4.2.0) + with xml (expat) support. + + Optionally: + * PHP5 with libxml2 support. + * cURL for SSL support + * iconv (preferred) or mb_string for expanded character set support + +QUICK START + + Magpie consists of 4 files (rss_fetch.inc, rss_parser.inc, rss_cache.inc, + and rss_utils.inc), and the directory extlib (which contains a modified + version of the Snoopy HTTP client) + + Copy these 5 resources to a directory named 'magpierss' in the same + directory as your PHP script. + + At the top of your script add the following line: + + require_once('magpierss/rss_fetch.inc'); + + Now you can use the fetch_rss() method: + + $rss = fetch_rss($url); + + Done. That's it. See README for more details on using MagpieRSS. + +NEXT STEPS + + Important: you'll probably want to get the cache directory working in + order to speed up your application, and not abuse the webserver you're + downloading the RSS from. + + Optionally you can install MagpieRSS in your PHP include path in order to + make it available server wide. + + Lastly you might want to look through the constants in rss_fetch.inc see if + there is anything you want to override (the defaults are pretty good) + + For more info, or if you have trouble, see TROUBLESHOOTING + +SETTING UP CACHING + + Magpie has built-in transparent caching. With caching Magpie will only + fetch and parse RSS feeds when there is new content. Without this feature + your pages will be slow, and the sites serving the RSS feed will be annoyed + with you. + +** Simple and Automatic ** + + By default Magpie will try to create a cache directory named 'cache' in the + same directory as your PHP script. + +** Creating a Local Cache Directory ** + + Often this will fail, because your webserver doesn't have sufficient + permissions to create the directory. + + Exact instructions for how to do this will vary from install to install and + platform to platform. The steps are: + + 1. Make a directory named 'cache' + 2. Give the web server write access to that directory. + + An example of how to do this on Debian would be: + + 1. mkdir /path/to/script/cache + 2. chgrp www-data /path/to/script/cache + 3. chmod 775 /path/to/script/cache + + On other Unixes you'll need to change 'www-data' to what ever user Apache + runs as. (on MacOS X the user would be 'www') + +** Cache in /tmp ** + + Sometimes you won't be able to create a local cache directory. Some reasons + might be: + + 1. No shell account + 2. Insufficient permissions to change ownership of a directory + 3. Webserver runs as 'nobody' + + In these situations using a cache directory in /tmp can often be a good + option. + + The drawback is /tmp is public, so anyone on the box can read the cache + files. Usually RSS feeds are public information, so you'll have to decide + how much of an issue that is. + + To use /tmp as your cache directory you need to add the following line to + your script: + + define('MAGPIE_CACHE_DIR', '/tmp/magpie_cache'); + +** Global Cache ** + + If you have several applications using Magpie, you can create a single + shared cache directory, either using the /tmp cache, or somewhere else on + the system. + + The upside is that you'll distribute fetching and parsing feeds across + several applications. + +INSTALLING MAGPIE SERVER WIDE + + Rather then following the Quickstart instructions which requires you to have + a copy of Magpie per application, alternately you can place it in some + shared location. + +** Adding Magpie to Your Include Path ** + + Copy the 5 resources (rss_fetch.inc, rss_parser.inc, rss_cache.inc, + rss_utils.inc, and extlib) to a directory named 'magpierss' in your include + path. Now any PHP file on your system can use Magpie with: + + require_once('magpierss/rss_fetch.inc'); + + Different installs have different include paths, and you'll have to figure + out what your include_path is. + + From shell you can try: + + php -i | grep 'include_path' + + Alternatley you can create a phpinfo.php file with contains: + + + + Debian's default is: + + /usr/share/php + + (though more idealogically pure location would be /usr/local/share/php) + + Apple's default include path is: + + /usr/lib/php + + While the Entropy PHP build seems to use: + + /usr/local/php/lib/php \ No newline at end of file diff --git a/html/includes/rss/NEWS b/html/includes/rss/NEWS new file mode 100644 index 0000000..5ac6b97 --- /dev/null +++ b/html/includes/rss/NEWS @@ -0,0 +1,53 @@ +MagpieRSS News + +MAGPIERSS 0.51 RELEASED + * important bugfix! + * fix "silent failure" when PHP doesn't have zlib + +FEED ON FEEDS USES MAGPIE + * web-based RSS aggregator built with Magpie + * easy to install, easy to use. + http://minutillo.com/steve/feedonfeeds/ + +MAGPIERSS 0.5 RELEASED + * supports transparent HTTP gzip content negotiation for reduced bandwidth usage + * quashed some undefined index notices + +MAGPIERSS 0.46 RELEASED + * minor release, more error handling clean up + * documentation fixes, simpler example + * new trouble shooting guide for installation and usage problems + http://magpierss.sourceforge.net/TROUBLESHOOTING + +MAGPIE NEWS AS RSS + * releases, bug fixes, releated stories in RSS + +MAGPIERSS COOKBOOK: SIMPLE PHP RSS HOW TOS + * answers some of the most frequently asked Magpie questions + * feedback, suggestions, requests, recipes welcome + http://magpierss.sourceforge.net/cookbook.html + +MAGPIERSS 0.4 RELEASED! + * improved error handling, more flexibility for script authors, backwards compatible + * new and better examples! including using MagpieRSS and Smarty + * new Smarty plugin for RSS date parsing + http://smarty.php.net + +INFINITE PENGUIN NOW SUPPORTS MAGPIE 0.3 + * simple, sophisticated RSS viewer + * includes auto-generated javascript ticker from RSS feed + http://www.infinitepenguins.net/rss/ + +TRAUMWIND RELEASES REX BACKEND FOR MAGPIERSS + * drop in support using regex based XML parser + * parses improperly formed XML that chokes expat + http://traumwind.de/blog/magpie/magpie_alike.php + +MAGPIERSS 0.3 RELEASED! + * Support added for HTTP Conditional GETs. + http://fishbowl.pastiche.org/archives/001132.html + +MAGPIERSS 0.2! + * Major clean up of the code. Easier to use. + * Simpler install on shared hosts. + * Better documentation and comments. diff --git a/html/includes/rss/README b/html/includes/rss/README new file mode 100644 index 0000000..6af7edb --- /dev/null +++ b/html/includes/rss/README @@ -0,0 +1,48 @@ +NAME + + MagpieRSS - a simple RSS integration tool + +SYNOPSIS + + require_once(rss_fetch.inc); + $url = $_GET['url']; + $rss = fetch_rss( $url ); + + echo "Channel Title: " . $rss->channel['title'] . "

    "; + echo "

      "; + foreach ($rss->items as $item) { + $href = $item['link']; + $title = $item['title']; + echo "
    • $title
    • "; + } + echo "
    "; + +DESCRIPTION + + MapieRSS is an XML-based RSS parser in PHP. It attempts to be "PHP-like", + and simple to use. + + Some features include: + + * supports RSS 0.9 - 1.0, with limited RSS 2.0 support + * supports namespaces, and modules, including mod_content and mod_event + * open minded [1] + * simple, functional interface, to object oriented backend parser + * automatic caching of parsed RSS objects makes its easy to integrate + * supports conditional GET with Last-Modified, and ETag + * uses constants for easy override of default behaviour + * heavily commented + + +1. By open minded I mean Magpie will accept any tag it finds in good faith that + it was supposed to be here. For strict validation, look elsewhere. + + +GETTING STARTED + + + +COPYRIGHT: + Copyright(c) 2002 kellan@protest.net. All rights reserved. + This software is released under the GNU General Public License. + Please read the disclaimer at the top of the Snoopy.class.inc file. diff --git a/html/includes/rss/TROUBLESHOOTING b/html/includes/rss/TROUBLESHOOTING new file mode 100644 index 0000000..89068d3 --- /dev/null +++ b/html/includes/rss/TROUBLESHOOTING @@ -0,0 +1,152 @@ +TROUBLESHOOTING + + +Trouble Installing MagpieRSS: + +1. Fatal error: Failed opening required '/path/to/script/rss_fetch.inc' + (include_path='.:/usr/local/lib/php:/usr/local/lib/php/pear') + +2. Cache couldn't make dir './cache'. + +3. Fatal error: Failed to load PHP's XML Extension. + http://www.php.net/manual/en/ref.xml.php + +Trouble Using MagpieRSS + +4. Warning: MagpieRSS: Failed to fetch example.com/index.rdf. + (HTTP Error: Invalid protocol "") + +5. Warning: MagpieRSS: Failed to parse RSS file. + (not well-formed (invalid token) at line 19, column 98) + +6. Warning: MagpieRSS: Failed to fetch http://localhost/rss/features.1-0.rss. + (HTTP Response: HTTP/1.1 404 Not Found) + +If you would rather provide a custom error, see the COOKBOOK +(http://magpierss.sf.net/cookbook.html) recipe 2. + +************************************************************************* +1. Fatal error: Failed opening required '/path/to/script/rss_fetch.inc' + (include_path='.:/usr/local/lib/php:/usr/local/lib/php/pear') + + This could mean that: + + a) PHP can't find the MagpieRSS files. + b) PHP found them the MagpieRSS files, but can't read them. + + a. Telling PHP where to look for MagpieRSS file. + + This might mean your PHP program can't find the MagpieRSS libraries. + Magpie relies on 4 include files, rss_fetch.inc, rss_parse.inc, + rss_cache.inc, rss_util.inc, and for normal use you'll need all 4 (see the + cookbook for exceptions). + + This can be fixed by making sure the MagpieRSS files are in your include + path. + + If you can edit your include path (for example your on a shared host) then + you need to replace: + + require_once('rss_fetch.inc'); + + -with- + + define('MAGPIE_DIR', '/path/to/magpierss/'); + require_once(MAGPIE_DIR.'rss_fetch.inc'); + + b. PHP can't read the MagpieRSS files + + All PHP libraries need to be readable by your webserver. + + On Unix you can accomplish this with: + + chmod 755 rss_fetch.inc rss_parse.inc rss_cache.inc rss_util.inc + +************************************************************************* +2. Cache couldn't make dir './cache'. + + MagpieRSS caches the results of fetched and parsed RSS to reduce the load on + both your server, and the remote server providing the RSS. It does this by + writing files to a cache directory. + + This error means the webserver doesn't have write access to the current + directory. + + a. Make a webserver writeable cache directory + + Find the webserver's group. (on my system it is 'www') + + mkdir ./cache + chgrp www directory_name + chmod g+w directory_name + + (this is the best, and desired solution) + + b. Tell MagpieRSS to create the cache directory somewhere the webserver can + write to. + + define('MAGPIE_CACHE_DIR', '/tmp/magpierss'); + + (this is not a great solution, and might have security considerations) + + c. Turn off cacheing. + + Magpie can work fine with cacheing, but it will be slower, and you might + become a nuiance to the RSS provider, but it is an option. + + define('MAGPIE_CACHE_ON', 0); + + d. And lastly, do NOT + + chmod 777 ./cache + + Any of the above solutions are better then this. + + NOTE: If none of this works for you, let me know. I've got root, and a + custom compiled Apache on almost any box I ever touch, so I can be a little + out of touch with reality. But I won't know that if I don't feedback. + +************************************************************************* 3. +3. Fatal error: Failed to load PHP's XML Extension. + http://www.php.net/manual/en/ref.xml.php + + -or- + + Fatal error: Failed to create an instance of PHP's XML parser. + http://www.php.net/manual/en/ref.xml.php + + Make sure your PHP was built with --with-xml + + This has been turned on by default for several versions of PHP, but it might + be turned off in your build. + + See php.net for details on building and configuring PHP. + + +************************************************************************* +4. Warning: MagpieRSS: Failed to fetch index.rdf. + (HTTP Error: Invalid protocol "") + + You need to put http:// in front of your the URL to your RSS feed + +************************************************************************* +5. Warning: MagpieRSS: Failed to parse RSS file. + (not well-formed (invalid token) at line 19, column 98) + + There is a problem with the RSS feed you are trying to read. + MagpieRSS is an XML parser, and therefore can't parse RSS feed with invalid + characters. Some RSS parser are based on regular expressions, and can + parse invalid RSS but they have their own problems. + + You could try contacting the author of the RSS feed, and pointing them to + the online RSS validator at: + + http://feeds.archive.org/validator/ + +************************************************************************* +6. Warning: MagpieRSS: Failed to fetch http://example.com/index.rdf + (HTTP Response: HTTP/1.1 404 Not Found) + + Its a 404! The RSS file ain't there. + + diff --git a/html/includes/rss/cookbook b/html/includes/rss/cookbook new file mode 100644 index 0000000..45dda98 --- /dev/null +++ b/html/includes/rss/cookbook @@ -0,0 +1,125 @@ +MAGPIERSS RECIPES: Cooking with Corbies + + "Four and twenty blackbirds baked in a pie." + +1. LIMIT THE NUMBER OF HEADLINES(AKA ITEMS) RETURNED. + +PROBLEM: + +You want to display the 10 (or 3) most recent headlines, but the RSS feed +contains 15. + +SOLUTION: + +$num_items = 10; +$rss = fetch_rss($url); + +$items = array_slice($rss->items, 0, $num_items); + +DISCUSSION: + +Rather then trying to limit the number of items Magpie parses, a much simpler, +and more flexible approach is to take a "slice" of the array of items. And +array_slice() is smart enough to do the right thing if the feed has less items +then $num_items. + +See: http://www.php.net/array_slice + + +2. DISPLAY A CUSTOM ERROR MESSAGE IF SOMETHING GOES WRONG + +PROBLEM: + +You don't want Magpie's error messages showing up if something goes wrong. + +SOLUTION: + +# Magpie throws USER_WARNINGS only +# so you can cloak these, by only showing ERRORs +error_reporting(E_ERROR); + +# check the return value of fetch_rss() + +$rss = fetch_rss($url); + +if ( $rss ) { +...display rss feed... +} +else { + echo "An error occured! " . + "Consider donating more $$$ for restoration of services." . + "
    Error Message: " . magpie_error(); +} + +DISCUSSION: + +MagpieRSS triggers a warning in a number of circumstances. The 2 most common +circumstances are: if the specified RSS file isn't properly formed (usually +because it includes illegal HTML), or if Magpie can't download the remote RSS +file, and there is no cached version. + +If you don't want your users to see these warnings change your error_reporting +settings to only display ERRORs. Another option is to turn off display_error, +so that WARNINGs, and NOTICEs still go to the error_log but not to the webpages. + +You can do this with: + +ini_set('display_errors', 0); + +See: http://www.php.net/error_reporting, + http://www.php.net/ini_set, + http://www.php.net/manual/en/ref.errorfunc.php + +3. GENERATE A NEW RSS FEED + +PROBLEM: + +Create an RSS feed for other people to use. + +SOLUTION: + +Use Useful Inc's RSSWriter (http://usefulinc.com/rss/rsswriter/) + +DISCUSSION: + +An example of turning a Magpie parsed RSS object back into an RSS file is forth +coming. In the meantime RSSWriter has great documentation. + +4. DISPLAY HEADLINES MORE RECENT THEN X DATE + +PROBLEM: + +You only want to display headlines that were published on, or after a certain +date. + + +SOLUTION: + +require 'rss_utils.inc'; + +# get all headlines published today +$today = getdate(); + +# today, 12AM +$date = mktime(0,0,0,$today['mon'], $today['mday'], $today['year']); + +$rss = fetch_rss($url); + +foreach ( $rss->items as $item ) { + $published = parse_w3cdtf($item['dc']['date']); + if ( $published >= $date ) { + echo "Title: " . $item['title']; + echo "Published: " . date("h:i:s A", $published); + echo "

    "; + } +} + +DISCUSSION: + +This recipe only works for RSS 1.0 feeds that include the field. +(which is very good RSS style) + +parse_w3cdtf is defined in rss_utils.inc, and parses RSS style dates into Unix +epoch seconds. + +See: http://www.php.net/manual/en/ref.datetime.php diff --git a/html/includes/rss/extlib/Snoopy.class.inc b/html/includes/rss/extlib/Snoopy.class.inc new file mode 100644 index 0000000..3ddecba --- /dev/null +++ b/html/includes/rss/extlib/Snoopy.class.inc @@ -0,0 +1,900 @@ + +Copyright (c): 1999-2000 ispi, all rights reserved +Version: 1.0 + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +You may contact the author of Snoopy by e-mail at: +monte@ispi.net + +Or, write to: +Monte Ohrt +CTO, ispi +237 S. 70th suite 220 +Lincoln, NE 68510 + +The latest version of Snoopy can be obtained from: +http://snoopy.sourceforge.com + +*************************************************/ + +class Snoopy +{ + /**** Public variables ****/ + + /* user definable vars */ + + var $host = "www.php.net"; // host name we are connecting to + var $port = 80; // port we are connecting to + var $proxy_host = ""; // proxy host to use + var $proxy_port = ""; // proxy port to use + var $agent = "Snoopy v1.0"; // agent we masquerade as + var $referer = ""; // referer info to pass + var $cookies = array(); // array of cookies to pass + // $cookies["username"]="joe"; + var $rawheaders = array(); // array of raw headers to send + // $rawheaders["Content-type"]="text/html"; + + var $maxredirs = 5; // http redirection depth maximum. 0 = disallow + var $lastredirectaddr = ""; // contains address of last redirected address + var $offsiteok = true; // allows redirection off-site + var $maxframes = 0; // frame content depth maximum. 0 = disallow + var $expandlinks = true; // expand links to fully qualified URLs. + // this only applies to fetchlinks() + // or submitlinks() + var $passcookies = true; // pass set cookies back through redirects + // NOTE: this currently does not respect + // dates, domains or paths. + + var $user = ""; // user for http authentication + var $pass = ""; // password for http authentication + + // http accept types + var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + + var $results = ""; // where the content is put + + var $error = ""; // error messages sent here + var $response_code = ""; // response code returned from server + var $headers = array(); // headers returned from server sent here + var $maxlength = 500000; // max return data length (body) + var $read_timeout = 0; // timeout on read operations, in seconds + // supported only since PHP 4 Beta 4 + // set to 0 to disallow timeouts + var $timed_out = false; // if a read operation timed out + var $status = 0; // http request status + + var $curl_path = "/usr/bin/curl"; + // Snoopy will use cURL for fetching + // SSL content if a full system path to + // the cURL binary is supplied here. + // set to false if you do not have + // cURL installed. See http://curl.haxx.se + // for details on installing cURL. + // Snoopy does *not* use the cURL + // library functions built into php, + // as these functions are not stable + // as of this Snoopy release. + + // send Accept-encoding: gzip? + var $use_gzip = true; + + /**** Private variables ****/ + + var $_maxlinelen = 4096; // max line length (headers) + + var $_httpmethod = "GET"; // default http request method + var $_httpversion = "HTTP/1.0"; // default http request version + var $_submit_method = "POST"; // default submit method + var $_submit_type = "application/x-www-form-urlencoded"; // default submit type + var $_mime_boundary = ""; // MIME boundary for multipart/form-data submit type + var $_redirectaddr = false; // will be set if page fetched is a redirect + var $_redirectdepth = 0; // increments on an http redirect + var $_frameurls = array(); // frame src urls + var $_framedepth = 0; // increments on frame depth + + var $_isproxy = false; // set if using a proxy server + var $_fp_timeout = 30; // timeout for socket connection + +/*======================================================================*\ + Function: fetch + Purpose: fetch the contents of a web page + (and possibly other protocols in the + future like ftp, nntp, gopher, etc.) + Input: $URI the location of the page to fetch + Output: $this->results the output text from the fetch +\*======================================================================*/ + + function fetch($URI) + { + + //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS); + $URI_PARTS = parse_url($URI); + if (!empty($URI_PARTS["user"])) + $this->user = $URI_PARTS["user"]; + if (!empty($URI_PARTS["pass"])) + $this->pass = $URI_PARTS["pass"]; + + switch($URI_PARTS["scheme"]) + { + case "http": + $this->host = $URI_PARTS["host"]; + if(!empty($URI_PARTS["port"])) + $this->port = $URI_PARTS["port"]; + if($this->_connect($fp)) + { + if($this->_isproxy) + { + // using proxy, send entire URI + $this->_httprequest($URI,$fp,$URI,$this->_httpmethod); + } + else + { + $path = $URI_PARTS["path"].(isset($URI_PARTS["query"]) ? "?".$URI_PARTS["query"] : ""); + // no proxy, send only the path + $this->_httprequest($path, $fp, $URI, $this->_httpmethod); + } + + $this->_disconnect($fp); + + if($this->_redirectaddr) + { + /* url was redirected, check if we've hit the max depth */ + if($this->maxredirs > $this->_redirectdepth) + { + // only follow redirect if it's on this site, or offsiteok is true + if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) + { + /* follow the redirect */ + $this->_redirectdepth++; + $this->lastredirectaddr=$this->_redirectaddr; + $this->fetch($this->_redirectaddr); + } + } + } + + if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) + { + $frameurls = $this->_frameurls; + $this->_frameurls = array(); + + while(list(,$frameurl) = each($frameurls)) + { + if($this->_framedepth < $this->maxframes) + { + $this->fetch($frameurl); + $this->_framedepth++; + } + else + break; + } + } + } + else + { + return false; + } + return true; + break; + case "https": + if(!$this->curl_path || (!is_executable($this->curl_path))) { + $this->error = "Bad curl ($this->curl_path), can't fetch HTTPS \n"; + return false; + } + $this->host = $URI_PARTS["host"]; + if(!empty($URI_PARTS["port"])) + $this->port = $URI_PARTS["port"]; + if($this->_isproxy) + { + // using proxy, send entire URI + $this->_httpsrequest($URI,$URI,$this->_httpmethod); + } + else + { + $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); + // no proxy, send only the path + $this->_httpsrequest($path, $URI, $this->_httpmethod); + } + + if($this->_redirectaddr) + { + /* url was redirected, check if we've hit the max depth */ + if($this->maxredirs > $this->_redirectdepth) + { + // only follow redirect if it's on this site, or offsiteok is true + if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) + { + /* follow the redirect */ + $this->_redirectdepth++; + $this->lastredirectaddr=$this->_redirectaddr; + $this->fetch($this->_redirectaddr); + } + } + } + + if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) + { + $frameurls = $this->_frameurls; + $this->_frameurls = array(); + + while(list(,$frameurl) = each($frameurls)) + { + if($this->_framedepth < $this->maxframes) + { + $this->fetch($frameurl); + $this->_framedepth++; + } + else + break; + } + } + return true; + break; + default: + // not a valid protocol + $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; + return false; + break; + } + return true; + } + + + +/*======================================================================*\ + Private functions +\*======================================================================*/ + + +/*======================================================================*\ + Function: _striplinks + Purpose: strip the hyperlinks from an html document + Input: $document document to strip. + Output: $match an array of the links +\*======================================================================*/ + + function _striplinks($document) + { + preg_match_all("'<\s*a\s+.*href\s*=\s* # find ]+)) # if quote found, match up to next matching + # quote, otherwise match up to next space + 'isx",$document,$links); + + + // catenate the non-empty matches from the conditional subpattern + + while(list($key,$val) = each($links[2])) + { + if(!empty($val)) + $match[] = $val; + } + + while(list($key,$val) = each($links[3])) + { + if(!empty($val)) + $match[] = $val; + } + + // return the links + return $match; + } + +/*======================================================================*\ + Function: _stripform + Purpose: strip the form elements from an html document + Input: $document document to strip. + Output: $match an array of the links +\*======================================================================*/ + + function _stripform($document) + { + preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements); + + // catenate the matches + $match = implode("\r\n",$elements[0]); + + // return the links + return $match; + } + + + +/*======================================================================*\ + Function: _striptext + Purpose: strip the text from an html document + Input: $document document to strip. + Output: $text the resulting text +\*======================================================================*/ + + function _striptext($document) + { + + // I didn't use preg eval (//e) since that is only available in PHP 4.0. + // so, list your entities one by one here. I included some of the + // more common ones. + + $search = array("']*?>.*?'si", // strip out javascript + "'<[\/\!]*?[^<>]*?>'si", // strip out html tags + "'([\r\n])[\s]+'", // strip out white space + "'&(quote|#34);'i", // replace html entities + "'&(amp|#38);'i", + "'&(lt|#60);'i", + "'&(gt|#62);'i", + "'&(nbsp|#160);'i", + "'&(iexcl|#161);'i", + "'&(cent|#162);'i", + "'&(pound|#163);'i", + "'&(copy|#169);'i" + ); + $replace = array( "", + "", + "\\1", + "\"", + "&", + "<", + ">", + " ", + chr(161), + chr(162), + chr(163), + chr(169)); + + $text = preg_replace($search,$replace,$document); + + return $text; + } + +/*======================================================================*\ + Function: _expandlinks + Purpose: expand each link into a fully qualified URL + Input: $links the links to qualify + $URI the full URI to get the base from + Output: $expandedLinks the expanded links +\*======================================================================*/ + + function _expandlinks($links,$URI) + { + + preg_match("/^[^\?]+/",$URI,$match); + + $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]); + + $search = array( "|^http://".preg_quote($this->host)."|i", + "|^(?!http://)(\/)?(?!mailto:)|i", + "|/\./|", + "|/[^\/]+/\.\./|" + ); + + $replace = array( "", + $match."/", + "/", + "/" + ); + + $expandedLinks = preg_replace($search,$replace,$links); + + return $expandedLinks; + } + +/*======================================================================*\ + Function: _httprequest + Purpose: go get the http data from the server + Input: $url the url to fetch + $fp the current open file pointer + $URI the full URI + $body body contents to send if any (POST) + Output: +\*======================================================================*/ + + function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="") + { + if($this->passcookies && $this->_redirectaddr) + $this->setcookies(); + + $URI_PARTS = parse_url($URI); + if(empty($url)) + $url = "/"; + $headers = $http_method." ".$url." ".$this->_httpversion."\r\n"; + if(!empty($this->agent)) + $headers .= "User-Agent: ".$this->agent."\r\n"; + if(!empty($this->host) && !isset($this->rawheaders['Host'])) + $headers .= "Host: ".$this->host."\r\n"; + if(!empty($this->accept)) + $headers .= "Accept: ".$this->accept."\r\n"; + + if($this->use_gzip) { + // make sure PHP was built with --with-zlib + // and we can handle gzipp'ed data + if ( function_exists(gzinflate) ) { + $headers .= "Accept-encoding: gzip\r\n"; + } + else { + trigger_error( + "use_gzip is on, but PHP was built without zlib support.". + " Requesting file(s) without gzip encoding.", + E_USER_NOTICE); + } + } + + if(!empty($this->referer)) + $headers .= "Referer: ".$this->referer."\r\n"; + if(!empty($this->cookies)) + { + if(!is_array($this->cookies)) + $this->cookies = (array)$this->cookies; + + reset($this->cookies); + if ( count($this->cookies) > 0 ) { + $cookie_headers .= 'Cookie: '; + foreach ( $this->cookies as $cookieKey => $cookieVal ) { + $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; "; + } + $headers .= substr($cookie_headers,0,-2) . "\r\n"; + } + } + if(!empty($this->rawheaders)) + { + if(!is_array($this->rawheaders)) + $this->rawheaders = (array)$this->rawheaders; + while(list($headerKey,$headerVal) = each($this->rawheaders)) + $headers .= $headerKey.": ".$headerVal."\r\n"; + } + if(!empty($content_type)) { + $headers .= "Content-type: $content_type"; + if ($content_type == "multipart/form-data") + $headers .= "; boundary=".$this->_mime_boundary; + $headers .= "\r\n"; + } + if(!empty($body)) + $headers .= "Content-length: ".strlen($body)."\r\n"; + if(!empty($this->user) || !empty($this->pass)) + $headers .= "Authorization: BASIC ".base64_encode($this->user.":".$this->pass)."\r\n"; + + $headers .= "\r\n"; + + // set the read timeout if needed + if ($this->read_timeout > 0) + socket_set_timeout($fp, $this->read_timeout); + $this->timed_out = false; + + fwrite($fp,$headers.$body,strlen($headers.$body)); + + $this->_redirectaddr = false; + unset($this->headers); + + // content was returned gzip encoded? + $is_gzipped = false; + + while($currentHeader = fgets($fp,$this->_maxlinelen)) + { + if ($this->read_timeout > 0 && $this->_check_timeout($fp)) + { + $this->status=-100; + return false; + } + + // if($currentHeader == "\r\n") + if(preg_match("/^\r?\n$/", $currentHeader) ) + break; + + // if a header begins with Location: or URI:, set the redirect + if(preg_match("/^(Location:|URI:)/i",$currentHeader)) + { + // get URL portion of the redirect + preg_match("/^(Location:|URI:)\s+(.*)/",chop($currentHeader),$matches); + // look for :// in the Location header to see if hostname is included + if(!preg_match("|\:\/\/|",$matches[2])) + { + // no host in the path, so prepend + $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port; + // eliminate double slash + if(!preg_match("|^/|",$matches[2])) + $this->_redirectaddr .= "/".$matches[2]; + else + $this->_redirectaddr .= $matches[2]; + } + else + $this->_redirectaddr = $matches[2]; + } + + if(preg_match("|^HTTP/|",$currentHeader)) + { + if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status)) + { + $this->status= $status[1]; + } + $this->response_code = $currentHeader; + } + + if (preg_match("/Content-Encoding: gzip/", $currentHeader) ) { + $is_gzipped = true; + } + + $this->headers[] = $currentHeader; + } + + # $results = fread($fp, $this->maxlength); + $results = ""; + while ( $data = fread($fp, $this->maxlength) ) { + $results .= $data; + if ( + strlen($results) > $this->maxlength ) { + break; + } + } + + // gunzip + if ( $is_gzipped ) { + // per http://www.php.net/manual/en/function.gzencode.php + $results = substr($results, 10); + $results = gzinflate($results); + } + + if ($this->read_timeout > 0 && $this->_check_timeout($fp)) + { + $this->status=-100; + return false; + } + + // check if there is a a redirect meta tag + + if(preg_match("']*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) + { + $this->_redirectaddr = $this->_expandlinks($match[1],$URI); + } + + // have we hit our frame depth and is there frame src to fetch? + if(($this->_framedepth < $this->maxframes) && preg_match_all("']+)'i",$results,$match)) + { + $this->results[] = $results; + for($x=0; $x_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host); + } + // have we already fetched framed content? + elseif(is_array($this->results)) + $this->results[] = $results; + // no framed content + else + $this->results = $results; + + return true; + } + +/*======================================================================*\ + Function: _httpsrequest + Purpose: go get the https data from the server using curl + Input: $url the url to fetch + $URI the full URI + $body body contents to send if any (POST) + Output: +\*======================================================================*/ + + function _httpsrequest($url,$URI,$http_method,$content_type="",$body="") + { + if($this->passcookies && $this->_redirectaddr) + $this->setcookies(); + + $headers = array(); + + $URI_PARTS = parse_url($URI); + if(empty($url)) + $url = "/"; + // GET ... header not needed for curl + //$headers[] = $http_method." ".$url." ".$this->_httpversion; + if(!empty($this->agent)) + $headers[] = "User-Agent: ".$this->agent; + if(!empty($this->host)) + $headers[] = "Host: ".$this->host; + if(!empty($this->accept)) + $headers[] = "Accept: ".$this->accept; + if(!empty($this->referer)) + $headers[] = "Referer: ".$this->referer; + if(!empty($this->cookies)) + { + if(!is_array($this->cookies)) + $this->cookies = (array)$this->cookies; + + reset($this->cookies); + if ( count($this->cookies) > 0 ) { + $cookie_str = 'Cookie: '; + foreach ( $this->cookies as $cookieKey => $cookieVal ) { + $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; "; + } + $headers[] = substr($cookie_str,0,-2); + } + } + if(!empty($this->rawheaders)) + { + if(!is_array($this->rawheaders)) + $this->rawheaders = (array)$this->rawheaders; + while(list($headerKey,$headerVal) = each($this->rawheaders)) + $headers[] = $headerKey.": ".$headerVal; + } + if(!empty($content_type)) { + if ($content_type == "multipart/form-data") + $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary; + else + $headers[] = "Content-type: $content_type"; + } + if(!empty($body)) + $headers[] = "Content-length: ".strlen($body); + if(!empty($this->user) || !empty($this->pass)) + $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass); + + for($curr_header = 0; $curr_header < count($headers); $curr_header++) { + $cmdline_params .= " -H \"".$headers[$curr_header]."\""; + } + + if(!empty($body)) + $cmdline_params .= " -d \"$body\""; + + if($this->read_timeout > 0) + $cmdline_params .= " -m ".$this->read_timeout; + + $headerfile = uniqid(time()); + + # accept self-signed certs + $cmdline_params .= " -k"; + exec($this->curl_path." -D \"/tmp/$headerfile\"".escapeshellcmd($cmdline_params)." ".escapeshellcmd($URI),$results,$return); + + if($return) + { + $this->error = "Error: cURL could not retrieve the document, error $return."; + return false; + } + + + $results = implode("\r\n",$results); + + $result_headers = file("/tmp/$headerfile"); + + $this->_redirectaddr = false; + unset($this->headers); + + for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++) + { + + // if a header begins with Location: or URI:, set the redirect + if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader])) + { + // get URL portion of the redirect + preg_match("/^(Location: |URI:)(.*)/",chop($result_headers[$currentHeader]),$matches); + // look for :// in the Location header to see if hostname is included + if(!preg_match("|\:\/\/|",$matches[2])) + { + // no host in the path, so prepend + $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port; + // eliminate double slash + if(!preg_match("|^/|",$matches[2])) + $this->_redirectaddr .= "/".$matches[2]; + else + $this->_redirectaddr .= $matches[2]; + } + else + $this->_redirectaddr = $matches[2]; + } + + if(preg_match("|^HTTP/|",$result_headers[$currentHeader])) + { + $this->response_code = $result_headers[$currentHeader]; + if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$this->response_code, $match)) + { + $this->status= $match[1]; + } + } + $this->headers[] = $result_headers[$currentHeader]; + } + + // check if there is a a redirect meta tag + + if(preg_match("']*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) + { + $this->_redirectaddr = $this->_expandlinks($match[1],$URI); + } + + // have we hit our frame depth and is there frame src to fetch? + if(($this->_framedepth < $this->maxframes) && preg_match_all("']+)'i",$results,$match)) + { + $this->results[] = $results; + for($x=0; $x_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host); + } + // have we already fetched framed content? + elseif(is_array($this->results)) + $this->results[] = $results; + // no framed content + else + $this->results = $results; + + unlink("/tmp/$headerfile"); + + return true; + } + +/*======================================================================*\ + Function: setcookies() + Purpose: set cookies for a redirection +\*======================================================================*/ + + function setcookies() + { + for($x=0; $xheaders); $x++) + { + if(preg_match("/^set-cookie:[\s]+([^=]+)=([^;]+)/i", $this->headers[$x],$match)) + $this->cookies[$match[1]] = $match[2]; + } + } + + +/*======================================================================*\ + Function: _check_timeout + Purpose: checks whether timeout has occurred + Input: $fp file pointer +\*======================================================================*/ + + function _check_timeout($fp) + { + if ($this->read_timeout > 0) { + $fp_status = socket_get_status($fp); + if ($fp_status["timed_out"]) { + $this->timed_out = true; + return true; + } + } + return false; + } + +/*======================================================================*\ + Function: _connect + Purpose: make a socket connection + Input: $fp file pointer +\*======================================================================*/ + + function _connect(&$fp) + { + if(!empty($this->proxy_host) && !empty($this->proxy_port)) + { + $this->_isproxy = true; + $host = $this->proxy_host; + $port = $this->proxy_port; + } + else + { + $host = $this->host; + $port = $this->port; + } + + $this->status = 0; + + if($fp = fsockopen( + $host, + $port, + $errno, + $errstr, + $this->_fp_timeout + )) + { + // socket connection succeeded + + return true; + } + else + { + // socket connection failed + $this->status = $errno; + switch($errno) + { + case -3: + $this->error="socket creation failed (-3)"; + case -4: + $this->error="dns lookup failure (-4)"; + case -5: + $this->error="connection refused or timed out (-5)"; + default: + $this->error="connection failed (".$errno.")"; + } + return false; + } + } +/*======================================================================*\ + Function: _disconnect + Purpose: disconnect a socket connection + Input: $fp file pointer +\*======================================================================*/ + + function _disconnect($fp) + { + return(fclose($fp)); + } + + +/*======================================================================*\ + Function: _prepare_post_body + Purpose: Prepare post body according to encoding type + Input: $formvars - form variables + $formfiles - form upload files + Output: post body +\*======================================================================*/ + + function _prepare_post_body($formvars, $formfiles) + { + settype($formvars, "array"); + settype($formfiles, "array"); + + if (count($formvars) == 0 && count($formfiles) == 0) + return; + + switch ($this->_submit_type) { + case "application/x-www-form-urlencoded": + reset($formvars); + while(list($key,$val) = each($formvars)) { + if (is_array($val) || is_object($val)) { + while (list($cur_key, $cur_val) = each($val)) { + $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&"; + } + } else + $postdata .= urlencode($key)."=".urlencode($val)."&"; + } + break; + + case "multipart/form-data": + $this->_mime_boundary = "Snoopy".md5(uniqid(microtime())); + + reset($formvars); + while(list($key,$val) = each($formvars)) { + if (is_array($val) || is_object($val)) { + while (list($cur_key, $cur_val) = each($val)) { + $postdata .= "--".$this->_mime_boundary."\r\n"; + $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n"; + $postdata .= "$cur_val\r\n"; + } + } else { + $postdata .= "--".$this->_mime_boundary."\r\n"; + $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n"; + $postdata .= "$val\r\n"; + } + } + + reset($formfiles); + while (list($field_name, $file_names) = each($formfiles)) { + settype($file_names, "array"); + while (list(, $file_name) = each($file_names)) { + if (!is_readable($file_name)) continue; + + $fp = fopen($file_name, "r"); + $file_content = fread($fp, filesize($file_name)); + fclose($fp); + $base_name = basename($file_name); + + $postdata .= "--".$this->_mime_boundary."\r\n"; + $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n"; + $postdata .= "$file_content\r\n"; + } + } + $postdata .= "--".$this->_mime_boundary."--\r\n"; + break; + } + + return $postdata; + } +} + +?> diff --git a/html/includes/rss/htdocs/cookbook.html b/html/includes/rss/htdocs/cookbook.html new file mode 100644 index 0000000..2a18e74 --- /dev/null +++ b/html/includes/rss/htdocs/cookbook.html @@ -0,0 +1,237 @@ + + + Magie RSS Recipes: Simple PHP RSS How To + + + +

    +

    MagpieRSS Recipes: Cooking with Corbies

    + +

    "Four and twenty blackbirds baked in a +pie."

    +

    +

    +

      +
    1. Limit the Number of Headlines(aka Items) Returned
    2. +
    3. Display a Custom Error Message if Something Goes +Wrong
    4. +
    5. Generate a New RSS Feed
    6. +
    7. Display Headlines More Recent then X Date
    8. +
    9. Parse a Local File Containing RSS
    10. + +
    +

    + +

    1. Limit the Number of Headlines(aka Items) Returned.

    + +

    Problem:

    + +You want to display the 10 (or 3 or whatever) most recent headlines, but the RSS feed +contains 15. + +

    Solution:

    + +
    +$num_items = 10;
    +$rss = fetch_rss($url);
    +
    +$items = array_slice($rss->items, 0, $num_items);
    +
    +foreach ( $items as $item ) {
    +
    +

    Discussion:

    + +Rather then trying to limit the number of items Magpie parses, a much simpler, +and more flexible approach is to take a "slice" of the array of items. And +array_slice() is smart enough to do the right thing if the feed has less items +then $num_items. + +

    See:

    http://www.php.net/array_slice +

    + +

    2. Display a Custom Error Message if Something Goes Wrong

    + +

    Problem:

    + +You don't want Magpie's error messages showing up if something goes wrong. + +

    Solution:

    +
    +# Magpie throws USER_WARNINGS only
    +# so you can cloak these, by only showing ERRORs
    +error_reporting(E_ERROR);
    +
    +# check the return value of fetch_rss()
    +
    +$rss = fetch_rss($url);
    +
    +if ( $rss ) {
    +...display rss feed...
    +}
    +else {
    +   echo "An error occured!  " .
    +        "Consider donating more $$$ for restoration of services." .
    +        "<br>Error Message: " . magpie_error();
    +}
    +
    +

    Discussion:

    + +MagpieRSS triggers a warning in a number of circumstances. The 2 most common +circumstances are: if the specified RSS file isn't properly formed (usually +because it includes illegal HTML), or if Magpie can't download the remote RSS +file, and there is no cached version. + +If you don't want your users to see these warnings change your error_reporting +settings to only display ERRORs.
    +Another option is to turn off display_error, +so that WARNINGs, and NOTICEs still go to the error_log but not to the webpages. + +You can do this with: + +
    +# you can also do this in your php.ini file
    +ini_set('display_errors', 0);
    +
    + +

    See:

    +http://www.php.net/error_reporting,
    +http://www.php.net/ini_set,
    +http://www.php.net/manual/en/ref.errorfunc.php
    + +

    3. Generate a New RSS Feed

    + +

    Problem:

    + +Create an RSS feed for other people to use. + +

    Solution:

    + +Use Useful Inc's RSSWriter. + +

    Discussion:

    + +An example of turning a Magpie parsed RSS object back into an RSS file is +forthcoming. In the meantime RSSWriter is well documented. + +

    4. Display Headlines More Recent then X Date

    + +

    Problem:

    + +You only want to display headlines that were published on, or after a certain +date. + + +

    Solution:

    +
    +require_once('rss_utils.inc');
    +
    +# get all headlines published today
    +$today = getdate();
    +
    +# today, 12AM
    +$date = mktime(0,0,0,$today['mon'], $today['mday'], $today['year']);
    +
    +$rss = fetch_rss($url);
    +
    +foreach ( $rss->items as $item ) {
    +   $published = parse_w3cdtf($item['dc']['date']);
    +   if ( $published >= $date ) {
    +        echo "Title: " . $item['title'];
    +        echo "Published: " . date("h:i:s A", $published);
    +        echo "<p>";
    +    }
    +}
    +
    +

    Discussion:

    + +This recipe only works for RSS 1.0 feeds that include the field. +(which is very good RSS style)
    +parse_w3cdtf() is defined in +rss_utils.inc, and parses RSS style dates into Unix epoch +seconds. + +

    See:

    +http://www.php.net/manual/en/ref.datetime.php + + +

    5. Parse a Local File Containing RSS

    +

    Problem:

    +MagpieRSS provides fetch_rss() which takes a URL and returns a +parsed RSS object, but what if you want to parse a file stored locally that +doesn't have a URL? + +

    Solution

    +
    +require_once('rss_parse.inc');
    +
    +$rss_file = 'some_rss_file.rdf';
    +$rss_string = read_file($rss_file);
    +$rss = new MagpieRSS( $rss_string );
    +
    +if ( $rss and !$rss->ERROR) {
    +...display rss...
    +}
    +else {
    +    echo "Error: " . $rss->ERROR;
    +}
    +
    +# efficiently read a file into a string
    +# in php >= 4.3.0 you can simply use file_get_contents()
    +#
    +function read_file($filename) {
    +    $fh = fopen($filename, 'r') or die($php_errormsg);
    +    $rss_string = fread($fh, filesize($filename) );
    +    fclose($fh);
    +    return $rss_string;
    +}
    +
    + +

    Discussion

    +Here we are using MagpieRSS's RSS parser directly without the convience wrapper +of fetch_rss(). We read the contents of the RSS file into a +string, and pass it to the parser constructor. Notice also that error handling +is subtly different. + +

    See:

    +http://www.php.net/manual/en/ref.filesystem.php,
    +http://www.php.net/manual/en/language.oop.php + + + + + diff --git a/html/includes/rss/htdocs/index.html b/html/includes/rss/htdocs/index.html new file mode 100644 index 0000000..e6b24b5 --- /dev/null +++ b/html/includes/rss/htdocs/index.html @@ -0,0 +1,419 @@ + + + Magpie RSS - PHP RSS Parser + + + + + +

    MagpieRSS

    +

    +

    MagpieRSS provides an XML-based (expat) RSS parser in PHP.

    +

    + MagpieRSS is compatible with RSS .9 through RSS 1.0, and supports the + RSS 1.0's modules. (with a few exceptions) +

    +

    + +

    News!

    + +

    +

    + +

    Why?

    + I wrote MagpieRSS out of a frustration with the limitations of existing + solutions. In particular many of the existing PHP solutions seemed to: +
      +
    • use a parser based on regular expressions, making for an inherently + fragile solution +
    • only support early versions of RSS +
    • discard all the interesting information besides item title, description, + and link. +
    • not build proper separation between parsing the RSS and displaying it. +
    + In particular I failed to find any PHP RSS parsers that could sufficiently + parse RSS 1.0 feeds, to be useful on the RSS based event feeds we generate + at Protest.net. +

    +

    + +

    Features

    + +
      +
    • +

      Easy to Use

      + As simple as: +
      +require('rss_fetch.inc');
      +$rss = fetch_rss($url);
      +
      + +
    • +
    • +

      Parses RSS 0.9 - RSS 1.0

      + + Parses most RSS formats, including support for + 1.0 modules and limited + namespace support. RSS is packed into convenient data structures; easy to + use in PHP, and appropriate for passing to a templating system, like + Smarty. +
    • +
    • +

      Integrated Object Cache

      + + Caching the parsed RSS means that the 2nd request is fast, and that +including the rss_fetch call in your PHP page won't destroy your performance, +and force you to reply on an external cron job. And it happens transparently. + +
    • +
    • +

      HTTP Conditional GETs

      + + Save bandwidth and speed up download times with intelligent use of + Last-Modified and ETag.
      See HTTP Conditional Get for RSS Hackers +
    • + +
    • Configurable

      + + Makes extensive use of constants to allow overriding default behaviour, and + installation on shared hosts. +
    • +
    • Modular

      +
        +
      • rss_fetch.inc - wraps a simple interface (fetch_rss()) + around the library. +
      • rss_parse.inc - provides the RSS parser, and the RSS object +
      • rss_cache.inc - a simple (no GC) object cache, optimized for RSS objects +
      • rss_utils.inc - utility functions for working with RSS. currently + provides parse_w3cdtf(), for parsing W3CDTF into epoch seconds. +
      +
    + + +

    +

    + +

    Magpie's approach to parsing RSS

    + + Magpie takes a naive, and inclusive approach. Absolutely + non-validating, as long as the RSS feed is well formed, Magpie will + cheerfully parse new, and never before seen tags in your RSS feeds. +

    +

    + This makes it very simple support the varied versions of RSS simply, but + forces the consumer of a RSS feed to be cognizant of how it is + structured.(at least if you want to do something fancy) +

    +

    + Magpie parses a RSS feed into a simple object, with 4 fields: + channel, items, image, and + textinput. +

    +

    +

    channel

    + $rss->channel contains key-value pairs of all tags, without + nested tags, found between the root tag (<rdf:RDF>, or <rss>) + and the end of the document. +

    +

    +

    items

    + $rss->items is an array of associative arrays, each one + describing a single item. An example that looks like: +
    +<item rdf:about="http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257">
    +<title>Weekly Peace Vigil</title>
    +<link>http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257</link>
    +<description>Wear a white ribbon</description>
    +<dc:subject>Peace</dc:subject>
    +<ev:startdate>2002-06-01T11:00:00</ev:startdate>
    +<ev:location>Northampton, MA</ev:location>
    +<ev:enddate>2002-06-01T12:00:00</ev:enddate>
    +<ev:type>Protest</ev:type>
    +</item>
    +	

    + Is parsed, and pushed on the $rss->items array as: +

    +array(
    +	title => 'Weekly Peace Vigil',
    +	link => 'http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257',
    +	description => 'Wear a white ribbon',
    +	dc => array (
    +			subject => 'Peace'
    +		),
    +	ev => array (
    +		startdate => '2002-06-01T11:00:00',
    +		enddate => '2002-06-01T12:00:00',
    +		type => 'Protest',
    +		location => 'Northampton, MA'
    +	)
    +);
    +
    +

    +

    +

    image and textinput

    +$rss->image and $rss-textinput are associative arrays +including name-value pairs for anything found between the respective parent +tags. +

    +

    + +

    Usage Examples:

    + +A very simple example would be: +
    +require_once 'rss_fetch.inc';
    +
    +$url = 'http://magpie.sf.net/samples/imc.1-0.rdf';
    +$rss = fetch_rss($url);
    +
    +echo "Site: ", $rss->channel['title'], "<br>\n";
    +foreach ($rss->items as $item ) {
    +	$title = $item[title];
    +	$url   = $item[link];
    +	echo "<a href=$url>$title</a></li><br>\n";
    +}
    +
    +More soon....in the meantime you can check out a +cool tool built with +MagpieRSS, version 0.1. +

    +

    + +

    Todos

    +

    RSS Parser

    +
      +
    • Swap in a smarter parser that includes optional + support for validation, and required fields.
    • + +
    • Support RSS 2.0 (as much as I'm annoyed by it)
    • + +
    • Improve support for modules that rely on attributes
    • +
    + +

    RSS Cache

    +
      +
    • Light-weight garbage collection +
    + +

    Fetch RSS

    + +

    Misc

    +
      +
    • More examples
    • +
    • A test suite
    • +
    • RSS generation, perhaps with RSSwriter? +
    • +
    + +

    +

    +

    RSS Resources

    + . +

    +

    License and Contact Info

    +Magpie is distributed under the GPL license... +

    +coded by: kellan (at) protest.net, feedback is always appreciated. +

    +SourceForge.net Logo + + + diff --git a/html/includes/rss/rss_cache.inc b/html/includes/rss/rss_cache.inc new file mode 100644 index 0000000..b8d436c --- /dev/null +++ b/html/includes/rss/rss_cache.inc @@ -0,0 +1,200 @@ + + * Version: 0.51 + * License: GPL + * + * The lastest version of MagpieRSS can be obtained from: + * http://magpierss.sourceforge.net + * + * For questions, help, comments, discussion, etc., please join the + * Magpie mailing list: + * http://lists.sourceforge.net/lists/listinfo/magpierss-general + * + */ + +class RSSCache { + var $BASE_CACHE = './cache'; // where the cache files are stored + var $MAX_AGE = 3600; // when are files stale, default one hour + var $ERROR = ""; // accumulate error messages + + function RSSCache ($base='', $age='') { + if ( $base ) { + $this->BASE_CACHE = $base; + } + if ( $age ) { + $this->MAX_AGE = $age; + } + + // attempt to make the cache directory + if ( ! file_exists( $this->BASE_CACHE ) ) { + $status = @mkdir( $this->BASE_CACHE, 0755 ); + + // if make failed + if ( ! $status ) { + $this->error( + "Cache couldn't make dir '" . $this->BASE_CACHE . "'." + ); + } + } + } + +/*=======================================================================*\ + Function: set + Purpose: add an item to the cache, keyed on url + Input: url from wich the rss file was fetched + Output: true on sucess +\*=======================================================================*/ + function set ($url, $rss) { + $this->ERROR = ""; + $cache_file = $this->file_name( $url ); + $fp = @fopen( $cache_file, 'w' ); + + if ( ! $fp ) { + $this->error( + "Cache unable to open file for writing: $cache_file" + ); + return 0; + } + + + $data = $this->serialize( $rss ); + fwrite( $fp, $data ); + fclose( $fp ); + + return $cache_file; + } + +/*=======================================================================*\ + Function: get + Purpose: fetch an item from the cache + Input: url from wich the rss file was fetched + Output: cached object on HIT, false on MISS +\*=======================================================================*/ + function get ($url) { + $this->ERROR = ""; + $cache_file = $this->file_name( $url ); + + if ( ! file_exists( $cache_file ) ) { + $this->debug( + "Cache doesn't contain: $url (cache file: $cache_file)" + ); + return 0; + } + + $fp = @fopen($cache_file, 'r'); + if ( ! $fp ) { + $this->error( + "Failed to open cache file for reading: $cache_file" + ); + return 0; + } + + if ($filesize = filesize($cache_file) ) { + $data = fread( $fp, filesize($cache_file) ); + $rss = $this->unserialize( $data ); + + return $rss; + } + + return 0; + } + +/*=======================================================================*\ + Function: check_cache + Purpose: check a url for membership in the cache + and whether the object is older then MAX_AGE (ie. STALE) + Input: url from wich the rss file was fetched + Output: cached object on HIT, false on MISS +\*=======================================================================*/ + function check_cache ( $url ) { + $this->ERROR = ""; + $filename = $this->file_name( $url ); + + if ( file_exists( $filename ) ) { + // find how long ago the file was added to the cache + // and whether that is longer then MAX_AGE + $mtime = filemtime( $filename ); + $age = time() - $mtime; + if ( $this->MAX_AGE > $age ) { + // object exists and is current + return 'HIT'; + } + else { + // object exists but is old + return 'STALE'; + } + } + else { + // object does not exist + return 'MISS'; + } + } + + function cache_age( $cache_key ) { + $filename = $this->file_name( $url ); + if ( file_exists( $filename ) ) { + $mtime = filemtime( $filename ); + $age = time() - $mtime; + return $age; + } + else { + return -1; + } + } + +/*=======================================================================*\ + Function: serialize +\*=======================================================================*/ + function serialize ( $rss ) { + return serialize( $rss ); + } + +/*=======================================================================*\ + Function: unserialize +\*=======================================================================*/ + function unserialize ( $data ) { + return unserialize( $data ); + } + +/*=======================================================================*\ + Function: file_name + Purpose: map url to location in cache + Input: url from wich the rss file was fetched + Output: a file name +\*=======================================================================*/ + function file_name ($url) { + $filename = md5( $url ); + return join( DIRECTORY_SEPARATOR, array( $this->BASE_CACHE, $filename ) ); + } + +/*=======================================================================*\ + Function: error + Purpose: register error +\*=======================================================================*/ + function error ($errormsg, $lvl=E_USER_WARNING) { + // append PHP's error message if track_errors enabled + if ( isset($php_errormsg) ) { + $errormsg .= " ($php_errormsg)"; + } + $this->ERROR = $errormsg; + if ( MAGPIE_DEBUG ) { + trigger_error( $errormsg, $lvl); + } + else { + error_log( $errormsg, 0); + } + } + + function debug ($debugmsg, $lvl=E_USER_NOTICE) { + if ( MAGPIE_DEBUG ) { + $this->error("MagpieRSS [debug] $debugmsg", $lvl); + } + } + +} + +?> diff --git a/html/includes/rss/rss_fetch.inc b/html/includes/rss/rss_fetch.inc new file mode 100644 index 0000000..f2fa2fa --- /dev/null +++ b/html/includes/rss/rss_fetch.inc @@ -0,0 +1,458 @@ + + * License: GPL + * + * The lastest version of MagpieRSS can be obtained from: + * http://magpierss.sourceforge.net + * + * For questions, help, comments, discussion, etc., please join the + * Magpie mailing list: + * magpierss-general@lists.sourceforge.net + * + */ + +// Setup MAGPIE_DIR for use on hosts that don't include +// the current path in include_path. +// with thanks to rajiv and smarty +if (!defined('DIR_SEP')) { + define('DIR_SEP', DIRECTORY_SEPARATOR); +} + +if (!defined('MAGPIE_DIR')) { + define('MAGPIE_DIR', dirname(__FILE__) . DIR_SEP); +} + +require_once( MAGPIE_DIR . 'rss_parse.inc' ); +require_once( MAGPIE_DIR . 'rss_cache.inc' ); + +// for including 3rd party libraries +define('MAGPIE_EXTLIB', MAGPIE_DIR . 'extlib' . DIR_SEP); +require_once( MAGPIE_EXTLIB . 'Snoopy.class.inc'); + + +/* + * CONSTANTS - redefine these in your script to change the + * behaviour of fetch_rss() currently, most options effect the cache + * + * MAGPIE_CACHE_ON - Should Magpie cache parsed RSS objects? + * For me a built in cache was essential to creating a "PHP-like" + * feel to Magpie, see rss_cache.inc for rationale + * + * + * MAGPIE_CACHE_DIR - Where should Magpie cache parsed RSS objects? + * This should be a location that the webserver can write to. If this + * directory does not already exist Mapie will try to be smart and create + * it. This will often fail for permissions reasons. + * + * + * MAGPIE_CACHE_AGE - How long to store cached RSS objects? In seconds. + * + * + * MAGPIE_CACHE_FRESH_ONLY - If remote fetch fails, throw error + * instead of returning stale object? + * + * MAGPIE_DEBUG - Display debugging notices? + * +*/ + + +/*=======================================================================*\ + Function: fetch_rss: + Purpose: return RSS object for the give url + maintain the cache + Input: url of RSS file + Output: parsed RSS object (see rss_parse.inc) + + NOTES ON CACHEING: + If caching is on (MAGPIE_CACHE_ON) fetch_rss will first check the cache. + + NOTES ON RETRIEVING REMOTE FILES: + If conditional gets are on (MAGPIE_CONDITIONAL_GET_ON) fetch_rss will + return a cached object, and touch the cache object upon recieving a + 304. + + NOTES ON FAILED REQUESTS: + If there is an HTTP error while fetching an RSS object, the cached + version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off) +\*=======================================================================*/ + +define('MAGPIE_VERSION', '0.72'); + +$MAGPIE_ERROR = ""; + +function fetch_rss ($url) { + // initialize constants + init(); + + if ( !isset($url) ) { + error("fetch_rss called without a url"); + return false; + } + + // if cache is disabled + if ( !MAGPIE_CACHE_ON ) { + // fetch file, and parse it + $resp = _fetch_remote_file( $url ); + if ( is_success( $resp->status ) ) { + return _response_to_rss( $resp ); + } + else { + error("Failed to fetch $url and cache is off"); + return false; + } + } + // else cache is ON + else { + // Flow + // 1. check cache + // 2. if there is a hit, make sure its fresh + // 3. if cached obj fails freshness check, fetch remote + // 4. if remote fails, return stale object, or error + + $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE ); + + if (MAGPIE_DEBUG and $cache->ERROR) { + debug($cache->ERROR, E_USER_WARNING); + } + + + $cache_status = 0; // response of check_cache + $request_headers = array(); // HTTP headers to send with fetch + $rss = 0; // parsed RSS object + $errormsg = 0; // errors, if any + + // store parsed XML by desired output encoding + // as character munging happens at parse time + $cache_key = $url . MAGPIE_OUTPUT_ENCODING; + + if (!$cache->ERROR) { + // return cache HIT, MISS, or STALE + $cache_status = $cache->check_cache( $cache_key); + } + + // if object cached, and cache is fresh, return cached obj + if ( $cache_status == 'HIT' ) { + $rss = $cache->get( $cache_key ); + if ( isset($rss) and $rss ) { + // should be cache age + $rss->from_cache = 1; + if ( MAGPIE_DEBUG > 1) { + debug("MagpieRSS: Cache HIT", E_USER_NOTICE); + } + return $rss; + } + } + + // else attempt a conditional get + + // setup headers + if ( $cache_status == 'STALE' ) { + $rss = $cache->get( $cache_key ); + if ( $rss and $rss->etag and $rss->last_modified ) { + $request_headers['If-None-Match'] = $rss->etag; + $request_headers['If-Last-Modified'] = $rss->last_modified; + } + } + + $resp = _fetch_remote_file( $url, $request_headers ); + + if (isset($resp) and $resp) { + if ($resp->status == '304' ) { + // we have the most current copy + if ( MAGPIE_DEBUG > 1) { + debug("Got 304 for $url"); + } + // reset cache on 304 (at minutillo insistent prodding) + $cache->set($cache_key, $rss); + return $rss; + } + elseif ( is_success( $resp->status ) ) { + $rss = _response_to_rss( $resp ); + if ( $rss ) { + if (MAGPIE_DEBUG > 1) { + debug("Fetch successful"); + } + // add object to cache + $cache->set( $cache_key, $rss ); + return $rss; + } + } + else { + $errormsg = "Failed to fetch $url "; + if ( $resp->status == '-100' ) { + $errormsg .= "(Request timed out after " . MAGPIE_FETCH_TIME_OUT . " seconds)"; + } + elseif ( $resp->error ) { + # compensate for Snoopy's annoying habbit to tacking + # on '\n' + $http_error = substr($resp->error, 0, -2); + $errormsg .= "(HTTP Error: $http_error)"; + } + else { + $errormsg .= "(HTTP Response: " . $resp->response_code .')'; + } + } + } + else { + $errormsg = "Unable to retrieve RSS file for unknown reasons."; + } + + // else fetch failed + + // attempt to return cached object + if ($rss) { + if ( MAGPIE_DEBUG ) { + debug("Returning STALE object for $url"); + } + return $rss; + } + + // else we totally failed + error( $errormsg ); + + return false; + + } // end if ( !MAGPIE_CACHE_ON ) { +} // end fetch_rss() + +/*=======================================================================*\ + Function: error + Purpose: set MAGPIE_ERROR, and trigger error +\*=======================================================================*/ + +function error ($errormsg, $lvl=E_USER_WARNING) { + global $MAGPIE_ERROR; + + // append PHP's error message if track_errors enabled + if ( isset($php_errormsg) ) { + $errormsg .= " ($php_errormsg)"; + } + if ( $errormsg ) { + $errormsg = "MagpieRSS: $errormsg"; + $MAGPIE_ERROR = $errormsg; + trigger_error( $errormsg, $lvl); + } +} + +function debug ($debugmsg, $lvl=E_USER_NOTICE) { + trigger_error("MagpieRSS [debug] $debugmsg", $lvl); +} + +/*=======================================================================*\ + Function: magpie_error + Purpose: accessor for the magpie error variable +\*=======================================================================*/ +function magpie_error ($errormsg="") { + global $MAGPIE_ERROR; + + if ( isset($errormsg) and $errormsg ) { + $MAGPIE_ERROR = $errormsg; + } + + return $MAGPIE_ERROR; +} + +/*=======================================================================*\ + Function: _fetch_remote_file + Purpose: retrieve an arbitrary remote file + Input: url of the remote file + headers to send along with the request (optional) + Output: an HTTP response object (see Snoopy.class.inc) +\*=======================================================================*/ +function _fetch_remote_file ($url, $headers = "" ) { + // Snoopy is an HTTP client in PHP + $client = new Snoopy(); + $client->agent = MAGPIE_USER_AGENT; + $client->read_timeout = MAGPIE_FETCH_TIME_OUT; + $client->use_gzip = MAGPIE_USE_GZIP; + if (is_array($headers) ) { + $client->rawheaders = $headers; + } + + @$client->fetch($url); + return $client; + +} + +/*=======================================================================*\ + Function: _response_to_rss + Purpose: parse an HTTP response object into an RSS object + Input: an HTTP response object (see Snoopy) + Output: parsed RSS object (see rss_parse) +\*=======================================================================*/ +function _response_to_rss ($resp) { + $rss = new MagpieRSS( $resp->results, MAGPIE_OUTPUT_ENCODING, MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING ); + + // if RSS parsed successfully + if ( $rss and !$rss->ERROR) { + + // find Etag, and Last-Modified + foreach($resp->headers as $h) { + // 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1" + if (strpos($h, ": ")) { + list($field, $val) = explode(": ", $h, 2); + } + else { + $field = $h; + $val = ""; + } + + if ( $field == 'ETag' ) { + $rss->etag = $val; + } + + if ( $field == 'Last-Modified' ) { + $rss->last_modified = $val; + } + } + + return $rss; + } // else construct error message + else { + $errormsg = "Failed to parse RSS file."; + + if ($rss) { + $errormsg .= " (" . $rss->ERROR . ")"; + } + error($errormsg); + + return false; + } // end if ($rss and !$rss->error) +} + +/*=======================================================================*\ + Function: init + Purpose: setup constants with default values + check for user overrides +\*=======================================================================*/ +function init () { + if ( defined('MAGPIE_INITALIZED') ) { + return; + } + else { + define('MAGPIE_INITALIZED', true); + } + + if ( !defined('MAGPIE_CACHE_ON') ) { + define('MAGPIE_CACHE_ON', true); + } + + if ( !defined('MAGPIE_CACHE_DIR') ) { + define('MAGPIE_CACHE_DIR', './cache'); + } + + if ( !defined('MAGPIE_CACHE_AGE') ) { + define('MAGPIE_CACHE_AGE', 60*60); // one hour + } + + if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) { + define('MAGPIE_CACHE_FRESH_ONLY', false); + } + + if ( !defined('MAGPIE_OUTPUT_ENCODING') ) { + define('MAGPIE_OUTPUT_ENCODING', 'ISO-8859-1'); + } + + if ( !defined('MAGPIE_INPUT_ENCODING') ) { + define('MAGPIE_INPUT_ENCODING', null); + } + + if ( !defined('MAGPIE_DETECT_ENCODING') ) { + define('MAGPIE_DETECT_ENCODING', true); + } + + if ( !defined('MAGPIE_DEBUG') ) { + define('MAGPIE_DEBUG', 0); + } + + if ( !defined('MAGPIE_USER_AGENT') ) { + $ua = 'MagpieRSS/'. MAGPIE_VERSION . ' (+http://magpierss.sf.net'; + + if ( MAGPIE_CACHE_ON ) { + $ua = $ua . ')'; + } + else { + $ua = $ua . '; No cache)'; + } + + define('MAGPIE_USER_AGENT', $ua); + } + + if ( !defined('MAGPIE_FETCH_TIME_OUT') ) { + define('MAGPIE_FETCH_TIME_OUT', 5); // 5 second timeout + } + + // use gzip encoding to fetch rss files if supported? + if ( !defined('MAGPIE_USE_GZIP') ) { + define('MAGPIE_USE_GZIP', true); + } +} + +// NOTE: the following code should really be in Snoopy, or at least +// somewhere other then rss_fetch! + +/*=======================================================================*\ + HTTP STATUS CODE PREDICATES + These functions attempt to classify an HTTP status code + based on RFC 2616 and RFC 2518. + + All of them take an HTTP status code as input, and return true or false + + All this code is adapted from LWP's HTTP::Status. +\*=======================================================================*/ + + +/*=======================================================================*\ + Function: is_info + Purpose: return true if Informational status code +\*=======================================================================*/ +function is_info ($sc) { + return $sc >= 100 && $sc < 200; +} + +/*=======================================================================*\ + Function: is_success + Purpose: return true if Successful status code +\*=======================================================================*/ +function is_success ($sc) { + return $sc >= 200 && $sc < 300; +} + +/*=======================================================================*\ + Function: is_redirect + Purpose: return true if Redirection status code +\*=======================================================================*/ +function is_redirect ($sc) { + return $sc >= 300 && $sc < 400; +} + +/*=======================================================================*\ + Function: is_error + Purpose: return true if Error status code +\*=======================================================================*/ +function is_error ($sc) { + return $sc >= 400 && $sc < 600; +} + +/*=======================================================================*\ + Function: is_client_error + Purpose: return true if Error status code, and its a client error +\*=======================================================================*/ +function is_client_error ($sc) { + return $sc >= 400 && $sc < 500; +} + +/*=======================================================================*\ + Function: is_client_error + Purpose: return true if Error status code, and its a server error +\*=======================================================================*/ +function is_server_error ($sc) { + return $sc >= 500 && $sc < 600; +} + +?> diff --git a/html/includes/rss/rss_parse.inc b/html/includes/rss/rss_parse.inc new file mode 100644 index 0000000..56d420f --- /dev/null +++ b/html/includes/rss/rss_parse.inc @@ -0,0 +1,605 @@ + +* @version 0.7a +* @license GPL +* +*/ + +define('RSS', 'RSS'); +define('ATOM', 'Atom'); + +require_once (MAGPIE_DIR . 'rss_utils.inc'); + +/** +* Hybrid parser, and object, takes RSS as a string and returns a simple object. +* +* see: rss_fetch.inc for a simpler interface with integrated caching support +* +*/ +class MagpieRSS { + var $parser; + + var $current_item = array(); // item currently being parsed + var $items = array(); // collection of parsed items + var $channel = array(); // hash of channel fields + var $textinput = array(); + var $image = array(); + var $feed_type; + var $feed_version; + var $encoding = ''; // output encoding of parsed rss + + var $_source_encoding = ''; // only set if we have to parse xml prolog + + var $ERROR = ""; + var $WARNING = ""; + + // define some constants + + var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright'); + var $_KNOWN_ENCODINGS = array('UTF-8', 'US-ASCII', 'ISO-8859-1'); + + // parser variables, useless if you're not a parser, treat as private + var $stack = array(); // parser stack + var $inchannel = false; + var $initem = false; + var $incontent = false; // if in Atom field + var $intextinput = false; + var $inimage = false; + var $current_namespace = false; + + + /** + * Set up XML parser, parse source, and return populated RSS object.. + * + * @param string $source string containing the RSS to be parsed + * + * NOTE: Probably a good idea to leave the encoding options alone unless + * you know what you're doing as PHP's character set support is + * a little weird. + * + * NOTE: A lot of this is unnecessary but harmless with PHP5 + * + * + * @param string $output_encoding output the parsed RSS in this character + * set defaults to ISO-8859-1 as this is PHP's + * default. + * + * NOTE: might be changed to UTF-8 in future + * versions. + * + * @param string $input_encoding the character set of the incoming RSS source. + * Leave blank and Magpie will try to figure it + * out. + * + * + * @param bool $detect_encoding if false Magpie won't attempt to detect + * source encoding. (caveat emptor) + * + */ + function MagpieRSS ($source, $output_encoding='ISO-8859-1', + $input_encoding=null, $detect_encoding=true) + { + # if PHP xml isn't compiled in, die + # + if (!function_exists('xml_parser_create')) { + $this->error( "Failed to load PHP's XML Extension. " . + "http://www.php.net/manual/en/ref.xml.php", + E_USER_ERROR ); + } + + list($parser, $source) = $this->create_parser($source, + $output_encoding, $input_encoding, $detect_encoding); + + + if (!is_resource($parser)) { + $this->error( "Failed to create an instance of PHP's XML parser. " . + "http://www.php.net/manual/en/ref.xml.php", + E_USER_ERROR ); + } + + + $this->parser = $parser; + + # pass in parser, and a reference to this object + # setup handlers + # + xml_set_object( $this->parser, $this ); + xml_set_element_handler($this->parser, + 'feed_start_element', 'feed_end_element' ); + + xml_set_character_data_handler( $this->parser, 'feed_cdata' ); + + $status = xml_parse( $this->parser, $source ); + + if (! $status ) { + $errorcode = xml_get_error_code( $this->parser ); + if ( $errorcode != XML_ERROR_NONE ) { + $xml_error = xml_error_string( $errorcode ); + $error_line = xml_get_current_line_number($this->parser); + $error_col = xml_get_current_column_number($this->parser); + $errormsg = "$xml_error at line $error_line, column $error_col"; + + $this->error( $errormsg ); + } + } + + xml_parser_free( $this->parser ); + + $this->normalize(); + } + + function feed_start_element($p, $element, &$attrs) { + $el = $element = strtolower($element); + $attrs = array_change_key_case($attrs, CASE_LOWER); + + // check for a namespace, and split if found + $ns = false; + if ( strpos( $element, ':' ) ) { + list($ns, $el) = split( ':', $element, 2); + } + if ( $ns and $ns != 'rdf' ) { + $this->current_namespace = $ns; + } + + # if feed type isn't set, then this is first element of feed + # identify feed from root element + # + if (!isset($this->feed_type) ) { + if ( $el == 'rdf' ) { + $this->feed_type = RSS; + $this->feed_version = '1.0'; + } + elseif ( $el == 'rss' ) { + $this->feed_type = RSS; + $this->feed_version = $attrs['version']; + } + elseif ( $el == 'feed' ) { + $this->feed_type = ATOM; + $this->feed_version = $attrs['version']; + $this->inchannel = true; + } + return; + } + + if ( $el == 'channel' ) + { + $this->inchannel = true; + } + elseif ($el == 'item' or $el == 'entry' ) + { + $this->initem = true; + if ( isset($attrs['rdf:about']) ) { + $this->current_item['about'] = $attrs['rdf:about']; + } + } + + // if we're in the default namespace of an RSS feed, + // record textinput or image fields + elseif ( + $this->feed_type == RSS and + $this->current_namespace == '' and + $el == 'textinput' ) + { + $this->intextinput = true; + } + + elseif ( + $this->feed_type == RSS and + $this->current_namespace == '' and + $el == 'image' ) + { + $this->inimage = true; + } + + # handle atom content constructs + elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) ) + { + // avoid clashing w/ RSS mod_content + if ($el == 'content' ) { + $el = 'atom_content'; + } + + $this->incontent = $el; + + + } + + // if inside an Atom content construct (e.g. content or summary) field treat tags as text + elseif ($this->feed_type == ATOM and $this->incontent ) + { + // if tags are inlined, then flatten + $attrs_str = join(' ', + array_map('map_attrs', + array_keys($attrs), + array_values($attrs) ) ); + + $this->append_content( "<$element $attrs_str>" ); + + array_unshift( $this->stack, $el ); + } + + // Atom support many links per containging element. + // Magpie treats link elements of type rel='alternate' + // as being equivalent to RSS's simple link element. + // + elseif ($this->feed_type == ATOM and $el == 'link' ) + { + if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' ) + { + $link_el = 'link'; + } + else { + $link_el = 'link_' . $attrs['rel']; + } + + $this->append($link_el, $attrs['href']); + } + // set stack[0] to current element + else { + array_unshift($this->stack, $el); + } + } + + + + function feed_cdata ($p, $text) { + if ($this->feed_type == ATOM and $this->incontent) + { + $this->append_content( $text ); + } + else { + $current_el = join('_', array_reverse($this->stack)); + $this->append($current_el, $text); + } + } + + function feed_end_element ($p, $el) { + $el = strtolower($el); + + if ( $el == 'item' or $el == 'entry' ) + { + $this->items[] = $this->current_item; + $this->current_item = array(); + $this->initem = false; + } + elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' ) + { + $this->intextinput = false; + } + elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' ) + { + $this->inimage = false; + } + elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) ) + { + $this->incontent = false; + } + elseif ($el == 'channel' or $el == 'feed' ) + { + $this->inchannel = false; + } + elseif ($this->feed_type == ATOM and $this->incontent ) { + // balance tags properly + // note: i don't think this is actually neccessary + if ( $this->stack[0] == $el ) + { + $this->append_content(""); + } + else { + $this->append_content("<$el />"); + } + + array_shift( $this->stack ); + } + else { + array_shift( $this->stack ); + } + + $this->current_namespace = false; + } + + function concat (&$str1, $str2="") { + if (!isset($str1) ) { + $str1=""; + } + $str1 .= $str2; + } + + + + function append_content($text) { + if ( $this->initem ) { + $this->concat( $this->current_item[ $this->incontent ], $text ); + } + elseif ( $this->inchannel ) { + $this->concat( $this->channel[ $this->incontent ], $text ); + } + } + + // smart append - field and namespace aware + function append($el, $text) { + if (!$el) { + return; + } + if ( $this->current_namespace ) + { + if ( $this->initem ) { + $this->concat( + $this->current_item[ $this->current_namespace ][ $el ], $text); + } + elseif ($this->inchannel) { + $this->concat( + $this->channel[ $this->current_namespace][ $el ], $text ); + } + elseif ($this->intextinput) { + $this->concat( + $this->textinput[ $this->current_namespace][ $el ], $text ); + } + elseif ($this->inimage) { + $this->concat( + $this->image[ $this->current_namespace ][ $el ], $text ); + } + } + else { + if ( $this->initem ) { + $this->concat( + $this->current_item[ $el ], $text); + } + elseif ($this->intextinput) { + $this->concat( + $this->textinput[ $el ], $text ); + } + elseif ($this->inimage) { + $this->concat( + $this->image[ $el ], $text ); + } + elseif ($this->inchannel) { + $this->concat( + $this->channel[ $el ], $text ); + } + + } + } + + function normalize () { + // if atom populate rss fields + if ( $this->is_atom() ) { + $this->channel['description'] = $this->channel['tagline']; + for ( $i = 0; $i < count($this->items); $i++) { + $item = $this->items[$i]; + if ( isset($item['summary']) ) + $item['description'] = $item['summary']; + if ( isset($item['atom_content'])) + $item['content']['encoded'] = $item['atom_content']; + + $atom_date = (isset($item['issued']) ) ? $item['issued'] : $item['modified']; + if ( $atom_date ) { + $epoch = @parse_w3cdtf($atom_date); + if ($epoch and $epoch > 0) { + $item['date_timestamp'] = $epoch; + } + } + + $this->items[$i] = $item; + } + } + elseif ( $this->is_rss() ) { + $this->channel['tagline'] = $this->channel['description']; + for ( $i = 0; $i < count($this->items); $i++) { + $item = $this->items[$i]; + if ( isset($item['description'])) + $item['summary'] = $item['description']; + if ( isset($item['content']['encoded'] ) ) + $item['atom_content'] = $item['content']['encoded']; + + if ( $this->is_rss() == '1.0' and isset($item['dc']['date']) ) { + $epoch = @parse_w3cdtf($item['dc']['date']); + if ($epoch and $epoch > 0) { + $item['date_timestamp'] = $epoch; + } + } + elseif ( isset($item['pubdate']) ) { + $epoch = @strtotime($item['pubdate']); + if ($epoch > 0) { + $item['date_timestamp'] = $epoch; + } + } + + $this->items[$i] = $item; + } + } + } + + + function is_rss () { + if ( $this->feed_type == RSS ) { + return $this->feed_version; + } + else { + return false; + } + } + + function is_atom() { + if ( $this->feed_type == ATOM ) { + return $this->feed_version; + } + else { + return false; + } + } + + /** + * return XML parser, and possibly re-encoded source + * + */ + function create_parser($source, $out_enc, $in_enc, $detect) { + if ( substr(phpversion(),0,1) == 5) { + $parser = $this->php5_create_parser($in_enc, $detect); + } + else { + list($parser, $source) = $this->php4_create_parser($source, $in_enc, $detect); + } + if ($out_enc) { + $this->encoding = $out_enc; + xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $out_enc); + } + + return array($parser, $source); + } + + /** + * Instantiate an XML parser under PHP5 + * + * PHP5 will do a fine job of detecting input encoding + * if passed an empty string as the encoding. + * + * All hail libxml2! + * + */ + function php5_create_parser($in_enc, $detect) { + // by default php5 does a fine job of detecting input encodings + if(!$detect && $in_enc) { + return xml_parser_create($in_enc); + } + else { + return xml_parser_create(''); + } + } + + /** + * Instaniate an XML parser under PHP4 + * + * Unfortunately PHP4's support for character encodings + * and especially XML and character encodings sucks. As + * long as the documents you parse only contain characters + * from the ISO-8859-1 character set (a superset of ASCII, + * and a subset of UTF-8) you're fine. However once you + * step out of that comfy little world things get mad, bad, + * and dangerous to know. + * + * The following code is based on SJM's work with FoF + * @see http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss + * + */ + function php4_create_parser($source, $in_enc, $detect) { + if ( !$detect ) { + return array(xml_parser_create($in_enc), $source); + } + + if (!$in_enc) { + if (preg_match('//m', $source, $m)) { + $in_enc = strtoupper($m[1]); + $this->source_encoding = $in_enc; + } + else { + $in_enc = 'UTF-8'; + } + } + + if ($this->known_encoding($in_enc)) { + return array(xml_parser_create($in_enc), $source); + } + + // the dectected encoding is not one of the simple encodings PHP knows + + // attempt to use the iconv extension to + // cast the XML to a known encoding + // @see http://php.net/iconv + + if (function_exists('iconv')) { + $encoded_source = iconv($in_enc,'UTF-8', $source); + if ($encoded_source) { + return array(xml_parser_create('UTF-8'), $encoded_source); + } + } + + // iconv didn't work, try mb_convert_encoding + // @see http://php.net/mbstring + if(function_exists('mb_convert_encoding')) { + $encoded_source = mb_convert_encoding($source, 'UTF-8', $in_enc ); + if ($encoded_source) { + return array(xml_parser_create('UTF-8'), $encoded_source); + } + } + + // else + $this->error("Feed is in an unsupported character encoding. ($in_enc) " . + "You may see strange artifacts, and mangled characters.", + E_USER_NOTICE); + + return array(xml_parser_create(), $source); + } + + function known_encoding($enc) { + $enc = strtoupper($enc); + if ( in_array($enc, $this->_KNOWN_ENCODINGS) ) { + return $enc; + } + else { + return false; + } + } + + function error ($errormsg, $lvl=E_USER_WARNING) { + // append PHP's error message if track_errors enabled + if ( isset($php_errormsg) ) { + $errormsg .= " ($php_errormsg)"; + } + if ( MAGPIE_DEBUG ) { + trigger_error( $errormsg, $lvl); + } + else { + error_log( $errormsg, 0); + } + + $notices = E_USER_NOTICE|E_NOTICE; + if ( $lvl&$notices ) { + $this->WARNING = $errormsg; + } else { + $this->ERROR = $errormsg; + } + } + + +} // end class RSS + +function map_attrs($k, $v) { + return "$k=\"$v\""; +} + +// patch to support medieval versions of PHP4.1.x, +// courtesy, Ryan Currie, ryan@digibliss.com + +if (!function_exists('array_change_key_case')) { + define("CASE_UPPER",1); + define("CASE_LOWER",0); + + + function array_change_key_case($array,$case=CASE_LOWER) { + if ($case=CASE_LOWER) $cmd=strtolower; + elseif ($case=CASE_UPPER) $cmd=strtoupper; + foreach($array as $key=>$value) { + $output[$cmd($key)]=$value; + } + return $output; + } + +} + +?> diff --git a/html/includes/rss/rss_utils.inc b/html/includes/rss/rss_utils.inc new file mode 100644 index 0000000..2a29e72 --- /dev/null +++ b/html/includes/rss/rss_utils.inc @@ -0,0 +1,67 @@ + + * Version: 0.51 + * License: GPL + * + * The lastest version of MagpieRSS can be obtained from: + * http://magpierss.sourceforge.net + * + * For questions, help, comments, discussion, etc., please join the + * Magpie mailing list: + * magpierss-general@lists.sourceforge.net + */ + + +/*======================================================================*\ + Function: parse_w3cdtf + Purpose: parse a W3CDTF date into unix epoch + + NOTE: http://www.w3.org/TR/NOTE-datetime +\*======================================================================*/ + +function parse_w3cdtf ( $date_str ) { + + # regex to match wc3dtf + $pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/"; + + if ( preg_match( $pat, $date_str, $match ) ) { + list( $year, $month, $day, $hours, $minutes, $seconds) = + array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[6]); + + # calc epoch for current date assuming GMT + $epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year); + + $offset = 0; + if ( $match[10] == 'Z' ) { + # zulu time, aka GMT + } + else { + list( $tz_mod, $tz_hour, $tz_min ) = + array( $match[8], $match[9], $match[10]); + + # zero out the variables + if ( ! $tz_hour ) { $tz_hour = 0; } + if ( ! $tz_min ) { $tz_min = 0; } + + $offset_secs = (($tz_hour*60)+$tz_min)*60; + + # is timezone ahead of GMT? then subtract offset + # + if ( $tz_mod == '+' ) { + $offset_secs = $offset_secs * -1; + } + + $offset = $offset_secs; + } + $epoch = $epoch + $offset; + return $epoch; + } + else { + return -1; + } +} + +?> diff --git a/html/includes/rss/scripts/README b/html/includes/rss/scripts/README new file mode 100644 index 0000000..e37afe5 --- /dev/null +++ b/html/includes/rss/scripts/README @@ -0,0 +1,27 @@ +Some example on how to use Magpie: + +* magpie_simple.php * + Simple example of fetching and parsing an RSS file. Expects to be + called with a query param 'rss_url=http://' + +* simple_smarty.php * + Similiar to magpie_simple, but using the Smarty template engine to do + display. Also demostrates using rss_utils.inc and a smarty plugin to + parse and display when each RSS item was published. + +* magpie_debug.php * + Displays all the information available from a parsed feed. + +* smarty_plugin/modifier.rss_date_parse.php * + + A Smarty plugin for parsing RSS style dates. You must include rss_utils.inc + for this plugin to work. It also must be installed in the Smarty plugin + directory, see the Smarty docs for details. + +* templates/simple.smarty + A Smarty template used by simple_smarty.php which demostrates + displaying an RSS feed and using the date parse plugin. + + +The Smarty template engine and documentation on how to use it are available from +http://smarty.php.net diff --git a/html/includes/rss/scripts/magpie_debug.php b/html/includes/rss/scripts/magpie_debug.php new file mode 100644 index 0000000..84549db --- /dev/null +++ b/html/includes/rss/scripts/magpie_debug.php @@ -0,0 +1,80 @@ +Example Output"; + echo "Channel: " . $rss->channel['title'] . "

    "; + echo "

      "; + foreach ($rss->items as $item) { + $href = $item['link']; + $title = $item['title']; + echo "
    • $title
    • "; + } + echo "
    "; +} +else { + echo "Error: " . magpie_error(); +} +?> + +
    + RSS URL:
    + +
    + +

    Parsed Results (var_dump'ed)

    +
    +
    +
    + +Error: PHP compiled without XML support (--with-xml), Mapgie won't work without PHP support for XML.
    \n"; + exit; + } + else { + echo "OK: Found an XML parser.
    \n"; + } + + if ( ! function_exists('gzinflate') ) { + echo "Warning: PHP compiled without Zlib support (--with-zlib). No support for GZIP encoding.
    \n"; + } + else { + echo "OK: Support for GZIP encoding.
    \n"; + } + + if ( ! (function_exists('iconv') and function_exists('mb_convert_encoding') ) ) { + echo "Warning: No support for iconv (--with-iconv) or multi-byte strings (--enable-mbstring)." . + "No support character set munging.
    \n"; + } + else { + echo "OK: Support for character munging.
    \n"; + } +} + +?> diff --git a/html/includes/rss/scripts/magpie_simple.php b/html/includes/rss/scripts/magpie_simple.php new file mode 100644 index 0000000..282735e --- /dev/null +++ b/html/includes/rss/scripts/magpie_simple.php @@ -0,0 +1,29 @@ +channel['title'] . "

    "; + echo "

      "; + foreach ($rss->items as $item) { + $href = $item['link']; + $title = $item['title']; + echo "
    • $title
    • "; + } + echo "
    "; +} +?> + +
    + RSS URL:
    + +
    + +

    +

    Security Note:

    +This is a simple example script. If this was a real script we probably wouldn't allow strangers to submit random URLs, and we certainly wouldn't simply echo anything passed in the URL. Additionally its a bad idea to leave this example script lying around. +

    \ No newline at end of file diff --git a/html/includes/rss/scripts/magpie_slashbox.php b/html/includes/rss/scripts/magpie_slashbox.php new file mode 100644 index 0000000..bbef30b --- /dev/null +++ b/html/includes/rss/scripts/magpie_slashbox.php @@ -0,0 +1,66 @@ + + + + +
    + +
    + +"; + $rss = fetch_rss( $url ); + echo slashbox ($rss); +} + +echo "
    ";
    +print_r($rss);
    +echo "
    "; +?> + + + + +"; + echo ""; + + # get the channel title and link properties off of the rss object + # + $title = $rss->channel['title']; + $link = $rss->channel['link']; + + echo "$title"; + echo ""; + + # foreach over each item in the array. + # displaying simple links + # + # we could be doing all sorts of neat things with the dublin core + # info, or the event info, or what not, but keeping it simple for now. + # + foreach ($rss->items as $item ) { + echo ""; + echo ""; + echo $item['title']; + echo ""; + } + + echo ""; +} + +?> diff --git a/html/includes/rss/scripts/simple_smarty.php b/html/includes/rss/scripts/simple_smarty.php new file mode 100644 index 0000000..a904d88 --- /dev/null +++ b/html/includes/rss/scripts/simple_smarty.php @@ -0,0 +1,58 @@ +compile_check = true; + +// url of an rss file +$url = $_GET['rss_url']; + + +if ( $url ) { + // assign a variable to smarty for use in the template + $smarty->assign('rss_url', $url); + + // use MagpieRSS to fetch remote RSS file, and parse it + $rss = fetch_rss( $url ); + + // if fetch_rss returned false, we encountered an error + if ( !$rss ) { + $smarty->assign( 'error', magpie_error() ); + } + $smarty->assign('rss', $rss ); + + $item = $rss->items[0]; + $date = parse_w3cdtf( $item['dc']['date'] ); + $smarty->assign( 'date', $date ); +} + +// parse smarty template, and display using the variables we assigned +$smarty->display('simple.smarty'); + +?> diff --git a/html/includes/rss/scripts/smarty_plugin/modifier.rss_date_parse.php b/html/includes/rss/scripts/smarty_plugin/modifier.rss_date_parse.php new file mode 100644 index 0000000..593270e --- /dev/null +++ b/html/includes/rss/scripts/smarty_plugin/modifier.rss_date_parse.php @@ -0,0 +1,31 @@ + diff --git a/html/includes/rss/scripts/templates/simple.smarty b/html/includes/rss/scripts/templates/simple.smarty new file mode 100644 index 0000000..c0761cf --- /dev/null +++ b/html/includes/rss/scripts/templates/simple.smarty @@ -0,0 +1,46 @@ + + +A Simple RSS Box: I'm not a designer + + + +
    +RSS File: + + +
    + +Displaying: {$rss_url} +

    + +{* if $error display the error + elseif parsed RSS object display the RSS + else solicit user for a URL +*} + +{if $error } +Error: {$error} +{elseif $rss} + + + + + {foreach from=$rss->items item=item} + + + + + {/foreach} +
    + {$rss->channel.title} +
    + {$item.title} + + {$item.dc.date|rss_date_parse|date_format:"%A, %B %e, %Y"} +
    +{else} + Enter the URL of an RSS file to display. +{/if} + + + diff --git a/html/includes/utils.inc.php b/html/includes/utils.inc.php new file mode 100644 index 0000000..1fbd948 --- /dev/null +++ b/html/includes/utils.inc.php @@ -0,0 +1,473 @@ + false, + "update_checks_enabled" => true, + "last_update_check" => "", + "update_available" => false, + "update_version" => "", + ); + + // first read CGI config file to determine main file location + $ccfc=read_cgi_config_file(); + //print_r($ccfc); + + // read main config file to determine file locations + if(isset($ccf['main_config_file'])) + $mcf=$ccf['main_config_file']; + else + $mcf=""; + $mcfc=read_main_config_file($mcf); + //print_r($mcfc); + + if(isset($mcf['status_file'])) + $sf=$mcf['status_file']; + else + $sf=""; + + if(isset($mcf['state_retention_file'])) + $rf=$mcf['state_retention_file']; + else + $rf=""; + + + /////////////////////////////////////////////// + // GET PROGRAM VARIABLES FROM MAIN CONFIG FILE + /////////////////////////////////////////////// + + // are update checks enabled? + if(isset($mcfc['check_for_updates']) && $mcfc['check_for_updates']=="0") + $updateinfo["update_checks_enabled"]=false; + + + ///////////////////////////////////////// + // DETERMINE UPDATE INFO FROM STATUS FILE + ///////////////////////////////////////// + + // read status file (just first few lines) + $sfc=read_status_file($sf,50); + //print_r($sfc); + //exit(); + + // last update time + if(isset($sfc['info']['last_update_check'])){ + $updateinfo["last_update_check"]=$sfc['info']['last_update_check']; + $updateinfo["found_update_info"]=true; + } + + // update available + if(isset($sfc['info']['update_available'])){ + if($sfc['info']['update_available']=="1") + $updateinfo["update_available"]=true; + else + $updateinfo["update_available"]=false; + } + + // update version + if(isset($sfc['info']['new_version'])){ + $updateinfo["update_version"]=$sfc['info']['new_version']; + } + + // did we find update information in the status file? if so, we're done + if($updateinfo["found_update_info"]==true) + return $updateinfo; + + + //////////////////////////////////////////// + // DETERMINE UPDATE INFO FROM RETENTION FILE + //////////////////////////////////////////// + + // Nagios might be shutdown (ie, no status file), so try and read data from the retention file + + // read retentiion file (just first few lines) + $rfc=read_retention_file($rf,50); + //print_r($rfc); + //exit(); + + // last update time + if(isset($rfc['info']['last_update_check'])){ + $updateinfo["last_update_check"]=$rfc['info']['last_update_check']; + $updateinfo["found_update_info"]=true; + } + + // update available + if(isset($rfc['info']['update_available'])){ + if($rfc['info']['update_available']=="1") + $updateinfo["update_available"]=true; + else + $updateinfo["update_available"]=false; + } + + // update version + if(isset($rfc['info']['new_version'])){ + $updateinfo["update_version"]=$rfc['info']['new_version']; + } + + + return $updateinfo; + } + + + + +//////////////////////////////////////////////////////////////////////////////////////////////// +// FILE PROCESSING FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////// + +// reads variables from main config file +function read_main_config_file($thefile=""){ + global $cfg; + + $contents=array(); + + // file name can be overridden from default + if(isset($thefile) && $thefile!="") + $fname=$thefile; + else + $fname=$cfg['main_config_file']; + + // open main config file for reading... + if(($fh=@fopen($fname,'r'))!=FALSE){ + // read all lines in the config file + while(!feof($fh)){ + $s=fgets($fh); + + // skip comments + if($s[0]=='#') + continue; + + // skip blank lines + // TODO - is this necessary? + + // split comments out from config + $s2=explode(";",$s); + + // get var/val pairs + $v=explode("=",$s2[0]); + + if(isset($v[0]) && isset($v[1])){ + + // trim var/val pairs + $v[0]=trim($v[0]); + $v[1]=trim($v[1]); + + // allow for multiple values for some variables... + $arr=false; + if(!strcmp($v[0],"cfg_file")) + $arr=true; + else if(!strcmp($v[0],"cfg_dir")) + $arr=true; + + if($arr==true) + $contents[$v[0]][] = $v[1]; + else + $contents[$v[0]] = $v[1]; + } + } + fclose($fh); + } + + return $contents; + } + + +// reads variables from cgi config file +function read_cgi_config_file($thefile=""){ + global $cfg; + + $contents=array(); + + // file name can be overridden from default + if(isset($thefile) && $thefile!="") + $fname=$thefile; + else + $fname=$cfg['cgi_config_file']; + + // open cgi config file for reading... + if(($fh=@fopen($fname,'r'))!=FALSE){ + // read all lines in the config file + while(!feof($fh)){ + $s=fgets($fh); + + // skip comments + if($s[0]=='#') + continue; + + // skip blank lines + // TODO - is this necessary? + + // split comments out from config + $s2=explode(";",$s); + + // get var/val pairs + $v=explode("=",$s2[0]); + + if(isset($v[0]) && isset($v[1])){ + + // trim var/val pairs + $v[0]=ltrim(rtrim($v[0])); + $v[1]=ltrim(rtrim($v[1])); + + // do not allow for multiple values + $contents[$v[0]] = $v[1]; + } + } + fclose($fh); + } + + return $contents; + } + + + +// reads status file +function read_status_file($thefile="",$maxlines=0){ + global $cfg; + + $contents=array( + "info" => array(), + "programstatus" => array(), + "hoststatus" => array(), + "servicestatus" => array(), + "contactstatus" => array() + ); + + $statustype="unknown"; + $current_host=0; + $current_service=0; + $current_contact=0; + + // file name can be overridden from default + if(isset($thefile) && $thefile!="") + $fname=$thefile; + else + $fname=$cfg['status_file']; + + // open file for reading... + $x=0; + if(($fh=@fopen($fname,'r'))!=FALSE){ + // read all lines + while(!feof($fh)){ + + $x++; + if($maxlines>0 && $x>$maxlines) + break; + + $s=fgets($fh); + + // skip comments + if($s[0]=='#') + continue; + + // trim lines + $s=ltrim(rtrim($s)); + + // skip blank lines + if($s=="") + continue; + + // we are in a new type of status data or new entry + if(!strcmp($s,"info {")){ + $statustype="info"; + continue; + } + else if(!strcmp($s,"programstatus {")){ + $statustype="programstatus"; + continue; + } + else if(!strcmp($s,"hoststatus {")){ + $statustype="hoststatus"; + $current_host++; + continue; + } + else if(!strcmp($s,"servicestatus {")){ + $statustype="servicestatus"; + $current_service++; + continue; + } + else if(!strcmp($s,"contactstatus {")){ + $statustype="contactstatus"; + $current_contact++; + continue; + } + + // we just ended an entry... + else if(!strcmp($s,"}")){ + $statustype="unknown"; + continue; + } + + // get/split var/val pairs + $v=explode("=",$s); + $var=""; + $val=""; + if(isset($v[0]) && isset($v[1])){ + // trim var/val pairs + $var=ltrim(rtrim($v[0])); + $val=ltrim(rtrim($v[1])); + } + + // INFO AND PROGRAM STATUS + if($statustype=="info" || $statustype=="programstatus"){ + $contents[$statustype][$var]=$val; + continue; + } + // HOST STATUS + else if($statustype=="hoststatus"){ + $contents[$statustype][$current_host][$var]=$val; + continue; + } + + // SERVICE STATUS + else if($statustype=="servicestatus"){ + $contents[$statustype][$current_service][$var]=$val; + continue; + } + + // CONTACT STATUS + else if($statustype=="contactstatus"){ + $contents[$statustype][$current_contact][$var]=$val; + continue; + } + } + fclose($fh); + } + + $contents["total_hosts"]=$current_host; + $contents["total_services"]=$current_service; + $contents["total_contacts"]=$current_contact; + + return $contents; + } + + + + +// reads retention file +function read_retention_file($thefile="",$maxlines=0){ + global $cfg; + + $contents=array( + "info" => array(), + "program" => array(), + "host" => array(), + "service" => array(), + "contact" => array() + ); + + $datatype="unknown"; + $current_host=0; + $current_service=0; + $current_contact=0; + + // file name can be overridden from default + if(isset($thefile) && $thefile!="") + $fname=$thefile; + else + $fname=$cfg['state_retention_file']; + + // open file for reading... + $x=0; + if(($fh=@fopen($fname,'r'))!=FALSE){ + // read all lines + while(!feof($fh)){ + + $x++; + if($maxlines>0 && $x>$maxlines) + break; + + $s=fgets($fh); + + // skip comments + if($s[0]=='#') + continue; + + // trim lines + $s=ltrim(rtrim($s)); + + // skip blank lines + if($s=="") + continue; + + // we are in a new type of status data or new entry + if(!strcmp($s,"info {")){ + $datatype="info"; + continue; + } + else if(!strcmp($s,"program {")){ + $datatype="program"; + continue; + } + else if(!strcmp($s,"host {")){ + $datatype="host"; + $current_host++; + continue; + } + else if(!strcmp($s,"service {")){ + $datatype="service"; + $current_service++; + continue; + } + else if(!strcmp($s,"contact {")){ + $datatype="contact"; + $current_contact++; + continue; + } + + // we just ended an entry... + else if(!strcmp($s,"}")){ + $datatype="unknown"; + continue; + } + + // get/split var/val pairs + $v=explode("=",$s); + $var=""; + $val=""; + if(isset($v[0]) && isset($v[1])){ + // trim var/val pairs + $var=ltrim(rtrim($v[0])); + $val=ltrim(rtrim($v[1])); + } + + // INFO AND PROGRAM STATUS + if($datatype=="info" || $datatype=="program"){ + $contents[$datatype][$var]=$val; + continue; + } + // HOST STATUS + else if($datatype=="host"){ + $contents[$datatype][$current_host][$var]=$val; + continue; + } + + // SERVICE STATUS + else if($datatype=="service"){ + $contents[$datatype][$current_service][$var]=$val; + continue; + } + + // CONTACT STATUS + else if($datatype=="contact"){ + $contents[$datatype][$current_contact][$var]=$val; + continue; + } + } + fclose($fh); + } + + $contents["total_hosts"]=$current_host; + $contents["total_services"]=$current_service; + $contents["total_contacts"]=$current_contact; + + return $contents; + } + +?> \ No newline at end of file diff --git a/html/index.php b/html/index.php new file mode 100644 index 0000000..55be47a --- /dev/null +++ b/html/index.php @@ -0,0 +1,64 @@ + + + + + +Nagios Core + + + + + + + + + + + +<!-- This page requires a web browser which supports frames. --> +<h2>Nagios Core</h2> +<p align="center"> +<a href="http://www.nagios.org/">www.nagios.org</a><br> +Copyright &copy; 2010-<?php echo date("Y");?> Nagios Core Development Team and Community Contributors. +Copyright &copy; 1999-2010 Ethan Galstad<br> +</p> +<p> +<i>Note: These pages require a browser which supports frames</i> +</p> + + + + + + diff --git a/html/main.php b/html/main.php new file mode 100644 index 0000000..ea9be26 --- /dev/null +++ b/html/main.php @@ -0,0 +1,139 @@ + + + + + + + +Nagios Core + + + + + + + + + + + +

    + +
    + +
    +
    Nagios® Core
    +
    Version 3.5.1
    +
    August 30, 2013
    + + +
    + + +
    + +
    +
    Warning: Automatic Update Checks are Disabled!
    +
    Disabling update checks presents a possible security risk. Visit nagios.org to check for updates manually or enable update checks in your Nagios config file.
    +
    + +
    +
    A new version of Nagios Core is available!
    +
    Visit nagios.org to download Nagios .
    +
    + +
    + + + +
    + + +
    + +
    +

    Quick Links

    + +
    + + +
    +

    Latest News

    +
    +
    +
    +
    + + +
    +
    Copyright © 2010- Nagios Core Development Team and Community Contributors. Copyright © 1999-2009 Ethan Galstad. See the THANKS file for more information on contributors.
    +
    +Nagios Core is licensed under the GNU General Public License and is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. Nagios, Nagios Core and the Nagios logo are trademarks, servicemarks, registered trademarks or registered servicemarks owned by Nagios Enterprises, LLC. Use of the Nagios marks is governed by the trademark use restrictions. +
    +
    + + + + +SourceForge.net Logo +
    +
    + + + + + diff --git a/html/robots.txt b/html/robots.txt new file mode 100644 index 0000000..1f53798 --- /dev/null +++ b/html/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/html/rss-corefeed.php b/html/rss-corefeed.php new file mode 100644 index 0000000..fbf8215 --- /dev/null +++ b/html/rss-corefeed.php @@ -0,0 +1,50 @@ +"; + + foreach ($rss->items as $item){ + $x++; + if($x>3) + break; + //$href = $item['link']; + //$title = $item['title']; + $desc = $item['description']; + $html .="
  • {$item['description']}
  • "; + } + $html .=""; + + print $html; + } + else{ + $html = " + An error occurred while trying to fetch the Nagios Core feed. Stay on top of what's happening by visiting http://www.nagios.org/. + "; + print $html; + } + } + + +?> \ No newline at end of file diff --git a/html/rss-newsfeed.php b/html/rss-newsfeed.php new file mode 100644 index 0000000..52d7901 --- /dev/null +++ b/html/rss-newsfeed.php @@ -0,0 +1,48 @@ +\n"; + + foreach ($rss->items as $item){ + $x++; + if($x>3) + break; + $href = $item['link']; + $title = $item['title']; + $html .="
  • $title
  • "; + } + $html .=' +
  • More news...
  • + '; + + print $html; + } + else{ + $html = " + An error occurred while trying to fetch the latest Nagios news. Stay on top of what's happening by visiting http://www.nagios.org/news. + "; + print $html; + } + } + + +?> \ No newline at end of file diff --git a/html/side.php b/html/side.php new file mode 100644 index 0000000..436f7dc --- /dev/null +++ b/html/side.php @@ -0,0 +1,127 @@ + + + + + + + + +Nagios Core + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/html/ssi/README b/html/ssi/README new file mode 100644 index 0000000..2adcdb1 --- /dev/null +++ b/html/ssi/README @@ -0,0 +1,47 @@ +========================== +NAGIOS CGI SSI FILE README +========================== + +This folder may contain optional header and footer files that will +be added to the CGI HTML output. The files you put can contain server +side include (SSI) statements. + +There are two types of header and footer files - common headers/footers +and CGI-specific headers/footers. Common header/footer files (if present) +will be included in the output of ALL CGIs. CGI-specific header/footer +files (if present) will be included in the output of the CGI they are +intended for. + +The order in which headers/footers are included with regards to the CGI +output and each other is shown below: + +1. COMMON HEADER +2. CGI-SPECIFIC HEADER +3. CGI OUTPUT +4. CGI-SPECIFIC FOOTER +5. COMMON FOOTER + +The header/footer files you create must be named exactly as shown below +in order to be included in the CGI output: + +Common headers/footers: + + common-header.ssi + common-footer.ssi + +CGI-specific header/footers: + -header.ssi + -footer.ssi + + +Some examples of CGI-specific header/footer file names are shown below: + + tac-header.ssi + tac-footer.ssi + status-header.ssi + status-footer.ssi + avail-header.ssi + avail-footer.ssi + notifications-header.ssi + notifications-footer.ssi + diff --git a/html/stylesheets/avail.css b/html/stylesheets/avail.css new file mode 100644 index 0000000..dedb68c --- /dev/null +++ b/html/stylesheets/avail.css @@ -0,0 +1,58 @@ + +.avail { background-color: white; color: black; font-size: 10pt; } + +.reportRange { text-align: center; font-weight: bold; font-size: 10pt; } +.reportDuration { text-align: center; } +.reportTime { text-align: center; } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +TABLE.data { font-size: 10pt; background-color: white; padding: 2px;border-collapse:separate; } + +/* TH.data { font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } */ +.dataOdd { background-color: #DBDBDB; } +.dataEven { background-color: #C4C2C2; } + +.optionBoxTitle { text-align: center; font-weight: bold; font-size: 10pt; } +.optionBox { font-size: 10pt; background-color: #EEEEF4; padding: 2px; } + +.hostUP { text-align: left; background-color: #33FF00; font-weight: bold; } +.hostDOWN { text-align: left; background-color: #F83838; font-weight: bold; } +.hostUNREACHABLE { text-align: left; background-color: #F83838; font-weight: bold; } + +.serviceOK { text-align: left; background-color: #33FF00; font-weight: bold; } +.serviceWARNING { text-align: left; background-color: #FFFF00; font-weight: bold; } +.serviceUNKNOWN { text-align: left; background-color: #FF9900; font-weight: bold; } +.serviceCRITICAL { text-align: left; background-color: #F83838; font-weight: bold; } + +.optBox { font-size: 10pt; font-weight: bold; } +.optBoxItem { font-weight: bold; color: red; } + +.helpfulHint { text-align: left; font-style: italic; text-align: center; } + +.dateSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.dateSelectSubTitle { text-align: left; font-weight: bold; font-size: 10pt; } +.dateSelectItem { text-align: left; } + +.reportSelectTip { text-align: left; font-style: italic; } +.reportSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.reportSelectSubTitle { text-align: right; font-size: 10pt; } +.reportSelectItem { text-align: left; } + +TABLE.logEntries { background-color: white; padding: 3px; } +TH.logEntries { font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } +.logEntriesEven { background-color: white; text-align: left; background-color: #C4C2C2; color: black; } +.logEntriesOdd { background-color: white; text-align: left; background-color: #DBDBDB; color: black; } + +.logEntriesINDETERMINATE { background-color: #ACACAC; } + +.logEntriesOK { background-color: #33FF00; } +.logEntriesUNKNOWN { background-color: #FF9900; } +.logEntriesWARNING { background-color: #FFFF00; } +.logEntriesCRITICAL { background-color: #F83838; } +.logEntriesUP { background-color: #33FF00; } +.logEntriesDOWN { background-color: #F83838; } +.logEntriesUNREACHABLE { background-color: #F83838; } + + + diff --git a/html/stylesheets/checksanity.css b/html/stylesheets/checksanity.css new file mode 100644 index 0000000..b7f8abd --- /dev/null +++ b/html/stylesheets/checksanity.css @@ -0,0 +1,23 @@ + +.extinfo { font-size: 10pt; } + + +.Title { font-size: large; text-align: center; font-weight: bold; } +.SectionTitle { font-size: 12pt; text-align: center; font-weight: bold; } + + +.DynamicData { font-size: 10pt; background-color: white; padding: 2px; } +.StaticData { font-size: 10pt; background-color: white; padding: 2px; } +.TableHeader { font-size: 10pt; background-color: #999797; color: #DCE5C1; text-align: left; font-weight: bold; } + +.Item { font-size: 10pt; text-align: left; background-color: #C4C2C2; font-weight: bold; } +.DataSource { font-size: 10pt; text-align: left; background-color: #C4C2C2; } +.Number { font-size: 10pt; text-align: left; background-color: #C4C2C2; } + +.Value { font-size: 10pt; text-align: left; background-color: #C4C2C2; font-weight: bold; } +.ValueOk { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } +.ValueError { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } + + + + diff --git a/html/stylesheets/cmd.css b/html/stylesheets/cmd.css new file mode 100644 index 0000000..7e12f14 --- /dev/null +++ b/html/stylesheets/cmd.css @@ -0,0 +1,14 @@ + +.cmd { } + +.cmdType { font-size: 10pt; font-weight: bold; text-align: center; color: red; } + +.commandDescription { text-align: center; background-color: #DBDBDB; padding: 5px; } +.descriptionTitle { font-size: 10pt; text-align: center; font-weight: bold; } + +.optBox { text-align: left; padding: 5px; background-color: #C4C2C2; } +.optBoxTitle { font-size: 10pt; text-align: center; font-weight: bold; } +.optBoxItem { font-size: 10pt; text-align: left; background-color: #C4C2C2; } +.optBoxRequiredItem { font-size: 10pt; text-align: left; color: red; background-color: #C4C2C2; } + + diff --git a/html/stylesheets/common.css b/html/stylesheets/common.css new file mode 100644 index 0000000..d986ebe --- /dev/null +++ b/html/stylesheets/common.css @@ -0,0 +1,295 @@ + +/***************** common to all pages, moved to this stylesheet ********************/ + +/* default font size for all elements */ +* {font-size:8pt;} + +body { + font-family: verdana,arial,serif; + font-weight: normal; + } + +/* most other link color scheme blue/light blue */ +a:link,a:visited { + text-decoration: none; + color: #40529b; /* blue */ + /* color: #DEE7C6; pale yellow */ +} +a:hover,a:active { + text-decoration: underline; + /* color: #3f5bcd; gold */ + color: #8391cd; /*dark blue */ + /*color: #8391cd; */ +} + +table {border-collapse:collapse;} +th { font-size: 10pt; text-align: left; background-color: #999797; } + +.infoBox { border: 1px solid #AAA; padding: 2px; font-size:8pt; margin-bottom:3px;} +.linkBox { padding: 3px; font-size:8pt; border: 1px solid #AAA;} +.infoBoxTitle { font-size: 10pt; font-weight: bold; } +.infoBoxTitle { font-size: 10pt; font-weight: bold; } +.infoBoxBadProcStatus { color: red; } +a.homepageURL:hover { color: red; } + + +/* feedback messages */ +.errorMessage { text-align: center; color: red; font-weight: bold; font-size: 12pt; } +.errorDescription { text-align: center; font-weight: bold; font-size: 12pt; } +.warningMessage { text-align: center; color: red; font-weight: bold; font-size: 10pt; } +.infoMessage { text-align: center; color: red; font-weight: bold; } + +/* nav and option boxes on several pages */ +.navBoxTitle { font-size: 10pt; font-weight: bold; } +.navBoxItem { font-size: 8pt; font-weight: bold; color: red; } +.navBoxDate { font-size: 8pt; font-weight: bold; } +.navBoxFile { font-size: 8pt; font-weight: bold; text-align: center; } +/* option boxes */ +.optBox { font-size: 10pt; font-weight: bold; } +.optBoxItem { font-size: 8pt; font-weight: bold; color: red; } +.optBoxTitle { font-weight: bold; font-size: 10pt; } +.optBoxValue { font-size: 8pt; font-style: italic; } + + + +/* *********navbar frame specific styles ********************* */ + +/* navbar */ +body.navbar { + background-color: black; + color: white; + } +/* navbar links +body.navbar a:link,a:visited { + text-decoration: none; + color: #DEE7C6; pale yellow +} +body.navbar a:hover,a:active { + text-decoration: underline; + color: #3f5bcd; gold +} +*/ +.navbarlogo { + margin: 0 0 10px 0; + } + +.navsection { + margin: 5px 0 10px 0; + /*color: #AAA; */ + } + +.navsectiontitle { + font-size: 9pt; + font-weight: bold; + border:1px solid #AAA; + padding: 2px; + text-align:center; + } + +div.navsectionlinks { + margin: 3px 0 0 0; + } + +ul.navsectionlinks { + margin: 0px; + padding: 0px; + list-style: none; + } + +ul.navsectionlinks li { + } + +/* main nav links */ +ul.navsectionlinks li a:link,ul.navsectionlinks li a:visited { + /*color: #DEE7C6; */ + font-weight: bold; + font-size: 8pt; + text-decoration: none; + padding: 0 0 0 15px; + background: transparent url(../images/greendot.gif) no-repeat scroll 0 0; + color: #DEE7C6; /* pale yellow */ + } +ul.navsectionlinks li a:hover ,ul.navsectionlinks li a:active{ + /*color: #8391cd;*/ + color:#FFC47F; /* this one was working before */ + background: transparent url(../images/orangedot.gif) no-repeat scroll 0 0; + /* color: #3f5bcd; gold */ + } + + +ul.navsectionlinks li ul { + margin: 0px; + padding: 0 0 0 30px; + } + +ul.navsectionlinks li ul li { + } + + +/* sub links on main nav */ +ul.navsectionlinks li ul li a:link,ul.navsectionlinks li ul li a:visited { +/* color: #DEE7C6; */ + background: none; + padding: 0; + font-weight: normal; + color: #DEE7C6; /* pale yellow */ + } + +ul.navsectionlinks li ul li a:hover,ul.navsectionlinks li ul li a:active { + background: none; + color:#FFC47F; + } + +ul.navsectionlinks li ul li ul { + margin: 0px; + padding: 0 0 0 15px; + } + + +.navbarsearch { + margin: 5px 0 0 0; + } + +.navbarsearch fieldset { + border: none; + } + +.navbarsearch fieldset legend { + font-size: 8pt; + } + +.navbarsearch input{ +/* font-size: 8pt; */ + color: black; + background-color: white; + } + + + + + +/* **************** main page *********************** */ +#splashpage{ + text-align: center; + } + +#mainbrandsplash{ + font-size: 12pt; + font-weight: bold; + margin: 0 0 35px 0; + } + +#maincopy{ + margin: 0 0 15px 0; + } + +#currentversioninfo{ + font-size: 12pt; + } +#currentversioninfo .product{ + font-size: 14pt; + font-weight: bold; + } +#currentversioninfo .version{ + font-size: 14pt; + font-weight: bold; + } +#currentversioninfo .releasedate{ + font-size: 11pt; + margin: 5px 0 0 0; + } +#currentversioninfo .checkforupdates{ + font-size: 11pt; + font-weight: bold; + } +#currentversioninfo .whatsnew{ + font-size: 11pt; + font-weight: bold; + margin: 50px 0 0 0; + } + +#updateversioninfo{ + margin: 15px auto 35px auto; + width: 400px; + } +.updatechecksdisabled{ + background-color: #FF9F9F; + border: 1px solid red; + padding: 10px; + } +.updatechecksdisabled div.warningmessage{ + font-weight: bold; + } +#updateversioninfo div.submessage{ + clear: left; + } +.updateavailable{ + background-color: #9FD4FF; + border: 1px solid blue; + padding: 10px; + } +.updateavailable div.updatemessage{ + font-size: 12pt; + font-weight: bold; + } + +#splashpage #mainfooter{ + /*margin: 100px 0 0 0;*/ + clear: both; + font-size: 8pt; + } +#splashpage #mainfooter .disclaimer{ + /*width: 80%;*/ + margin: auto; + } +#splashpage #mainfooter .logos{ + margin: 15px 0 0 0; + } + + +a img { + border: none; + } + +#splashboxes { + + /*border: 1px solid blue;*/ + clear:both; + width: 800px; + height:300px; + margin-left: auto; + margin-right:auto; + line-height:1.2em; /* added for better X-browser/OS viewing */ + + } +#topsplashbox { + height:150px; + } +#bottomsplashbox { + height:150px; + } + +.splashbox { + padding: 5px; + margin: 5px; + border: 1px solid #AAAAAA; + float: left; + text-align: left; + width:375px; + } + +.splashbox h2{ + margin: 0px; + font-size: 12pt; + } +.splashbox ul{ + margin: 0; + padding: 5px 5px 5px 15px; + } +.splashbox ul li{ + clear: both; + } +#splashbox1 { + } +#splashbox2 { + } diff --git a/html/stylesheets/config.css b/html/stylesheets/config.css new file mode 100644 index 0000000..d3c3e82 --- /dev/null +++ b/html/stylesheets/config.css @@ -0,0 +1,14 @@ + +.config { } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +TABLE.data { background-color: white; padding: 2px; border-collapse:separate;} +TH.data { background-color: white; text-align: left; background-color: #999797; } +.dataOdd { background-color: #DBDBDB; } +.dataEven { background-color: #C4C2C2; } + +.reportSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.reportSelectSubTitle { text-align: left; font-weight: bold; font-size: 10pt; } +.reportSelectItem { text-align: left; } + diff --git a/html/stylesheets/extinfo.css b/html/stylesheets/extinfo.css new file mode 100644 index 0000000..a8d8c3a --- /dev/null +++ b/html/stylesheets/extinfo.css @@ -0,0 +1,96 @@ + +.extinfo { } + +DIV.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } +DIV.data { text-align: center; font-size: 12pt; } + +DIV.perfTypeTitle { text-align: right; font-weight: bold; font-size: 10pt; } +/* +TABLE.data { font-size: 10pt; background-color: white; padding: 2px; border-collapse:separate;} +TH.data { font-size: 10pt; text-align: left; background-color: #999797; } +*/ + +.dataOdd { font-size: 10pt; background-color: #DBDBDB; } +.dataEven { font-size: 10pt; background-color: #C4C2C2; } + + +.commandTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +TABLE.command { font-size: 10pt; background-color: #DBDBDB; padding: 3px; } +.command { font-size: 10pt; padding: 2px; } + +.commentTitle { text-align: center; font-weight: bold; font-size: 12pt; } +DIV.commentNav { font-size: 10pt; text-align: center; } +A.commentNav { font-size: 10pt; } + +TABLE.comment { font-size: 10pt; background-color: white; padding: 2px; border-collapse:separate;} +TH.comment { font-size: 10pt; text-align: left; background-color: #999797; } +.commentOdd { font-size: 9pt; background-color: #DBDBDB; } +.commentEven { font-size: 9pt; background-color: #C4C2C2; } +DIV.comment,A.comment { font-size: 10pt; background-color: white; text-align: center; } + +.downtimeTitle { text-align: center; font-weight: bold; font-size: 12pt; } +DIV.downtimeNav { font-size: 10pt; text-align: center; } +A.downtimeNav { font-size: 10pt; } + +TABLE.downtime { font-size: 10pt; background-color: white; padding: 2px; border-collapse:separate;} +TH.downtime { font-size: 10pt; text-align: left; background-color: #999797; } +.downtimeOdd { font-size: 9pt; background-color: #DBDBDB; } +.downtimeEven { font-size: 9pt; background-color: #C4C2C2; } + +.notificationsENABLED { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } +.notificationsDISABLED { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } + +.checksENABLED { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } +.checksDISABLED { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } + +.eventhandlersENABLED { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } +.eventhandlersDISABLED { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } + +.flapdetectionENABLED { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } +.flapdetectionDISABLED { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } + +.notflapping { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; float: left; } +.flapping { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; float: left; } + +.downtimeACTIVE { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; float: left; } +.downtimeINACTIVE { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; float: left; } + +.processOK { font-size: 10pt; background-color: #33FF00; font-weight: bold; } +.processUNKNOWN { font-size: 10pt; background-color: #FF9900; font-weight: bold; } +.processWARNING { font-size: 10pt; background-color: #FFFF00; font-weight: bold; } +.processCRITICAL { font-size: 10pt; background-color: #F83838; font-weight: bold; } + +.modeACTIVE { font-size: 10pt; background-color: #33FF00; font-weight: bold; } +.modeSTANDBY { font-size: 10pt; background-color: #FFFF00; font-weight: bold; } + +.hostUP { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; float: left; } +.hostDOWN { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; float: left; } +.hostUNREACHABLE { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; float: left; } + +.serviceOK { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; float: left; } +.serviceWARNING { font-size: 10pt; text-align: left; background-color: #FFFF00; font-weight: bold; float: left; } +.serviceUNKNOWN { font-size: 10pt; text-align: left; background-color: #FF9900; font-weight: bold; float: left; } +.serviceCRITICAL { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; float: left; } + +.commandPanel { background-color: white; } +.commentPanel { background-color: white; } + +.stateInfoPanel { background-color: white; } +.stateStatisticsPanel { background-color: white; } +.stateInfoTable1 { font-size: 10pt; background-color: #DBDBDB; } +.stateInfoTable2 { font-size: 10pt; background-color: #C4C2C2; } + +.dataVar { font-size: 10pt; } +.dataVal { font-size: 10pt; } + +.queueTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +TABLE.queue { font-size: 10pt; background-color: white; padding: 2px; border-collapse:separate;} +TH.queue { font-size: 10pt; text-align: left; background-color: #999797; } +.queueOdd { font-size: 9pt; background-color: #DBDBDB; } +.queueEven { font-size: 9pt; background-color: #C4C2C2; } +.queueENABLED { font-size: 9pt; background-color: #33FF00; } +.queueDISABLED { font-size: 9pt; background-color: #F83838; } + + diff --git a/html/stylesheets/histogram.css b/html/stylesheets/histogram.css new file mode 100644 index 0000000..6044192 --- /dev/null +++ b/html/stylesheets/histogram.css @@ -0,0 +1,14 @@ +.histogram { } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +.reportRange { text-align: center; font-weight: bold; font-size: 10pt; } +.reportDuration { text-align: center; } +.reportTime { text-align: center; } + +.reportSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.reportSelectSubTitle { text-align: right; font-size: 10pt; } +.reportSelectItem { text-align: left; } + +.helpfulHint { text-align: left; font-style: italic; text-align: center; } + diff --git a/html/stylesheets/history.css b/html/stylesheets/history.css new file mode 100644 index 0000000..e440007 --- /dev/null +++ b/html/stylesheets/history.css @@ -0,0 +1,9 @@ + +.history {} + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +.logEntries { } + +.dateTimeBreak { font-size: 10pt; font-weight: bold; color: red; } + diff --git a/html/stylesheets/ministatus.css b/html/stylesheets/ministatus.css new file mode 100644 index 0000000..dcd8c82 --- /dev/null +++ b/html/stylesheets/ministatus.css @@ -0,0 +1,69 @@ + +.status {} + +.filter { background-color: #DBDBDB; } +.filterTitle { font-size: 10pt; font-weight: bold; background-color: #DBDBDB; } +.filterName { background-color: #DBDBDB; } +.filterValue { background-color: #DBDBDB; } + +.statusTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.statusSort { } + +TABLE.status { background-color: white; padding: 2px; } +TH.status { font-size: 10pt; text-align: left; background-color: #999797; } +DIV.status { font-size: 10pt; text-align: center; } +.statusOdd { background-color: #DBDBDB; } +.statusEven { background-color: #C4C2C2; } + +.statusPENDING { background-color: #ACACAC; } +.statusOK { background-color: #33FF00; } +.statusRECOVERY { background-color: #33FF00; } +.statusUNKNOWN { background-color: #FF9900; } +.statusWARNING { background-color: #FFFF00; } +.statusCRITICAL { background-color: #F83838; } + +.statusHOSTPENDING { background-color: #ACACAC; } +.statusHOSTUP { background-color: #33FF00; } +.statusHOSTDOWN { background-color: #F83838; } +.statusHOSTUNREACHABLE { background-color: #F83838; } + +.statusBGUNKNOWN { background-color: #FFDA9F; } +.statusBGWARNING { background-color: #FEFFC1; } +.statusBGCRITICAL { background-color: #FFBBBB; } +.statusBGDOWN { background-color: #FFBBBB; } +.statusBGUNREACHABLE { background-color: #FFBBBB; } + +DIV.serviceTotals { text-align: center; font-weight: bold; font-size: 10pt; } +TABLE.serviceTotals { font-size: 10pt; background-color: white; padding: 2px; } +TH.serviceTotals,A.serviceTotals { font-size: 10pt; text-align: center; background-color: #999797; } +TD.serviceTotals { text-align: center; background-color: #e9e9e9; } + +.serviceTotalsOK { text-align: center; background-color: #33FF00; } +.serviceTotalsWARNING { text-align: center; background-color: #FFFF00; font-weight: bold; } +.serviceTotalsUNKNOWN { text-align: center; background-color: #FF9900; font-weight: bold; } +.serviceTotalsCRITICAL { text-align: center; background-color: #F83838; font-weight: bold; } +.serviceTotalsPENDING { text-align: center; background-color: #ACACAC; } +.serviceTotalsPROBLEMS { text-align: center; background-color: orange; font-weight: bold; } + + +DIV.hostTotals { text-align: center; font-weight: bold; font-size: 10pt; } +TABLE.hostTotals { font-size: 10pt; background-color: white; padding: 2px; } +TH.hostTotals,A.hostTotals { font-size: 10pt; text-align: center; background-color: #999797; } +TD.hostTotals { text-align: center; background-color: #e9e9e9; } + +.hostTotalsUP { text-align: center; background-color: #33FF00; } +.hostTotalsDOWN { text-align: center; background-color: #F83838; font-weight: bold; } +.hostTotalsUNREACHABLE { text-align: center; background-color: #F83838; font-weight: bold; } +.hostTotalsPENDING { text-align: center; background-color: #ACACAC; } +.hostTotalsPROBLEMS { text-align: center; background-color: orange; font-weight: bold; } + +.miniStatusPENDING { background-color: #ACACAC; text-align: center; } +.miniStatusOK { background-color: #33FF00; text-align: center; } +.miniStatusUNKNOWN { background-color: #FF9900; text-align: center; } +.miniStatusWARNING { background-color: #FFFF00; text-align: center; } +.miniStatusCRITICAL { background-color: #F83838; text-align: center; } + +.miniStatusUP { background-color: #33FF00; text-align: center; } +.miniStatusDOWN { background-color: #F83838; text-align: center; } +.miniStatusUNREACHABLE { background-color: #F83838; text-align: center; } + diff --git a/html/stylesheets/notifications.css b/html/stylesheets/notifications.css new file mode 100644 index 0000000..1f4fc4d --- /dev/null +++ b/html/stylesheets/notifications.css @@ -0,0 +1,24 @@ + +.notifications { } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } + + +TABLE.notifications { font-size: 10pt; background-color: white; padding: 5px; border-collapse:separate; } +TH.notifications { font-size: 10pt; text-align: left; background-color: #999797; } +.notificationsOdd { background-color: #DBDBDB; } +.notificationsEven { background-color: #C4C2C2; } + +.notificationsOK { background-color: #33FF00; } +.notificationsUNKNOWN { background-color: #FF9900; } +.notificationsWARNING { background-color: #FFFF00; } +.notificationsCRITICAL { background-color: #F83838; } +.notificationsACKNOWLEDGEMENT { background-color: #AAAAAA; } +.notificationsCUSTOM { background-color: #778899; } + +.notificationsHOSTUP { background-color: #33FF00; } +.notificationsHOSTDOWN { background-color: #F83838; } +.notificationsHOSTUNREACHABLE { background-color: #F83838; } +.notificationsHOSTACKNOWLEDGEMENT { background-color: #AAAAAA; } +.notificationsHOSTCUSTOM { background-color: #778899; } + diff --git a/html/stylesheets/outages.css b/html/stylesheets/outages.css new file mode 100644 index 0000000..5f9577b --- /dev/null +++ b/html/stylesheets/outages.css @@ -0,0 +1,15 @@ + +.outages { } + +.itemTotalsTitle { text-align: center; } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } +TABLE.data { font-size: 10pt; background-color: white; padding: 2px; border-collapse:separate;} +TH.data { font-size: 10pt; text-align: left; background-color: #999797; } +.dataOdd { font-size: 10pt; background-color: #DBDBDB; } +.dataEven { font-size: 10pt; background-color: #C4C2C2; } + +.hostUP { font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } +.hostDOWN { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } +.hostUNREACHABLE { font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } + diff --git a/html/stylesheets/showlog.css b/html/stylesheets/showlog.css new file mode 100644 index 0000000..06b6ce4 --- /dev/null +++ b/html/stylesheets/showlog.css @@ -0,0 +1,7 @@ + +.showlog { } + +.logEntries { } + +.dateTimeBreak { font-size: 10pt; font-weight: bold; color: red; } + diff --git a/html/stylesheets/status.css b/html/stylesheets/status.css new file mode 100644 index 0000000..b3b19f4 --- /dev/null +++ b/html/stylesheets/status.css @@ -0,0 +1,115 @@ + +.status { background-color: white; color: black;} + +/* classes to replace deprecated inline styles */ +.headertable{border:0; width:100%; } + + +table.filter {border:1px solid #AAA; padding:2px;} +.filterTitle { font-size: 10pt; font-weight: bold; padding:0 2px; } +td.filter {padding:0 3px;} +/* +.filter { background-color: #DBDBDB; } +.filterName { background-color: #DBDBDB; } +.filterValue { background-color: #DBDBDB; } +*/ + +.itemTotalsTitle { text-align: center; clear:both;} + +.statusTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.statusSort { } + +table.status { background-color: white; padding: 2px; border-collapse:separate;} /* border-collapse:separate; */ +/* table.status tr td {border:1px solid white;} */ +table.pageTitle {margin-bottom:3px;} +th.status { font-size: 10pt; text-align: left; background-color: #999797; } +div.status { font-size: 10pt; text-align: center; } +.statusOdd { background-color: #DBDBDB; } +.statusEven { background-color: #C4C2C2; } + +/* CSS styles won't inherit correctly as long as there are nested tables */ +/* .statusPENDING { background-color: #ACACAC; } */ + /* .statusOK { background-color: #33FF00; } */ +.statusRECOVERY { background-color: #33FF00; } +.statusUNKNOWN { background-color: #FF9900; } +.statusWARNING { background-color: #FFFF00; } +/* .statusCRITICAL { background-color: #F83838; } */ + +.statusHOSTPENDING,.statusPENDING { background-color: #ACACAC; } +.statusHOSTUP,.statusOK { background-color: #33FF00; } +.statusHOSTDOWN,.statusCRITICAL { background-color: #F83838; } +.statusHOSTDOWNACK { background-color: #F83838; } +.statusHOSTDOWNSCHED { background-color: #F83838; } +.statusHOSTUNREACHABLE { background-color: #F83838; } +.statusHOSTUNREACHABLEACK { background-color: #F83838; } +.statusHOSTUNREACHABLESCHED { background-color: #F83838; } + + +.statusBGUNKNOWN { background-color: #FFDA9F; } +.statusBGUNKNOWNACK { background-color: #FFDA9F; } +.statusBGUNKNOWNSCHED { background-color: #FFDA9F; } +.statusBGWARNING { background-color: #FEFFC1; } +.statusBGWARNINGACK { background-color: #FEFFC1; } +.statusBGWARNINGSCHED { background-color: #FEFFC1; } +.statusBGCRITICAL { background-color: #FFBBBB; } +.statusBGCRITICALACK { background-color: #FFBBBB; } +.statusBGCRITICALSCHED { background-color: #FFBBBB;} +.statusBGDOWN { background-color: #FFBBBB; } +.statusBGDOWNACK { background-color: #FFBBBB; } +.statusBGDOWNSCHED { background-color: #FFBBBB; } +.statusBGUNREACHABLE { background-color: #FFBBBB; } +.statusBGUNREACHABLEACK { background-color: #FFBBBB; } +.statusBGUNREACHABLESCHED { background-color: #FFBBBB; } + + +div.serviceTotals,div.hostTotals { text-align: center; font-weight: bold; font-size: 10pt; } +table.serviceTotals, table.hostTotals { font-size: 10pt; padding: 2px; margin-bottom:3px;border-collapse:separate;} +th.serviceTotals,th.hostTotals{ font-size: 10pt; text-align: center; background-color: #999797; } +th.serviceTotals a:hover,th.hostTotals a:hover {color: #FFC47F;} +/* removed styles */ + +td.serviceTotals,td.hostTotals,td.hostTotals { text-align: center; background-color: #e9e9e9; } + +.serviceTotalsOK { text-align: center; background-color: #33FF00; } +.serviceTotalsWARNING { text-align: center; background-color: #FFFF00; font-weight: bold; } +.serviceTotalsUNKNOWN { text-align: center; background-color: #FF9900; font-weight: bold; } +.serviceTotalsCRITICAL { text-align: center; background-color: #F83838; font-weight: bold; } +.serviceTotalsPENDING { text-align: center; background-color: #ACACAC; } +.serviceTotalsPROBLEMS { text-align: center; background-color: orange; font-weight: bold; } + +/* +div.hostTotals { text-align: center; font-weight: bold; font-size: 10pt; } +table.hostTotals { font-size: 10pt; background-color: white; padding: 2px; border:1px solid #AAA; border-collapse:collapse;} +th.hostTotals,a.hostTotals { font-size: 10pt; text-align: center; background-color: #999797; } +td.hostTotals { text-align: center; background-color: #e9e9e9; } +*/ +.hostTotalsUP { text-align: center; background-color: #33FF00; } +.hostTotalsDOWN { text-align: center; background-color: #F83838; font-weight: bold; } +.hostTotalsUNREACHABLE { text-align: center; background-color: orange; font-weight: bold; } +.hostTotalsPENDING { text-align: center; background-color: #ACACAC; } +.hostTotalsPROBLEMS { text-align: center; background-color: orange; font-weight: bold; } + +.miniStatusPENDING { background-color: #ACACAC; text-align: center; } +.miniStatusOK { background-color: #33FF00; text-align: center; } +.miniStatusUNKNOWN { background-color: #FF9900; text-align: center; } +.miniStatusWARNING { background-color: #FFFF00; text-align: center; } +.miniStatusCRITICAL { background-color: #F83838; text-align: center; } + +.miniStatusUP { background-color: #33FF00; text-align: center; } +.miniStatusDOWN { background-color: #F83838; text-align: center; } +.miniStatusUNREACHABLE { background-color: #F83838; text-align: center; } + +.hostImportantProblem { text-align: left; background-color: #ff0000; color: black; text-decoration: blink; } +.hostUnimportantProblem { text-align: left; background-color: #ffcccc; color: black; } + +.serviceImportantProblem { text-align: left; background-color: #ff0000; color: black; text-decoration: blink; } +.serviceUnimportantProblem { text-align: left; background-color: #ffcccc; color: black; } + +/* page number styles, added 2/01/2012 -MG */ +#top_page_numbers {float:right;} +#result_limit {display:inline;} +.pagenumber { display: block; float:left; border: 1px solid #AAAAAA; padding: 0 2px 0 2px; margin: 1px;text-align:center; height:15px; } +a.pagenumber:hover,a.pagenumber:active { background-color: #EFEFEF;text-decoration:none;} +.current_page { color: #AAA; } +#inner_numbers { clear:right;} +#pagelimit,#bottom_page_numbers {margin-bottom:1em;} diff --git a/html/stylesheets/statusmap.css b/html/stylesheets/statusmap.css new file mode 100644 index 0000000..a40e821 --- /dev/null +++ b/html/stylesheets/statusmap.css @@ -0,0 +1,10 @@ + +.statusmap {} + + +.imageInfo { font-weight: bold; text-align: center; } + +.zoomTitle { font-size: 12pt; font-weight: bold; } + +.popupText { font-weight: bold; } + diff --git a/html/stylesheets/summary.css b/html/stylesheets/summary.css new file mode 100644 index 0000000..c3c6325 --- /dev/null +++ b/html/stylesheets/summary.css @@ -0,0 +1,40 @@ + +.summary { } + +.reportRange { text-align: center; font-weight: bold; font-size: 10pt; } +.reportDuration { text-align: center; } +.reportTime { text-align: center; } + +.reportDataEven { background-color: #B4B5CC; padding: 2px; } +.reportDataOdd { background-color: #CDCEE9; padding: 2px; } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.dataSubTitle { text-align: center; font-weight: bold; font-size: 10pt; } + +TABLE.data { font-size: 10pt; background-color: white; padding: 2px; border-collapse:separate;} +TH.data { font-size: 10pt; text-align: left; background-color: #999797; } +.dataOdd { font-size: 9pt; background-color: #DBDBDB; } +.dataEven { font-size: 9pt; background-color: #C4C2C2; } + +.hostUP { font-size: 9pt; text-align: left; background-color: #33FF00; } +.hostDOWN { font-size: 9pt; text-align: left; background-color: #F83838; } +.hostUNREACHABLE { font-size: 9pt; text-align: left; background-color: #F83838; } + +.serviceOK { font-size: 9pt; text-align: left; background-color: #33FF00; } +.serviceWARNING { font-size: 9pt; text-align: left; background-color: #FFFF00; } +.serviceUNKNOWN { font-size: 9pt; text-align: left; background-color: #FF9900; } +.serviceCRITICAL { font-size: 9pt; text-align: left; background-color: #F83838; } + + +.helpfulHint { text-align: left; font-style: italic; text-align: center; } + +.dateSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.dateSelectSubTitle { text-align: left; font-weight: bold; font-size: 10pt; } +.dateSelectItem { text-align: left; } + +.reportSelectTip { text-align: left; font-style: italic; } + +.reportSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.reportSelectSubTitle { text-align: right; font-size: 10pt; } +.reportSelectItem { text-align: left; } + diff --git a/html/stylesheets/tac.css b/html/stylesheets/tac.css new file mode 100644 index 0000000..e53b5f9 --- /dev/null +++ b/html/stylesheets/tac.css @@ -0,0 +1,86 @@ + +.tac { background-color: black; background: black; color: white; background-color: black; margin:10px;} + +.infoBoxBadProcStatus { color: red; } + +body.tac a,a:visited { color: black; } +body.tac a:active,a:hover: {text-decoration:underline;} +body.tac table.infoBox {background-color:#C4C2C2;color:black;} + +.title { text-align: left; font-weight: bold; font-size: large; background-color: black; color: white; } +.titleItem { text-align: left; font-weight: bold; background-color: black; color: white; } +.infoBoxBadProcStatus { text-align: left; font-weight: bold; background-color: #C4C2C2; color: red; } + +.healthTitle { text-align: left; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } +.healthBox { text-align: left; font-weight: bold; background-color: #C4C2C2; color: white; } +.healthItem { text-align: left; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; } +.healthBar { text-align: left; font-weight: bold; background-color: gray; color: white; } + +.perfTitle { text-align: left; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; text-decoration: none; } +.perfBox { text-align: left; font-weight: bold; background-color: #C4C2C2; color: white; } +.perfItem { text-align: left; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } +.perfValue { text-align: left; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } + +.featureTitle { text-align: left; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } +.featureHeader { text-align: center; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; } + +.featureEnabled { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } +.featureDisabled { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } + +.featureEnabledFlapDetection { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } +.featureDisabledFlapDetection { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } +.featureItemEnabledServiceFlapDetection { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledServiceFlapDetection { text-align: left; background-color: #ff0000; color: black; } +.featureItemEnabledHostFlapDetection { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledHostFlapDetection { text-align: left; background-color: #ff0000; color: black; } +.featureItemServicesNotFlapping { text-align: left; background-color: #ccffcc; color: black; } +.featureItemServicesFlapping { text-align: left; background-color: #ff0000; color: black; } +.featureItemHostsNotFlapping { text-align: left; background-color: #ccffcc; color: black; } +.featureItemHostsFlapping { text-align: left; background-color: #ff0000; color: black; } + +.featureEnabledNotifications { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } +.featureDisabledNotifications { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } +.featureItemEnabledServiceNotifications { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledServiceNotifications { text-align: left; background-color: #ff0000; color: black; } +.featureItemEnabledHostNotifications { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledHostNotifications { text-align: left; background-color: #ff0000; color: black; } + +.featureEnabledHandlers { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } +.featureDisabledHandlers { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } +.featureItemEnabledServiceHandlers { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledServiceHandlers { text-align: left; background-color: #ff0000; color: black; } +.featureItemEnabledHostHandlers { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledHostHandlers { text-align: left; background-color: #ff0000; color: black; } + +.featureEnabledActiveChecks { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } +.featureDisabledActiveChecks { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } +.featureItemEnabledActiveServiceChecks { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledActiveServiceChecks { text-align: left; background-color: #ff0000; color: black; } +.featureItemEnabledActiveHostChecks { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledActiveHostChecks { text-align: left; background-color: #ff0000; color: black; } + +.featureEnabledPassiveChecks { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } +.featureDisabledPassiveChecks { text-align: center; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } +.featureItemEnabledPassiveServiceChecks { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledPassiveServiceChecks { text-align: left; background-color: #ff0000; color: black; } +.featureItemEnabledPassiveHostChecks { text-align: left; background-color: #ccffcc; color: black; } +.featureItemDisabledPassiveHostChecks { text-align: left; background-color: #ff0000; color: black; } + +.outageTitle { text-align: left; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } +.outageHeader { text-align: center; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } + +.outageImportantProblem { text-align: left; background-color: #ff0000; color: black; } +.outageUnimportantProblem { text-align: left; background-color: #ffcccc; color: black; } + +.hostTitle { text-align: left; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } +.hostHeader { text-align: center; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } + +.hostImportantProblem { text-align: left; background-color: #ff0000; color: black; } +.hostUnimportantProblem { text-align: left; background-color: #ffcccc; color: black; } + +.serviceTitle { text-align: left; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } +.serviceHeader { text-align: center; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } + +.serviceImportantProblem { text-align: left; background-color: #ff0000; color: black; } +.serviceUnimportantProblem { text-align: left; background-color: #ffcccc; color: black; } + diff --git a/html/stylesheets/trends.css b/html/stylesheets/trends.css new file mode 100644 index 0000000..16efbcc --- /dev/null +++ b/html/stylesheets/trends.css @@ -0,0 +1,16 @@ + +.trends { } + +.dataTitle { text-align: center; font-weight: bold; font-size: 12pt; } + +.reportRange { text-align: center; font-weight: bold; font-size: 10pt; } +.reportDuration { text-align: center; } +.reportTime { text-align: center; } + +.reportSelectTitle { text-align: center; font-weight: bold; font-size: 12pt; } +.reportSelectSubTitle { text-align: right; font-size: 10pt; } +.reportSelectItem { text-align: left; } + +.helpfulHint { text-align: left; font-style: italic; text-align: center; } + +.popupText { font-weight: bold; } diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 0000000..0f80662 --- /dev/null +++ b/include/.gitignore @@ -0,0 +1,3 @@ +locations.h +config.h +snprintf.h diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..a11914d --- /dev/null +++ b/include/Makefile @@ -0,0 +1,13 @@ +############################### +# Makefile for Include Files +# +# Last Modified: 10-18-2007 +############################### + +clean: + rm -f *~ + +distclean: clean + rm -f config.h locations.h snprintf.h + +devclean: distclean diff --git a/include/broker.h b/include/broker.h new file mode 100644 index 0000000..64e3b39 --- /dev/null +++ b/include/broker.h @@ -0,0 +1,216 @@ +/***************************************************************************** + * + * BROKER.H - Event broker includes for Nagios + * + * Copyright (c) 2002-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-12-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _BROKER_H +#define _BROKER_H + +#include "nagios.h" + +/*************** EVENT BROKER OPTIONS *****************/ + +#define BROKER_NOTHING 0 +#define BROKER_EVERYTHING 1048575 + +#define BROKER_PROGRAM_STATE 1 /* DONE */ +#define BROKER_TIMED_EVENTS 2 /* DONE */ +#define BROKER_SERVICE_CHECKS 4 /* DONE */ +#define BROKER_HOST_CHECKS 8 /* DONE */ +#define BROKER_EVENT_HANDLERS 16 /* DONE */ +#define BROKER_LOGGED_DATA 32 /* DONE */ +#define BROKER_NOTIFICATIONS 64 /* DONE */ +#define BROKER_FLAPPING_DATA 128 /* DONE */ +#define BROKER_COMMENT_DATA 256 /* DONE */ +#define BROKER_DOWNTIME_DATA 512 /* DONE */ +#define BROKER_SYSTEM_COMMANDS 1024 /* DONE */ +#define BROKER_OCP_DATA_UNUSED 2048 /* reusable */ +#define BROKER_STATUS_DATA 4096 /* DONE */ +#define BROKER_ADAPTIVE_DATA 8192 /* DONE */ +#define BROKER_EXTERNALCOMMAND_DATA 16384 /* DONE */ +#define BROKER_RETENTION_DATA 32768 /* DONE */ +#define BROKER_ACKNOWLEDGEMENT_DATA 65536 +#define BROKER_STATECHANGE_DATA 131072 +#define BROKER_RESERVED18 262144 +#define BROKER_RESERVED19 524288 + + +/****** EVENT TYPES ************************/ + +#define NEBTYPE_NONE 0 + +#define NEBTYPE_HELLO 1 +#define NEBTYPE_GOODBYE 2 +#define NEBTYPE_INFO 3 + +#define NEBTYPE_PROCESS_START 100 +#define NEBTYPE_PROCESS_DAEMONIZE 101 +#define NEBTYPE_PROCESS_RESTART 102 +#define NEBTYPE_PROCESS_SHUTDOWN 103 +#define NEBTYPE_PROCESS_PRELAUNCH 104 /* before objects are read or verified */ +#define NEBTYPE_PROCESS_EVENTLOOPSTART 105 +#define NEBTYPE_PROCESS_EVENTLOOPEND 106 + +#define NEBTYPE_TIMEDEVENT_ADD 200 +#define NEBTYPE_TIMEDEVENT_REMOVE 201 +#define NEBTYPE_TIMEDEVENT_EXECUTE 202 +#define NEBTYPE_TIMEDEVENT_DELAY 203 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SKIP 204 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SLEEP 205 + +#define NEBTYPE_LOG_DATA 300 +#define NEBTYPE_LOG_ROTATION 301 + +#define NEBTYPE_SYSTEM_COMMAND_START 400 +#define NEBTYPE_SYSTEM_COMMAND_END 401 + +#define NEBTYPE_EVENTHANDLER_START 500 +#define NEBTYPE_EVENTHANDLER_END 501 + +#define NEBTYPE_NOTIFICATION_START 600 +#define NEBTYPE_NOTIFICATION_END 601 +#define NEBTYPE_CONTACTNOTIFICATION_START 602 +#define NEBTYPE_CONTACTNOTIFICATION_END 603 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_START 604 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_END 605 + +#define NEBTYPE_SERVICECHECK_INITIATE 700 +#define NEBTYPE_SERVICECHECK_PROCESSED 701 +#define NEBTYPE_SERVICECHECK_RAW_START 702 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_RAW_END 703 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_ASYNC_PRECHECK 704 + +#define NEBTYPE_HOSTCHECK_INITIATE 800 /* a check of the route to the host has been initiated */ +#define NEBTYPE_HOSTCHECK_PROCESSED 801 /* the processed/final result of a host check */ +#define NEBTYPE_HOSTCHECK_RAW_START 802 /* the start of a "raw" host check */ +#define NEBTYPE_HOSTCHECK_RAW_END 803 /* a finished "raw" host check */ +#define NEBTYPE_HOSTCHECK_ASYNC_PRECHECK 804 +#define NEBTYPE_HOSTCHECK_SYNC_PRECHECK 805 + +#define NEBTYPE_COMMENT_ADD 900 +#define NEBTYPE_COMMENT_DELETE 901 +#define NEBTYPE_COMMENT_LOAD 902 + +#define NEBTYPE_FLAPPING_START 1000 +#define NEBTYPE_FLAPPING_STOP 1001 + +#define NEBTYPE_DOWNTIME_ADD 1100 +#define NEBTYPE_DOWNTIME_DELETE 1101 +#define NEBTYPE_DOWNTIME_LOAD 1102 +#define NEBTYPE_DOWNTIME_START 1103 +#define NEBTYPE_DOWNTIME_STOP 1104 + +#define NEBTYPE_PROGRAMSTATUS_UPDATE 1200 +#define NEBTYPE_HOSTSTATUS_UPDATE 1201 +#define NEBTYPE_SERVICESTATUS_UPDATE 1202 +#define NEBTYPE_CONTACTSTATUS_UPDATE 1203 + +#define NEBTYPE_ADAPTIVEPROGRAM_UPDATE 1300 +#define NEBTYPE_ADAPTIVEHOST_UPDATE 1301 +#define NEBTYPE_ADAPTIVESERVICE_UPDATE 1302 +#define NEBTYPE_ADAPTIVECONTACT_UPDATE 1303 + +#define NEBTYPE_EXTERNALCOMMAND_START 1400 +#define NEBTYPE_EXTERNALCOMMAND_END 1401 + +#define NEBTYPE_AGGREGATEDSTATUS_STARTDUMP 1500 +#define NEBTYPE_AGGREGATEDSTATUS_ENDDUMP 1501 + +#define NEBTYPE_RETENTIONDATA_STARTLOAD 1600 +#define NEBTYPE_RETENTIONDATA_ENDLOAD 1601 +#define NEBTYPE_RETENTIONDATA_STARTSAVE 1602 +#define NEBTYPE_RETENTIONDATA_ENDSAVE 1603 + +#define NEBTYPE_ACKNOWLEDGEMENT_ADD 1700 +#define NEBTYPE_ACKNOWLEDGEMENT_REMOVE 1701 /* NOT IMPLEMENTED */ +#define NEBTYPE_ACKNOWLEDGEMENT_LOAD 1702 /* NOT IMPLEMENTED */ + +#define NEBTYPE_STATECHANGE_START 1800 /* NOT IMPLEMENTED */ +#define NEBTYPE_STATECHANGE_END 1801 + + + +/****** EVENT FLAGS ************************/ + +#define NEBFLAG_NONE 0 +#define NEBFLAG_PROCESS_INITIATED 1 /* event was initiated by Nagios process */ +#define NEBFLAG_USER_INITIATED 2 /* event was initiated by a user request */ +#define NEBFLAG_MODULE_INITIATED 3 /* event was initiated by an event broker module */ + + + + +/****** EVENT ATTRIBUTES *******************/ + +#define NEBATTR_NONE 0 + +#define NEBATTR_SHUTDOWN_NORMAL 1 +#define NEBATTR_SHUTDOWN_ABNORMAL 2 +#define NEBATTR_RESTART_NORMAL 4 +#define NEBATTR_RESTART_ABNORMAL 8 + +#define NEBATTR_FLAPPING_STOP_NORMAL 1 +#define NEBATTR_FLAPPING_STOP_DISABLED 2 /* flapping stopped because flap detection was disabled */ + +#define NEBATTR_DOWNTIME_STOP_NORMAL 1 +#define NEBATTR_DOWNTIME_STOP_CANCELLED 2 + + + +/****** EVENT BROKER FUNCTIONS *************/ + +#ifdef USE_EVENT_BROKER +#include "compat.h" +NAGIOS_BEGIN_DECL + +struct timeval get_broker_timestamp(struct timeval *); +void broker_program_state(int, int, int, struct timeval *); +void broker_timed_event(int, int, int, timed_event *, struct timeval *); +void broker_log_data(int, int, int, char *, unsigned long, time_t, struct timeval *); +int broker_event_handler(int, int, int, int, void *, int, int, struct timeval, struct timeval, double, int, int, int, char *, char *, char *, struct timeval *); +void broker_system_command(int, int, int, struct timeval, struct timeval, double, int, int, int, char *, char *, struct timeval *); +int broker_host_check(int, int, int, host *, int, int, int, struct timeval, struct timeval, char *, double, double, int, int, int, char *, char *, char *, char *, struct timeval *); +int broker_service_check(int, int, int, service *, int, struct timeval, struct timeval, char *, double, double, int, int, int, char *, struct timeval *); +void broker_comment_data(int, int, int, int, int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long, struct timeval *); +void broker_downtime_data(int, int, int, int, char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long, struct timeval *); +void broker_flapping_data(int, int, int, int, void *, double, double, double, struct timeval *); +void broker_program_status(int, int, int, struct timeval *); +void broker_host_status(int, int, int, host *, struct timeval *); +void broker_service_status(int, int, int, service *, struct timeval *); +void broker_contact_status(int, int, int, contact *, struct timeval *); +int broker_notification_data(int, int, int, int, int, struct timeval, struct timeval, void *, char *, char *, int, int, struct timeval *); +int broker_contact_notification_data(int, int, int, int, int, struct timeval, struct timeval, void *, contact *, char *, char *, int, struct timeval *); +int broker_contact_notification_method_data(int, int, int, int, int, struct timeval, struct timeval, void *, contact *, char *, char *, char *, int, struct timeval *); +void broker_adaptive_program_data(int, int, int, int, unsigned long, unsigned long, unsigned long, unsigned long, struct timeval *); +void broker_adaptive_host_data(int, int, int, host *, int, unsigned long, unsigned long, struct timeval *); +void broker_adaptive_service_data(int, int, int, service *, int, unsigned long, unsigned long, struct timeval *); +void broker_adaptive_contact_data(int, int, int, contact *, int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, struct timeval *); +void broker_external_command(int, int, int, int, time_t, char *, char *, struct timeval *); +void broker_aggregated_status_data(int, int, int, struct timeval *); +void broker_retention_data(int, int, int, struct timeval *); +void broker_acknowledgement_data(int, int, int, int, void *, char *, char *, int, int, int, struct timeval *); +void broker_statechange_data(int, int, int, int, void *, int, int, int, int, struct timeval *); + +NAGIOS_END_DECL +#endif + +#endif diff --git a/include/cgiauth.h b/include/cgiauth.h new file mode 100644 index 0000000..53ad9c9 --- /dev/null +++ b/include/cgiauth.h @@ -0,0 +1,72 @@ +/***************************************************************************** + * + * CGIAUTH.H - Authorization utilities header file + * + * Last Modified: 11-24-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _AUTH_H +#define _AUTH_H +#include "compat.h" +#include "common.h" +#include "objects.h" + +NAGIOS_BEGIN_DECL + +typedef struct authdata_struct { + char *username; + int authorized_for_all_hosts; + int authorized_for_all_host_commands; + int authorized_for_all_services; + int authorized_for_all_service_commands; + int authorized_for_system_information; + int authorized_for_system_commands; + int authorized_for_configuration_information; + int authorized_for_read_only; + int authenticated; + } authdata; + + + +int get_authentication_information(authdata *); /* gets current authentication information */ + +int is_authorized_for_host(host *, authdata *); +int is_authorized_for_service(service *, authdata *); + +int is_authorized_for_all_hosts(authdata *); +int is_authorized_for_all_services(authdata *); + +int is_authorized_for_system_information(authdata *); +int is_authorized_for_system_commands(authdata *); +int is_authorized_for_host_commands(host *, authdata *); +int is_authorized_for_service_commands(service *, authdata *); + +int is_authorized_for_hostgroup(hostgroup *, authdata *); +int is_authorized_for_servicegroup(servicegroup *, authdata *); + +int is_authorized_for_hostgroup_commands(hostgroup *, authdata *); +int is_authorized_for_servicegroup_commands(servicegroup *, authdata *); + +int is_authorized_for_configuration_information(authdata *); + +int is_authorized_for_read_only(authdata *); + +NAGIOS_END_DECL + +#endif diff --git a/include/cgiutils.h b/include/cgiutils.h new file mode 100644 index 0000000..fcf69ed --- /dev/null +++ b/include/cgiutils.h @@ -0,0 +1,488 @@ +/************************************************************************ + * + * CGIUTILS.H - Header file for common CGI functions + * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-15-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _CGIUTILS_H +#define _CGIUTILS_H +#include "compat.h" +#include "logging.h" +#include "objects.h" +#include "cgiauth.h" + +NAGIOS_BEGIN_DECL + + /**************************** CGI REFRESH RATE ******************************/ + +#define DEFAULT_REFRESH_RATE 60 /* 60 second refresh rate for CGIs */ + + + /******************************* CGI NAMES **********************************/ + +#define STATUS_CGI "status.cgi" +#define STATUSMAP_CGI "statusmap.cgi" +#define STATUSWORLD_CGI "statuswrl.cgi" +#define COMMAND_CGI "cmd.cgi" +#define EXTINFO_CGI "extinfo.cgi" +#define SHOWLOG_CGI "showlog.cgi" +#define NOTIFICATIONS_CGI "notifications.cgi" +#define HISTORY_CGI "history.cgi" +#define CONFIG_CGI "config.cgi" +#define OUTAGES_CGI "outages.cgi" +#define TRENDS_CGI "trends.cgi" +#define AVAIL_CGI "avail.cgi" +#define TAC_CGI "tac.cgi" +#define STATUSWML_CGI "statuswml.cgi" +#define TRACEROUTE_CGI "traceroute.cgi" +#define HISTOGRAM_CGI "histogram.cgi" +#define CHECKSANITY_CGI "checksanity.cgi" +#define MINISTATUS_CGI "ministatus.cgi" +#define SUMMARY_CGI "summary.cgi" + + + /**************************** STYLE SHEET NAMES ******************************/ + +#define COMMON_CSS "common.css" + +#define SHOWLOG_CSS "showlog.css" +#define STATUS_CSS "status.css" +#define STATUSMAP_CSS "statusmap.css" +#define COMMAND_CSS "cmd.css" +#define EXTINFO_CSS "extinfo.css" +#define NOTIFICATIONS_CSS "notifications.css" +#define HISTORY_CSS "history.css" +#define CONFIG_CSS "config.css" +#define OUTAGES_CSS "outages.css" +#define TRENDS_CSS "trends.css" +#define AVAIL_CSS "avail.css" +#define TAC_CSS "tac.css" +#define HISTOGRAM_CSS "histogram.css" +#define CHECKSANITY_CSS "checksanity.css" +#define MINISTATUS_CSS "ministatus.css" +#define SUMMARY_CSS "summary.css" + + /********************************* JAVASCRIPT INCLUDES **********************/ +#define JQUERY_JS "jquery-1.7.1.min.js" + + /********************************* ICONS ************************************/ + +#define STATUS_ICON_WIDTH 20 +#define STATUS_ICON_HEIGHT 20 + +#define INFO_ICON "info.png" +#define INFO_ICON_ALT "Informational Message" +#define START_ICON "start.gif" +#define START_ICON_ALT "Program Start" +#define STOP_ICON "stop.gif" +#define STOP_ICON_ALT "Program End" +#define RESTART_ICON "restart.gif" +#define RESTART_ICON_ALT "Program Restart" +#define OK_ICON "recovery.png" +#define OK_ICON_ALT "Service Ok" +#define CRITICAL_ICON "critical.png" +#define CRITICAL_ICON_ALT "Service Critical" +#define WARNING_ICON "warning.png" +#define WARNING_ICON_ALT "Service Warning" +#define UNKNOWN_ICON "unknown.png" +#define UNKNOWN_ICON_ALT "Service Unknown" +#define NOTIFICATION_ICON "notify.gif" +#define NOTIFICATION_ICON_ALT "Service Notification" +#define LOG_ROTATION_ICON "logrotate.png" +#define LOG_ROTATION_ICON_ALT "Log Rotation" +#define EXTERNAL_COMMAND_ICON "command.png" +#define EXTERNAL_COMMAND_ICON_ALT "External Command" + +#define STATUS_DETAIL_ICON "status2.gif" +#define STATUS_OVERVIEW_ICON "status.gif" +#define STATUSMAP_ICON "status3.gif" +#define STATUSWORLD_ICON "status4.gif" +#define EXTINFO_ICON "extinfo.gif" +#define HISTORY_ICON "history.gif" +#define CONTACTGROUP_ICON "contactgroup.gif" +#define TRENDS_ICON "trends.gif" + +#define DISABLED_ICON "disabled.gif" +#define ENABLED_ICON "enabled.gif" +#define PASSIVE_ONLY_ICON "passiveonly.gif" +#define NOTIFICATIONS_DISABLED_ICON "ndisabled.gif" +#define ACKNOWLEDGEMENT_ICON "ack.gif" +#define REMOVE_ACKNOWLEDGEMENT_ICON "noack.gif" +#define COMMENT_ICON "comment.gif" +#define DELETE_ICON "delete.gif" +#define DELAY_ICON "delay.gif" +#define DOWNTIME_ICON "downtime.gif" +#define PASSIVE_ICON "passiveonly.gif" +#define RIGHT_ARROW_ICON "right.gif" +#define LEFT_ARROW_ICON "left.gif" +#define UP_ARROW_ICON "up.gif" +#define DOWN_ARROW_ICON "down.gif" +#define FLAPPING_ICON "flapping.gif" +#define SCHEDULED_DOWNTIME_ICON "downtime.gif" +#define EMPTY_ICON "empty.gif" + +#define ACTIVE_ICON "active.gif" +#define ACTIVE_ICON_ALT "Active Mode" +#define STANDBY_ICON "standby.gif" +#define STANDBY_ICON_ALT "Standby Mode" + +#define HOST_DOWN_ICON "critical.png" +#define HOST_DOWN_ICON_ALT "Host Down" +#define HOST_UNREACHABLE_ICON "critical.png" +#define HOST_UNREACHABLE_ICON_ALT "Host Unreachable" +#define HOST_UP_ICON "recovery.png" +#define HOST_UP_ICON_ALT "Host Up" +#define HOST_NOTIFICATION_ICON "notify.gif" +#define HOST_NOTIFICATION_ICON_ALT "Host Notification" + +#define SERVICE_EVENT_ICON "serviceevent.gif" +#define SERVICE_EVENT_ICON_ALT "Service Event Handler" +#define HOST_EVENT_ICON "hostevent.gif" +#define HOST_EVENT_ICON_ALT "Host Event Handler" + +#define THERM_OK_IMAGE "thermok.png" +#define THERM_WARNING_IMAGE "thermwarn.png" +#define THERM_CRITICAL_IMAGE "thermcrit.png" + +#define CONFIGURATION_ICON "config.gif" +#define NOTES_ICON "notes.gif" +#define ACTION_ICON "action.gif" +#define DETAIL_ICON "detail.gif" + +#define PARENT_TRAVERSAL_ICON "parentup.gif" + +#define TAC_DISABLED_ICON "tacdisabled.png" +#define TAC_ENABLED_ICON "tacenabled.png" + +#define ZOOM1_ICON "zoom1.gif" +#define ZOOM2_ICON "zoom2.gif" + +#define CONTEXT_HELP_ICON1 "contexthelp1.gif" +#define CONTEXT_HELP_ICON2 "contexthelp2.gif" + +#define SPLUNK_SMALL_WHITE_ICON "splunk1.gif" +#define SPLUNK_SMALL_BLACK_ICON "splunk2.gif" + +#define FIRST_PAGE_ICON "b_first2.png" +#define LAST_PAGE_ICON "b_last2.png" +#define NEXT_PAGE_ICON "b_next2.png" +#define PREVIOUS_PAGE_ICON "b_prev2.png" + + + /************************** PLUGIN RETURN VALUES ****************************/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ + + + /********************* EXTENDED INFO CGI DISPLAY TYPES *********************/ + +#define DISPLAY_PROCESS_INFO 0 +#define DISPLAY_HOST_INFO 1 +#define DISPLAY_SERVICE_INFO 2 +#define DISPLAY_COMMENTS 3 +#define DISPLAY_PERFORMANCE 4 +#define DISPLAY_HOSTGROUP_INFO 5 +#define DISPLAY_DOWNTIME 6 +#define DISPLAY_SCHEDULING_QUEUE 7 +#define DISPLAY_SERVICEGROUP_INFO 8 + + + /************************ COMMAND CGI COMMAND MODES *************************/ + +#define CMDMODE_NONE 0 +#define CMDMODE_REQUEST 1 +#define CMDMODE_COMMIT 2 + + + + /******************** HOST AND SERVICE NOTIFICATION TYPES ******************/ + +#define NOTIFICATION_ALL 0 /* all service and host notifications */ +#define NOTIFICATION_SERVICE_ALL 1 /* all types of service notifications */ +#define NOTIFICATION_HOST_ALL 2 /* all types of host notifications */ +#define NOTIFICATION_SERVICE_WARNING 4 +#define NOTIFICATION_SERVICE_UNKNOWN 8 +#define NOTIFICATION_SERVICE_CRITICAL 16 +#define NOTIFICATION_SERVICE_RECOVERY 32 +#define NOTIFICATION_HOST_DOWN 64 +#define NOTIFICATION_HOST_UNREACHABLE 128 +#define NOTIFICATION_HOST_RECOVERY 256 +#define NOTIFICATION_SERVICE_ACK 512 +#define NOTIFICATION_HOST_ACK 1024 +#define NOTIFICATION_SERVICE_FLAP 2048 +#define NOTIFICATION_HOST_FLAP 4096 +#define NOTIFICATION_SERVICE_CUSTOM 8192 +#define NOTIFICATION_HOST_CUSTOM 16384 + + + /********************** HOST AND SERVICE ALERT TYPES **********************/ + +#define HISTORY_ALL 0 /* all service and host alert */ +#define HISTORY_SERVICE_ALL 1 /* all types of service alerts */ +#define HISTORY_HOST_ALL 2 /* all types of host alerts */ +#define HISTORY_SERVICE_WARNING 4 +#define HISTORY_SERVICE_UNKNOWN 8 +#define HISTORY_SERVICE_CRITICAL 16 +#define HISTORY_SERVICE_RECOVERY 32 +#define HISTORY_HOST_DOWN 64 +#define HISTORY_HOST_UNREACHABLE 128 +#define HISTORY_HOST_RECOVERY 256 + + + /****************************** SORT TYPES *******************************/ + +#define SORT_NONE 0 +#define SORT_ASCENDING 1 +#define SORT_DESCENDING 2 + + + /***************************** SORT OPTIONS ******************************/ + +#define SORT_NOTHING 0 +#define SORT_HOSTNAME 1 +#define SORT_SERVICENAME 2 +#define SORT_SERVICESTATUS 3 +#define SORT_LASTCHECKTIME 4 +#define SORT_CURRENTATTEMPT 5 +#define SORT_STATEDURATION 6 +#define SORT_NEXTCHECKTIME 7 +#define SORT_HOSTSTATUS 8 +#define SORT_HOSTURGENCY 9 + + + /****************** HOST AND SERVICE FILTER PROPERTIES *******************/ + +#define HOST_SCHEDULED_DOWNTIME 1 +#define HOST_NO_SCHEDULED_DOWNTIME 2 +#define HOST_STATE_ACKNOWLEDGED 4 +#define HOST_STATE_UNACKNOWLEDGED 8 +#define HOST_CHECKS_DISABLED 16 +#define HOST_CHECKS_ENABLED 32 +#define HOST_EVENT_HANDLER_DISABLED 64 +#define HOST_EVENT_HANDLER_ENABLED 128 +#define HOST_FLAP_DETECTION_DISABLED 256 +#define HOST_FLAP_DETECTION_ENABLED 512 +#define HOST_IS_FLAPPING 1024 +#define HOST_IS_NOT_FLAPPING 2048 +#define HOST_NOTIFICATIONS_DISABLED 4096 +#define HOST_NOTIFICATIONS_ENABLED 8192 +#define HOST_PASSIVE_CHECKS_DISABLED 16384 +#define HOST_PASSIVE_CHECKS_ENABLED 32768 +#define HOST_PASSIVE_CHECK 65536 +#define HOST_ACTIVE_CHECK 131072 +#define HOST_HARD_STATE 262144 +#define HOST_SOFT_STATE 524288 + + +#define SERVICE_SCHEDULED_DOWNTIME 1 +#define SERVICE_NO_SCHEDULED_DOWNTIME 2 +#define SERVICE_STATE_ACKNOWLEDGED 4 +#define SERVICE_STATE_UNACKNOWLEDGED 8 +#define SERVICE_CHECKS_DISABLED 16 +#define SERVICE_CHECKS_ENABLED 32 +#define SERVICE_EVENT_HANDLER_DISABLED 64 +#define SERVICE_EVENT_HANDLER_ENABLED 128 +#define SERVICE_FLAP_DETECTION_ENABLED 256 +#define SERVICE_FLAP_DETECTION_DISABLED 512 +#define SERVICE_IS_FLAPPING 1024 +#define SERVICE_IS_NOT_FLAPPING 2048 +#define SERVICE_NOTIFICATIONS_DISABLED 4096 +#define SERVICE_NOTIFICATIONS_ENABLED 8192 +#define SERVICE_PASSIVE_CHECKS_DISABLED 16384 +#define SERVICE_PASSIVE_CHECKS_ENABLED 32768 +#define SERVICE_PASSIVE_CHECK 65536 +#define SERVICE_ACTIVE_CHECK 131072 +#define SERVICE_HARD_STATE 262144 +#define SERVICE_SOFT_STATE 524288 + + + /****************************** SSI TYPES ********************************/ + +#define SSI_HEADER 0 +#define SSI_FOOTER 1 + + + + /************************ CONTEXT-SENSITIVE HELP *************************/ + +#define CONTEXTHELP_STATUS_DETAIL "A1" +#define CONTEXTHELP_STATUS_HGOVERVIEW "A2" +#define CONTEXTHELP_STATUS_HGSUMMARY "A3" +#define CONTEXTHELP_STATUS_HGGRID "A4" +#define CONTEXTHELP_STATUS_SVCPROBLEMS "A5" +#define CONTEXTHELP_STATUS_HOST_DETAIL "A6" +#define CONTEXTHELP_STATUS_HOSTPROBLEMS "A7" +#define CONTEXTHELP_STATUS_SGOVERVIEW "A8" +#define CONTEXTHELP_STATUS_SGSUMMARY "A9" +#define CONTEXTHELP_STATUS_SGGRID "A10" + +#define CONTEXTHELP_TAC "B1" + +#define CONTEXTHELP_MAP "C1" + +#define CONTEXTHELP_LOG "D1" + +#define CONTEXTHELP_HISTORY "E1" + +#define CONTEXTHELP_NOTIFICATIONS "F1" + +#define CONTEXTHELP_TRENDS_MENU1 "G1" +#define CONTEXTHELP_TRENDS_MENU2 "G2" +#define CONTEXTHELP_TRENDS_MENU3 "G3" +#define CONTEXTHELP_TRENDS_MENU4 "G4" +#define CONTEXTHELP_TRENDS_HOST "G5" +#define CONTEXTHELP_TRENDS_SERVICE "G6" + +#define CONTEXTHELP_AVAIL_MENU1 "H1" +#define CONTEXTHELP_AVAIL_MENU2 "H2" +#define CONTEXTHELP_AVAIL_MENU3 "H3" +#define CONTEXTHELP_AVAIL_MENU4 "H4" +#define CONTEXTHELP_AVAIL_MENU5 "H5" +#define CONTEXTHELP_AVAIL_HOSTGROUP "H6" +#define CONTEXTHELP_AVAIL_HOST "H7" +#define CONTEXTHELP_AVAIL_SERVICE "H8" +#define CONTEXTHELP_AVAIL_SERVICEGROUP "H9" + +#define CONTEXTHELP_EXT_HOST "I1" +#define CONTEXTHELP_EXT_SERVICE "I2" +#define CONTEXTHELP_EXT_HOSTGROUP "I3" +#define CONTEXTHELP_EXT_PROCESS "I4" +#define CONTEXTHELP_EXT_PERFORMANCE "I5" +#define CONTEXTHELP_EXT_COMMENTS "I6" +#define CONTEXTHELP_EXT_DOWNTIME "I7" +#define CONTEXTHELP_EXT_QUEUE "I8" +#define CONTEXTHELP_EXT_SERVICEGROUP "I9" + +#define CONTEXTHELP_CMD_INPUT "J1" +#define CONTEXTHELP_CMD_COMMIT "J2" + +#define CONTEXTHELP_OUTAGES "K1" + +#define CONTEXTHELP_CONFIG_MENU "L1" +#define CONTEXTHELP_CONFIG_HOSTS "L2" +#define CONTEXTHELP_CONFIG_HOSTDEPENDENCIES "L3" +#define CONTEXTHELP_CONFIG_HOSTESCALATIONS "L4" +#define CONTEXTHELP_CONFIG_HOSTGROUPS "L5" +#define CONTEXTHELP_CONFIG_HOSTGROUPESCALATIONS "L6" +#define CONTEXTHELP_CONFIG_SERVICES "L7" +#define CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES "L8" +#define CONTEXTHELP_CONFIG_SERVICEESCALATIONS "L9" +#define CONTEXTHELP_CONFIG_CONTACTS "L10" +#define CONTEXTHELP_CONFIG_CONTACTGROUPS "L11" +#define CONTEXTHELP_CONFIG_TIMEPERIODS "L12" +#define CONTEXTHELP_CONFIG_COMMANDS "L13" +#define CONTEXTHELP_CONFIG_HOSTEXTINFO "L14" +#define CONTEXTHELP_CONFIG_SERVICEEXTINFO "L15" +#define CONTEXTHELP_CONFIG_SERVICEGROUPS "L16" + +#define CONTEXTHELP_HISTOGRAM_MENU1 "M1" +#define CONTEXTHELP_HISTOGRAM_MENU2 "M2" +#define CONTEXTHELP_HISTOGRAM_MENU3 "M3" +#define CONTEXTHELP_HISTOGRAM_MENU4 "M4" +#define CONTEXTHELP_HISTOGRAM_HOST "M5" +#define CONTEXTHELP_HISTOGRAM_SERVICE "M6" + +#define CONTEXTHELP_SUMMARY_MENU "N1" +#define CONTEXTHELP_SUMMARY_RECENT_ALERTS "N2" +#define CONTEXTHELP_SUMMARY_ALERT_TOTALS "N3" +#define CONTEXTHELP_SUMMARY_HOSTGROUP_ALERT_TOTALS "N4" +#define CONTEXTHELP_SUMMARY_HOST_ALERT_TOTALS "N5" +#define CONTEXTHELP_SUMMARY_SERVICE_ALERT_TOTALS "N6" +#define CONTEXTHELP_SUMMARY_ALERT_PRODUCERS "N7" +#define CONTEXTHELP_SUMMARY_SERVICEGROUP_ALERT_TOTALS "N8" + + + /************************** LIFO RETURN CODES ****************************/ + +#define LIFO_OK 0 +#define LIFO_ERROR_MEMORY 1 +#define LIFO_ERROR_FILE 2 +#define LIFO_ERROR_DATA 3 + + + + + +/*************************** DATA STRUCTURES *****************************/ + +/* LIFO data structure */ +typedef struct lifo_struct { + char *data; + struct lifo_struct *next; + } lifo; + +/******************************** FUNCTIONS *******************************/ + +void reset_cgi_vars(void); +void free_memory(void); + +char *get_cgi_config_location(void); /* gets location of the CGI config file to read */ +char *get_cmd_file_location(void); /* gets location of external command file to write to */ + +int read_cgi_config_file(char *); +int read_main_config_file(char *); +int read_all_object_configuration_data(char *, int); +int read_all_status_data(char *, int); + +char *unescape_newlines(char *); +void sanitize_plugin_output(char *); /* strips HTML and bad characters from plugin output */ +void strip_html_brackets(char *); /* strips > and < from string */ + +void get_time_string(time_t *, char *, int, int); /* gets a date/time string */ +void get_interval_time_string(double, char *, int); /* gets a time string for an interval of time */ + +char *url_encode(char *); /* encodes a string in proper URL format */ +char *html_encode(char *, int); /* encodes a string in HTML format (for what the user sees) */ +char *escape_string(char *); /* escape string for html form usage */ + +void get_log_archive_to_use(int, char *, int); /* determines the name of the log archive to use */ +void determine_log_rotation_times(int); +int determine_archive_to_use_from_time(time_t); + +void print_extra_hostgroup_url(char *, char *); +void print_extra_servicegroup_url(char *, char *); + +void display_info_table(char *, int, authdata *); +void display_nav_table(char *, int); + +void display_splunk_host_url(host *); +void display_splunk_service_url(service *); +void display_splunk_generic_url(char *, int); +void strip_splunk_query_terms(char *); + +void include_ssi_files(char *, int); /* include user-defined SSI footers/headers */ +void include_ssi_file(char *); /* include user-defined SSI footer/header */ + +void cgi_config_file_error(char *); +void main_config_file_error(char *); +void object_data_error(void); +void status_data_error(void); + +void display_context_help(char *); /* displays context-sensitive help window */ + +int read_file_into_lifo(char *); /* LIFO functions */ +void free_lifo_memory(void); +int push_lifo(char *); +char *pop_lifo(void); + +NAGIOS_END_DECL +#endif diff --git a/include/comments.h b/include/comments.h new file mode 100644 index 0000000..9ea8fa3 --- /dev/null +++ b/include/comments.h @@ -0,0 +1,126 @@ +/***************************************************************************** + * + * COMMENTS.H - Header file for comment functions + * + * Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-26-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _COMMENTS_H +#define _COMMENTS_H +#include "compat.h" +#include "common.h" +#include "objects.h" + + +/**************************** COMMENT SOURCES ******************************/ + +#define COMMENTSOURCE_INTERNAL 0 +#define COMMENTSOURCE_EXTERNAL 1 + + + +/***************************** COMMENT TYPES *******************************/ + +#define HOST_COMMENT 1 +#define SERVICE_COMMENT 2 + + +/****************************** ENTRY TYPES ********************************/ + +#define USER_COMMENT 1 +#define DOWNTIME_COMMENT 2 +#define FLAPPING_COMMENT 3 +#define ACKNOWLEDGEMENT_COMMENT 4 + + +/*************************** CHAINED HASH LIMITS ***************************/ + +#define COMMENT_HASHSLOTS 1024 + + +/**************************** DATA STRUCTURES ******************************/ + +NAGIOS_BEGIN_DECL + +/* COMMENT structure */ +typedef struct comment_struct { + int comment_type; + int entry_type; + unsigned long comment_id; + int source; + int persistent; + time_t entry_time; + int expires; + time_t expire_time; + char *host_name; + char *service_description; + char *author; + char *comment_data; + struct comment_struct *next; + struct comment_struct *nexthash; + } comment; + + +#ifdef NSCORE +int initialize_comment_data(char *); /* initializes comment data */ +int cleanup_comment_data(char *); /* cleans up comment data */ +int add_new_comment(int, int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); /* adds a new host or service comment */ +int add_new_host_comment(int, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); /* adds a new host comment */ +int add_new_service_comment(int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); /* adds a new service comment */ +int delete_comment(int, unsigned long); /* deletes a host or service comment */ +int delete_host_comment(unsigned long); /* deletes a host comment */ +int delete_service_comment(unsigned long); /* deletes a service comment */ +int delete_all_comments(int, char *, char *); /* deletes all comments for a particular host or service */ +int delete_all_host_comments(char *); /* deletes all comments for a specific host */ +int delete_host_acknowledgement_comments(host *); /* deletes all non-persistent ack comments for a specific host */ +int delete_all_service_comments(char *, char *); /* deletes all comments for a specific service */ +int delete_service_acknowledgement_comments(service *); /* deletes all non-persistent ack comments for a specific service */ + +int check_for_expired_comment(unsigned long); /* expires a comment */ +#endif + +comment *find_comment(unsigned long, int); /* finds a specific comment */ +comment *find_service_comment(unsigned long); /* finds a specific service comment */ +comment *find_host_comment(unsigned long); /* finds a specific host comment */ + +comment *get_first_comment_by_host(char *); +comment *get_next_comment_by_host(char *, comment *); + +int number_of_host_comments(char *); /* returns the number of comments associated with a particular host */ +int number_of_service_comments(char *, char *); /* returns the number of comments associated with a particular service */ + +/* If you are going to be adding a lot of comments in sequence, set + defer_comment_sorting to 1 before you start and then call + sort_comments afterwards. Things will go MUCH faster. */ + +extern int defer_comment_sorting; +int add_comment(int, int, char *, char *, time_t, char *, char *, unsigned long, int, int, time_t, int); /* adds a comment (host or service) */ +int sort_comments(void); +int add_host_comment(int, char *, time_t, char *, char *, unsigned long, int, int, time_t, int); /* adds a host comment */ +int add_service_comment(int, char *, char *, time_t, char *, char *, unsigned long, int, int, time_t, int); /* adds a service comment */ + +int add_comment_to_hashlist(comment *); + +void free_comment_data(void); /* frees memory allocated to the comment list */ + +NAGIOS_BEGIN_DECL + +#endif diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..84fd102 --- /dev/null +++ b/include/common.h @@ -0,0 +1,503 @@ +/************************************************************************ + * + * Nagios Common Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-22-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#include "shared.h" + +#define PROGRAM_VERSION "3.5.1" +#define PROGRAM_MODIFICATION_DATE "08-30-2013" + +/*#define DEBUG_CHECK_IPC 1 */ +/*#define DEBUG_CHECK_IPC2 1*/ + + + +/* daemon is thread safe */ +#ifdef NSCORE +#ifndef _REENTRANT +#define _REENTRANT +#endif +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif +#endif + +/* Experimental performance tweaks - use with caution */ +#undef USE_MEMORY_PERFORMANCE_TWEAKS + +/* my_free has been freed from bondage as a function */ +#define my_free(ptr) do { if(ptr) { free(ptr); ptr = NULL; } } while(0) + + + +/***************************** COMMANDS *********************************/ + +#define CMD_NONE 0 + +#define CMD_ADD_HOST_COMMENT 1 +#define CMD_DEL_HOST_COMMENT 2 + +#define CMD_ADD_SVC_COMMENT 3 +#define CMD_DEL_SVC_COMMENT 4 + +#define CMD_ENABLE_SVC_CHECK 5 +#define CMD_DISABLE_SVC_CHECK 6 + +#define CMD_SCHEDULE_SVC_CHECK 7 + +#define CMD_DELAY_SVC_NOTIFICATION 9 + +#define CMD_DELAY_HOST_NOTIFICATION 10 + +#define CMD_DISABLE_NOTIFICATIONS 11 +#define CMD_ENABLE_NOTIFICATIONS 12 + +#define CMD_RESTART_PROCESS 13 +#define CMD_SHUTDOWN_PROCESS 14 + +#define CMD_ENABLE_HOST_SVC_CHECKS 15 +#define CMD_DISABLE_HOST_SVC_CHECKS 16 + +#define CMD_SCHEDULE_HOST_SVC_CHECKS 17 + +#define CMD_DELAY_HOST_SVC_NOTIFICATIONS 19 /* currently unimplemented */ + +#define CMD_DEL_ALL_HOST_COMMENTS 20 +#define CMD_DEL_ALL_SVC_COMMENTS 21 + +#define CMD_ENABLE_SVC_NOTIFICATIONS 22 +#define CMD_DISABLE_SVC_NOTIFICATIONS 23 +#define CMD_ENABLE_HOST_NOTIFICATIONS 24 +#define CMD_DISABLE_HOST_NOTIFICATIONS 25 +#define CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST 26 +#define CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST 27 +#define CMD_ENABLE_HOST_SVC_NOTIFICATIONS 28 +#define CMD_DISABLE_HOST_SVC_NOTIFICATIONS 29 + +#define CMD_PROCESS_SERVICE_CHECK_RESULT 30 + +#define CMD_SAVE_STATE_INFORMATION 31 +#define CMD_READ_STATE_INFORMATION 32 + +#define CMD_ACKNOWLEDGE_HOST_PROBLEM 33 +#define CMD_ACKNOWLEDGE_SVC_PROBLEM 34 + +#define CMD_START_EXECUTING_SVC_CHECKS 35 +#define CMD_STOP_EXECUTING_SVC_CHECKS 36 + +#define CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS 37 +#define CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS 38 + +#define CMD_ENABLE_PASSIVE_SVC_CHECKS 39 +#define CMD_DISABLE_PASSIVE_SVC_CHECKS 40 + +#define CMD_ENABLE_EVENT_HANDLERS 41 +#define CMD_DISABLE_EVENT_HANDLERS 42 + +#define CMD_ENABLE_HOST_EVENT_HANDLER 43 +#define CMD_DISABLE_HOST_EVENT_HANDLER 44 + +#define CMD_ENABLE_SVC_EVENT_HANDLER 45 +#define CMD_DISABLE_SVC_EVENT_HANDLER 46 + +#define CMD_ENABLE_HOST_CHECK 47 +#define CMD_DISABLE_HOST_CHECK 48 + +#define CMD_START_OBSESSING_OVER_SVC_CHECKS 49 +#define CMD_STOP_OBSESSING_OVER_SVC_CHECKS 50 + +#define CMD_REMOVE_HOST_ACKNOWLEDGEMENT 51 +#define CMD_REMOVE_SVC_ACKNOWLEDGEMENT 52 + +#define CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS 53 +#define CMD_SCHEDULE_FORCED_SVC_CHECK 54 + +#define CMD_SCHEDULE_HOST_DOWNTIME 55 +#define CMD_SCHEDULE_SVC_DOWNTIME 56 + +#define CMD_ENABLE_HOST_FLAP_DETECTION 57 +#define CMD_DISABLE_HOST_FLAP_DETECTION 58 + +#define CMD_ENABLE_SVC_FLAP_DETECTION 59 +#define CMD_DISABLE_SVC_FLAP_DETECTION 60 + +#define CMD_ENABLE_FLAP_DETECTION 61 +#define CMD_DISABLE_FLAP_DETECTION 62 + +#define CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS 63 +#define CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS 64 + +#define CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS 65 +#define CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS 66 + +#define CMD_ENABLE_HOSTGROUP_SVC_CHECKS 67 +#define CMD_DISABLE_HOSTGROUP_SVC_CHECKS 68 + +#define CMD_CANCEL_HOST_DOWNTIME 69 /* not internally implemented */ +#define CMD_CANCEL_SVC_DOWNTIME 70 /* not internally implemented */ + +#define CMD_CANCEL_ACTIVE_HOST_DOWNTIME 71 /* old - no longer used */ +#define CMD_CANCEL_PENDING_HOST_DOWNTIME 72 /* old - no longer used */ + +#define CMD_CANCEL_ACTIVE_SVC_DOWNTIME 73 /* old - no longer used */ +#define CMD_CANCEL_PENDING_SVC_DOWNTIME 74 /* old - no longer used */ + +#define CMD_CANCEL_ACTIVE_HOST_SVC_DOWNTIME 75 /* unimplemented */ +#define CMD_CANCEL_PENDING_HOST_SVC_DOWNTIME 76 /* unimplemented */ + +#define CMD_FLUSH_PENDING_COMMANDS 77 + +#define CMD_DEL_HOST_DOWNTIME 78 +#define CMD_DEL_SVC_DOWNTIME 79 + +#define CMD_ENABLE_FAILURE_PREDICTION 80 +#define CMD_DISABLE_FAILURE_PREDICTION 81 + +#define CMD_ENABLE_PERFORMANCE_DATA 82 +#define CMD_DISABLE_PERFORMANCE_DATA 83 + +#define CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME 84 +#define CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME 85 +#define CMD_SCHEDULE_HOST_SVC_DOWNTIME 86 + +/* new commands in Nagios 2.x found below... */ +#define CMD_PROCESS_HOST_CHECK_RESULT 87 + +#define CMD_START_EXECUTING_HOST_CHECKS 88 +#define CMD_STOP_EXECUTING_HOST_CHECKS 89 + +#define CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS 90 +#define CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS 91 + +#define CMD_ENABLE_PASSIVE_HOST_CHECKS 92 +#define CMD_DISABLE_PASSIVE_HOST_CHECKS 93 + +#define CMD_START_OBSESSING_OVER_HOST_CHECKS 94 +#define CMD_STOP_OBSESSING_OVER_HOST_CHECKS 95 + +#define CMD_SCHEDULE_HOST_CHECK 96 +#define CMD_SCHEDULE_FORCED_HOST_CHECK 98 + +#define CMD_START_OBSESSING_OVER_SVC 99 +#define CMD_STOP_OBSESSING_OVER_SVC 100 + +#define CMD_START_OBSESSING_OVER_HOST 101 +#define CMD_STOP_OBSESSING_OVER_HOST 102 + +#define CMD_ENABLE_HOSTGROUP_HOST_CHECKS 103 +#define CMD_DISABLE_HOSTGROUP_HOST_CHECKS 104 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 105 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 106 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 107 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 108 + +#define CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS 109 +#define CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS 110 + +#define CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS 111 +#define CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS 112 + +#define CMD_ENABLE_SERVICEGROUP_SVC_CHECKS 113 +#define CMD_DISABLE_SERVICEGROUP_SVC_CHECKS 114 + +#define CMD_ENABLE_SERVICEGROUP_HOST_CHECKS 115 +#define CMD_DISABLE_SERVICEGROUP_HOST_CHECKS 116 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 117 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 118 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 119 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 120 + +#define CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME 121 +#define CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME 122 + +#define CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER 123 +#define CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER 124 + +#define CMD_CHANGE_HOST_EVENT_HANDLER 125 +#define CMD_CHANGE_SVC_EVENT_HANDLER 126 + +#define CMD_CHANGE_HOST_CHECK_COMMAND 127 +#define CMD_CHANGE_SVC_CHECK_COMMAND 128 + +#define CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL 129 +#define CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL 130 +#define CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL 131 + +#define CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS 132 +#define CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS 133 + +#define CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME 134 + +#define CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS 135 +#define CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS 136 + +#define CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME 137 + +#define CMD_ENABLE_SERVICE_FRESHNESS_CHECKS 138 +#define CMD_DISABLE_SERVICE_FRESHNESS_CHECKS 139 + +#define CMD_ENABLE_HOST_FRESHNESS_CHECKS 140 +#define CMD_DISABLE_HOST_FRESHNESS_CHECKS 141 + +#define CMD_SET_HOST_NOTIFICATION_NUMBER 142 +#define CMD_SET_SVC_NOTIFICATION_NUMBER 143 + +/* new commands in Nagios 3.x found below... */ +#define CMD_CHANGE_HOST_CHECK_TIMEPERIOD 144 +#define CMD_CHANGE_SVC_CHECK_TIMEPERIOD 145 + +#define CMD_PROCESS_FILE 146 + +#define CMD_CHANGE_CUSTOM_HOST_VAR 147 +#define CMD_CHANGE_CUSTOM_SVC_VAR 148 +#define CMD_CHANGE_CUSTOM_CONTACT_VAR 149 + +#define CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS 150 +#define CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS 151 +#define CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS 152 +#define CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS 153 + +#define CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS 154 +#define CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS 155 +#define CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS 156 +#define CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS 157 + +#define CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL 158 + +#define CMD_SEND_CUSTOM_HOST_NOTIFICATION 159 +#define CMD_SEND_CUSTOM_SVC_NOTIFICATION 160 + +#define CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD 161 +#define CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD 162 +#define CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD 163 +#define CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD 164 + +#define CMD_CHANGE_HOST_MODATTR 165 +#define CMD_CHANGE_SVC_MODATTR 166 +#define CMD_CHANGE_CONTACT_MODATTR 167 +#define CMD_CHANGE_CONTACT_MODHATTR 168 +#define CMD_CHANGE_CONTACT_MODSATTR 169 + +#define CMD_DEL_DOWNTIME_BY_HOST_NAME 170 +#define CMD_DEL_DOWNTIME_BY_HOSTGROUP_NAME 171 +#define CMD_DEL_DOWNTIME_BY_START_TIME_COMMENT 172 + +/* custom command introduced in Nagios 3.x */ +#define CMD_CUSTOM_COMMAND 999 + + + +/************************ SERVICE CHECK TYPES ****************************/ + +#define SERVICE_CHECK_ACTIVE 0 /* Nagios performed the service check */ +#define SERVICE_CHECK_PASSIVE 1 /* the service check result was submitted by an external source */ + + +/************************** HOST CHECK TYPES *****************************/ + +#define HOST_CHECK_ACTIVE 0 /* Nagios performed the host check */ +#define HOST_CHECK_PASSIVE 1 /* the host check result was submitted by an external source */ + + +/************************ SERVICE STATE TYPES ****************************/ + +#define SOFT_STATE 0 +#define HARD_STATE 1 + + +/************************* SCHEDULED DOWNTIME TYPES **********************/ + +#define SERVICE_DOWNTIME 1 /* service downtime */ +#define HOST_DOWNTIME 2 /* host downtime */ +#define ANY_DOWNTIME 3 /* host or service downtime */ + + +/************************** NOTIFICATION OPTIONS *************************/ + +#define NOTIFICATION_OPTION_NONE 0 +#define NOTIFICATION_OPTION_BROADCAST 1 +#define NOTIFICATION_OPTION_FORCED 2 +#define NOTIFICATION_OPTION_INCREMENT 4 + + +/************************** ACKNOWLEDGEMENT TYPES ************************/ + +#define HOST_ACKNOWLEDGEMENT 0 +#define SERVICE_ACKNOWLEDGEMENT 1 + +#define ACKNOWLEDGEMENT_NONE 0 +#define ACKNOWLEDGEMENT_NORMAL 1 +#define ACKNOWLEDGEMENT_STICKY 2 + + +/**************************** DEPENDENCY TYPES ***************************/ + +#define NOTIFICATION_DEPENDENCY 1 +#define EXECUTION_DEPENDENCY 2 + + + +/********************** HOST/SERVICE CHECK OPTIONS ***********************/ + +#define CHECK_OPTION_NONE 0 /* no check options */ +#define CHECK_OPTION_FORCE_EXECUTION 1 /* force execution of a check (ignores disabled services/hosts, invalid timeperiods) */ +#define CHECK_OPTION_FRESHNESS_CHECK 2 /* this is a freshness check */ +#define CHECK_OPTION_ORPHAN_CHECK 4 /* this is an orphan check */ + + +/**************************** PROGRAM MODES ******************************/ + +#define STANDBY_MODE 0 +#define ACTIVE_MODE 1 + + +/************************** LOG ROTATION MODES ***************************/ + +#define LOG_ROTATION_NONE 0 +#define LOG_ROTATION_HOURLY 1 +#define LOG_ROTATION_DAILY 2 +#define LOG_ROTATION_WEEKLY 3 +#define LOG_ROTATION_MONTHLY 4 + + +/***************************** LOG VERSIONS ******************************/ + +#define LOG_VERSION_1 "1.0" +#define LOG_VERSION_2 "2.0" + + + +/*************************** CHECK STATISTICS ****************************/ + +#define ACTIVE_SCHEDULED_SERVICE_CHECK_STATS 0 +#define ACTIVE_ONDEMAND_SERVICE_CHECK_STATS 1 +#define PASSIVE_SERVICE_CHECK_STATS 2 +#define ACTIVE_SCHEDULED_HOST_CHECK_STATS 3 +#define ACTIVE_ONDEMAND_HOST_CHECK_STATS 4 +#define PASSIVE_HOST_CHECK_STATS 5 +#define ACTIVE_CACHED_HOST_CHECK_STATS 6 +#define ACTIVE_CACHED_SERVICE_CHECK_STATS 7 +#define EXTERNAL_COMMAND_STATS 8 +#define PARALLEL_HOST_CHECK_STATS 9 +#define SERIAL_HOST_CHECK_STATS 10 +#define MAX_CHECK_STATS_TYPES 11 + + +/************************* GENERAL DEFINITIONS **************************/ + +#define OK 0 +#define ERROR -2 /* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */ + + +#ifndef TRUE +#define TRUE 1 +#elif (TRUE!=1) +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#elif (FALSE!=0) +#define FALSE 0 +#endif + + +/****************** HOST CONFIG FILE READING OPTIONS ********************/ + +#define READ_HOSTS 1 +#define READ_HOSTGROUPS 2 +#define READ_CONTACTS 4 +#define READ_CONTACTGROUPS 8 +#define READ_SERVICES 16 +#define READ_COMMANDS 32 +#define READ_TIMEPERIODS 64 +#define READ_SERVICEESCALATIONS 128 +#define READ_HOSTGROUPESCALATIONS 256 /* no longer implemented */ +#define READ_SERVICEDEPENDENCIES 512 +#define READ_HOSTDEPENDENCIES 1024 +#define READ_HOSTESCALATIONS 2048 +#define READ_HOSTEXTINFO 4096 +#define READ_SERVICEEXTINFO 8192 +#define READ_SERVICEGROUPS 16384 + +#define READ_ALL_OBJECT_DATA READ_HOSTS | READ_HOSTGROUPS | READ_CONTACTS | READ_CONTACTGROUPS | READ_SERVICES | READ_COMMANDS | READ_TIMEPERIODS | READ_SERVICEESCALATIONS | READ_SERVICEDEPENDENCIES | READ_HOSTDEPENDENCIES | READ_HOSTESCALATIONS | READ_HOSTEXTINFO | READ_SERVICEEXTINFO | READ_SERVICEGROUPS + + +/************************** DATE RANGE TYPES ****************************/ + +#define DATERANGE_CALENDAR_DATE 0 /* 2008-12-25 */ +#define DATERANGE_MONTH_DATE 1 /* july 4 (specific month) */ +#define DATERANGE_MONTH_DAY 2 /* day 21 (generic month) */ +#define DATERANGE_MONTH_WEEK_DAY 3 /* 3rd thursday (specific month) */ +#define DATERANGE_WEEK_DAY 4 /* 3rd thursday (generic month) */ +#define DATERANGE_TYPES 5 + + +/************************** DATE/TIME TYPES *****************************/ + +#define LONG_DATE_TIME 0 +#define SHORT_DATE_TIME 1 +#define SHORT_DATE 2 +#define SHORT_TIME 3 +#define HTTP_DATE_TIME 4 /* time formatted for use in HTTP headers */ + + +/**************************** DATE FORMATS ******************************/ + +#define DATE_FORMAT_US 0 /* U.S. (MM-DD-YYYY HH:MM:SS) */ +#define DATE_FORMAT_EURO 1 /* European (DD-MM-YYYY HH:MM:SS) */ +#define DATE_FORMAT_ISO8601 2 /* ISO8601 (YYYY-MM-DD HH:MM:SS) */ +#define DATE_FORMAT_STRICT_ISO8601 3 /* ISO8601 (YYYY-MM-DDTHH:MM:SS) */ + + +/************************** MISC DEFINITIONS ****************************/ + +#define MAX_FILENAME_LENGTH 256 /* max length of path/filename that Nagios will process */ +#define MAX_INPUT_BUFFER 1024 /* size in bytes of max. input buffer (for reading files, misc stuff) */ +#define MAX_COMMAND_BUFFER 8192 /* max length of raw or processed command line */ +#define MAX_EXTERNAL_COMMAND_LENGTH 8192 /* max length of an external command */ + +#define MAX_DATETIME_LENGTH 48 + + +/************************* MODIFIED ATTRIBUTES **************************/ + +#define MODATTR_NONE 0 +#define MODATTR_NOTIFICATIONS_ENABLED 1 +#define MODATTR_ACTIVE_CHECKS_ENABLED 2 +#define MODATTR_PASSIVE_CHECKS_ENABLED 4 +#define MODATTR_EVENT_HANDLER_ENABLED 8 +#define MODATTR_FLAP_DETECTION_ENABLED 16 +#define MODATTR_FAILURE_PREDICTION_ENABLED 32 +#define MODATTR_PERFORMANCE_DATA_ENABLED 64 +#define MODATTR_OBSESSIVE_HANDLER_ENABLED 128 +#define MODATTR_EVENT_HANDLER_COMMAND 256 +#define MODATTR_CHECK_COMMAND 512 +#define MODATTR_NORMAL_CHECK_INTERVAL 1024 +#define MODATTR_RETRY_CHECK_INTERVAL 2048 +#define MODATTR_MAX_CHECK_ATTEMPTS 4096 +#define MODATTR_FRESHNESS_CHECKS_ENABLED 8192 +#define MODATTR_CHECK_TIMEPERIOD 16384 +#define MODATTR_CUSTOM_VARIABLE 32768 +#define MODATTR_NOTIFICATION_TIMEPERIOD 65536 diff --git a/include/compat.h b/include/compat.h new file mode 100644 index 0000000..cf7dd27 --- /dev/null +++ b/include/compat.h @@ -0,0 +1,19 @@ +/* compatibility macros, primarily to keep indentation programs + * from going bananas when indenting everything below + #ifdef __cplusplus + 'extern "C" {' + #endif + * as if it was a real block, which is just godsdamn annoying. + */ +#ifndef _COMPAT_H +#define _COMPAT_H + +#ifdef __cplusplus +# define NAGIOS_BEGIN_DECL extern "C" { +# define NAGIOS_END_DECL } +#else +# define NAGIOS_BEGIN_DECL /* nothing */ +# define NAGIOS_END_DECL /* more of nothing */ +#endif + +#endif /* _COMPAT_H */ diff --git a/include/config.h.in b/include/config.h.in new file mode 100644 index 0000000..22fc438 --- /dev/null +++ b/include/config.h.in @@ -0,0 +1,355 @@ +/************************************************************************ + * + * Nagios Config Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-02-2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + + +/***** NAGIOS STUFF *****/ + +#define DEFAULT_NAGIOS_USER nagios +#define DEFAULT_NAGIOS_GROUP nagios + +/* stop gcc from bitching about implicit asprintf declarations */ +#define _GNU_SOURCE 1 + +/* Event broker integration */ +#undef USE_EVENT_BROKER + +/* Embed a PERL interpreter into Nagios with optional cache for compiled code (contributed by Stephen Davies) */ +#undef EMBEDDEDPERL +#undef THREADEDPERL +/* 0 = cache, 1 = do not cache */ +#define DO_CLEAN "1" + +/* commands used by CGIs */ +#undef TRACEROUTE_COMMAND +#undef PING_COMMAND +#undef PING_PACKETS_FIRST + +/* Debugging options */ +/* function entry and exit */ +#undef DEBUG0 +/* general info messages */ +#undef DEBUG1 +/* warning messages */ +#undef DEBUG2 +/* service and host checks, other events */ +#undef DEBUG3 +/* service and host notifications */ +#undef DEBUG4 +/* SQL queries (defunct) */ +#undef DEBUG5 + +/* I/O implementations */ +#undef USE_XSDDEFAULT +#undef USE_XCDDEFAULT +#undef USE_XRDDEFAULT +#undef USE_XODTEMPLATE +#undef USE_XPDDEFAULT +#undef USE_XDDDEFAULT + + +/***** CGI COMPILE OPTIONS *****/ +/* should we compile and use the statusmap CGI? */ +#undef USE_STATUSMAP +/* should we compile and use the statuswrl CGI? */ +#undef USE_STATUSWRL +/* should we compile and use the trends CGI? */ +#undef USE_TRENDS +/* should we compile and use the histogram CGI? */ +#undef USE_HISTOGRAM + + + +/***** FUNCTION DEFINITIONS *****/ + +#undef HAVE_SETENV +#undef HAVE_UNSETENV +#undef HAVE_SOCKET +#undef HAVE_STRDUP +#undef HAVE_STRSTR +#undef HAVE_STRTOUL +#undef HAVE_INITGROUPS +#undef HAVE_GETLOADAVG +#undef HAVE_GDIMAGECREATETRUECOLOR + + + +/***** ASPRINTF() AND FRIENDS *****/ + +#undef HAVE_VSNPRINTF +#undef HAVE_SNPRINTF +#undef HAVE_ASPRINTF +#undef HAVE_VASPRINTF +#undef HAVE_C99_VSNPRINTF +#undef HAVE_VA_COPY +#undef HAVE___VA_COPY + + + +/***** MISC DEFINITIONS *****/ + +#undef USE_NANOSLEEP +#undef STDC_HEADERS +#undef HAVE_TM_ZONE +#undef HAVE_TZNAME +#undef USE_PROC +#define SOCKET_SIZE_TYPE "" +#define GETGROUPS_T "" +#define RETSIGTYPE "" + + + +/***** HEADER FILES *****/ + +#include +#include + +/* needed for the time_t structures we use later... */ +/* this include must come before sys/resource.h or we can have problems on some OSes */ +#undef TIME_WITH_SYS_TIME +#undef HAVE_SYS_TIME_H +#if TIME_WITH_SYS_TIME +#include +#include +#else +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + +#undef HAVE_SYS_RESOURCE_H +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +#undef HAVE_LIMITS_H +#ifdef HAVE_LIMITS_H +#include +#endif + +#undef HAVE_PWD_H +#ifdef HAVE_PWD_H +#include +#endif + +#undef HAVE_GRP_H +#ifdef HAVE_GRP_H +#include +#endif + +#undef HAVE_STRINGS_H +#ifdef HAVE_STRINGS_H +#include +#endif + +#undef HAVE_STRING_H +#ifdef HAVE_STRINGS_H +#include +#endif + +#undef HAVE_UNISTD_H +#ifdef HAVE_UNISTD_H +#include +#endif + +#undef HAVE_SYSLOG_H +#ifdef HAVE_SYSLOG_H +#include +#endif + +#undef HAVE_SIGNAL_H +#ifdef HAVE_SIGNAL_H +#include +#endif + +#undef HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#undef HAVE_SYS_MMAN_H +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +#undef HAVE_FCNTL_H +#ifdef HAVE_FCNTL_H +#include +#endif + +#undef HAVE_STDARG_H +#ifdef HAVE_STDARG_H +#include +#endif + +#undef HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#undef HAVE_SYS_WAIT_H +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#undef HAVE_ERRNO_H +#ifdef HAVE_ERRNO_H +#include +#endif + +#undef HAVE_SYS_TIMEB_H +#if HAVE_SYS_TIMEB_H +#include +#endif + +#undef HAVE_SYS_IPC_H +#ifdef HAVE_SYS_IPC_H +#include +#endif + +#undef HAVE_SYS_MSG_H +#ifdef HAVE_SYS_MSG_H +#include +#endif + +#undef HAVE_MATH_H +#ifdef HAVE_MATH_H +#include +#endif + +#undef HAVE_CTYPE_H +#ifdef HAVE_CTYPE_H +#include +#endif + +#undef HAVE_DIRENT_H +#ifdef HAVE_DIRENT_H +#include +#endif + +#undef HAVE_PTHREAD_H +#ifdef HAVE_PTHREAD_H +#include +#endif + +#undef HAVE_REGEX_H +#ifdef HAVE_REGEX_H +#include + +#undef HAVE_SYS_SOCKET_H +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#undef HAVE_SOCKET +#ifdef HAVE_SOCKET_H +#include +#endif + +#undef HAVE_NETINET_IN_H +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#undef HAVE_ARPA_INET_H +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#undef HAVE_NETDB_H +#ifdef HAVE_NETDB_H +#include +#endif + +#undef HAVE_LIBGEN_H +#ifdef HAVE_LIBGEN_H +#include +#endif + +#undef HAVE_SYS_UN_H +#ifdef HAVE_SYS_UN_H +#include +#endif + +#undef HAVE_SYS_POLL_H +#ifdef HAVE_SYS_POLL_H +#include +#endif + +#undef HAVE_GETOPT_H +#ifdef HAVE_GETOPT_H +#include +#endif + +#undef HAVE_LINUX_MODULE_H +#ifdef HAVE_LINUX_MODULE_H +#include +#endif + +#undef HAVE_LOCALE_H +#ifdef HAVE_LOCALE_H +#include +#endif + +#undef HAVE_WCHAR_H +#ifdef HAVE_WCHAR_H +#include +#endif + +/* configure script should allow user to override ltdl choice, but this will do for now... */ +#undef USE_LTDL +#undef HAVE_LTDL_H +#ifdef HAVE_LTDL_H +#define USE_LTDL +#endif + +#ifdef USE_LTDL +#include +#else +#undef HAVE_DLFCN_H +#ifdef HAVE_DLFCN_H +#include +#endif +#endif + + +/* moved to end to prevent AIX compiler warnings */ +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif + + +/***** MARO DEFINITIONS *****/ + +/* this needs to come after all system include files, so we don't accidentally attempt to redefine it */ +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + + +#endif diff --git a/include/downtime.h b/include/downtime.h new file mode 100644 index 0000000..e9b873b --- /dev/null +++ b/include/downtime.h @@ -0,0 +1,109 @@ +/***************************************************************************** + * + * DOWNTIME.H - Header file for scheduled downtime functions + * + * Copyright (c) 2001-2005 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-25-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _DOWNTIME_H +#define _DOWNTIME_H + +#include "compat.h" +#include "common.h" +#include "objects.h" + +NAGIOS_BEGIN_DECL + +/* SCHEDULED_DOWNTIME_ENTRY structure */ +typedef struct scheduled_downtime_struct { + int type; + char *host_name; + char *service_description; + time_t entry_time; + time_t start_time; + time_t flex_downtime_start; /* Time the flexible downtime started */ + time_t end_time; + int fixed; + unsigned long triggered_by; + unsigned long duration; + unsigned long downtime_id; + int is_in_effect; + int start_notification_sent; + char *author; + char *comment; +#ifdef NSCORE + unsigned long comment_id; + int start_flex_downtime; + int incremented_pending_downtime; +// int start_event; +// int stop_event; +#endif + struct scheduled_downtime_struct *next; + } scheduled_downtime; + + + +#ifdef NSCORE +int initialize_downtime_data(char *); /* initializes scheduled downtime data */ +int cleanup_downtime_data(char *); /* cleans up scheduled downtime data */ + +int add_new_downtime(int, char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); +int add_new_host_downtime(char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); +int add_new_service_downtime(char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); + +int delete_host_downtime(unsigned long); +int delete_service_downtime(unsigned long); +int delete_downtime(int, unsigned long); + +int schedule_downtime(int, char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *); +int unschedule_downtime(int, unsigned long); + +int register_downtime(int, unsigned long); +int handle_scheduled_downtime(scheduled_downtime *); +int handle_scheduled_downtime_by_id(unsigned long); + +int check_pending_flex_host_downtime(host *); +int check_pending_flex_service_downtime(service *); + +int check_for_expired_downtime(void); +#endif + +int add_host_downtime(char *, time_t, char *, char *, time_t, time_t, time_t, int, unsigned long, unsigned long, unsigned long, int, int); +int add_service_downtime(char *, char *, time_t, char *, char *, time_t, time_t, time_t, int, unsigned long, unsigned long, unsigned long, int, int); + +/* If you are going to be adding a lot of downtime in sequence, set + defer_downtime_sorting to 1 before you start and then call + sort_downtime afterwards. Things will go MUCH faster. */ + +extern int defer_downtime_sorting; +int add_downtime(int, char *, char *, time_t, char *, char *, time_t, time_t, time_t, int, unsigned long, unsigned long, unsigned long, int, int); +int sort_downtime(void); + +scheduled_downtime *find_downtime(int, unsigned long); +scheduled_downtime *find_host_downtime(unsigned long); +scheduled_downtime *find_service_downtime(unsigned long); + +void free_downtime_data(void); /* frees memory allocated to scheduled downtime list */ + +int delete_downtime_by_hostname_service_description_start_time_comment(char *, char *, time_t, char *); + +NAGIOS_END_DECL +#endif diff --git a/include/epn_nagios.h b/include/epn_nagios.h new file mode 100644 index 0000000..2399afe --- /dev/null +++ b/include/epn_nagios.h @@ -0,0 +1,34 @@ +/************************************************************************ + * + * Embedded Perl Header File + * Last Modified: 01-15-2009 + * + ************************************************************************/ + + +/******** BEGIN EMBEDDED PERL INTERPRETER DECLARATIONS ********/ + +#include +#include + +#include +#undef DEBUG /* epn-compiled Nagios spews just - this has a side effect of potentially disabling debug output on epn systems */ +#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 ********/ diff --git a/include/getcgi.h b/include/getcgi.h new file mode 100644 index 0000000..7cbb8db --- /dev/null +++ b/include/getcgi.h @@ -0,0 +1,40 @@ +/****************************************************** + * + * GETCGI.H - Nagios CGI Input Routine Include File + * + * Last Modified: 11-25-2005 + * + *****************************************************/ + +#include "compat.h" +NAGIOS_BEGIN_DECL + +#define ACCEPT_LANGUAGE_Q_DELIMITER ";q=" + +/* information for a single language in the variable HTTP_ACCEPT_LANGUAGE + sent by the browser */ +typedef struct accept_language_struct { + char * language; + char * locality; + double q; +} accept_language; + +/* information for all languages in the variable HTTP_ACCEPT_LANGUAGE + sent by the browser */ +typedef struct accept_languages_struct { + int count; + accept_language ** languages; +} accept_languages; + +char **getcgivars(void); +void free_cgivars(char **); +void unescape_cgi_input(char *); +void sanitize_cgi_input(char **); +unsigned char hex_to_char(char *); + +void process_language( char *); +accept_languages * parse_accept_languages( char *); +int compare_accept_languages( const void *, const void *); +void free_accept_languages( accept_languages *); + +NAGIOS_END_DECL diff --git a/include/locations.h.in b/include/locations.h.in new file mode 100644 index 0000000..c8516e8 --- /dev/null +++ b/include/locations.h.in @@ -0,0 +1,43 @@ +/************************************************************************ + * + * Nagios Locations Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 04-30-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#define DEFAULT_TEMP_FILE "@localstatedir@/tempfile" +#define DEFAULT_TEMP_PATH "/tmp" +#define DEFAULT_CHECK_RESULT_PATH "@localstatedir@/spool/checkresults" +#define DEFAULT_STATUS_FILE "@localstatedir@/status.dat" +#define DEFAULT_LOG_FILE "@localstatedir@/nagios.log" +#define DEFAULT_LOG_ARCHIVE_PATH "@localstatedir@/archives/" +#define DEFAULT_DEBUG_FILE "@localstatedir@/nagios.debug" +#define DEFAULT_COMMENT_FILE "@localstatedir@/comments.dat" +#define DEFAULT_DOWNTIME_FILE "@localstatedir@/downtime.dat" +#define DEFAULT_RETENTION_FILE "@localstatedir@/retention.dat" +#define DEFAULT_COMMAND_FILE "@localstatedir@/rw/nagios.cmd" +#define DEFAULT_CONFIG_FILE "@sysconfdir@/nagios.cfg" +#define DEFAULT_PHYSICAL_HTML_PATH "@datadir@" +#define DEFAULT_URL_HTML_PATH "@htmurl@" +#define DEFAULT_PHYSICAL_CGIBIN_PATH "@sbindir@" +#define DEFAULT_URL_CGIBIN_PATH "@cgiurl@" +#define DEFAULT_CGI_CONFIG_FILE "@sysconfdir@/cgi.cfg" +#define DEFAULT_LOCK_FILE "@lockfile@" +#define DEFAULT_OBJECT_CACHE_FILE "@localstatedir@/objects.cache" +#define DEFAULT_PRECACHED_OBJECT_FILE "@localstatedir@/objects.precache" +#define DEFAULT_EVENT_BROKER_FILE "@localstatedir@/broker.socket" +#define DEFAULT_P1_FILE "@bindir@/p1.pl" /**** EMBEDDED PERL ****/ +#define DEFAULT_AUTH_FILE "" /**** EMBEDDED PERL - IS THIS USED? ****/ diff --git a/include/logging.h b/include/logging.h new file mode 100644 index 0000000..bf14837 --- /dev/null +++ b/include/logging.h @@ -0,0 +1,89 @@ +#ifndef INCLUDE_logging_h__ +#define INCLUDE_logging_h__ + +#include "compat.h" +#include "objects.h" + +/******************* LOGGING TYPES ********************/ + +#define NSLOG_RUNTIME_ERROR 1 +#define NSLOG_RUNTIME_WARNING 2 + +#define NSLOG_VERIFICATION_ERROR 4 +#define NSLOG_VERIFICATION_WARNING 8 + +#define NSLOG_CONFIG_ERROR 16 +#define NSLOG_CONFIG_WARNING 32 + +#define NSLOG_PROCESS_INFO 64 +#define NSLOG_EVENT_HANDLER 128 +/*#define NSLOG_NOTIFICATION 256*/ /* NOT USED ANYMORE - CAN BE REUSED */ +#define NSLOG_EXTERNAL_COMMAND 512 + +#define NSLOG_HOST_UP 1024 +#define NSLOG_HOST_DOWN 2048 +#define NSLOG_HOST_UNREACHABLE 4096 + +#define NSLOG_SERVICE_OK 8192 +#define NSLOG_SERVICE_UNKNOWN 16384 +#define NSLOG_SERVICE_WARNING 32768 +#define NSLOG_SERVICE_CRITICAL 65536 + +#define NSLOG_PASSIVE_CHECK 131072 + +#define NSLOG_INFO_MESSAGE 262144 + +#define NSLOG_HOST_NOTIFICATION 524288 +#define NSLOG_SERVICE_NOTIFICATION 1048576 + +/***************** DEBUGGING LEVELS *******************/ + +#define DEBUGL_ALL -1 +#define DEBUGL_NONE 0 +#define DEBUGL_FUNCTIONS 1 +#define DEBUGL_CONFIG 2 +#define DEBUGL_PROCESS 4 +#define DEBUGL_STATUSDATA 4 +#define DEBUGL_RETENTIONDATA 4 +#define DEBUGL_EVENTS 8 +#define DEBUGL_CHECKS 16 +#define DEBUGL_IPC 16 +#define DEBUGL_FLAPPING 16 +#define DEBUGL_EVENTHANDLERS 16 +#define DEBUGL_PERFDATA 16 +#define DEBUGL_NOTIFICATIONS 32 +#define DEBUGL_EVENTBROKER 64 +#define DEBUGL_EXTERNALCOMMANDS 128 +#define DEBUGL_COMMANDS 256 +#define DEBUGL_DOWNTIME 512 +#define DEBUGL_COMMENTS 1024 +#define DEBUGL_MACROS 2048 + +#define DEBUGV_BASIC 0 +#define DEBUGV_MORE 1 +#define DEBUGV_MOST 2 + +NAGIOS_BEGIN_DECL +/**** Logging Functions ****/ +void logit(int, int, const char *, ...) +__attribute__((__format__(__printf__, 3, 4))); +int log_debug_info(int, int, const char *, ...) +__attribute__((__format__(__printf__, 3, 4))); + +#ifndef NSCGI +int write_to_all_logs(char *, unsigned long); /* writes a string to main log file and syslog facility */ +int write_to_log(char *, unsigned long, time_t *); /* write a string to the main log file */ +int write_to_syslog(char *, unsigned long); /* write a string to the syslog facility */ +int log_service_event(service *); /* logs a service event */ +int log_host_event(host *); /* logs a host event */ +int log_host_states(int, time_t *); /* logs initial/current host states */ +int log_service_states(int, time_t *); /* logs initial/current service states */ +int rotate_log_file(time_t); /* rotates the main log file */ +int write_log_file_info(time_t *); /* records log file/version info */ +int open_debug_log(void); +int chown_debug_log(uid_t, gid_t); +int close_debug_log(void); +#endif /* !NSCGI */ + +NAGIOS_END_DECL +#endif diff --git a/include/macros.h b/include/macros.h new file mode 100644 index 0000000..aca43f1 --- /dev/null +++ b/include/macros.h @@ -0,0 +1,339 @@ +/************************************************************************ + * + * MACROS.H - Common macro functions + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-28-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _MACROS_H +#define _MACROS_H + +#include "compat.h" +#include "common.h" +#include "objects.h" + + + +/****************** LENGTH LIMITATIONS ****************/ + +#define MAX_COMMAND_ARGUMENTS 32 /* maximum number of $ARGx$ macros */ + + +/****************** MACRO DEFINITIONS *****************/ + +#define MACRO_ENV_VAR_PREFIX "NAGIOS_" + +#define MAX_USER_MACROS 256 /* maximum number of $USERx$ macros */ + +#define MACRO_X_COUNT 153 /* size of macro_x[] array */ + +NAGIOS_BEGIN_DECL + +struct nagios_macros { + char *x[MACRO_X_COUNT]; + char *argv[MAX_COMMAND_ARGUMENTS]; + char *contactaddress[MAX_CONTACT_ADDRESSES]; + char *ondemand; + host *host_ptr; + hostgroup *hostgroup_ptr; + service *service_ptr; + servicegroup *servicegroup_ptr; + contact *contact_ptr; + contactgroup *contactgroup_ptr; + customvariablesmember *custom_host_vars; + customvariablesmember *custom_service_vars; + customvariablesmember *custom_contact_vars; + }; +typedef struct nagios_macros nagios_macros; + + + +#define MACRO_HOSTNAME 0 +#define MACRO_HOSTALIAS 1 +#define MACRO_HOSTADDRESS 2 +#define MACRO_SERVICEDESC 3 +#define MACRO_SERVICESTATE 4 +#define MACRO_SERVICESTATEID 5 +#define MACRO_SERVICEATTEMPT 6 +#define MACRO_LONGDATETIME 7 +#define MACRO_SHORTDATETIME 8 +#define MACRO_DATE 9 +#define MACRO_TIME 10 +#define MACRO_TIMET 11 +#define MACRO_LASTHOSTCHECK 12 +#define MACRO_LASTSERVICECHECK 13 +#define MACRO_LASTHOSTSTATECHANGE 14 +#define MACRO_LASTSERVICESTATECHANGE 15 +#define MACRO_HOSTOUTPUT 16 +#define MACRO_SERVICEOUTPUT 17 +#define MACRO_HOSTPERFDATA 18 +#define MACRO_SERVICEPERFDATA 19 +#define MACRO_CONTACTNAME 20 +#define MACRO_CONTACTALIAS 21 +#define MACRO_CONTACTEMAIL 22 +#define MACRO_CONTACTPAGER 23 +#define MACRO_ADMINEMAIL 24 +#define MACRO_ADMINPAGER 25 +#define MACRO_HOSTSTATE 26 +#define MACRO_HOSTSTATEID 27 +#define MACRO_HOSTATTEMPT 28 +#define MACRO_NOTIFICATIONTYPE 29 +#define MACRO_NOTIFICATIONNUMBER 30 /* deprecated - see HOSTNOTIFICATIONNUMBER and SERVICENOTIFICATIONNUMBER macros */ +#define MACRO_HOSTEXECUTIONTIME 31 +#define MACRO_SERVICEEXECUTIONTIME 32 +#define MACRO_HOSTLATENCY 33 +#define MACRO_SERVICELATENCY 34 +#define MACRO_HOSTDURATION 35 +#define MACRO_SERVICEDURATION 36 +#define MACRO_HOSTDURATIONSEC 37 +#define MACRO_SERVICEDURATIONSEC 38 +#define MACRO_HOSTDOWNTIME 39 +#define MACRO_SERVICEDOWNTIME 40 +#define MACRO_HOSTSTATETYPE 41 +#define MACRO_SERVICESTATETYPE 42 +#define MACRO_HOSTPERCENTCHANGE 43 +#define MACRO_SERVICEPERCENTCHANGE 44 +#define MACRO_HOSTGROUPNAME 45 +#define MACRO_HOSTGROUPALIAS 46 +#define MACRO_SERVICEGROUPNAME 47 +#define MACRO_SERVICEGROUPALIAS 48 +#define MACRO_HOSTACKAUTHOR 49 +#define MACRO_HOSTACKCOMMENT 50 +#define MACRO_SERVICEACKAUTHOR 51 +#define MACRO_SERVICEACKCOMMENT 52 +#define MACRO_LASTSERVICEOK 53 +#define MACRO_LASTSERVICEWARNING 54 +#define MACRO_LASTSERVICEUNKNOWN 55 +#define MACRO_LASTSERVICECRITICAL 56 +#define MACRO_LASTHOSTUP 57 +#define MACRO_LASTHOSTDOWN 58 +#define MACRO_LASTHOSTUNREACHABLE 59 +#define MACRO_SERVICECHECKCOMMAND 60 +#define MACRO_HOSTCHECKCOMMAND 61 +#define MACRO_MAINCONFIGFILE 62 +#define MACRO_STATUSDATAFILE 63 +#define MACRO_HOSTDISPLAYNAME 64 +#define MACRO_SERVICEDISPLAYNAME 65 +#define MACRO_RETENTIONDATAFILE 66 +#define MACRO_OBJECTCACHEFILE 67 +#define MACRO_TEMPFILE 68 +#define MACRO_LOGFILE 69 +#define MACRO_RESOURCEFILE 70 +#define MACRO_COMMANDFILE 71 +#define MACRO_HOSTPERFDATAFILE 72 +#define MACRO_SERVICEPERFDATAFILE 73 +#define MACRO_HOSTACTIONURL 74 +#define MACRO_HOSTNOTESURL 75 +#define MACRO_HOSTNOTES 76 +#define MACRO_SERVICEACTIONURL 77 +#define MACRO_SERVICENOTESURL 78 +#define MACRO_SERVICENOTES 79 +#define MACRO_TOTALHOSTSUP 80 +#define MACRO_TOTALHOSTSDOWN 81 +#define MACRO_TOTALHOSTSUNREACHABLE 82 +#define MACRO_TOTALHOSTSDOWNUNHANDLED 83 +#define MACRO_TOTALHOSTSUNREACHABLEUNHANDLED 84 +#define MACRO_TOTALHOSTPROBLEMS 85 +#define MACRO_TOTALHOSTPROBLEMSUNHANDLED 86 +#define MACRO_TOTALSERVICESOK 87 +#define MACRO_TOTALSERVICESWARNING 88 +#define MACRO_TOTALSERVICESCRITICAL 89 +#define MACRO_TOTALSERVICESUNKNOWN 90 +#define MACRO_TOTALSERVICESWARNINGUNHANDLED 91 +#define MACRO_TOTALSERVICESCRITICALUNHANDLED 92 +#define MACRO_TOTALSERVICESUNKNOWNUNHANDLED 93 +#define MACRO_TOTALSERVICEPROBLEMS 94 +#define MACRO_TOTALSERVICEPROBLEMSUNHANDLED 95 +#define MACRO_PROCESSSTARTTIME 96 +#define MACRO_HOSTCHECKTYPE 97 +#define MACRO_SERVICECHECKTYPE 98 +#define MACRO_LONGHOSTOUTPUT 99 +#define MACRO_LONGSERVICEOUTPUT 100 +#define MACRO_TEMPPATH 101 +#define MACRO_HOSTNOTIFICATIONNUMBER 102 +#define MACRO_SERVICENOTIFICATIONNUMBER 103 +#define MACRO_HOSTNOTIFICATIONID 104 +#define MACRO_SERVICENOTIFICATIONID 105 +#define MACRO_HOSTEVENTID 106 +#define MACRO_LASTHOSTEVENTID 107 +#define MACRO_SERVICEEVENTID 108 +#define MACRO_LASTSERVICEEVENTID 109 +#define MACRO_HOSTGROUPNAMES 110 +#define MACRO_SERVICEGROUPNAMES 111 +#define MACRO_HOSTACKAUTHORNAME 112 +#define MACRO_HOSTACKAUTHORALIAS 113 +#define MACRO_SERVICEACKAUTHORNAME 114 +#define MACRO_SERVICEACKAUTHORALIAS 115 +#define MACRO_MAXHOSTATTEMPTS 116 +#define MACRO_MAXSERVICEATTEMPTS 117 +#define MACRO_SERVICEISVOLATILE 118 +#define MACRO_TOTALHOSTSERVICES 119 +#define MACRO_TOTALHOSTSERVICESOK 120 +#define MACRO_TOTALHOSTSERVICESWARNING 121 +#define MACRO_TOTALHOSTSERVICESUNKNOWN 122 +#define MACRO_TOTALHOSTSERVICESCRITICAL 123 +#define MACRO_HOSTGROUPNOTES 124 +#define MACRO_HOSTGROUPNOTESURL 125 +#define MACRO_HOSTGROUPACTIONURL 126 +#define MACRO_SERVICEGROUPNOTES 127 +#define MACRO_SERVICEGROUPNOTESURL 128 +#define MACRO_SERVICEGROUPACTIONURL 129 +#define MACRO_HOSTGROUPMEMBERS 130 +#define MACRO_SERVICEGROUPMEMBERS 131 +#define MACRO_CONTACTGROUPNAME 132 +#define MACRO_CONTACTGROUPALIAS 133 +#define MACRO_CONTACTGROUPMEMBERS 134 +#define MACRO_CONTACTGROUPNAMES 135 +#define MACRO_NOTIFICATIONRECIPIENTS 136 +#define MACRO_NOTIFICATIONISESCALATED 137 +#define MACRO_NOTIFICATIONAUTHOR 138 +#define MACRO_NOTIFICATIONAUTHORNAME 139 +#define MACRO_NOTIFICATIONAUTHORALIAS 140 +#define MACRO_NOTIFICATIONCOMMENT 141 +#define MACRO_EVENTSTARTTIME 142 +#define MACRO_HOSTPROBLEMID 143 +#define MACRO_LASTHOSTPROBLEMID 144 +#define MACRO_SERVICEPROBLEMID 145 +#define MACRO_LASTSERVICEPROBLEMID 146 +#define MACRO_ISVALIDTIME 147 +#define MACRO_NEXTVALIDTIME 148 +#define MACRO_LASTHOSTSTATE 149 +#define MACRO_LASTHOSTSTATEID 150 +#define MACRO_LASTSERVICESTATE 151 +#define MACRO_LASTSERVICESTATEID 152 + + + +/************* MACRO CLEANING OPTIONS *****************/ + +#define STRIP_ILLEGAL_MACRO_CHARS 1 +#define ESCAPE_MACRO_CHARS 2 +#define URL_ENCODE_MACRO_CHARS 4 + + + +/****************** MACRO FUNCTIONS ******************/ + +nagios_macros *get_global_macros(void); + +/* + * Replace macros with their actual values + * This function modifies the global_macros struct and is thus + * not thread-safe. + */ +int process_macros(char *, char **, int); + +/* thread-safe version of the above */ +int process_macros_r(nagios_macros *mac, char *, char **, int); + +/* cleans macros characters before insertion into output string */ +char *clean_macro_chars(char *, int); + +/* + * These functions updates **macros with the values from + * their respective object type. + */ + +int grab_service_macros(service *); +int grab_host_macros(host *); +int grab_servicegroup_macros(servicegroup *); +int grab_hostgroup_macros(hostgroup *); +int grab_contact_macros(contact *); + +int grab_macro_value(char *, char **, int *, int *); +int grab_macrox_value(int, char *, char *, char **, int *); +int grab_custom_macro_value(char *, char *, char *, char **); +int grab_datetime_macro(int, char *, char *, char **); +int grab_standard_host_macro(int, host *, char **, int *); +int grab_standard_hostgroup_macro(int, hostgroup *, char **); +int grab_standard_service_macro(int, service *, char **, int *); +int grab_standard_servicegroup_macro(int, servicegroup *, char **); +int grab_standard_contact_macro(int, contact *, char **); +int grab_contact_address_macro(int, contact *, char **); +int grab_standard_contactgroup_macro(int, contactgroup *, char **); +int grab_custom_object_macro(char *, customvariablesmember *, char **); + +/* thread-safe version of the above */ +int grab_service_macros_r(nagios_macros *mac, service *); +int grab_host_macros_r(nagios_macros *mac, host *); +int grab_servicegroup_macros_r(nagios_macros *mac, servicegroup *); +int grab_hostgroup_macros_r(nagios_macros *mac, hostgroup *); +int grab_contact_macros_r(nagios_macros *mac, contact *); + +int grab_macro_value_r(nagios_macros *mac, char *, char **, int *, int *); +int grab_macrox_value_r(nagios_macros *mac, int, char *, char *, char **, int *); +int grab_custom_macro_value_r(nagios_macros *mac, char *, char *, char *, char **); +int grab_datetime_macro_r(nagios_macros *mac, int, char *, char *, char **); +int grab_standard_host_macro_r(nagios_macros *mac, int, host *, char **, int *); +int grab_standard_hostgroup_macro_r(nagios_macros *mac, int, hostgroup *, char **); +int grab_standard_service_macro_r(nagios_macros *mac, int, service *, char **, int *); +int grab_standard_servicegroup_macro_r(nagios_macros *mac, int, servicegroup *, char **); +int grab_standard_contact_macro_r(nagios_macros *mac, int, contact *, char **); +int grab_custom_object_macro_r(nagios_macros *mac, char *, customvariablesmember *, char **); + + +char *get_url_encoded_string(char *); /* URL encode a string */ + +int init_macros(void); +int init_macrox_names(void); +int free_macrox_names(void); + +extern void copy_constant_macros(char **dest); + +/* clear macros */ +int clear_argv_macros(void); +int clear_volatile_macros(void); +int clear_host_macros(void); +int clear_service_macros(void); +int clear_hostgroup_macros(void); +int clear_servicegroup_macros(void); +int clear_contact_macros(void); +int clear_contactgroup_macros(void); +int clear_summary_macros(void); + +/* thread-safe version of the above */ +int clear_argv_macros_r(nagios_macros *mac); +int clear_volatile_macros_r(nagios_macros *mac); +int clear_host_macros_r(nagios_macros *mac); +int clear_service_macros_r(nagios_macros *mac); +int clear_hostgroup_macros_r(nagios_macros *mac); +int clear_servicegroup_macros_r(nagios_macros *mac); +int clear_contact_macros_r(nagios_macros *mac); +int clear_contactgroup_macros_r(nagios_macros *mac); +int clear_summary_macros_r(nagios_macros *mac); + + +#ifdef NSCORE +int set_all_macro_environment_vars(int); +int set_macrox_environment_vars(int); +int set_argv_macro_environment_vars(int); +int set_custom_macro_environment_vars(int); +int set_contact_address_environment_vars(int); +int set_macro_environment_var(char *, char *, int); + +/* thread-safe version of the above */ +int set_all_macro_environment_vars_r(nagios_macros *mac, int); +int set_macrox_environment_vars_r(nagios_macros *mac, int); +int set_argv_macro_environment_vars_r(nagios_macros *mac, int); +int set_custom_macro_environment_vars_r(nagios_macros *mac, int); +int set_contact_address_environment_vars_r(nagios_macros *mac, int); + +#endif + +NAGIOS_END_DECL +#endif diff --git a/include/nagios.h b/include/nagios.h new file mode 100644 index 0000000..4fda64b --- /dev/null +++ b/include/nagios.h @@ -0,0 +1,738 @@ +/************************************************************************ + * + * Nagios Main Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-14-2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _NAGIOS_H +#define _NAGIOS_H + +#ifndef __GNUC__ +# define __attribute__(x) /* nothing */ +#endif +#ifndef NSCORE +# define NSCORE +#endif + +#include "compat.h" +#include "logging.h" +#include "common.h" +#include "locations.h" +#include "objects.h" +#include "macros.h" + + /************* MISC LENGTH/SIZE DEFINITIONS ***********/ + + /* + NOTE: Plugin length is artificially capped at 8k to prevent runaway plugins from returning MBs/GBs of data + back to Nagios. If you increase the 8k cap by modifying this value, make sure you also increase the value + of MAX_EXTERNAL_COMMAND_LENGTH in common.h to allow for passive checks results received through the external + command file. EG 10/19/07 + */ +#define MAX_PLUGIN_OUTPUT_LENGTH 8192 /* max length of plugin output (including perf data) */ + + + + /******************* DEFAULT VALUES *******************/ + +#define DEFAULT_LOG_LEVEL 1 /* log all events to main log file */ +#define DEFAULT_USE_SYSLOG 1 /* log events to syslog? 1=yes, 0=no */ +#define DEFAULT_SYSLOG_LEVEL 2 /* log only severe events to syslog */ + +#define DEFAULT_NOTIFICATION_LOGGING 1 /* log notification events? 1=yes, 0=no */ + +#define DEFAULT_INTER_CHECK_DELAY 5.0 /* seconds between initial service check scheduling */ +#define DEFAULT_INTERLEAVE_FACTOR 1 /* default interleave to use when scheduling checks */ +#define DEFAULT_SLEEP_TIME 0.5 /* seconds between event run checks */ +#define DEFAULT_INTERVAL_LENGTH 60 /* seconds per interval unit for check scheduling */ +#define DEFAULT_RETRY_INTERVAL 30 /* services are retried in 30 seconds if they're not OK */ +#define DEFAULT_COMMAND_CHECK_INTERVAL -1 /* interval to check for external commands (default = as often as possible) */ +#define DEFAULT_CHECK_REAPER_INTERVAL 10 /* interval in seconds to reap host and service check results */ +#define DEFAULT_MAX_REAPER_TIME 30 /* maximum number of seconds to spend reaping service checks before we break out for a while */ +#define DEFAULT_MAX_CHECK_RESULT_AGE 3600 /* maximum number of seconds that a check result file is considered to be valid */ +#define DEFAULT_MAX_PARALLEL_SERVICE_CHECKS 0 /* maximum number of service checks we can have running at any given time (0=unlimited) */ +#define DEFAULT_RETENTION_UPDATE_INTERVAL 60 /* minutes between auto-save of retention data */ +#define DEFAULT_RETENTION_SCHEDULING_HORIZON 900 /* max seconds between program restarts that we will preserve scheduling information */ +#define DEFAULT_STATUS_UPDATE_INTERVAL 60 /* seconds between aggregated status data updates */ +#define DEFAULT_FRESHNESS_CHECK_INTERVAL 60 /* seconds between service result freshness checks */ +#define DEFAULT_AUTO_RESCHEDULING_INTERVAL 30 /* seconds between host and service check rescheduling events */ +#define DEFAULT_AUTO_RESCHEDULING_WINDOW 180 /* window of time (in seconds) for which we should reschedule host and service checks */ +#define DEFAULT_ORPHAN_CHECK_INTERVAL 60 /* seconds between checks for orphaned hosts and services */ + +#define DEFAULT_NOTIFICATION_TIMEOUT 30 /* max time in seconds to wait for notification commands to complete */ +#define DEFAULT_EVENT_HANDLER_TIMEOUT 30 /* max time in seconds to wait for event handler commands to complete */ +#define DEFAULT_HOST_CHECK_TIMEOUT 30 /* max time in seconds to wait for host check commands to complete */ +#define DEFAULT_SERVICE_CHECK_TIMEOUT 60 /* max time in seconds to wait for service check commands to complete */ +#define DEFAULT_OCSP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_OCHP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_PERFDATA_TIMEOUT 5 /* max time in seconds to wait for performance data commands to complete */ +#define DEFAULT_TIME_CHANGE_THRESHOLD 900 /* compensate for time changes of more than 15 minutes */ + +#define DEFAULT_LOG_HOST_RETRIES 0 /* don't log host retries */ +#define DEFAULT_LOG_SERVICE_RETRIES 0 /* don't log service retries */ +#define DEFAULT_LOG_EVENT_HANDLERS 1 /* log event handlers */ +#define DEFAULT_LOG_INITIAL_STATES 0 /* don't log initial service and host states */ +#define DEFAULT_LOG_EXTERNAL_COMMANDS 1 /* log external commands */ +#define DEFAULT_LOG_PASSIVE_CHECKS 1 /* log passive service checks */ + +#define DEFAULT_DEBUG_LEVEL 0 /* don't log any debugging information */ +#define DEFAULT_DEBUG_VERBOSITY 1 +#define DEFAULT_MAX_DEBUG_FILE_SIZE 1000000 /* max size of debug log */ + +#define DEFAULT_AGGRESSIVE_HOST_CHECKING 0 /* don't use "aggressive" host checking */ +#define DEFAULT_CHECK_EXTERNAL_COMMANDS 1 /* check for external commands */ +#define DEFAULT_CHECK_ORPHANED_SERVICES 1 /* check for orphaned services */ +#define DEFAULT_CHECK_ORPHANED_HOSTS 1 /* check for orphaned hosts */ +#define DEFAULT_ENABLE_FLAP_DETECTION 0 /* don't enable flap detection */ +#define DEFAULT_PROCESS_PERFORMANCE_DATA 0 /* don't process performance data */ +#define DEFAULT_CHECK_SERVICE_FRESHNESS 1 /* check service result freshness */ +#define DEFAULT_CHECK_HOST_FRESHNESS 0 /* don't check host result freshness */ +#define DEFAULT_AUTO_RESCHEDULE_CHECKS 0 /* don't auto-reschedule host and service checks */ +#define DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS 0 /* should we translate DOWN/UNREACHABLE passive host checks? */ +#define DEFAULT_PASSIVE_HOST_CHECKS_SOFT 0 /* passive host checks are treated as HARD by default */ + +#define DEFAULT_LOW_SERVICE_FLAP_THRESHOLD 20.0 /* low threshold for detection of service flapping */ +#define DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD 30.0 /* high threshold for detection of service flapping */ +#define DEFAULT_LOW_HOST_FLAP_THRESHOLD 20.0 /* low threshold for detection of host flapping */ +#define DEFAULT_HIGH_HOST_FLAP_THRESHOLD 30.0 /* high threshold for detection of host flapping */ + +#define DEFAULT_HOST_CHECK_SPREAD 30 /* max minutes to schedule all initial host checks */ +#define DEFAULT_SERVICE_CHECK_SPREAD 30 /* max minutes to schedule all initial service checks */ + +#define DEFAULT_CACHED_HOST_CHECK_HORIZON 15 /* max age in seconds that cached host checks can be used */ +#define DEFAULT_CACHED_SERVICE_CHECK_HORIZON 15 /* max age in seconds that cached service checks can be used */ +#define DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS 1 /* should we use predictive host dependency checks? */ +#define DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS 1 /* should we use predictive service dependency checks? */ + +#define DEFAULT_USE_LARGE_INSTALLATION_TWEAKS 0 /* don't use tweaks for large Nagios installations */ + +#define DEFAULT_ENABLE_EMBEDDED_PERL 0 /* enable embedded Perl interpreter (if compiled in) */ +#define DEFAULT_USE_EMBEDDED_PERL_IMPLICITLY 1 /* by default, embedded Perl is used for Perl plugins that don't explicitly disable it */ + +#define DEFAULT_ADDITIONAL_FRESHNESS_LATENCY 15 /* seconds to be added to freshness thresholds when automatically calculated by Nagios */ + +#define DEFAULT_CHECK_FOR_UPDATES 1 /* should we check for new Nagios releases? */ +#define DEFAULT_BARE_UPDATE_CHECK 0 /* report current version and new installs */ +#define MINIMUM_UPDATE_CHECK_INTERVAL 60*60*22 /* 22 hours minimum between checks - please be kind to our servers! */ +#define BASE_UPDATE_CHECK_INTERVAL 60*60*22 /* 22 hours base interval */ +#define UPDATE_CHECK_INTERVAL_WOBBLE 60*60*4 /* 4 hour wobble on top of base interval */ +#define BASE_UPDATE_CHECK_RETRY_INTERVAL 60*60*1 /* 1 hour base retry interval */ +#define UPDATE_CHECK_RETRY_INTERVAL_WOBBLE 60*60*3 /* 3 hour wobble on top of base retry interval */ + +#define DEFAULT_ALLOW_EMPTY_HOSTGROUP_ASSIGNMENT 0 /* Do not allow empty hostgroups by default */ + + /******************** HOST STATUS *********************/ + +#define HOST_UP 0 +#define HOST_DOWN 1 +#define HOST_UNREACHABLE 2 + + + + /******************* STATE LOGGING TYPES **************/ + +#define INITIAL_STATES 1 +#define CURRENT_STATES 2 + + + + /************ SERVICE DEPENDENCY VALUES ***************/ + +#define DEPENDENCIES_OK 0 +#define DEPENDENCIES_FAILED 1 + + + + /*********** ROUTE CHECK PROPAGATION TYPES ************/ + +#define PROPAGATE_TO_PARENT_HOSTS 1 +#define PROPAGATE_TO_CHILD_HOSTS 2 + + + + /****************** SERVICE STATES ********************/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ + + + + /****************** FLAPPING TYPES ********************/ + +#define HOST_FLAPPING 0 +#define SERVICE_FLAPPING 1 + + + + /**************** NOTIFICATION TYPES ******************/ + +#define HOST_NOTIFICATION 0 +#define SERVICE_NOTIFICATION 1 + + + + /************* NOTIFICATION REASON TYPES ***************/ + +#define NOTIFICATION_NORMAL 0 +#define NOTIFICATION_ACKNOWLEDGEMENT 1 +#define NOTIFICATION_FLAPPINGSTART 2 +#define NOTIFICATION_FLAPPINGSTOP 3 +#define NOTIFICATION_FLAPPINGDISABLED 4 +#define NOTIFICATION_DOWNTIMESTART 5 +#define NOTIFICATION_DOWNTIMEEND 6 +#define NOTIFICATION_DOWNTIMECANCELLED 7 +#define NOTIFICATION_CUSTOM 99 + + + + /**************** EVENT HANDLER TYPES *****************/ + +#define HOST_EVENTHANDLER 0 +#define SERVICE_EVENTHANDLER 1 +#define GLOBAL_HOST_EVENTHANDLER 2 +#define GLOBAL_SERVICE_EVENTHANDLER 3 + + + + /***************** STATE CHANGE TYPES *****************/ + +#define HOST_STATECHANGE 0 +#define SERVICE_STATECHANGE 1 + + + + /***************** OBJECT CHECK TYPES *****************/ +#define SERVICE_CHECK 0 +#define HOST_CHECK 1 + + + + /******************* EVENT TYPES **********************/ + +#define EVENT_SERVICE_CHECK 0 /* active service check */ +#define EVENT_COMMAND_CHECK 1 /* external command check */ +#define EVENT_LOG_ROTATION 2 /* log file rotation */ +#define EVENT_PROGRAM_SHUTDOWN 3 /* program shutdown */ +#define EVENT_PROGRAM_RESTART 4 /* program restart */ +#define EVENT_CHECK_REAPER 5 /* reaps results from host and service checks */ +#define EVENT_ORPHAN_CHECK 6 /* checks for orphaned hosts and services */ +#define EVENT_RETENTION_SAVE 7 /* save (dump) retention data */ +#define EVENT_STATUS_SAVE 8 /* save (dump) status data */ +#define EVENT_SCHEDULED_DOWNTIME 9 /* scheduled host or service downtime */ +#define EVENT_SFRESHNESS_CHECK 10 /* checks service result "freshness" */ +#define EVENT_EXPIRE_DOWNTIME 11 /* checks for (and removes) expired scheduled downtime */ +#define EVENT_HOST_CHECK 12 /* active host check */ +#define EVENT_HFRESHNESS_CHECK 13 /* checks host result "freshness" */ +#define EVENT_RESCHEDULE_CHECKS 14 /* adjust scheduling of host and service checks */ +#define EVENT_EXPIRE_COMMENT 15 /* removes expired comments */ +#define EVENT_CHECK_PROGRAM_UPDATE 16 /* checks for new version of Nagios */ +#define EVENT_SLEEP 98 /* asynchronous sleep event that occurs when event queues are empty */ +#define EVENT_USER_FUNCTION 99 /* USER-defined function (modules) */ + +#define EVENT_TYPE_STR( type) ( \ + type == EVENT_SERVICE_CHECK ? "EVENT_SERVICE_CHECK" : \ + type == EVENT_COMMAND_CHECK ? "EVENT_COMMAND_CHECK" : \ + type == EVENT_LOG_ROTATION ? "EVENT_LOG_ROTATION" : \ + type == EVENT_PROGRAM_SHUTDOWN ? "EVENT_PROGRAM_SHUTDOWN" : \ + type == EVENT_PROGRAM_RESTART ? "EVENT_PROGRAM_RESTART" : \ + type == EVENT_CHECK_REAPER ? "EVENT_CHECK_REAPER" : \ + type == EVENT_ORPHAN_CHECK ? "EVENT_ORPHAN_CHECK" : \ + type == EVENT_RETENTION_SAVE ? "EVENT_RETENTION_SAVE" : \ + type == EVENT_STATUS_SAVE ? "EVENT_STATUS_SAVE" : \ + type == EVENT_SCHEDULED_DOWNTIME ? "EVENT_SCHEDULED_DOWNTIME" : \ + type == EVENT_SFRESHNESS_CHECK ? "EVENT_SFRESHNESS_CHECK" : \ + type == EVENT_EXPIRE_DOWNTIME ? "EVENT_EXPIRE_DOWNTIME" : \ + type == EVENT_HOST_CHECK ? "EVENT_HOST_CHECK" : \ + type == EVENT_HFRESHNESS_CHECK ? "EVENT_HFRESHNESS_CHECK" : \ + type == EVENT_RESCHEDULE_CHECKS ? "EVENT_RESCHEDULE_CHECKS" : \ + type == EVENT_EXPIRE_COMMENT ? "EVENT_EXPIRE_COMMENT" : \ + type == EVENT_CHECK_PROGRAM_UPDATE ? "EVENT_CHECK_PROGRAM_UPDATE" : \ + type == EVENT_SLEEP ? "EVENT_SLEEP" : \ + type == EVENT_USER_FUNCTION ? "EVENT_USER_FUNCTION" : \ + "UNKNOWN_EVENT_TYPE" \ +) + + + /******* INTER-CHECK DELAY CALCULATION TYPES **********/ + +#define ICD_NONE 0 /* no inter-check delay */ +#define ICD_DUMB 1 /* dumb delay of 1 second */ +#define ICD_SMART 2 /* smart delay */ +#define ICD_USER 3 /* user-specified delay */ + + + + /******* INTERLEAVE FACTOR CALCULATION TYPES **********/ + +#define ILF_USER 0 /* user-specified interleave factor */ +#define ILF_SMART 1 /* smart interleave */ + + + + /************ SCHEDULED DOWNTIME TYPES ****************/ + +#define ACTIVE_DOWNTIME 0 /* active downtime - currently in effect */ +#define PENDING_DOWNTIME 1 /* pending downtime - scheduled for the future */ + + + + /****************** DATA STRUCTURES *******************/ + +NAGIOS_BEGIN_DECL + +/* TIMED_EVENT structure */ +typedef struct timed_event_struct { + int event_type; + time_t run_time; + int recurring; + unsigned long event_interval; + int compensate_for_time_change; + void *timing_func; + void *event_data; + void *event_args; + int event_options; + struct timed_event_struct *next; + struct timed_event_struct *prev; + } timed_event; + + +/* NOTIFY_LIST structure */ +typedef struct notify_list_struct { + contact *contact; + struct notify_list_struct *next; + } notification; + + +/* CHECK_RESULT structure */ +typedef struct check_result_struct { + int object_check_type; /* is this a service or a host check? */ + char *host_name; /* host name */ + char *service_description; /* service description */ + int check_type; /* was this an active or passive service check? */ + int check_options; + int scheduled_check; /* was this a scheduled or an on-demand check? */ + int reschedule_check; /* should we reschedule the next check */ + char *output_file; /* what file is the output stored in? */ + FILE *output_file_fp; + int output_file_fd; + double latency; + struct timeval start_time; /* time the service check was initiated */ + struct timeval finish_time; /* time the service check was completed */ + int early_timeout; /* did the service check timeout? */ + int exited_ok; /* did the plugin check return okay? */ + int return_code; /* plugin return code */ + char *output; /* plugin output */ + struct check_result_struct *next; + } check_result; + + +/* SCHED_INFO structure */ +typedef struct sched_info_struct { + int total_services; + int total_scheduled_services; + int total_hosts; + int total_scheduled_hosts; + double average_services_per_host; + double average_scheduled_services_per_host; + unsigned long service_check_interval_total; + unsigned long host_check_interval_total; + double average_service_execution_time; + double average_service_check_interval; + double average_host_check_interval; + double average_service_inter_check_delay; + double average_host_inter_check_delay; + double service_inter_check_delay; + double host_inter_check_delay; + int service_interleave_factor; + int max_service_check_spread; + int max_host_check_spread; + time_t first_service_check; + time_t last_service_check; + time_t first_host_check; + time_t last_host_check; + } sched_info; + + +/* PASSIVE_CHECK_RESULT structure */ +typedef struct passive_check_result_struct { + int object_check_type; + char *host_name; + char *service_description; + int return_code; + char *output; + time_t check_time; + double latency; + struct passive_check_result_struct *next; + } passive_check_result; + + +/* CIRCULAR_BUFFER structure - used by worker threads */ +typedef struct circular_buffer_struct { + void **buffer; + int tail; + int head; + int items; + int high; /* highest number of items that has ever been stored in buffer */ + unsigned long overflow; + pthread_mutex_t buffer_lock; + } circular_buffer; + + +/* DBUF structure - dynamic string storage */ +typedef struct dbuf_struct { + char *buf; + unsigned long used_size; + unsigned long allocated_size; + unsigned long chunk_size; + } dbuf; + + +#define CHECK_STATS_BUCKETS 15 + +/* used for tracking host and service check statistics */ +typedef struct check_stats_struct { + int current_bucket; + int bucket[CHECK_STATS_BUCKETS]; + int overflow_bucket; + int minute_stats[3]; + time_t last_update; + } check_stats; + + +/******************* THREAD STUFF ********************/ + + /* slots in circular buffers */ +#define DEFAULT_EXTERNAL_COMMAND_BUFFER_SLOTS 4096 + + /* worker threads */ +#define TOTAL_WORKER_THREADS 1 + +#define COMMAND_WORKER_THREAD 0 + + + +/******************** FUNCTIONS **********************/ + +/**** Configuration Functions ****/ +int read_main_config_file(char *); /* reads the main config file (nagios.cfg) */ +int read_resource_file(char *); /* processes macros in resource file */ +int read_all_object_data(char *); /* reads all object config data */ + + +/**** Setup Functions ****/ +int pre_flight_check(void); /* try and verify the configuration data */ +int pre_flight_object_check(int *, int *); /* verify object relationships and settings */ +int pre_flight_circular_check(int *, int *); /* detects circular dependencies and paths */ +void init_timing_loop(void); /* setup the initial scheduling queue */ +void setup_sighandler(void); /* trap signals */ +void reset_sighandler(void); /* reset signals to default action */ +extern void handle_sigxfsz(int); /* handle SIGXFSZ */ +int daemon_init(void); /* switches to daemon mode */ +int drop_privileges(char *, char *); /* drops privileges before startup */ +void display_scheduling_info(void); /* displays service check scheduling information */ + + +/**** Event Queue Functions ****/ +int schedule_new_event(int, int, time_t, int, unsigned long, void *, int, void *, void *, int); /* schedules a new timed event */ +void reschedule_event(timed_event *, timed_event **, timed_event **); /* reschedules an event */ +void add_event(timed_event *, timed_event **, timed_event **); /* adds an event to the execution queue */ +void remove_event(timed_event *, timed_event **, timed_event **); /* remove an event from the execution queue */ +int event_execution_loop(void); /* main monitoring/event handler loop */ +int handle_timed_event(timed_event *); /* top level handler for timed events */ +void adjust_check_scheduling(void); /* auto-adjusts scheduling of host and service checks */ +void compensate_for_system_time_change(unsigned long, unsigned long); /* attempts to compensate for a change in the system time */ +void adjust_timestamp_for_time_change(time_t, time_t, unsigned long, time_t *); /* adjusts a timestamp variable for a system time change */ +void resort_event_list(timed_event **, timed_event **); /* resorts event list by event run time for system time changes */ + + +/**** IPC Functions ****/ +int move_check_result_to_queue(char *); +int process_check_result_queue(char *); +int find_executing_checks(char *); +int process_check_result_file(char *, check_result **, int, int); +int add_check_result_to_list(check_result **, check_result *); +check_result *read_check_result(check_result **); /* reads a host/service check result from the list in memory */ +int delete_check_result_file(char *); +int free_check_result_list(check_result **); +int init_check_result(check_result *); +int free_check_result(check_result *); /* frees memory associated with a host/service check result */ +int parse_check_output(char *, char **, char **, char **, int, int); +int open_command_file(void); /* creates the external command file as a named pipe (FIFO) and opens it for reading */ +int close_command_file(void); /* closes and deletes the external command file (FIFO) */ + + +/**** Monitoring/Event Handler Functions ****/ +int check_service_dependencies(service *, int); /* checks service dependencies */ +int check_host_dependencies(host *, int); /* checks host dependencies */ +void check_for_orphaned_services(void); /* checks for orphaned services */ +void check_for_orphaned_hosts(void); /* checks for orphaned hosts */ +void check_service_result_freshness(void); /* checks the "freshness" of service check results */ +int is_service_result_fresh(service *, time_t, int); /* determines if a service's check results are fresh */ +void check_host_result_freshness(void); /* checks the "freshness" of host check results */ +int is_host_result_fresh(host *, time_t, int); /* determines if a host's check results are fresh */ +int my_system(char *, int, int *, double *, char **, int); /* executes a command via popen(), but also protects against timeouts */ +int my_system_r(nagios_macros *mac, char *, int, int *, double *, char **, int); /* thread-safe version of the above */ + + +/**** Flap Detection Functions ****/ +void check_for_service_flapping(service *, int, int); /* determines whether or not a service is "flapping" between states */ +void check_for_host_flapping(host *, int, int, int); /* determines whether or not a host is "flapping" between states */ +void set_service_flap(service *, double, double, double, int); /* handles a service that is flapping */ +void clear_service_flap(service *, double, double, double); /* handles a service that has stopped flapping */ +void set_host_flap(host *, double, double, double, int); /* handles a host that is flapping */ +void clear_host_flap(host *, double, double, double); /* handles a host that has stopped flapping */ +void enable_flap_detection_routines(void); /* enables flap detection on a program-wide basis */ +void disable_flap_detection_routines(void); /* disables flap detection on a program-wide basis */ +void enable_host_flap_detection(host *); /* enables flap detection for a particular host */ +void disable_host_flap_detection(host *); /* disables flap detection for a particular host */ +void enable_service_flap_detection(service *); /* enables flap detection for a particular service */ +void disable_service_flap_detection(service *); /* disables flap detection for a particular service */ +void handle_host_flap_detection_disabled(host *); /* handles the details when flap detection is disabled globally or on a per-host basis */ +void handle_service_flap_detection_disabled(service *); /* handles the details when flap detection is disabled globally or on a per-service basis */ + + +/**** Route/Host Check Functions ****/ +int perform_on_demand_host_check(host *, int *, int, int, unsigned long); +int perform_scheduled_host_check(host *, int, double); +int check_host_check_viability_3x(host *, int, int *, time_t *); +int adjust_host_check_attempt_3x(host *, int); +int determine_host_reachability(host *); +int process_host_check_result_3x(host *, int, char *, int, int, int, unsigned long); +int perform_on_demand_host_check_3x(host *, int *, int, int, unsigned long); +int run_sync_host_check_3x(host *, int *, int, int, unsigned long); +int execute_sync_host_check_3x(host *); +int run_scheduled_host_check_3x(host *, int, double); +int run_async_host_check_3x(host *, int, double, int, int, int *, time_t *); +int handle_async_host_check_result_3x(host *, check_result *); + + +/**** Service Check Functions ****/ +int check_service_check_viability(service *, int, int *, time_t *); +int run_scheduled_service_check(service *, int, double); +int run_async_service_check(service *, int, double, int, int, int *, time_t *); +int handle_async_service_check_result(service *, check_result *); + + +/**** Event Handler Functions ****/ +int handle_host_state(host *); /* top level host state handler */ + + +/**** Common Check Fucntions *****/ +int reap_check_results(void); + + +/**** Check Statistics Functions ****/ +int init_check_stats(void); +int update_check_stats(int, time_t); +int generate_check_stats(void); + + +/**** Event Handler Functions ****/ +int obsessive_compulsive_service_check_processor(service *); /* distributed monitoring craziness... */ +int obsessive_compulsive_host_check_processor(host *); /* distributed monitoring craziness... */ +int handle_service_event(service *); /* top level service event logic */ +int run_service_event_handler(nagios_macros *mac, service *); /* runs the event handler for a specific service */ +int run_global_service_event_handler(nagios_macros *mac, service *); /* runs the global service event handler */ +int handle_host_event(host *); /* top level host event logic */ +int run_host_event_handler(nagios_macros *mac, host *); /* runs the event handler for a specific host */ +int run_global_host_event_handler(nagios_macros *mac, host *); /* runs the global host event handler */ + + +/**** Notification Functions ****/ +int check_service_notification_viability(service *, int, int); /* checks viability of notifying all contacts about a service */ +int is_valid_escalation_for_service_notification(service *, serviceescalation *, int); /* checks if an escalation entry is valid for a particular service notification */ +int should_service_notification_be_escalated(service *); /* checks if a service notification should be escalated */ +int service_notification(service *, int, char *, char *, int); /* notify all contacts about a service (problem or recovery) */ +int check_contact_service_notification_viability(contact *, service *, int, int); /* checks viability of notifying a contact about a service */ +int notify_contact_of_service(nagios_macros *mac, contact *, service *, int, char *, char *, int, int); /* notify a single contact about a service */ +int check_host_notification_viability(host *, int, int); /* checks viability of notifying all contacts about a host */ +int is_valid_escalation_for_host_notification(host *, hostescalation *, int); /* checks if an escalation entry is valid for a particular host notification */ +int should_host_notification_be_escalated(host *); /* checks if a host notification should be escalated */ +int host_notification(host *, int, char *, char *, int); /* notify all contacts about a host (problem or recovery) */ +int check_contact_host_notification_viability(contact *, host *, int, int); /* checks viability of notifying a contact about a host */ +int notify_contact_of_host(nagios_macros *mac, contact *, host *, int, char *, char *, int, int); /* notify a single contact about a host */ +int create_notification_list_from_host(nagios_macros *mac, host *,int,int *,int); /* given a host, create list of contacts to be notified (remove duplicates) */ +int create_notification_list_from_service(nagios_macros *mac, service *,int,int *,int); /* given a service, create list of contacts to be notified (remove duplicates) */ +int add_notification(nagios_macros *mac, contact *); /* adds a notification instance */ +notification *find_notification(contact *); /* finds a notification object */ +time_t get_next_host_notification_time(host *, time_t); /* calculates nex acceptable re-notification time for a host */ +time_t get_next_service_notification_time(service *, time_t); /* calculates nex acceptable re-notification time for a service */ + + +/**** Cleanup Functions ****/ +void cleanup(void); /* cleanup after ourselves (before quitting or restarting) */ +void free_memory(nagios_macros *mac); /* free memory allocated to all linked lists in memory */ +int reset_variables(void); /* reset all global variables */ +void free_notification_list(void); /* frees all memory allocated to the notification list */ + + +/**** Miscellaneous Functions ****/ +void sighandler(int); /* handles signals */ +void service_check_sighandler(int); /* handles timeouts when executing service checks */ +void host_check_sighandler(int); /* handles timeouts when executing host checks */ +void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ +char *get_next_string_from_buf(char *buf, int *start_index, int bufsize); +int compare_strings(char *, char *); /* compares two strings for equality */ +char *escape_newlines(char *); +int contains_illegal_object_chars(char *); /* tests whether or not an object name (host, service, etc.) contains illegal characters */ +int my_rename(char *, char *); /* renames a file - works across filesystems */ +int my_fcopy(char *, char *); /* copies a file - works across filesystems */ +int my_fdcopy(char *, char *, int); /* copies a named source to an already opened destination file */ + +/* thread-safe version of get_raw_command_line_r() */ +extern int get_raw_command_line_r(nagios_macros *mac, command *, char *, char **, int); + +/* + * given a raw command line, determine the actual command to run + * Manipulates global_macros.argv and is thus not threadsafe + */ +extern int get_raw_command_line(command *, char *, char **, int); + +int check_time_against_period(time_t, timeperiod *); /* check to see if a specific time is covered by a time period */ +int is_daterange_single_day(daterange *); +time_t calculate_time_from_weekday_of_month(int, int, int, int); /* calculates midnight time of specific (3rd, last, etc.) weekday of a particular month */ +time_t calculate_time_from_day_of_month(int, int, int); /* calculates midnight time of specific (1st, last, etc.) day of a particular month */ +void get_next_valid_time(time_t, time_t *, timeperiod *); /* get the next valid time in a time period */ +time_t get_next_log_rotation_time(void); /* determine the next time to schedule a log rotation */ +int init_embedded_perl(char **); /* initialized embedded perl interpreter */ +int deinit_embedded_perl(void); /* cleans up embedded perl */ +int file_uses_embedded_perl(char *); /* tests whether or not the embedded perl interpreter should be used on a file */ +int dbuf_init(dbuf *, int); +int dbuf_free(dbuf *); +int dbuf_strcat(dbuf *, char *); +int set_environment_var(char *, char *, int); /* sets/clears and environment variable */ +int check_for_nagios_updates(int, int); /* checks to see if new version of Nagios are available */ +int query_update_api(void); /* checks to see if new version of Nagios are available */ + + +/**** External Command Functions ****/ +int check_for_external_commands(void); /* checks for any external commands */ +int process_external_command1(char *); /* top-level external command processor */ +int process_external_command2(int, time_t, char *); /* process an external command */ +int process_external_commands_from_file(char *, int); /* process external commands in a file */ +int process_host_command(int, time_t, char *); /* process an external host command */ +int process_hostgroup_command(int, time_t, char *); /* process an external hostgroup command */ +int process_service_command(int, time_t, char *); /* process an external service command */ +int process_servicegroup_command(int, time_t, char *); /* process an external servicegroup command */ +int process_contact_command(int, time_t, char *); /* process an external contact command */ +int process_contactgroup_command(int, time_t, char *); /* process an external contactgroup command */ + + +/**** External Command Implementations ****/ +int cmd_add_comment(int, time_t, char *); /* add a service or host comment */ +int cmd_delete_comment(int, char *); /* delete a service or host comment */ +int cmd_delete_all_comments(int, char *); /* delete all comments associated with a host or service */ +int cmd_delay_notification(int, char *); /* delay a service or host notification */ +int cmd_schedule_check(int, char *); /* schedule an immediate or delayed host check */ +int cmd_schedule_host_service_checks(int, char *, int); /* schedule an immediate or delayed checks of all services on a host */ +int cmd_signal_process(int, char *); /* schedules a program shutdown or restart */ +int cmd_process_service_check_result(int, time_t, char *); /* processes a passive service check */ +int cmd_process_host_check_result(int, time_t, char *); /* processes a passive host check */ +int cmd_acknowledge_problem(int, char *); /* acknowledges a host or service problem */ +int cmd_remove_acknowledgement(int, char *); /* removes a host or service acknowledgement */ +int cmd_schedule_downtime(int, time_t, char *); /* schedules host or service downtime */ +int cmd_delete_downtime(int, char *); /* cancels active/pending host or service scheduled downtime */ +int cmd_change_object_int_var(int, char *); /* changes host/svc (int) variable */ +int cmd_change_object_char_var(int, char *); /* changes host/svc (char) variable */ +int cmd_change_object_custom_var(int, char *); /* changes host/svc custom variable */ +int cmd_process_external_commands_from_file(int, char *); /* process external commands from a file */ +int cmd_delete_downtime_by_start_time_comment(int, char *); +int cmd_delete_downtime_by_host_name(int, char *); +int cmd_delete_downtime_by_hostgroup_name(int, char *); + +int process_passive_service_check(time_t, char *, char *, int, char *); +int process_passive_host_check(time_t, char *, int, char *); + + +/**** Internal Command Implementations ****/ +void disable_service_checks(service *); /* disables a service check */ +void enable_service_checks(service *); /* enables a service check */ +void schedule_service_check(service *, time_t, int); /* schedules an immediate or delayed service check */ +void schedule_host_check(host *, time_t, int); /* schedules an immediate or delayed host check */ +void enable_all_notifications(void); /* enables notifications on a program-wide basis */ +void disable_all_notifications(void); /* disables notifications on a program-wide basis */ +void enable_service_notifications(service *); /* enables service notifications */ +void disable_service_notifications(service *); /* disables service notifications */ +void enable_host_notifications(host *); /* enables host notifications */ +void disable_host_notifications(host *); /* disables host notifications */ +void enable_and_propagate_notifications(host *, int, int, int, int); /* enables notifications for all hosts and services beyond a given host */ +void disable_and_propagate_notifications(host *, int, int, int, int); /* disables notifications for all hosts and services beyond a given host */ +void schedule_and_propagate_downtime(host *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long); /* schedules downtime for all hosts beyond a given host */ +void acknowledge_host_problem(host *, char *, char *, int, int, int); /* acknowledges a host problem */ +void acknowledge_service_problem(service *, char *, char *, int, int, int); /* acknowledges a service problem */ +void remove_host_acknowledgement(host *); /* removes a host acknowledgement */ +void remove_service_acknowledgement(service *); /* removes a service acknowledgement */ +void start_executing_service_checks(void); /* starts executing service checks */ +void stop_executing_service_checks(void); /* stops executing service checks */ +void start_accepting_passive_service_checks(void); /* starts accepting passive service check results */ +void stop_accepting_passive_service_checks(void); /* stops accepting passive service check results */ +void enable_passive_service_checks(service *); /* enables passive service checks for a particular service */ +void disable_passive_service_checks(service *); /* disables passive service checks for a particular service */ +void start_using_event_handlers(void); /* enables event handlers on a program-wide basis */ +void stop_using_event_handlers(void); /* disables event handlers on a program-wide basis */ +void enable_service_event_handler(service *); /* enables the event handler for a particular service */ +void disable_service_event_handler(service *); /* disables the event handler for a particular service */ +void enable_host_event_handler(host *); /* enables the event handler for a particular host */ +void disable_host_event_handler(host *); /* disables the event handler for a particular host */ +void enable_host_checks(host *); /* enables checks of a particular host */ +void disable_host_checks(host *); /* disables checks of a particular host */ +void start_obsessing_over_service_checks(void); /* start obsessing about service check results */ +void stop_obsessing_over_service_checks(void); /* stop obsessing about service check results */ +void start_obsessing_over_host_checks(void); /* start obsessing about host check results */ +void stop_obsessing_over_host_checks(void); /* stop obsessing about host check results */ +void enable_service_freshness_checks(void); /* enable service freshness checks */ +void disable_service_freshness_checks(void); /* disable service freshness checks */ +void enable_host_freshness_checks(void); /* enable host freshness checks */ +void disable_host_freshness_checks(void); /* disable host freshness checks */ +void process_passive_checks(void); /* processes passive host and service check results */ +void enable_all_failure_prediction(void); /* enables failure prediction on a program-wide basis */ +void disable_all_failure_prediction(void); /* disables failure prediction on a program-wide basis */ +void enable_performance_data(void); /* enables processing of performance data on a program-wide basis */ +void disable_performance_data(void); /* disables processing of performance data on a program-wide basis */ +void start_executing_host_checks(void); /* starts executing host checks */ +void stop_executing_host_checks(void); /* stops executing host checks */ +void start_accepting_passive_host_checks(void); /* starts accepting passive host check results */ +void stop_accepting_passive_host_checks(void); /* stops accepting passive host check results */ +void enable_passive_host_checks(host *); /* enables passive host checks for a particular host */ +void disable_passive_host_checks(host *); /* disables passive host checks for a particular host */ +void start_obsessing_over_service(service *); /* start obsessing about specific service check results */ +void stop_obsessing_over_service(service *); /* stop obsessing about specific service check results */ +void start_obsessing_over_host(host *); /* start obsessing about specific host check results */ +void stop_obsessing_over_host(host *); /* stop obsessing about specific host check results */ +void set_host_notification_number(host *, int); /* sets current notification number for a specific host */ +void set_service_notification_number(service *, int); /* sets current notification number for a specific service */ +void enable_contact_host_notifications(contact *); /* enables host notifications for a specific contact */ +void disable_contact_host_notifications(contact *); /* disables host notifications for a specific contact */ +void enable_contact_service_notifications(contact *); /* enables service notifications for a specific contact */ +void disable_contact_service_notifications(contact *); /* disables service notifications for a specific contact */ + +int init_command_file_worker_thread(void); +int shutdown_command_file_worker_thread(void); +void * command_file_worker_thread(void *); +void cleanup_command_file_worker_thread(void *); + +int submit_external_command(char *, int *); +int submit_raw_external_command(char *, time_t *, int *); + +char *get_program_version(void); +char *get_program_modification_date(void); + +NAGIOS_END_DECL +#endif + diff --git a/include/nebcallbacks.h b/include/nebcallbacks.h new file mode 100644 index 0000000..a9e631a --- /dev/null +++ b/include/nebcallbacks.h @@ -0,0 +1,81 @@ +/***************************************************************************** + * + * NEBCALLBACKS.H - Include file for event broker modules + * + * Copyright (c) 2002-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 01-06-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBCALLBACKS_H +#define _NEBCALLBACKS_H + +#include "compat.h" +#include "nebmodules.h" + + +/***** CALLBACK TYPES *****/ + +#define NEBCALLBACK_NUMITEMS 33 /* total number of callback types we have */ + +#define NEBCALLBACK_RESERVED0 0 /* reserved for future use */ +#define NEBCALLBACK_RESERVED1 1 +#define NEBCALLBACK_RESERVED2 2 +#define NEBCALLBACK_RESERVED3 3 +#define NEBCALLBACK_RESERVED4 4 + +#define NEBCALLBACK_RAW_DATA 5 +#define NEBCALLBACK_NEB_DATA 6 + +#define NEBCALLBACK_PROCESS_DATA 7 +#define NEBCALLBACK_TIMED_EVENT_DATA 8 +#define NEBCALLBACK_LOG_DATA 9 +#define NEBCALLBACK_SYSTEM_COMMAND_DATA 10 +#define NEBCALLBACK_EVENT_HANDLER_DATA 11 +#define NEBCALLBACK_NOTIFICATION_DATA 12 +#define NEBCALLBACK_SERVICE_CHECK_DATA 13 +#define NEBCALLBACK_HOST_CHECK_DATA 14 +#define NEBCALLBACK_COMMENT_DATA 15 +#define NEBCALLBACK_DOWNTIME_DATA 16 +#define NEBCALLBACK_FLAPPING_DATA 17 +#define NEBCALLBACK_PROGRAM_STATUS_DATA 18 +#define NEBCALLBACK_HOST_STATUS_DATA 19 +#define NEBCALLBACK_SERVICE_STATUS_DATA 20 +#define NEBCALLBACK_ADAPTIVE_PROGRAM_DATA 21 +#define NEBCALLBACK_ADAPTIVE_HOST_DATA 22 +#define NEBCALLBACK_ADAPTIVE_SERVICE_DATA 23 +#define NEBCALLBACK_EXTERNAL_COMMAND_DATA 24 +#define NEBCALLBACK_AGGREGATED_STATUS_DATA 25 +#define NEBCALLBACK_RETENTION_DATA 26 +#define NEBCALLBACK_CONTACT_NOTIFICATION_DATA 27 +#define NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA 28 +#define NEBCALLBACK_ACKNOWLEDGEMENT_DATA 29 +#define NEBCALLBACK_STATE_CHANGE_DATA 30 +#define NEBCALLBACK_CONTACT_STATUS_DATA 31 +#define NEBCALLBACK_ADAPTIVE_CONTACT_DATA 32 + + +/***** CALLBACK FUNCTIONS *****/ +NAGIOS_BEGIN_DECL + +int neb_register_callback(int callback_type, void *mod_handle, int priority, int (*callback_func)(int, void *)); +int neb_deregister_callback(int callback_type, int (*callback_func)(int, void *)); +int neb_deregister_module_callbacks(nebmodule *); + +NAGIOS_END_DECL +#endif diff --git a/include/neberrors.h b/include/neberrors.h new file mode 100644 index 0000000..31e6e83 --- /dev/null +++ b/include/neberrors.h @@ -0,0 +1,69 @@ +/***************************************************************************** + * + * NEBERRORS.H - Event broker errors + * + * Copyright (c) 2003-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-12-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBERRORS_H +#define _NEBERRORS_H + + +/***** GENERIC DEFINES *****/ + +#define NEB_OK 0 +#define NEB_ERROR -1 + +#define NEB_TRUE 1 +#define NEB_FALSE 0 + + + +/***** GENERIC ERRORS *****/ + +#define NEBERROR_NOMEM 100 /* memory could not be allocated */ + + + +/***** CALLBACK ERRORS *****/ + +#define NEBERROR_NOCALLBACKFUNC 200 /* no callback function was specified */ +#define NEBERROR_NOCALLBACKLIST 201 /* callback list not initialized */ +#define NEBERROR_CALLBACKBOUNDS 202 /* callback type was out of bounds */ +#define NEBERROR_CALLBACKNOTFOUND 203 /* the callback could not be found */ +#define NEBERROR_NOMODULEHANDLE 204 /* no module handle specified */ +#define NEBERROR_BADMODULEHANDLE 205 /* bad module handle */ +#define NEBERROR_CALLBACKOVERRIDE 206 /* module wants to override default Nagios handling of event */ +#define NEBERROR_CALLBACKCANCEL 207 /* module wants to cancel callbacks to other modules */ + + + +/***** MODULE ERRORS *****/ + +#define NEBERROR_NOMODULE 300 /* no module was specified */ + + + +/***** MODULE INFO ERRORS *****/ + +#define NEBERROR_MODINFOBOUNDS 400 /* module info index was out of bounds */ + + +#endif diff --git a/include/nebmods.h b/include/nebmods.h new file mode 100644 index 0000000..8cbcdf8 --- /dev/null +++ b/include/nebmods.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * + * NEBMODS.H - Include file for event broker modules + * + * Copyright (c) 2002-2005 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-25-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODS_H +#define _NEBMODS_H + +#include "compat.h" +#include "nebcallbacks.h" +#include "nebmodules.h" + +NAGIOS_BEGIN_DECL + +/***** MODULE STRUCTURES *****/ + +/* NEB module callback list struct */ +typedef struct nebcallback_struct { + void *callback_func; + void *module_handle; + int priority; + struct nebcallback_struct *next; + } nebcallback; + + + +/***** MODULE FUNCTIONS *****/ + +int neb_init_modules(void); +int neb_deinit_modules(void); +int neb_load_all_modules(void); +int neb_load_module(nebmodule *); +int neb_free_module_list(void); +int neb_unload_all_modules(int, int); +int neb_unload_module(nebmodule *, int, int); +int neb_add_module(char *, char *, int); + + +/***** CALLBACK FUNCTIONS *****/ +int neb_init_callback_list(void); +int neb_free_callback_list(void); +int neb_make_callbacks(int, void *); + +NAGIOS_END_DECL +#endif diff --git a/include/nebmodules.h b/include/nebmodules.h new file mode 100644 index 0000000..2638501 --- /dev/null +++ b/include/nebmodules.h @@ -0,0 +1,97 @@ +/***************************************************************************** + * + * NEBMODULES.H - Include file for event broker modules + * + * Copyright (c) 2002-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-27-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODULES_H +#define _NEBMODULES_H + +#include "compat.h" +NAGIOS_BEGIN_DECL + + /***** MODULE VERSION INFORMATION *****/ + +#define NEB_API_VERSION(x) int __neb_api_version = x; +#define CURRENT_NEB_API_VERSION 3 + + + + /***** MODULE INFORMATION *****/ + +#define NEBMODULE_MODINFO_NUMITEMS 6 +#define NEBMODULE_MODINFO_TITLE 0 +#define NEBMODULE_MODINFO_AUTHOR 1 +#define NEBMODULE_MODINFO_COPYRIGHT 2 +#define NEBMODULE_MODINFO_VERSION 3 +#define NEBMODULE_MODINFO_LICENSE 4 +#define NEBMODULE_MODINFO_DESC 5 + + + + /***** MODULE LOAD/UNLOAD OPTIONS *****/ + +#define NEBMODULE_NORMAL_LOAD 0 /* module is being loaded normally */ +#define NEBMODULE_REQUEST_UNLOAD 0 /* request module to unload (but don't force it) */ +#define NEBMODULE_FORCE_UNLOAD 1 /* force module to unload */ + + + + /***** MODULES UNLOAD REASONS *****/ + +#define NEBMODULE_NEB_SHUTDOWN 1 /* event broker is shutting down */ +#define NEBMODULE_NEB_RESTART 2 /* event broker is restarting */ +#define NEBMODULE_ERROR_NO_INIT 3 /* _module_init() function was not found in module */ +#define NEBMODULE_ERROR_BAD_INIT 4 /* _module_init() function returned a bad code */ +#define NEBMODULE_ERROR_API_VERSION 5 /* module version is incompatible with current api */ + + + +/***** MODULE STRUCTURES *****/ + +/* NEB module structure */ +typedef struct nebmodule_struct { + char *filename; + char *args; + char *info[NEBMODULE_MODINFO_NUMITEMS]; + int should_be_loaded; + int is_currently_loaded; +#ifdef USE_LTDL + lt_dlhandle module_handle; + lt_ptr init_func; + lt_ptr deinit_func; +#else + void *module_handle; + void *init_func; + void *deinit_func; +#endif +#ifdef HAVE_PTHREAD_H + pthread_t thread_id; +#endif + struct nebmodule_struct *next; + } nebmodule; + + +/***** MODULE FUNCTIONS *****/ +int neb_set_module_info(void *, int, char *); + +NAGIOS_END_DECL +#endif diff --git a/include/nebstructs.h b/include/nebstructs.h new file mode 100644 index 0000000..38965d2 --- /dev/null +++ b/include/nebstructs.h @@ -0,0 +1,527 @@ +/***************************************************************************** + * + * NEBSTRUCTS.H - Event broker includes for Nagios + * + * Copyright (c) 2003-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-28-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBSTRUCTS_H +#define _NEBSTRUCTS_H + +#include "compat.h" +#include "objects.h" +#include "nagios.h" + +NAGIOS_BEGIN_DECL + +/****** STRUCTURES *************************/ + +/* process data structure */ +typedef struct nebstruct_process_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + } nebstruct_process_data; + + +/* timed event data structure */ +typedef struct nebstruct_timed_event_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int event_type; + int recurring; + time_t run_time; + void *event_data; + + void *event_ptr; + } nebstruct_timed_event_data; + + +/* log data structure */ +typedef struct nebstruct_log_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t entry_time; + int data_type; + char *data; + } nebstruct_log_data; + + +/* system command structure */ +typedef struct nebstruct_system_command_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + struct timeval start_time; + struct timeval end_time; + int timeout; + char *command_line; + int early_timeout; + double execution_time; + int return_code; + char *output; + } nebstruct_system_command_data; + + +/* event handler structure */ +typedef struct nebstruct_event_handler_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int eventhandler_type; + char *host_name; + char *service_description; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + int return_code; + char *output; + + void *object_ptr; + } nebstruct_event_handler_data; + + +/* host check structure */ +typedef struct nebstruct_host_check_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + int current_attempt; + int check_type; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + + void *object_ptr; + } nebstruct_host_check_data; + + +/* service check structure */ +typedef struct nebstruct_service_check_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + char *service_description; + int check_type; + int current_attempt; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + + void *object_ptr; + } nebstruct_service_check_data; + + +/* comment data structure */ +typedef struct nebstruct_comment_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int comment_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + int persistent; + int source; + int entry_type; + int expires; + time_t expire_time; + unsigned long comment_id; + + void *object_ptr; /* not implemented yet */ + } nebstruct_comment_data; + + +/* downtime data structure */ +typedef struct nebstruct_downtime_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int downtime_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + time_t start_time; + time_t end_time; + int fixed; + unsigned long duration; + unsigned long triggered_by; + unsigned long downtime_id; + + void *object_ptr; /* not implemented yet */ + } nebstruct_downtime_data; + + +/* flapping data structure */ +typedef struct nebstruct_flapping_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int flapping_type; + char *host_name; + char *service_description; + double percent_change; + double high_threshold; + double low_threshold; + unsigned long comment_id; + + void *object_ptr; + } nebstruct_flapping_data; + + +/* program status structure */ +typedef struct nebstruct_program_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t program_start; + int pid; + int daemon_mode; + time_t last_command_check; + time_t last_log_rotation; + int notifications_enabled; + int active_service_checks_enabled; + int passive_service_checks_enabled; + int active_host_checks_enabled; + int passive_host_checks_enabled; + int event_handlers_enabled; + int flap_detection_enabled; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_hosts; + int obsess_over_services; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + char *global_host_event_handler; + char *global_service_event_handler; + } nebstruct_program_status_data; + + +/* host status structure */ +typedef struct nebstruct_host_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + } nebstruct_host_status_data; + + +/* service status structure */ +typedef struct nebstruct_service_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + } nebstruct_service_status_data; + + +/* contact status structure */ +typedef struct nebstruct_contact_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + } nebstruct_contact_status_data; + + +/* notification data structure */ +typedef struct nebstruct_notification_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + int contacts_notified; + + void *object_ptr; + } nebstruct_notification_data; + + +/* contact notification data structure */ +typedef struct nebstruct_contact_notification_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + } nebstruct_contact_notification_data; + + +/* contact notification method data structure */ +typedef struct nebstruct_contact_notification_method_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + char *command_name; + char *command_args; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + } nebstruct_contact_notification_method_data; + + +/* adaptive program data structure */ +typedef struct nebstruct_adaptive_program_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + } nebstruct_adaptive_program_data; + + +/* adaptive host data structure */ +typedef struct nebstruct_adaptive_host_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + } nebstruct_adaptive_host_data; + + +/* adaptive service data structure */ +typedef struct nebstruct_adaptive_service_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + } nebstruct_adaptive_service_data; + + +/* adaptive contact data structure */ +typedef struct nebstruct_adaptive_contact_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + + void *object_ptr; + } nebstruct_adaptive_contact_data; + + +/* external command data structure */ +typedef struct nebstruct_external_command_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + time_t entry_time; + char *command_string; + char *command_args; + } nebstruct_external_command_data; + + +/* aggregated status data structure */ +typedef struct nebstruct_aggregated_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + } nebstruct_aggregated_status_data; + + +/* retention data structure */ +typedef struct nebstruct_retention_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + } nebstruct_retention_data; + + +/* acknowledgement structure */ +typedef struct nebstruct_acknowledgement_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int acknowledgement_type; + char *host_name; + char *service_description; + int state; + char *author_name; + char *comment_data; + int is_sticky; + int persistent_comment; + int notify_contacts; + + void *object_ptr; + } nebstruct_acknowledgement_data; + + +/* state change structure */ +typedef struct nebstruct_statechange_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int statechange_type; + char *host_name; + char *service_description; + int state; + int state_type; + int current_attempt; + int max_attempts; + char *output; + + void *object_ptr; + } nebstruct_statechange_data; + +NAGIOS_END_DECL +#endif diff --git a/include/netutils.h b/include/netutils.h new file mode 100644 index 0000000..839fa8f --- /dev/null +++ b/include/netutils.h @@ -0,0 +1,10 @@ +#ifndef _NETUTILS_H +#define _NETUTILS_H +#include "compat.h" +NAGIOS_BEGIN_DECL +int my_tcp_connect(char *host_name, int port, int *sd, int timeout); +int my_sendall(int s, char *buf, int *len, int timeout); +int my_recvall(int s, char *buf, int *len, int timeout); +NAGIOS_END_DECL +#endif + diff --git a/include/objects.h b/include/objects.h new file mode 100644 index 0000000..57d458e --- /dev/null +++ b/include/objects.h @@ -0,0 +1,754 @@ +/***************************************************************************** + * + * OBJECTS.H - Header file for object addition/search functions + * + * Copyright (c) 1999-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-10-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _OBJECTS_H +#define _OBJECTS_H + +#include "compat.h" +#include "common.h" + +NAGIOS_BEGIN_DECL + + +/*************** CURRENT OBJECT REVISION **************/ + +#define CURRENT_OBJECT_STRUCTURE_VERSION 307 /* increment when changes are made to data structures... */ +/* Nagios 3 starts at 300, Nagios 4 at 400, etc. */ + + + +/***************** OBJECT SIZE LIMITS *****************/ + +#define MAX_STATE_HISTORY_ENTRIES 21 /* max number of old states to keep track of for flap detection */ +#define MAX_CONTACT_ADDRESSES 6 /* max number of custom addresses a contact can have */ + + + +/***************** SKIP LISTS ****************/ + +#define NUM_OBJECT_SKIPLISTS 12 + +#define HOST_SKIPLIST 0 +#define SERVICE_SKIPLIST 1 +#define COMMAND_SKIPLIST 2 +#define TIMEPERIOD_SKIPLIST 3 +#define CONTACT_SKIPLIST 4 +#define CONTACTGROUP_SKIPLIST 5 +#define HOSTGROUP_SKIPLIST 6 +#define SERVICEGROUP_SKIPLIST 7 +#define HOSTDEPENDENCY_SKIPLIST 8 +#define SERVICEDEPENDENCY_SKIPLIST 9 +#define HOSTESCALATION_SKIPLIST 10 +#define SERVICEESCALATION_SKIPLIST 11 + + +/****************** DATA STRUCTURES *******************/ + +typedef struct host_struct host; +typedef struct service_struct service; +typedef struct contact_struct contact; + +/* OBJECT LIST STRUCTURE */ +typedef struct objectlist_struct { + void *object_ptr; + struct objectlist_struct *next; + } objectlist; + + +/* TIMERANGE structure */ +typedef struct timerange_struct { + unsigned long range_start; + unsigned long range_end; + struct timerange_struct *next; + } timerange; + + +/* DATERANGE structure */ +typedef struct daterange_struct { + int type; + int syear; /* start year */ + int smon; /* start month */ + int smday; /* start day of month (may 3rd, last day in feb) */ + int swday; /* start day of week (thursday) */ + int swday_offset; /* start weekday offset (3rd thursday, last monday in jan) */ + int eyear; + int emon; + int emday; + int ewday; + int ewday_offset; + int skip_interval; + timerange *times; + struct daterange_struct *next; + } daterange; + + +/* TIMEPERIODEXCLUSION structure */ +typedef struct timeperiodexclusion_struct { + char *timeperiod_name; + struct timeperiod_struct *timeperiod_ptr; + struct timeperiodexclusion_struct *next; + } timeperiodexclusion; + + +/* TIMEPERIOD structure */ +typedef struct timeperiod_struct { + char *name; + char *alias; + timerange *days[7]; + daterange *exceptions[DATERANGE_TYPES]; + timeperiodexclusion *exclusions; + struct timeperiod_struct *next; + struct timeperiod_struct *nexthash; + } timeperiod; + + +/* CONTACTSMEMBER structure */ +typedef struct contactsmember_struct { + char *contact_name; +#ifdef NSCORE + contact *contact_ptr; +#endif + struct contactsmember_struct *next; + } contactsmember; + + +/* CONTACTGROUP structure */ +typedef struct contactgroup_struct { + char *group_name; + char *alias; + contactsmember *members; + struct contactgroup_struct *next; + struct contactgroup_struct *nexthash; + } contactgroup; + + +/* CONTACTGROUPSMEMBER structure */ +typedef struct contactgroupsmember_struct { + char *group_name; +#ifdef NSCORE + contactgroup *group_ptr; +#endif + struct contactgroupsmember_struct *next; + } contactgroupsmember; + + +/* CUSTOMVARIABLESMEMBER structure */ +typedef struct customvariablesmember_struct { + char *variable_name; + char *variable_value; + int has_been_modified; + struct customvariablesmember_struct *next; + } customvariablesmember; + + +/* COMMAND structure */ +typedef struct command_struct { + char *name; + char *command_line; + struct command_struct *next; + struct command_struct *nexthash; + } command; + + +/* COMMANDSMEMBER structure */ +typedef struct commandsmember_struct { + char *command; +#ifdef NSCORE + command *command_ptr; +#endif + struct commandsmember_struct *next; + } commandsmember; + + +/* CONTACT structure */ + struct contact_struct { + char *name; + char *alias; + char *email; + char *pager; + char *address[MAX_CONTACT_ADDRESSES]; + commandsmember *host_notification_commands; + commandsmember *service_notification_commands; + int notify_on_service_unknown; + int notify_on_service_warning; + int notify_on_service_critical; + int notify_on_service_recovery; + int notify_on_service_flapping; + int notify_on_service_downtime; + int notify_on_host_down; + int notify_on_host_unreachable; + int notify_on_host_recovery; + int notify_on_host_flapping; + int notify_on_host_downtime; + char *host_notification_period; + char *service_notification_period; + int host_notifications_enabled; + int service_notifications_enabled; + int can_submit_commands; + int retain_status_information; + int retain_nonstatus_information; + customvariablesmember *custom_variables; +#ifdef NSCORE + time_t last_host_notification; + time_t last_service_notification; + unsigned long modified_attributes; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + + timeperiod *host_notification_period_ptr; + timeperiod *service_notification_period_ptr; + objectlist *contactgroups_ptr; +#endif + struct contact_struct *next; + struct contact_struct *nexthash; + }; + + +/* SERVICESMEMBER structure */ +typedef struct servicesmember_struct { + char *host_name; + char *service_description; +#ifdef NSCORE + service *service_ptr; +#endif + struct servicesmember_struct *next; + } servicesmember; + + +/* HOSTSMEMBER structure */ +typedef struct hostsmember_struct { + char *host_name; +#ifdef NSCORE + host *host_ptr; +#endif + struct hostsmember_struct *next; + } hostsmember; + + +/* HOSTGROUP structure */ +typedef struct hostgroup_struct { + char *group_name; + char *alias; + hostsmember *members; + char *notes; + char *notes_url; + char *action_url; + struct hostgroup_struct *next; + struct hostgroup_struct *nexthash; + } hostgroup; + + +/* HOST structure */ +struct host_struct { + char *name; + char *display_name; + char *alias; + char *address; + hostsmember *parent_hosts; + hostsmember *child_hosts; + servicesmember *services; + char *host_check_command; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + char *event_handler; + contactgroupsmember *contact_groups; + contactsmember *contacts; + double notification_interval; + double first_notification_delay; + int notify_on_down; + int notify_on_unreachable; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_on_up; + int flap_detection_on_down; + int flap_detection_on_unreachable; + int stalk_on_up; + int stalk_on_down; + int stalk_on_unreachable; + int check_freshness; + int freshness_threshold; + int process_performance_data; + int checks_enabled; + int accept_passive_host_checks; + int event_handler_enabled; + int retain_status_information; + int retain_nonstatus_information; + int failure_prediction_enabled; + char *failure_prediction_options; + int obsess_over_host; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + char *vrml_image; + char *statusmap_image; + int have_2d_coords; + int x_2d; + int y_2d; + int have_3d_coords; + double x_3d; + double y_3d; + double z_3d; + int should_be_drawn; + customvariablesmember *custom_variables; +#ifdef NSCORE + int problem_has_been_acknowledged; + int acknowledgement_type; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int notifications_enabled; + time_t last_host_notification; + time_t next_host_notification; + time_t next_check; + int should_be_scheduled; + time_t last_check; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int has_been_checked; + int is_being_freshened; + int notified_on_down; + int notified_on_unreachable; + int current_notification_number; + int no_more_notifications; + unsigned long current_notification_id; + int check_flapping_recovery_notification; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + time_t last_state_history_update; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + int total_services; + unsigned long total_service_check_interval; + unsigned long modified_attributes; + int circular_path_checked; + int contains_circular_path; + + command *event_handler_ptr; + command *check_command_ptr; + timeperiod *check_period_ptr; + timeperiod *notification_period_ptr; + objectlist *hostgroups_ptr; +#endif + struct host_struct *next; + void *next_check_event; + }; + + +/* SERVICEGROUP structure */ +typedef struct servicegroup_struct { + char *group_name; + char *alias; + servicesmember *members; + char *notes; + char *notes_url; + char *action_url; + struct servicegroup_struct *next; + struct servicegroup_struct *nexthash; + } servicegroup; + + +/* SERVICE structure */ +struct service_struct { + char *host_name; + char *description; + char *display_name; + char *service_check_command; + char *event_handler; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + int parallelize; + contactgroupsmember *contact_groups; + contactsmember *contacts; + double notification_interval; + double first_notification_delay; + int notify_on_unknown; + int notify_on_warning; + int notify_on_critical; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + int stalk_on_ok; + int stalk_on_warning; + int stalk_on_unknown; + int stalk_on_critical; + int is_volatile; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_on_ok; + int flap_detection_on_warning; + int flap_detection_on_unknown; + int flap_detection_on_critical; + int process_performance_data; + int check_freshness; + int freshness_threshold; + int accept_passive_service_checks; + int event_handler_enabled; + int checks_enabled; + int retain_status_information; + int retain_nonstatus_information; + int notifications_enabled; + int obsess_over_service; + int failure_prediction_enabled; + char *failure_prediction_options; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + customvariablesmember *custom_variables; +#ifdef NSCORE + int problem_has_been_acknowledged; + int acknowledgement_type; + int host_problem_at_last_check; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + time_t next_check; + int should_be_scheduled; + time_t last_check; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int check_flapping_recovery_notification; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int has_been_checked; + int is_being_freshened; + int notified_on_unknown; + int notified_on_warning; + int notified_on_critical; + int current_notification_number; + unsigned long current_notification_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + unsigned long modified_attributes; + + host *host_ptr; + command *event_handler_ptr; + char *event_handler_args; + command *check_command_ptr; + char *check_command_args; + timeperiod *check_period_ptr; + timeperiod *notification_period_ptr; + objectlist *servicegroups_ptr; +#endif + struct service_struct *next; + void *next_check_event; + }; + + +/* SERVICE ESCALATION structure */ +typedef struct serviceescalation_struct { + char *host_name; + char *description; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_recovery; + int escalate_on_warning; + int escalate_on_unknown; + int escalate_on_critical; + contactgroupsmember *contact_groups; + contactsmember *contacts; +#ifdef NSCORE + service *service_ptr; + timeperiod *escalation_period_ptr; +#endif + struct serviceescalation_struct *next; + struct serviceescalation_struct *nexthash; + } serviceescalation; + + +/* SERVICE DEPENDENCY structure */ +typedef struct servicedependency_struct { + int dependency_type; + char *dependent_host_name; + char *dependent_service_description; + char *host_name; + char *service_description; + char *dependency_period; + int inherits_parent; + int fail_on_ok; + int fail_on_warning; + int fail_on_unknown; + int fail_on_critical; + int fail_on_pending; +#ifdef NSCORE + int circular_path_checked; + int contains_circular_path; + + service *master_service_ptr; + service *dependent_service_ptr; + timeperiod *dependency_period_ptr; +#endif + struct servicedependency_struct *next; + struct servicedependency_struct *nexthash; + } servicedependency; + + +/* HOST ESCALATION structure */ +typedef struct hostescalation_struct { + char *host_name; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_recovery; + int escalate_on_down; + int escalate_on_unreachable; + contactgroupsmember *contact_groups; + contactsmember *contacts; +#ifdef NSCORE + host *host_ptr; + timeperiod *escalation_period_ptr; +#endif + struct hostescalation_struct *next; + struct hostescalation_struct *nexthash; + } hostescalation; + + +/* HOST DEPENDENCY structure */ +typedef struct hostdependency_struct { + int dependency_type; + char *dependent_host_name; + char *host_name; + char *dependency_period; + int inherits_parent; + int fail_on_up; + int fail_on_down; + int fail_on_unreachable; + int fail_on_pending; +#ifdef NSCORE + int circular_path_checked; + int contains_circular_path; + + host *master_host_ptr; + host *dependent_host_ptr; + timeperiod *dependency_period_ptr; +#endif + struct hostdependency_struct *next; + struct hostdependency_struct *nexthash; + } hostdependency; + + + + +/****************** HASH STRUCTURES ********************/ + +typedef struct host_cursor_struct { + int host_hashchain_iterator; + host *current_host_pointer; + } host_cursor; + + + +/********************* FUNCTIONS **********************/ + +/**** Top-level input functions ****/ +int read_object_config_data(char *, int, int, int); /* reads all external configuration data of specific types */ + + +/**** Object Creation Functions ****/ +contact *add_contact(char *, char *, char *, char *, char **, char *, char *, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int); /* adds a contact definition */ +commandsmember *add_service_notification_command_to_contact(contact *, char *); /* adds a service notification command to a contact definition */ +commandsmember *add_host_notification_command_to_contact(contact *, char *); /* adds a host notification command to a contact definition */ +customvariablesmember *add_custom_variable_to_contact(contact *, char *, char *); /* adds a custom variable to a service definition */ +host *add_host(char *, char *, char *, char *, char *, int, double, double, int, int, int, int, int, int, double, double, char *, int, char *, int, int, char *, int, int, double, double, int, int, int, int, int, int, int, int, char *, int, int, char *, char *, char *, char *, char *, char *, char *, int, int, int, double, double, double, int, int, int, int, int); /* adds a host definition */ +hostsmember *add_parent_host_to_host(host *, char *); /* adds a parent host to a host definition */ +hostsmember *add_child_link_to_host(host *, host *); /* adds a child host to a host definition */ +contactgroupsmember *add_contactgroup_to_host(host *, char *); /* adds a contactgroup to a host definition */ +contactsmember *add_contact_to_host(host *, char *); /* adds a contact to a host definition */ +customvariablesmember *add_custom_variable_to_host(host *, char *, char *); /* adds a custom variable to a host definition */ +timeperiod *add_timeperiod(char *, char *); /* adds a timeperiod definition */ +timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *, char *); /* adds an exclusion to a timeperiod */ +timerange *add_timerange_to_timeperiod(timeperiod *, int, unsigned long, unsigned long); /* adds a timerange to a timeperiod definition */ +daterange *add_exception_to_timeperiod(timeperiod *, int, int, int, int, int, int, int, int, int, int, int, int); +timerange *add_timerange_to_daterange(daterange *, unsigned long, unsigned long); +hostgroup *add_hostgroup(char *, char *, char *, char *, char *); /* adds a hostgroup definition */ +hostsmember *add_host_to_hostgroup(hostgroup *, char *); /* adds a host to a hostgroup definition */ +servicegroup *add_servicegroup(char *, char *, char *, char *, char *); /* adds a servicegroup definition */ +servicesmember *add_service_to_servicegroup(servicegroup *, char *, char *); /* adds a service to a servicegroup definition */ +contactgroup *add_contactgroup(char *, char *); /* adds a contactgroup definition */ +contactsmember *add_contact_to_contactgroup(contactgroup *, char *); /* adds a contact to a contact group definition */ +command *add_command(char *, char *); /* adds a command definition */ +service *add_service(char *, char *, char *, char *, int, int, int, int, double, double, double, double, char *, int, int, int, int, int, int, int, int, char *, int, char *, int, int, double, double, int, int, int, int, int, int, int, int, int, int, char *, int, int, char *, char *, char *, char *, char *, int, int, int); /* adds a service definition */ +contactgroupsmember *add_contactgroup_to_service(service *, char *); /* adds a contact group to a service definition */ +contactsmember *add_contact_to_service(service *, char *); /* adds a contact to a host definition */ +serviceescalation *add_serviceescalation(char *, char *, int, int, double, char *, int, int, int, int); /* adds a service escalation definition */ +contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *, char *); /* adds a contact group to a service escalation definition */ +contactsmember *add_contact_to_serviceescalation(serviceescalation *, char *); /* adds a contact to a service escalation definition */ +customvariablesmember *add_custom_variable_to_service(service *, char *, char *); /* adds a custom variable to a service definition */ +servicedependency *add_service_dependency(char *, char *, char *, char *, int, int, int, int, int, int, int, char *); /* adds a service dependency definition */ +hostdependency *add_host_dependency(char *, char *, int, int, int, int, int, int, char *); /* adds a host dependency definition */ +hostescalation *add_hostescalation(char *, int, int, double, char *, int, int, int); /* adds a host escalation definition */ +contactsmember *add_contact_to_hostescalation(hostescalation *, char *); /* adds a contact to a host escalation definition */ +contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *, char *); /* adds a contact group to a host escalation definition */ + +contactsmember *add_contact_to_object(contactsmember **, char *); /* adds a contact to an object */ +customvariablesmember *add_custom_variable_to_object(customvariablesmember **, char *, char *); /* adds a custom variable to an object */ + + +servicesmember *add_service_link_to_host(host *, service *); + + +/*** Object Skiplist Functions ****/ +int init_object_skiplists(void); +int free_object_skiplists(void); +int skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b); +int skiplist_compare_host(void *a, void *b); +int skiplist_compare_service(void *a, void *b); +int skiplist_compare_command(void *a, void *b); +int skiplist_compare_timeperiod(void *a, void *b); +int skiplist_compare_contact(void *a, void *b); +int skiplist_compare_contactgroup(void *a, void *b); +int skiplist_compare_hostgroup(void *a, void *b); +int skiplist_compare_servicegroup(void *a, void *b); +int skiplist_compare_hostescalation(void *a, void *b); +int skiplist_compare_serviceescalation(void *a, void *b); +int skiplist_compare_hostdependency(void *a, void *b); +int skiplist_compare_servicedependency(void *a, void *b); + +int get_host_count(void); +int get_service_count(void); + + + +/**** Object Search Functions ****/ +timeperiod *find_timeperiod(char *); /* finds a timeperiod object */ +host *find_host(char *); /* finds a host object */ +hostgroup *find_hostgroup(char *); /* finds a hostgroup object */ +servicegroup *find_servicegroup(char *); /* finds a servicegroup object */ +contact *find_contact(char *); /* finds a contact object */ +contactgroup *find_contactgroup(char *); /* finds a contactgroup object */ +command *find_command(char *); /* finds a command object */ +service *find_service(char *, char *); /* finds a service object */ + + +/**** Object Traversal Functions ****/ +hostescalation *get_first_hostescalation_by_host(char *, void **); +hostescalation *get_next_hostescalation_by_host(char *, void **); +serviceescalation *get_first_serviceescalation_by_service(char *, char *, void **); +serviceescalation *get_next_serviceescalation_by_service(char *, char *, void **); +hostdependency *get_first_hostdependency_by_dependent_host(char *, void **); +hostdependency *get_next_hostdependency_by_dependent_host(char *, void **); +servicedependency *get_first_servicedependency_by_dependent_service(char *, char *, void **); +servicedependency *get_next_servicedependency_by_dependent_service(char *, char *, void **); + +#ifdef NSCORE +int add_object_to_objectlist(objectlist **, void *); +int free_objectlist(objectlist **); +#endif + + +/**** Object Query Functions ****/ +int is_host_immediate_child_of_host(host *, host *); /* checks if a host is an immediate child of another host */ +int is_host_primary_immediate_child_of_host(host *, host *); /* checks if a host is an immediate child (and primary child) of another host */ +int is_host_immediate_parent_of_host(host *, host *); /* checks if a host is an immediate child of another host */ +int is_host_member_of_hostgroup(hostgroup *, host *); /* tests whether or not a host is a member of a specific hostgroup */ +int is_host_member_of_servicegroup(servicegroup *, host *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_service_member_of_servicegroup(servicegroup *, service *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_contact_member_of_contactgroup(contactgroup *, contact *); /* tests whether or not a contact is a member of a specific contact group */ +int is_contact_for_host(host *, contact *); /* tests whether or not a contact is a contact member for a specific host */ +int is_escalated_contact_for_host(host *, contact *); /* checks whether or not a contact is an escalated contact for a specific host */ +int is_contact_for_service(service *, contact *); /* tests whether or not a contact is a contact member for a specific service */ +int is_escalated_contact_for_service(service *, contact *); /* checks whether or not a contact is an escalated contact for a specific service */ +int is_host_immediate_parent_of_host(host *, host *); /* tests whether or not a host is an immediate parent of another host */ + +int number_of_immediate_child_hosts(host *); /* counts the number of immediate child hosts for a particular host */ +int number_of_total_child_hosts(host *); /* counts the number of total child hosts for a particular host */ +int number_of_immediate_parent_hosts(host *); /* counts the number of immediate parents hosts for a particular host */ +int number_of_total_parent_hosts(host *); /* counts the number of total parents hosts for a particular host */ + +#ifdef NSCORE +int check_for_circular_servicedependency_path(servicedependency *, servicedependency *, int); /* checks if a circular dependency exists for a given service */ +int check_for_circular_hostdependency_path(hostdependency *, hostdependency *, int); /* checks if a circular dependency exists for a given host */ +#endif + + +/**** Object Cleanup Functions ****/ +int free_object_data(void); /* frees all allocated memory for the object definitions */ + + +NAGIOS_END_DECL +#endif diff --git a/include/perfdata.h b/include/perfdata.h new file mode 100644 index 0000000..6326f38 --- /dev/null +++ b/include/perfdata.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * + * PERFDATA.H - Include file for performance data routines + * + * Copyright (c) 2001-2005 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-25-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _PERFDATA_H +#define _PERFDATA_H + +#include "compat.h" +#include "objects.h" + +NAGIOS_BEGIN_DECL + +int initialize_performance_data(char *); /* initializes performance data */ +int cleanup_performance_data(char *); /* cleans up performance data */ + +int update_host_performance_data(host *); /* updates host performance data */ +int update_service_performance_data(service *); /* updates service performance data */ + +NAGIOS_END_DECL +#endif diff --git a/include/shared.h b/include/shared.h new file mode 100644 index 0000000..021f425 --- /dev/null +++ b/include/shared.h @@ -0,0 +1,39 @@ +#ifndef INCLUDE__shared_h__ +#define INCLUDE__shared_h__ + +#include +#include "compat.h" + +NAGIOS_BEGIN_DECL + +/* mmapfile structure - used for reading files via mmap() */ +typedef struct mmapfile_struct { + char *path; + int mode; + int fd; + unsigned long file_size; + unsigned long current_position; + unsigned long current_line; + void *mmap_buf; + } mmapfile; + +/* only usable on compile-time initialized arrays, for obvious reasons */ +#define ARRAY_SIZE(ary) (sizeof(ary) / sizeof(ary[0])) + +extern char *my_strtok(char *buffer, char *tokens); +extern char *my_strsep(char **stringp, const char *delim); +extern mmapfile *mmap_fopen(char *filename); +extern int mmap_fclose(mmapfile *temp_mmapfile); +extern char *mmap_fgets(mmapfile *temp_mmapfile); +extern char *mmap_fgets_multiline(mmapfile * temp_mmapfile); +extern void strip(char *buffer); +extern int hashfunc(const char *name1, const char *name2, int hashslots); +extern int compare_hashdata(const char *val1a, const char *val1b, const char *val2a, + const char *val2b); +extern void get_datetime_string(time_t *raw_time, char *buffer, + int buffer_length, int type); +extern void get_time_breakdown(unsigned long raw_time, int *days, int *hours, + int *minutes, int *seconds); + +NAGIOS_END_DECL +#endif diff --git a/include/skiplist.h b/include/skiplist.h new file mode 100644 index 0000000..18d3add --- /dev/null +++ b/include/skiplist.h @@ -0,0 +1,70 @@ +/************************************************************************ + * + * SKIPLIST.H - Skiplist data structures and functions + * + * Copyright (c) 2008 Ethan Galstad + * Last Modified: 02-24-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _SKIPLIST_H +#define _SKIPLIST_H +#include "compat.h" + +#define SKIPLIST_OK 0 +#define SKIPLIST_ERROR_ARGS 1 +#define SKIPLIST_ERROR_MEMORY 2 +#define SKIPLIST_ERROR_DUPLICATE 3 + +NAGIOS_BEGIN_DECL + +typedef struct skiplistnode_struct { + void *data; + struct skiplistnode_struct *forward[1]; /* this must be the last element of the struct, as we allocate # of elements during runtime*/ + } skiplistnode; + +typedef struct skiplist_struct { + int current_level; + int max_levels; + float level_probability; + unsigned long items; + int allow_duplicates; + int append_duplicates; + int (*compare_function)(void *, void *); + skiplistnode *head; + } skiplist; + + +skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *)); +skiplistnode *skiplist_new_node(skiplist *list, int node_levels); +int skiplist_insert(skiplist *list, void *data); +int skiplist_random_level(skiplist *list); +int skiplist_empty(skiplist *list); +int skiplist_free(skiplist **list); +void *skiplist_peek(skiplist *); +void *skiplist_pop(skiplist *); +void *skiplist_get_first(skiplist *list, void **node_ptr); +void *skiplist_get_next(void **node_ptr); +void *skiplist_find_first(skiplist *list, void *data, void **node_ptr); +void *skiplist_find_next(skiplist *list, void *data, void **node_ptr); +int skiplist_delete(skiplist *list, void *data); +int skiplist_delete_first(skiplist *list, void *data); +int skiplist_delete_all(skiplist *list, void *data); +int skiplist_delete_node(skiplist *list, void *node_ptr); + +NAGIOS_END_DECL +#endif diff --git a/include/snprintf.h.in b/include/snprintf.h.in new file mode 100644 index 0000000..c4a1446 --- /dev/null +++ b/include/snprintf.h.in @@ -0,0 +1,3 @@ +/* -*- C -*- */ +#undef HAVE_SNPRINTF +#undef NEED_VA_LIST diff --git a/include/sretention.h b/include/sretention.h new file mode 100644 index 0000000..95379db --- /dev/null +++ b/include/sretention.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * + * SRETENTION.H - Header for state retention routines + * + * Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-28-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "compat.h" +NAGIOS_BEGIN_DECL + +int initialize_retention_data(char *); +int cleanup_retention_data(char *); +int save_state_information(int); /* saves all host and state information */ +int read_initial_state_information(void); /* reads in initial host and state information */ + +NAGIOS_END_DECL diff --git a/include/statusdata.h b/include/statusdata.h new file mode 100644 index 0000000..fdb6f0c --- /dev/null +++ b/include/statusdata.h @@ -0,0 +1,207 @@ +/***************************************************************************** + * + * STATUSDATA.H - Header for external status data routines + * + * Copyright (c) 2000-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-19-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _STATUSDATA_H +#define _STATUSDATA_H + +#include "compat.h" + +#ifdef NSCORE +#include "objects.h" +#endif + +#ifdef NSCGI + +#define READ_PROGRAM_STATUS 1 +#define READ_HOST_STATUS 2 +#define READ_SERVICE_STATUS 4 +#define READ_CONTACT_STATUS 8 + +#define READ_ALL_STATUS_DATA READ_PROGRAM_STATUS | READ_HOST_STATUS | READ_SERVICE_STATUS | READ_CONTACT_STATUS + + + + /*************************** CHAINED HASH LIMITS ***************************/ + +#define SERVICESTATUS_HASHSLOTS 1024 +#define HOSTSTATUS_HASHSLOTS 1024 + + + /**************************** DATA STRUCTURES ******************************/ + +NAGIOS_BEGIN_DECL + +/* HOST STATUS structure */ +typedef struct hoststatus_struct { + char *host_name; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int status; + time_t last_update; + int has_been_checked; + int should_be_scheduled; + int current_attempt; + int max_attempts; + time_t last_check; + time_t next_check; + int check_options; + int check_type; + time_t last_state_change; + time_t last_hard_state_change; + int last_hard_state; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int state_type; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int notifications_enabled; + int problem_has_been_acknowledged; + int acknowledgement_type; + int current_notification_number; + int accept_passive_host_checks; + int event_handler_enabled; + int checks_enabled; + int flap_detection_enabled; + int is_flapping; + double percent_state_change; + double latency; + double execution_time; + int scheduled_downtime_depth; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_host; + struct hoststatus_struct *next; + struct hoststatus_struct *nexthash; + } hoststatus; + + +/* SERVICE STATUS structure */ +typedef struct servicestatus_struct { + char *host_name; + char *description; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int max_attempts; + int current_attempt; + int status; + time_t last_update; + int has_been_checked; + int should_be_scheduled; + time_t last_check; + time_t next_check; + int check_options; + int check_type; + int checks_enabled; + time_t last_state_change; + time_t last_hard_state_change; + int last_hard_state; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int state_type; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int notifications_enabled; + int problem_has_been_acknowledged; + int acknowledgement_type; + int current_notification_number; + int accept_passive_service_checks; + int event_handler_enabled; + int flap_detection_enabled; + int is_flapping; + double percent_state_change; + double latency; + double execution_time; + int scheduled_downtime_depth; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_service; + struct servicestatus_struct *next; + struct servicestatus_struct *nexthash; + } servicestatus; + + +/*************************** SERVICE STATES ***************************/ + +#define SERVICE_PENDING 1 +#define SERVICE_OK 2 +#define SERVICE_WARNING 4 +#define SERVICE_UNKNOWN 8 +#define SERVICE_CRITICAL 16 + + + +/**************************** HOST STATES ****************************/ + +#define HOST_PENDING 1 +#define HOST_UP 2 +#define HOST_DOWN 4 +#define HOST_UNREACHABLE 8 + +/* Convert the (historically ordered) host states into a notion of "urgency". + This is defined as, in ascending order: + HOST_UP (business as usual) + HOST_PENDING (waiting for - supposedly first - check result) + HOST_UNREACHABLE (a problem, but likely not its cause) + HOST_DOWN (look here!!) + The exact values are irrelevant, so I try to make the conversion as + CPU-efficient as possible: */ +#define HOST_URGENCY(hs) ((hs)|(((hs)&0x5)<<1)) + + + +/**************************** FUNCTIONS ******************************/ + +int read_status_data(char *, int); /* reads all status data */ +int add_host_status(hoststatus *); /* adds a host status entry to the list in memory */ +int add_service_status(servicestatus *); /* adds a service status entry to the list in memory */ + +int add_hoststatus_to_hashlist(hoststatus *); +int add_servicestatus_to_hashlist(servicestatus *); + +servicestatus *find_servicestatus(char *, char *); /* finds status information for a specific service */ +hoststatus *find_hoststatus(char *); /* finds status information for a specific host */ +int get_servicestatus_count(char *, int); /* gets total number of services of a certain type for a specific host */ + +void free_status_data(void); /* free all memory allocated to status data */ +#endif + +#ifdef NSCORE +int initialize_status_data(char *); /* initializes status data at program start */ +int update_all_status_data(void); /* updates all status data */ +int cleanup_status_data(char *, int); /* cleans up status data at program termination */ +int update_program_status(int); /* updates program status data */ +int update_host_status(host *, int); /* updates host status data */ +int update_service_status(service *, int); /* updates service status data */ +int update_contact_status(contact *, int); /* updates contact status data */ +#endif + +NAGIOS_END_DECL +#endif diff --git a/indent-all.sh b/indent-all.sh new file mode 100755 index 0000000..0f8fccd --- /dev/null +++ b/indent-all.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +for f in `find . -type f -name "*.[c]"`; do + ./indent.sh $f +done + diff --git a/indent.sh b/indent.sh new file mode 100755 index 0000000..d561da1 --- /dev/null +++ b/indent.sh @@ -0,0 +1,6 @@ +#!/bin/sh +ARTISTIC_STYLE_OPTIONS=/dev/null + +export ARTISTIC_STYLE_OPTIONS + +astyle --style=banner --indent=tab --unpad-paren --pad-oper --suffix=none "$@" diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..5ea6382 --- /dev/null +++ b/install-sh @@ -0,0 +1,256 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -b) shift + # ADDED 10/20/07 EG + # This script doesn't understand how to make backups, so make this a noop in case the option is used + echo "!!! WARNING !!! This install-sh script doesn't understand how to make backups (-b option), so none will be made" + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/make-tarball b/make-tarball new file mode 100755 index 0000000..960e9d7 --- /dev/null +++ b/make-tarball @@ -0,0 +1,25 @@ +#! /bin/sh +if [ "x$1" = "x" ] +then + echo "Usage: $0 " + exit 1 +fi + +if test -e Makefile; then + make distclean +fi +autoconf + +# Update version number and modification date in code +./update-version $1 + +PWDSAVE=`pwd` +PACKAGE=nagios +pushd .. +if [ ! -d $PACKAGE-$1 ]; then + ln -s `basename $PWDSAVE` $PACKAGE-$1 +fi +tar zhcvf $PACKAGE-$1.tar.gz --exclude RCS --exclude CVS --exclude build-* --exclude *~ --exclude .\#* $PACKAGE-$1 +#rm $PACKAGE-$1 +popd + diff --git a/mkpackage b/mkpackage new file mode 100755 index 0000000..1f949a1 --- /dev/null +++ b/mkpackage @@ -0,0 +1,38 @@ +#! /bin/sh + +if [ "z$1" = "z" ] ; then + echo You must specify an architecture to build for! + exit 1 +fi + +case "$1" in + solaris) + LD_RUN_PATH=/usr/lib:/usr/local/lib + autoreconf + PATH=.:..:$PATH configure --with-cgiurl=/nagios/cgi-bin \ +--with-htmurl=/nagios \ +--with-lockfile=/var/run/nagios.pid \ +--with-nagios-user=nagios \ +--with-nagios-grp=nagios \ +--with-command-user=nagios \ +--with-command-grp=www \ +--prefix=/usr/local \ +--exec-prefix=/usr/local/sbin \ +--bindir=/usr/local/sbin \ +--sbindir=/usr/local/lib/nagios/cgi \ +--libexecdir=/usr/local/lib/nagios/plugins \ +--datadir=/usr/local/share/nagios \ +--sysconfdir=/etc/nagios \ +--localstatedir=/var/log/nagios \ +--with-mail=/usr/bin/mailx + make pkgclean + make all + make pkgset + ;; + *) + echo Platform $1 is not currently supported + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/module/.gitignore b/module/.gitignore new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/module/.gitignore @@ -0,0 +1 @@ +Makefile diff --git a/module/Makefile.in b/module/Makefile.in new file mode 100644 index 0000000..a0eb7c5 --- /dev/null +++ b/module/Makefile.in @@ -0,0 +1,44 @@ +################################### +# Makefile for NEB examples +# +# Last Modified: 12-14-2007 +################################### + + +# Source code directories +SRC_INCLUDE=../include + +CC=@CC@ +MOD_CFLAGS=@MOD_CFLAGS@ +CFLAGS=@CFLAGS@ @DEFS@ +MOD_LDFLAGS=@MOD_LDFLAGS@ +LDFLAGS=@LDFLAGS@ +LIBS=@LIBS@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +BINDIR=@bindir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +COMMAND_OPTS=@COMMAND_OPTS@ +STRIP=@STRIP@ + +CP=@CP@ + +all: helloworld.o + +helloworld.o: helloworld.c + $(CC) $(MOD_CFLAGS) $(CFLAGS) -o helloworld.o helloworld.c $(MOD_LDFLAGS) $(LDFLAGS) $(LIBS) + +clean: + rm -f helloworld.o + rm -f core *.o + rm -f *~ *.*~ + +distclean: clean + rm -f Makefile + +devclean: distclean + +install: + diff --git a/module/helloworld.c b/module/helloworld.c new file mode 100644 index 0000000..4748d9a --- /dev/null +++ b/module/helloworld.c @@ -0,0 +1,143 @@ +/***************************************************************************** + * + * HELLOWORLD.C - Example of a simple NEB module + * + * Copyright (c) 2003-2007 Ethan Galstad (http://www.nagios.org) + * + * Last Modified: 12-26-2007 + * + * Description: + * + * This is an example of a very basic module. It does nothing useful other + * than logging some messages to the main Nagios log file when it is initialized + * (loaded), when it is closed (unloaded), and when aggregated status updates + * occur. I would not call that too useful, but hopefully it will serve as a + * very basic example of how to write a NEB module... + * + * Instructions: + * + * Compile with the following command: + * + * gcc -shared -o helloworld.o helloworld.c + * + *****************************************************************************/ + +#include "../include/config.h" + +/* include (minimum required) event broker header files */ +#include "../include/nebmodules.h" +#include "../include/nebcallbacks.h" + +/* include other event broker header files that we need for our work */ +#include "../include/nebstructs.h" +#include "../include/broker.h" + +/* include some Nagios stuff as well */ +#include "../include/config.h" +#include "../include/common.h" +#include "../include/nagios.h" + +/* specify event broker API version (required) */ +NEB_API_VERSION(CURRENT_NEB_API_VERSION); + + +void *helloworld_module_handle = NULL; + +void helloworld_reminder_message(char *); +int helloworld_handle_data(int, void *); + + +/* this function gets called when the module is loaded by the event broker */ +int nebmodule_init(int flags, char *args, nebmodule *handle) { + char temp_buffer[1024]; + time_t current_time; + unsigned long interval; + + /* save our handle */ + helloworld_module_handle = handle; + + /* set some info - this is completely optional, as Nagios doesn't do anything with this data */ + neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_TITLE, "helloworld"); + neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_AUTHOR, "Ethan Galstad"); + neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_TITLE, "Copyright (c) 2003-2007 Ethan Galstad"); + neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_VERSION, "noversion"); + neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_LICENSE, "GPL v2"); + neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_DESC, "A simple example to get you started with Nagios Event Broker (NEB) modules."); + + /* log module info to the Nagios log file */ + write_to_all_logs("helloworld: Copyright (c) 2003-2007 Ethan Galstad (egalstad@nagios.org)", NSLOG_INFO_MESSAGE); + + /* log a message to the Nagios log file */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "helloworld: Hello world!\n"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); + + /* log a reminder message every 15 minutes (how's that for annoying? :-)) */ + time(¤t_time); + interval = 900; + schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + interval, TRUE, interval, NULL, TRUE, (void *)helloworld_reminder_message, "How about you?", 0); + + /* register to be notified of certain events... */ + neb_register_callback(NEBCALLBACK_AGGREGATED_STATUS_DATA, helloworld_module_handle, 0, helloworld_handle_data); + + return 0; + } + + +/* this function gets called when the module is unloaded by the event broker */ +int nebmodule_deinit(int flags, int reason) { + char temp_buffer[1024]; + + /* deregister for all events we previously registered for... */ + neb_deregister_callback(NEBCALLBACK_AGGREGATED_STATUS_DATA, helloworld_handle_data); + + /* log a message to the Nagios log file */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "helloworld: Goodbye world!\n"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); + + return 0; + } + + +/* gets called every X minutes by an event in the scheduling queue */ +void helloworld_reminder_message(char *message) { + char temp_buffer[1024]; + + /* log a message to the Nagios log file */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "helloworld: I'm still here! %s", message); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); + + return; + } + + +/* handle data from Nagios daemon */ +int helloworld_handle_data(int event_type, void *data) { + nebstruct_aggregated_status_data *agsdata = NULL; + char temp_buffer[1024]; + + /* what type of event/data do we have? */ + switch(event_type) { + + case NEBCALLBACK_AGGREGATED_STATUS_DATA: + + /* an aggregated status data dump just started or ended... */ + if((agsdata = (nebstruct_aggregated_status_data *)data)) { + + /* log a message to the Nagios log file */ + snprintf(temp_buffer, sizeof(temp_buffer) - 1, "helloworld: An aggregated status update just %s.", (agsdata->type == NEBTYPE_AGGREGATEDSTATUS_STARTDUMP) ? "started" : "finished"); + temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; + write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); + } + + break; + + default: + break; + } + + return 0; + } + diff --git a/nagios.spec b/nagios.spec new file mode 100644 index 0000000..4f599c6 --- /dev/null +++ b/nagios.spec @@ -0,0 +1,435 @@ +%define name nagios +%define version 3.5.1 +%define release 1 +%define nsusr nagios +%define nsgrp nagios +%define cmdgrp nagiocmd +%define wwwusr apache +%define wwwgrp apache + +# Performance data handling method to use. By default we will use +# the file-based one (as existed in NetSaint). +# You can select the external command based method (the defaut for +# Nagios) by specifying +# --define 'PERF_EXTERNAL 1' +# in the rpm command-line +%{!?PERF_EXTERNAL: %define PERF_EXTERNAL 0} + +# Embedded Perl stuff, specify +# --define 'EMBPERL 1' +# in the rpm command-line to enable it +%{!?EMBPERL: %define EMBPERL 0} + +# Macro that print mesages to syslog at package (un)install time +%define nnmmsg logger -t %{name}/rpm + +Summary: Host/service/network monitoring program +Name: %{name} +Version: %{version} +Release: %{release} +License: GPL +Group: Application/System +Source0: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-buildroot +Prefix: %{_prefix} +Prefix: /etc/init.d +Prefix: /etc/nagios +Prefix: /var/log/nagios +Prefix: /var/spool/nagios +Requires: gd > 1.8, zlib, libpng, libjpeg, bash, grep +PreReq: /usr/bin/logger, chkconfig, sh-utils, shadow-utils, sed, initscripts, fileutils, mktemp +BuildRequires: gd-devel > 1.8, zlib-devel, libpng-devel, libjpeg-devel + +%description +Nagios is a program that will monitor hosts and services on your +network. It has the ability to email or page you when a problem arises +and when a problem is resolved. Nagios is written in C and is +designed to run under Linux (and some other *NIX variants) as a +background process, intermittently running checks on various services +that you specify. + +The actual service checks are performed by separate "plugin" programs +which return the status of the checks to Nagios. The plugins are +available at http://sourceforge.net/projects/nagiosplug + +This package provide core programs for nagios. The web interface, +documentation, and development files are built as separate packages + + +%package www +Group: Application/System +Summary: Provides the HTML and CGI files for the Nagios web interface. +Requires: %{name} = %{version} +Requires: webserver + + +%description www +Nagios is a program that will monitor hosts and services on your +network. It has the ability to email or page you when a problem arises +and when a problem is resolved. Nagios is written in C and is +designed to run under Linux (and some other *NIX variants) as a +background process, intermittently running checks on various services +that you specify. + +Several CGI programs are included with Nagios in order to allow you +to view the current service status, problem history, notification +history, and log file via the web. This package provides the HTML and +CGI files for the Nagios web interface. In addition, HTML +documentation is included in this package + + +%package devel +Group: Application/System +Summary: Provides include files that Nagios-related applications may compile against. +Requires: %{name} = %{version} + +%description devel +Nagios is a program that will monitor hosts and services on your +network. It has the ability to email or page you when a problem arises +and when a problem is resolved. Nagios is written in C and is +designed to run under Linux (and some other *NIX variants) as a +background process, intermittently running checks on various services +that you specify. + +This package provides include files that Nagios-related applications +may compile against. + + +%prep +%setup -q + + +%pre +# Create `nagios' user on the system if necessary +if /usr/bin/id %{nsusr} > /dev/null 2>&1 ; then + : # user already exists +else + /usr/sbin/useradd -r -d /var/log/nagios -s /bin/sh -c "%{nsusr}" %{nsusr} || \ + %nnmmsg Unexpected error adding user "%{nsusr}". Aborting install process. +fi + +# id cannot tell us if the group already exists +# so just try to create it and assume it works +/usr/sbin/groupadd %{cmdgrp} > /dev/null 2>&1 + +# if LSB standard /etc/init.d does not exist, +# create it as a symlink to the first match we find +if [ -d /etc/init.d -o -L /etc/init.d ]; then + : # we're done +elif [ -d /etc/rc.d/init.d ]; then + ln -s /etc/rc.d/init.d /etc/init.d +elif [ -d /usr/local/etc/rc.d ]; then + ln -s /usr/local/etc/rc.d /etc/init.d +elif [ -d /sbin/init.d ]; then + ln -s /sbin/init.d /etc/init.d +fi + + +%preun +if [ "$1" = 0 ]; then + /sbin/service nagios stop > /dev/null 2>&1 + /sbin/chkconfig --del nagios +fi + +%postun +if [ "$1" -ge "1" ]; then + /sbin/service nagios condrestart >/dev/null 2>&1 || : +fi +# Delete nagios user and group +# (if grep doesn't find a match, then it is NIS or LDAP served and cannot be deleted) +if [ $1 = 0 ]; then + /bin/grep '^%{nsusr}:' /etc/passwd > /dev/null 2>&1 && /usr/sbin/userdel %{nsusr} || %nnmmsg "User %{nsusr} could not be deleted." + /bin/grep '^%{nsgrp}:' /etc/group > /dev/null 2>&1 && /usr/sbin/groupdel %{nsgrp} || %nnmmsg "Group %{nsgrp} could not be deleted." + /bin/grep '^%{cmdgrp}:' /etc/group > /dev/null 2>&1 && /usr/sbin/groupdel %{cmdgrp} || %nnmmsg "Group %{cmdgrp} could not be deleted." +fi + + +%post www +# If apache is installed, and we can find the apache user, set a shell var +wwwusr=`awk '/^[ \t]*User[ \t]+[a-zA-Z0-9]+/ {print $2}' /etc/httpd/conf/*.conf` +if [ "z" == "z$wwwusr" ]; then # otherwise, use the default + wwwusr=%{wwwusr} +fi +# if apache user is not in cmdgrp, add it +if /usr/bin/id -Gn $wwwusr 2>/dev/null | /bin/grep -q %{cmdgrp} > /dev/null 2>&1 ; then + : # $wwwusr (default: apache) is already in nagiocmd group +else + # first find apache primary group + pgrp=`/usr/bin/id -gn $wwwusr 2>/dev/null` + # filter apache primary group from secondary groups + sgrps=`/usr/bin/id -Gn $wwwusr 2>/dev/null | /bin/sed "s/^$pgrp //;s/ $pgrp //;s/^$pgrp$//;s/ /,/g;"` + if [ "z" == "z$sgrps" ] ; then + sgrps=%{cmdgrp} + else + sgrps=$sgrps,%{cmdgrp} + fi + # modify apache user, adding it to cmdgrp + /usr/sbin/usermod -G $sgrps $wwwusr >/dev/null 2>&1 + %nnmmsg "User $wwwusr added to group %{cmdgrp} so sending commands to Nagios from the command CGI is possible." +fi + + +%preun www +if [ $1 = 0 ]; then +if test -f /etc/httpd/conf/httpd.conf; then + TEMPFILE=`mktemp /etc/httpd/conf/httpd.conf.tmp.XXXXXX` + if grep "^ *Include /etc/httpd/conf.d/nagios.conf" /etc/httpd/conf/httpd.conf > /dev/null; then + grep -v "^ *Include /etc/httpd/conf.d/nagios.conf" /etc/httpd/conf/httpd.conf > $TEMPFILE + mv $TEMPFILE /etc/httpd/conf/httpd.conf + chmod 664 /etc/httpd/conf/httpd.conf + /etc/rc.d/init.d/httpd restart + fi +fi +fi + + +%build +export PATH=$PATH:/usr/sbin +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" \ +./configure \ + --with-init-dir=/etc/init.d \ + --with-cgiurl=/nagios/cgi-bin \ + --with-htmurl=/nagios \ + --with-lockfile=/var/run/nagios.pid \ + --with-nagios-user=%{nsusr} \ + --with-nagios-group=%{nsgrp} \ + --prefix=%{_prefix} \ + --exec-prefix=%{_prefix}/sbin \ + --bindir=%{_prefix}/sbin \ + --sbindir=%{_prefix}/lib/nagios/cgi \ + --libexecdir=%{_prefix}/lib/nagios/plugins \ + --datarootdir=%{_prefix}/share/nagios \ + --sysconfdir=/etc/nagios \ + --localstatedir=/var/log/nagios \ +%if ! %{PERF_EXTERNAL} + --with-file-perfdata \ +%endif +%if %{EMBPERL} + --enable-embedded-perl \ +%endif + --with-gd-lib=/usr/lib \ + --with-gd-inc=/usr/include \ + --with-template-objects \ + --with-template-extinfo + +make all + +# make sample configs +###cd sample-config +###F=`mktemp temp.XXXXXX` +###sed -e 's=/var/log/nagios/rw/=/var/spool/nagios/=;s=@sysconfdir@/resource.cfg=@sysconfdir@/private/resource.cfg=' nagios.cfg > ${F} +###mv ${F} nagios.cfg +###cd .. + +# make daemonchk.cgi and event handlers +cd contrib +make +cd eventhandlers +for f in `find . -type f` ; do + F=`mktemp temp.XXXXXX` + sed "s=/usr/local/nagios/var/rw/=/var/spool/nagios/=; \ + s=/usr/local/nagios/libexec/eventhandlers/=%{_prefix}/lib/nagios/plugins/eventhandlers=; \ + s=/usr/local/nagios/test/var=/var/log/nagios=" ${f} > ${F} + mv ${F} ${f} +done +cd ../.. + + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +install -d -m 0775 ${RPM_BUILD_ROOT}/var/spool/nagios +install -d -m 0755 ${RPM_BUILD_ROOT}%{_prefix}/include/nagios +install -d -m 0755 ${RPM_BUILD_ROOT}/etc/init.d +install -d -m 0755 ${RPM_BUILD_ROOT}/etc/logrotate.d +install -d -m 0755 ${RPM_BUILD_ROOT}/etc/httpd/conf.d +install -d -m 0755 ${RPM_BUILD_ROOT}/etc/nagios +install -d -m 0755 ${RPM_BUILD_ROOT}/etc/nagios/objects +### install -d -m 0755 ${RPM_BUILD_ROOT}/etc/nagios/private +make DESTDIR=${RPM_BUILD_ROOT} INSTALL_OPTS="" COMMAND_OPTS="" install +make DESTDIR=${RPM_BUILD_ROOT} INSTALL_OPTS="" COMMAND_OPTS="" INIT_OPTS="" install-daemoninit + +# install templated configuration files +cd sample-config +for f in {nagios,cgi}.cfg ; do + [ -f $f ] && install -c -m 664 $f ${RPM_BUILD_ROOT}/etc/nagios/${f} +done +###mkdir -p ${RPM_BUILD_ROOT}/etc/nagios/private +for f in resource.cfg ; do + [ -f $f ] && install -c -m 664 $f ${RPM_BUILD_ROOT}/etc/nagios/${f} +done +cd template-object +for f in {commands,contacts,localhost,switch,templates,timeperiods}.cfg +do + [ -f $f ] && install -c -m 664 $f ${RPM_BUILD_ROOT}/etc/nagios/objects/${f} +done +cd .. +cd .. + +# install headers for development package +install -m 0644 include/locations.h ${RPM_BUILD_ROOT}%{_prefix}/include/nagios + +# install httpd configuration in RH80-style httpd config subdir +cp sample-config/httpd.conf ${RPM_BUILD_ROOT}/etc/httpd/conf.d/nagios.conf + +# install CGIs +cd contrib +make INSTALL=install DESTDIR=${RPM_BUILD_ROOT} INSTALL_OPTS="" COMMAND_OPTS="" CGIDIR=%{_prefix}/lib/nagios/cgi install +#mv ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/cgi/convertcfg ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/ +#mv ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/cgi/mini_epn ${RPM_BUILD_ROOT}%{_prefix}/sbin/ +cd .. + +# install event handlers +cd contrib/eventhandlers +install -d -m 0755 ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/eventhandlers +for file in * ; do + test -f $file && install -m 0755 $file ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/eventhandlers && rm -f $file +done +cd ../.. + + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(755,root,root) +/etc/init.d/nagios +%{_prefix}/sbin/nagios +%{_prefix}/sbin/nagiostats +%if %{EMBPERL} +%{_prefix}/sbin/p1.pl +%endif +%{_prefix}/sbin/mini_epn +%{_prefix}/sbin/new_mini_epn +%dir %{_prefix}/lib/nagios/eventhandlers +%{_prefix}/lib/nagios/eventhandlers/* +%{_sbindir}/convertcfg +%dir /etc/nagios +%dir /etc/nagios/objects +%defattr(644,root,root) +%config(noreplace) /etc/nagios/*.cfg +%config(noreplace) /etc/nagios/objects/*.cfg +%defattr(750,root,%{nsgrp}) +###%dir /etc/nagios/private +%defattr(640,root,%{nsgrp}) +### %config(noreplace) /etc/nagios/private/resource.cfg +%defattr(755,%{nsusr},%{nsgrp}) +%dir /var/log/nagios +%dir /var/log/nagios/archives +%defattr(2775,%{nsusr},%{nsgrp}) +%dir /var/spool/nagios +%doc Changelog INSTALLING LICENSE README UPGRADING + + +%files www +%defattr(755,root,root) +%dir %{_prefix}/lib/nagios/cgi +%{_prefix}/lib/nagios/cgi/* +%dir %{_prefix}/share/nagios +%defattr(-,root,root) +%{_prefix}/share/nagios/* +%config(noreplace) /etc/httpd/conf.d/nagios.conf + + +%files devel +%defattr(-,root,root) +%dir %{_prefix}/include/nagios +%{_prefix}/include/nagios/locations.h + + +%changelog +* Tue Nov 22 2005 Andreas Kasenides +- packaged %{_prefix}/sbin/new_mini_epn +- moved resource.cfg in /etc/nagios + +* Thu Dec 30 2004 Rui Miguel Silva Seabra +- FIX spec (wrong tag for License, and update to current state of compile) + +* Sat May 31 2003 Karl DeBisschop (1.1-1) +- Merge with CVS for 1.1 release + +* Fri May 30 2003 Karl DeBisschop (1.0-4) +- cmdgrp was not always getting created +- patches for cmd.cgi and history.cgi + +* Sat May 24 2003 Karl DeBisschop (1.0-3) +- patches for doco and PostgreSQL timestamp +- make sure all files are packaged (otherwise, will not build on RH9) + +* Sat May 17 2003 Karl DeBisschop (1.0-2) +- patch for file descriptor leak + +* Fri Oct 04 2002 Karl DeBisschop +- merge many improvements from Ramiro Morales + (macros for PERF_EXTERNAL and EMBPERL, cleanup pre/post scripts, + nnmmsg logger macro, include eventhandlers, convertcfg, mini_epn) +- use LSB-standard /etc/init.d/nagios startup location + +* Tue Aug 13 2002 Karl DeBisschop +- INSTALL was renamed INSTALLING +- p1.pl script included in package +- web server restarted because Red Hat 7.3 init does not do 'reload' + +* Fri Jun 14 2002 Ethan Galstad (1.0a4) +- Fixed spec file to work with Nagios + +* Wed Jan 17 2001 Karl DeBisschop (0.0.7a5-1) +- switch from /usr/libexec to /usr/lib because linux FHS has no libexec +- use global macro to set location of init script +- fold htaccess.sample into contrib directory of tarball + +* Fri Nov 03 2000 Karl DeBisschop (0.0.6-1) +- Rebuild with final sources + +* Wed Sep 06 2000 Karl DeBisschop (0.0.6b5-1) +- Create separate cgi, html, and devel packages +- Include commands.cfg + +* Sun Aug 27 2000 Karl DeBisschop (0.0.6b5-1) +- beta 5 + +* Sun Jul 23 2000 Karl DeBisschop (0.0.6b3-2) +- fixes for daemon-init, multi-OS RPM building + +* Wed Jul 12 2000 Karl DeBisschop (0.0.6b3-1) +- beta 3 + +* Sun Jun 25 2000 Karl DeBisschop (0.0.6b2-3) +- true beta2 sources + +* Sat Jun 24 2000 Karl DeBisschop (0.0.6b2-2) +- cleanup spec, still using pre-beta2 sources + +* Sat Jun 24 2000 Karl DeBisschop (0.0.6b2-1) +- mandrake merge using pre-beta2 sources (many thanks to Stefan van der Eijk ) + +* Wed Jun 14 2000 Karl DeBisschop (0.0.6b1-1) +- add stylesheet diffs + +* Mon Jun 12 2000 Karl DeBisschop (0.0.6b1-1) +- adapt for 0.0.6b1 + +* Mon Jun 05 2000 Karl DeBisschop (0.0.5-4) +- add traceroute.cgi and htaccess.sample +- move placement of docs (in files) to avoid group warnings +- change www user and group to nobody and add warning + +* Mon Jun 05 2000 Karsten Weiss (0.0.5-3) +- official group name +- improved user detection + +* Tue Oct 19 1999 Mike McHenry (0.0.4-1) +- Upgraded package from 0.0.4b4 to 0.0.4 + +* Mon Aug 16 1999 Mike McHenry +- First RPM build (0.0.4b4) diff --git a/p1.pl b/p1.pl new file mode 100644 index 0000000..0e95291 --- /dev/null +++ b/p1.pl @@ -0,0 +1,775 @@ + package Embed::Persistent; + +# p1.pl for Nagios + +use strict ; + +use Text::ParseWords qw(parse_line) ; + +use constant LEAVE_MSG => 1 ; +use constant CACHE_DUMP => 2 ; +use constant PLUGIN_DUMP => 4 ; + +use constant DEBUG_LEVEL => 0 ; +# use constant DEBUG_LEVEL => CACHE_DUMP ; +# use constant DEBUG_LEVEL => LEAVE_MSG ; +# use constant DEBUG_LEVEL => LEAVE_MSG | CACHE_DUMP ; +# use constant DEBUG_LEVEL => LEAVE_MSG | CACHE_DUMP | PLUGIN_DUMP ; + +use constant DEBUG_LOG_PATH => '/usr/local/nagios/var/' ; +# use constant DEBUG_LOG_PATH => './' ; +use constant LEAVE_MSG_STREAM => DEBUG_LOG_PATH . 'epn_leave-msgs.log' ; +use constant CACHE_DUMP_STREAM => DEBUG_LOG_PATH . 'epn_cache-dump.log' ; +use constant PLUGIN_DUMP_STREAM => DEBUG_LOG_PATH . 'epn_plugin-dump.log' ; + +use constant NUMBER_OF_PERL_PLUGINS => 60 ; + +use constant Cache_Dump_Interval => 20 ; + # Cache will be dumped every Cache_Dump_Interval plugin compilations + +(DEBUG_LEVEL & LEAVE_MSG) && do { + open LH, '>> ' . LEAVE_MSG_STREAM + or die "Can't open " . LEAVE_MSG_STREAM . ": $!" ; + + # Unbuffer LH since this will be written by child processes. + + select( (select(LH), $| = 1)[0] ) ; + } ; +(DEBUG_LEVEL & CACHE_DUMP) && do { + (open CH, '>> ' . CACHE_DUMP_STREAM + or die "Can't open " . CACHE_DUMP_STREAM . ": $!") ; + select( (select(CH), $| = 1)[0] ) ; + } ; +(DEBUG_LEVEL & PLUGIN_DUMP) && (open PH, '>> ' . PLUGIN_DUMP_STREAM + or die "Can't open " . PLUGIN_DUMP_STREAM . ": $!") ; + +require Data::Dumper + if DEBUG_LEVEL & CACHE_DUMP ; + +my (%Cache, $Current_Run) ; +keys %Cache = NUMBER_OF_PERL_PLUGINS ; + # Offsets in %Cache{$filename} +use constant MTIME => 0 ; +use constant PLUGIN_ARGS => 1 ; +use constant PLUGIN_ERROR => 2 ; +use constant PLUGIN_HNDLR => 3 ; + +package main; + +use subs 'CORE::GLOBAL::exit'; + +sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] (Redefine exit to trap plugin exit with eval BLOCK)" } + + +package OutputTrap; + + # Methods for use by tied STDOUT in embedded PERL module. + # Simply ties STDOUT to a scalar and caches values written to it. + # NB No more than 4KB characters per line are kept. + +sub TIEHANDLE { + my ($class) = @_; + my $me = ''; + bless \$me, $class; +} + +sub PRINT { + my $self = shift; + # $$self = substr(join('',@_), 0, 256) ; + $$self .= substr(join('',@_), 0, 4096) ; +} + +sub PRINTF { + my $self = shift; + my $fmt = shift; + # $$self = substr(sprintf($fmt,@_), 0, 256) ; + $$self .= substr(sprintf($fmt,@_), 0, 4096) ; +} + +sub READLINE { + my $self = shift; + +# CHANGED 12/26/07 EG Following two statements didn't allow for multi-line output or output > 256 chars + # Omit all lines after the first, per the nagios plugin guidelines +# $$self = (split /\n/, $$self)[0]; + # Perl code other than plugins may print nothing; in this case return "(No output!)\n". +# return $$self ? substr($$self, 0, 256) : "(No output!)\n" ; + + return $$self; +} + +sub CLOSE { + my $self = shift; + undef $self ; +} + +sub DESTROY { + my $self = shift; + undef $self; +} + +package Embed::Persistent; + +sub valid_package_name { + local $_ = shift ; + s|([^A-Za-z0-9\/])|sprintf("_%2x",unpack("C",$1))|eg; + # second pass only for words starting with a digit + s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; + + # Dress it up as a real package name + s|/|::|g; + return /^::/ ? "Embed$_" : "Embed::$_" ; + } + +# Perl 5.005_03 only traps warnings for errors classed by perldiag +# as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). +# Therefore treat all warnings as fatal. + +sub throw_exception { + die shift ; +} + +sub eval_file { + my ($filename, $delete, undef, $plugin_args) = @_ ; + + my $mtime = -M $filename ; + my $ts = localtime(time()) + if DEBUG_LEVEL ; + + + if ( + exists($Cache{$filename}) && + $Cache{$filename}[MTIME] && + $Cache{$filename}[MTIME] <= $mtime + ) { + # We have compiled this plugin before and + # it has not changed on disk; nothing to do except + # 1 parse the plugin arguments and cache them (to save + # repeated parsing of the same args) - the same + # plugin could be called with different args. + # 2 return the error from a former compilation + # if there was one. + + $Cache{$filename}[PLUGIN_ARGS]{$plugin_args} ||= [ parse_line('\s+', 0, $plugin_args) ] + if $plugin_args ; + + if ( $Cache{$filename}[PLUGIN_ERROR] ) { + print LH qq($ts eval_file: $filename failed compilation formerly and file has not changed; skipping compilation.\n) + if DEBUG_LEVEL & LEAVE_MSG ; + die qq(**ePN failed to compile $filename: "$Cache{$filename}[PLUGIN_ERROR]") ; + } else { + print LH qq($ts eval_file: $filename already successfully compiled and file has not changed; skipping compilation.\n) + if DEBUG_LEVEL & LEAVE_MSG ; + return $Cache{$filename}[PLUGIN_HNDLR] ; + } + } + + my $package = valid_package_name($filename) ; + + $Cache{$filename}[PLUGIN_ARGS]{$plugin_args} ||= [ parse_line('\s+', 0, $plugin_args) ] + if $plugin_args ; + + local *FH; + # die will be trapped by caller (checking ERRSV) + open FH, $filename + or die qq(**ePN failed to open "$filename": "$!") ; + + my $sub ; + sysread FH, $sub, -s FH ; + close FH; + # Cater for scripts that have embedded EOF symbols (__END__) + # XXXX + # Doesn't make sense to me. + + # $sub =~ s/__END__/\;}\n__END__/; + # Wrap the code into a subroutine inside our unique package + # (using $_ here [to save a lexical] is not a good idea since + # the definition of the package is visible to any other Perl + # code that uses [non localised] $_). + my $hndlr = <>> +$sub + # <<< END of PLUGIN >>> +} +EOSUB + + $Cache{$filename}[MTIME] = $mtime + unless $delete ; + # Suppress warning display. + local $SIG{__WARN__} = \&throw_exception ; + + + # Following 3 lines added 10/18/07 by Larry Low to fix problem where + # modified Perl plugins didn't get recached by the epn + no strict 'refs'; + undef %{$package.'::'}; + use strict 'refs'; + + # Compile &$package::hndlr. Since non executable code is being eval'd + # there is no need to protect lexicals in this scope. + eval $hndlr; + + # $@ is set for any warning and error. + # This guarantees that the plugin will not be run. + if ($@) { + # Report error line number wrt to original plugin text (7 lines added by eval_file). + # Error text looks like + # 'Use of uninitialized ..' at (eval 23) line 186, line 218 + # The error line number is 'line 186' + chomp($@) ; + $@ =~ s/line (\d+)[\.,]/'line ' . ($1 - 7) . ','/e ; + + print LH qq($ts eval_file: syntax error in $filename: "$@".\n) + if DEBUG_LEVEL & LEAVE_MSG ; + + if ( DEBUG_LEVEL & PLUGIN_DUMP ) { + my $i = 1 ; + $_ = $hndlr ; + s/^/sprintf('%10d ', $i++)/meg ; + # Will only get here once (when a faulty plugin is compiled). + # Therefore only _faulty_ plugins are dumped once each time the text changes. + + print PH qq($ts eval_file: transformed plugin "$filename" to ==>\n$_\n) ; + } + + $@ = substr($@, 0, 4096) + if length($@) > 4096 ; + + $Cache{$filename}[PLUGIN_ERROR] = $@ ; + # If the compilation fails, leave nothing behind that may affect subsequent + # compilations. This will be trapped by caller (checking ERRSV). + die qq(**ePN failed to compile $filename: "$@") ; + + } else { + $Cache{$filename}[PLUGIN_ERROR] = '' ; + } + + print LH qq($ts eval_file: successfully compiled "$filename $plugin_args".\n) + if DEBUG_LEVEL & LEAVE_MSG ; + + print CH qq($ts eval_file: after $Current_Run compilations \%Cache =>\n), Data::Dumper->Dump([\%Cache], [qw(*Cache)]), "\n" + if ( (DEBUG_LEVEL & CACHE_DUMP) && (++$Current_Run % Cache_Dump_Interval == 0) ) ; + + no strict 'refs' ; + return $Cache{$filename}[PLUGIN_HNDLR] = *{ $package . '::hndlr' }{CODE} ; + +} + +sub run_package { + my ($filename, undef, $plugin_hndlr_cr, $plugin_args) = @_; + # Second parm (after $filename) _may_ be used to wallop stashes. + + my $res = 3 ; + my $ts = localtime(time()) + if DEBUG_LEVEL ; + + local $SIG{__WARN__} = \&throw_exception ; + my $stdout = tie (*STDOUT, 'OutputTrap'); + my @plugin_args = $plugin_args ? @{ $Cache{$filename}[PLUGIN_ARGS]{$plugin_args} } : () ; + + # If the plugin has args, they have been cached by eval_file. + # ( cannot cache @plugin_args here because run_package() is + # called by child processes so cannot update %Cache.) + + eval { $plugin_hndlr_cr->(@plugin_args) } ; + + if ($@) { + # Error => normal plugin termination (exit) || run time error. + $_ = $@ ; + /^ExitTrap: (-?\d+)/ ? $res = $1 : + # For normal plugin exit, $@ will always match /^ExitTrap: (-?\d+)/ + /^ExitTrap: / ? $res = 0 : do { + # Run time error/abnormal plugin termination. + + chomp ; + # Report error line number wrt to original plugin text (7 lines added by eval_file). + s/line (\d+)[\.,]/'line ' . ($1 - 7) . ','/e ; + print STDOUT qq(**ePN $filename: "$_".\n) ; + } ; + + ($@, $_) = ('', '') ; + } + # ! Error => Perl code is not a plugin (fell off the end; no exit) + + # !! (read any output from the tied file handle.) + my $plugin_output = ; + + undef $stdout ; + untie *STDOUT; + + print LH qq($ts run_package: "$filename $plugin_args" returning ($res, "$plugin_output").\n) + if DEBUG_LEVEL & LEAVE_MSG ; + + return ($res, $plugin_output) ; +} + +1; + +=head1 NAME + +p1.pl - Perl program to provide Perl code persistence for the Nagios project (http://www.Nagios.Org). + +This program provides an API for calling Nagios Perl plugins from Nagios when it is built with embedded Perl support. The +intent is to tradeoff memory usage (see BUGS) against repeated context switches to recompile Perl plugins. + +=head1 SYNOPSIS + + +B + + /* 1 Initialise Perl - see perlembed - maintaining a persistent interpreter> */ + /* 2 Push the arguments (char *args[]) of call_pv() onto the Perl stack */ + /* 3 Compile the plugin - char *args[] is an array of pointers to strings required by p1.pl */ + + call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL) + + /* 4 if (SvTrue(ERRSV)) */ + goto outahere ; + + /* 5 Pop the code reference to the Perl sub (corresp to the plugin) returned by Perl */ + /* 6 Push the arguments (char *args[]) of call_pv() onto the Perl stack */ + /* 7 Run the plugin */ + + call_pv("Embed::Persistent::run_package", G_ARRAY) + + /* 8 example arguments for call_ functions */ + + args = { "check_rcp", /* pointer to plugin file name */ + "1", /* 1 to recompile plugins each time */ + "", /* temporary file name - no longer used */ + "-H sundev -C nfs" /* pointer to plugin argument string */ + } + +B + + my ($plugin_file, $plugin_args) = split(/\s+/, $_, 2) ; + my $plugin_hndlr_cr ; + eval { + + # 'eval {}' simulates the G_EVAL flag to perl_call_argv('code', 'flags') + # Otherwise, die in 'eval_file' will end the caller also. + + $plugin_hndlr_cr = Embed::Persistent::eval_file($plugin_file, 0, '', $plugin_args) ; + + } ; + + if ( $@) { + print "plugin compilation failed.\n" ; + } else { + my ($rc, $output) = Embed::Persistent::run_package($plugin_file, 0, $plugin_hndlr_cr, $plugin_args) ; + printf "embedded perl plugin return code and output was: %d & %s\n", $rc, $output) ; + +In the p1.pl text, 'use constant' statements set the log path and the log level. + +The log level flags determine the amount and type of messages logged in the log path. + +The default log level results in similar behaviour to former versions of p1.pl - +log files will B be opened. + +If you want to enable logging + +=over 4 + +=item 1 Choose log options (see below) + +=item 2 Choose a log path + +=item 3 Edit p1.pl + +=back + +Set the values of (the 'use constant' statements) the log path, B, and set the B constant to +one or more of the log options (B and friends ) or'ed together. +The default is to log nothing and to use S</var/epn_stderr.log> as the log path. + +=head1 DESCRIPTION + +Nagios is a program to monitor service availability by scheduling 'plugins' - discrete programs +that check a service (by for example simulating a users interaction with a web server using WWW::Mechanize) and output a line of +text (the summary of the service state) for those responsible for the service, and exit with a coded value to relay the same information to Nagios. + +Each plugin is run in a new child process forked by Nagios. + +Plugins, like CGIs, can be coded in Perl. The persistence framework embeds a Perl interpreter in Nagios to + +=over 4 + +=item * reduce the time taken for the Perl compile and execute cycle. + +=item * eliminate the need for Nagios to fork a process (with popen) to run the Perl code. + +=item * eliminate reloading of frequently used modules. + +=back + +and all the good things mentioned in the B man page under 'Maintaining a persistent interpreter'. + +Plugin run-time and syntax errors, are returned to Nagios as the 'plugin output'. These messages +appear in the Nagios log like S<**ePN 'check_test' Global symbol "$status" requires explicit package name at (eval 54) line 15.> + +Extra logging is given by setting DEBUG_LEVEL to include + + +B + +B<1> opens an extra output stream in the path given by the value of DEBUG_LOG_PATH + +B<2> logs messages describing the success or otherwise of the plugin compilation and the result of the plugin run. + +An example of such messages are + + Fri Apr 22 11:54:21 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_bass ". + Fri Apr 22 11:54:21 2005 run_package: "/usr/local/nagios/libexec/check_bass " returning ("0", "BASS Transaction completed Ok. + "). + Fri Apr 22 11:55:02 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_ad -D production.prod -S". + Fri Apr 22 11:55:02 2005 run_package: "/usr/local/nagios/libexec/check_ad -D foo.dom -S" returning ("0", "Ok. Expected 2 domain controllers [foo1 foo2] for "foo.dom.prod" domain from "1.1.2.3" DNS, found 8 [foo1 foo2 ..] + "). + Fri Apr 22 11:55:19 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_ldap adonis". + Fri Apr 22 11:55:19 2005 run_package: "/usr/local/nagios/libexec/check_ldap adonis" returning ("0", "Ok. Schema query response DN: dc=ipaustralia,dc=gov,dc=au aci: (target="ldap:///dc=ipaustralia,dc=gov,dc=au")(targetattr!="userPassword")(targetfi + "). + Fri Apr 22 11:55:29 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_scheduler -H aphrodite -p 7003". + Fri Apr 22 11:55:30 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_pams -H aphrodite -p 7003 -R". + Fri Apr 22 11:55:29 2005 run_package: "/usr/local/nagios/libexec/check_scheduler -H aphrodite -p 7003" returning ("0", "Ok. COMSQ last ran 31 seconds ago. System: 0.02s Number of jobs waiting 0 "Detail" system sch_V2_6 14/01/2005 12:22:53 aimali Jobs: COMSQ/PollerManager Fri Apr 22 11:55:00, adhoc pause Fri Apr 22 09:00:00, PAMS/SchedExamDocCheck Thu Apr 21 23:00:00, CFX Cl" + ). + Fri Apr 22 11:55:30 2005 run_package: "/usr/local/nagios/libexec/check_pams -H aphrodite -p 7003 -R" returning ("0", "OK PAMS Worst: Test Time 2.61 Failure Ratio 0 [0:5] Statii: BASE OK Oracle (direct) OK COMS Processor OK CCS Name Search (direct) OK Correspondence Manager OK PAMS Tier OK CASEWORK OK Objective (direct) OK Customer Manager OK + "). + Fri Apr 22 11:55:45 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_coms ". + Fri Apr 22 11:55:45 2005 run_package: "/usr/local/nagios/libexec/check_coms " returning ("0", "COMS Ok. 11 successes 20 minutes ago. 55 minute deltas: (0 0 0 11 0 1 3 4 0 6) or graph + ) + + .. after all the plugins are compiled, the 'successfully compiled mesages' are replaced by 'skipping compilation' + + Fri Apr 22 12:05:10 2005 eval_file: /usr/local/nagios/libexec/check_adds already successfully compiled and file has not changed; skipping compilation. + Fri Apr 22 12:05:11 2005 eval_file: /usr/local/nagios/libexec/check_aub already successfully compiled and file has not changed; skipping compilation + . + Fri Apr 22 12:05:10 2005 run_package: "/usr/local/nagios/libexec/check_adds " returning ("0", "ADDS Transaction completed Ok. + "). + Fri Apr 22 12:05:13 2005 eval_file: /usr/local/nagios/libexec/check_eForm already successfully compiled and file has not changed; skipping compilation. + Fri Apr 22 12:05:13 2005 run_package: "/usr/local/nagios/libexec/check_eForm " returning ("0", "eForm Transaction completed Ok. + "). + Fri Apr 22 12:05:15 2005 eval_file: /usr/local/nagios/libexec/check_cfx_log already successfully compiled and file has not changed; skipping compilation. + Fri Apr 22 12:05:15 2005 run_package: "/usr/local/nagios/libexec/check_cfx_log -H faxgw1" returning ("0", "Ok. Last write of "//faxgw1/Faxloader$/cfxFaxLoaderClient.log" 0.0 minutes ago. File info (create, access, modify, write times): "Wed Mar 26 17:19:42 2003 Fri Apr 22 12:05:13 2005 Fri Apr 22 12:05:13 2005 Fri Apr 22 12:05:13 2005". + "). + Fri Apr 22 12:05:16 2005 eval_file: /usr/local/nagios/libexec/check_cfx_log already successfully compiled and file has not changed; skipping compilation. + Fri Apr 22 12:05:16 2005 run_package: "/usr/local/nagios/libexec/check_cfx_log -H faxgw2" returning ("0", "Ok. Last write of "//faxgw2/Faxloader$/cfxFaxLoaderClient.log" 0.3 minutes ago. File info (create, access, modify, write times): "Wed Mar 26 17:27:24 2003 Fri Apr 22 12:04:55 2005 Fri Apr 22 12:04:55 2005 Fri Apr 22 12:04:55 2005". + "). + Fri Apr 22 12:05:17 2005 eval_file: /usr/local/nagios/libexec/check_apps_asearch already successfully compiled and file has not changed; skipping compilation. + Fri Apr 22 12:05:18 2005 eval_file: /usr/local/nagios/libexec/check_aurioness already successfully compiled and file has not changed; skipping compi lation. + Fri Apr 22 12:05:11 2005 run_package: "/usr/local/nagios/libexec/check_aub " returning ("0", "AU-B Transaction completed Ok. + "). + +If you are lucky enough to have plugins with errors in them, + + Fri Apr 22 12:16:01 2005 run_package: "//usr/local/nagios/libexec/eventhandlers/restart_coldfusion OK SOFT" returning ("3", "**ePN "//usr/local/nagios/libexec/eventhandlers/restart_coldfusion": "Can't use string ("") as a subroutine ref while "strict refs" in use at /usr/local/nagios/bin/p1.pl line 291, line 218". + + +B + +B<1> opens an extra output stream in the path given by the value of DEBUG_LOG_PATH. + +B<2> logs a listing of the text of any B plugin - as transformed by the persistence framework. Note that plugins that compile +are B dumped. This option is only useful for investigating WTF a plugin that runs from the CLI does not run under Nagios with embedded Perl. + + Sat Apr 23 19:25:32 2005 eval_file: transformed plugin "check_dummy_plugin" to ==> + 1 package Embed::check_5fdummy_5fplugin; + 2 + 3 sub hndlr { + 4 @ARGV = @_ ; + 5 local $^W = 1 ; + 6 + 7 # <<< START of PLUGIN (first line of plugin is line 8 in the text) >>> + 8 #!/usr/bin/perl -w + 9 + 10 use strict + 11 # use strict ; + 12 + 13 my @texts = split(/\n/, < 0 ? 2 : 0 ; + 24 exit $rc ; + 25 + 26 + 27 # <<< END of PLUGIN >>> + 28 } + + +This listing is logged each time the plugin source file modification time stamp is changed (when the file is +compiled for the first time and then either by correcting a syntax error or touching the file). + +Note that the plugin text (lines 8 to 27 inclusive) has been transformed by the persistence framework as described below. + +B + +B<1> opens an extra output stream in the path given by the value of DEBUG_LOG_PATH. + +B<2> A dump of the %Cache data structure (showing the plugin file modification time, a hash keyed by the plugin argument string of arrays of parsed +arguments (if non null), the last compilation error, and a code ref to the Perl subroutine corresponding the plugin (this is undef if the plugin failed to compile). + + Sat Apr 23 19:24:59 2005 eval_file: after 5 compilations %Cache => + %Cache = ( + '/usr/local/nagios/libexec/check_adds' => [ + '100.230810185185', + undef, + '', + sub { "DUMMY" } + ], + 'check_adds' => [ + '3.96288194444444', + undef, + '', + sub { "DUMMY" } + ], + 'check_atmoss' => [ + '3.96288194444444', + undef, + '', + sub { "DUMMY" } + ], + '/usr/local/nagios/libexec/check_pams' => [ + '1.90859953703704', + { + '-R -I -H asterix -p 7003' => [ + '-R', + '-I', + '-H', + 'asterix', + '-p', + '7003' + ] + }, + sub { "DUMMY" } + ], + 'check_dummy_plugin' => [ + '3.96288194444444', + undef, + '', + sub { "DUMMY" } + ] + ); + .. + + + + +This dump is produced periodically: each B<$Cache_Dump_Interval> plugin compilations the %Cache data structure is dumped. + +=head1 SUBROUTINES + +Unless otherwise stated, all subroutines take two (4) arguments :- + +=over 4 + +=item 1 plugin_filename - char * (called from C) or scalar (called from Perl): the path to the plugin. + +=item 2 DO_CLEAN - boolean: set if plugin is not to be cached. Defaults to 0. + +Setting this flag means that the plugin is compiled each time it is executed. Nagios B sets this flag when the +Nagios is compiled with the configure setting --with-perlcache. + +=item 3 (SV *) code ref to the Perl subroutine corresponding to the plugin + +This argument is only used by run_package(); it is returned by eval_file(). + +=item 4 plugin arguments - char ** (called from C) or scalar (called from Perl); the plugin options and arguments + + +=back + +=over 4 + +=item Embed::Persistent::eval_file( plugin_filename, DO_CLEAN, "", plugin_arguments ) + +E<10> +Returns B a Perl code reference (an SV containing a hard reference to a subroutine) to the subroutine that +has been produced and compiled by eval_file, B raises an exception (by calling die) and setting the value of B or +B<$@> (if called from Perl). + + +eval_file() transforms the plugin to a subroutine in a package, by compiling the string containing the +transformed plugin, and caches the plugin file modification time (to avoid recompiling it), +the parsed plugin arguments. and either the error trapped when the plugin is compiled or a code reference to the +compiled subroutine representing the plugin. + +eval_file() caches these values in the cache named B<%Cache>. The plugin file name is the key to an array containing +the values illustrated above. + +If the plugin file has not been modified, eval_file returns the cached plugin error B the code ref to the plugin subroutine. + +Otherwise, the plugin is compiled into a subroutine in a new package by + +=over 4 + +=item 1 creating a package name from the plugin file name (C) + +=item 2 turning off subroutine redefinition warnings (C) + +=item 3 overriding CORE::GLOBAL::exit from within package main (C) + +This allows the plugin to both call exit without taking down the persistence framework, and to return the exit code to the +Nagios. + +=item 4 prepending the plugin text with code to let the plugin function as a subroutine. + +The plugin command line arguments are expected to be in @ARGV, so @ARGV is set to the subroutine arguments (@_). + +The new subroutine also sets the warning level to trap all warnings that may have been caused by +by the transformation (the -w option to Perl in the text is no longer significant (because the shebang line is not fed to exec()). + +=item 5 writing the plugin as the subroutine named B in the new package. + +=item 6 returning either a code reference to the subroutine named hndlr in the package named in item 1, OR the +compilation error trapped by eval 'string'. It is the callers responsibility to check either ERRSV (from C) or $@ (from Perl) +and skip run_package() if these values are true. + +=back + +=item Embed::Persistent::run_package( plugin_filename, DO_CLEAN, (SV *) plugin_hndlr_cr, plugin_argument_string ) + +E<10> +Returns (plugin_return_code, plugin_output) + +run_plugin() actually runs the plugins with the arguments contained in the (space separated string) 4th argument. + +=back + +=head1 DIFFERENCES FROM PERSISTENT.PL + +The example B takes no account of + +=over 4 + +=item * Capturing output from the Perl program being run + +This framework ties STDOUT to a scalar that stores the result of PRINT or PRINTF. + +=item * Running Perl programs in child processes + +This is the largest single difference between this framework and the example program persistent.pl. The example uses one +subroutine (eval_file()) to compile and run the program. This is unsuitable for a process like Nagios that +fork a new process to run a plugin. (It is unsuitable because were the child process +to call eval_file() and then the update its copy of %Cache, other child processes would not get the updated %Cache, +and would therefore recompile the plugin). + +Instead, eval_file() is split into two: eval_file() and run_package(). + +Eval_file is called by the Nagios parent process to compile the plugin +and update %Cache. Child processes forked in base/checks.c have the same copy of %Cache and call run_plugin() to check the +last compilation error (from %Cache) and run the plugin if the plugin was error free. + +=item * Dealing with Perl programs that call exit + +This framework redefines exit() to die emitting a string containing the plugin return code (the first argument of exit). +Since the plugin is run by eval(), B<$@> contains this string from which the return code is extracted. + +=item * Providing command line arguments to the Perl program + +This framework sets @ARGV in the B subroutine to the remaining subroutine arguments. + +All of these clever ideas came from, AFAIK, Stephen Davies. + +=back + +=head1 BUGS + +=item * MEMORY LEAK + + + +This framework does nothing to prevent the memory leaks mentioned in B, relying on operator intervention. + +Probably the best way of doing so is by periodically scheduling + +=over 4 + +=item 1 A check of the memory used by the Nagios process (by running for example the standard Nagios plugin check_procs) + +=item 2 Restarting Nagios with the (supplied with Nagios) startup script (restart command). + + +=back + +If you do periodically restart Nagios, make sure that + +=over 4 + +=item 1 plugins all set the PATH environment variable if they need other system binaries (otherwise, if the +init script is excec'd by cron, the PATH will be reset and the plugins will fail - but only when reatsrted by cron). + +=item 2 that the group owning the Nagios command pipe is the same as the Nagios group (otherwise, the restarted +Nagios will not be able to read from the command pipe). + +=back + +Nagios installations using the persistence framework B monitor the memory use of the Nagios process and stop/start it when +the usage is exorbidant (eg, for a site with 400 services on 200 hosts and custom Perl plugins used for about 10% of the +service checks, the Nagios process uses ~80 MB after 20-30 days runningi with Perl 5.005 [Memory usage is +B greater with recent Perls]. It is usually stopped and started at this point). + +Note that a HUP signal is B sufficient to deallocate the Perl memory; the Nagios process must be stopped and started. In fact, since HUP +causes Nagios to re-run the Perl interpreter initialisation code, memory use increases significantly. B; use the 'restart' argument +of the Nagios supplied startup script. + +There are all sorts of suprising gotchas about the debug logging including + +=over 4 + +=item * No dump of good plugins. + +Only plugins that fail to compile (after transformation) are dumped. + +=item * Cache dump is periodic + +The Cache is only dumped after the user specified number of plugin B. If plugins are not compiled, you get +no dump of the cache. + +=item * Debug level set at compile time + +Nagios must be restarted to change the debug level (use the examples if you have a troublesome plugin;l you may need a debug copy +of Nagios) + +=item * Not all Cached fields visible + +Always compile one more plugin to ensure that all the fields in the cache are set. + + +=back + +=head1 SEE ALSO + +=over 4 + +=item * perlembed (section on maintaining a persistent interpreter) + +=item * examples in the examples/ directory including both C and Perl drivers that run Nagios plugins using p1.pl. + +=back + + +=head1 AUTHOR + +Originally by Stephen Davies. + +Now maintained by Stanley Hopcroft who retains responsibility for the 'bad bits'. + +=head1 COPYRIGHT + +Copyright (c) 2004 Stanley Hopcroft. All rights reserved. +This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. + +=cut + diff --git a/pkginfo.in b/pkginfo.in new file mode 100644 index 0000000..3ec021a --- /dev/null +++ b/pkginfo.in @@ -0,0 +1,10 @@ +PKG="nagios" +VERSION="@VERSION@" +NAME="Nagios @VERSION@" +CLASSES="none" +CATEGORY="utility" +VENDOR="www.nagios.org" +EMAIL="nagios-users@lists.sourceforge.net" +ISTATES="S s 1 2 3" +RSTATES="S s 1 2 3" +BASEDIR="/" diff --git a/sample-config/.gitignore b/sample-config/.gitignore new file mode 100644 index 0000000..32d26a5 --- /dev/null +++ b/sample-config/.gitignore @@ -0,0 +1,2 @@ +*.cfg +httpd.conf diff --git a/sample-config/README b/sample-config/README new file mode 100644 index 0000000..be16b80 --- /dev/null +++ b/sample-config/README @@ -0,0 +1,32 @@ +========================= +SAMPLE CONFIG FILE README +========================= + +This directory contains *sample* configuration files for Nagios. +You should read the HTML documentation for information on +customizing these config files to suit your needs. + +A description of the sample config files and subdirectories +contained here follows: + + + +CONTENTS: +--------- + +cgi.cfg - This is a sample CGI config file + +nagios.cfg - This is a sample main config file + +resource.cfg - This is a sample resource config file, used for definining + custom macros, storing sensitive data, etc. + +httpd.conf - This file contains sample snippets that you'll need to + include in your Apache web server config file if you want + to use the web interface. + +template-object/ - This directory contains sample object config files. You'll + need to define object config files like these before you can + actually start to monitor anything. + + diff --git a/sample-config/cgi.cfg.in b/sample-config/cgi.cfg.in new file mode 100644 index 0000000..c36fb28 --- /dev/null +++ b/sample-config/cgi.cfg.in @@ -0,0 +1,364 @@ +################################################################# +# +# CGI.CFG - Sample CGI Configuration File for Nagios @VERSION@ +# +# Last Modified: 06-17-2009 +# +################################################################# + + +# MAIN CONFIGURATION FILE +# This tells the CGIs where to find your main configuration file. +# The CGIs will read the main and host config files for any other +# data they might need. + +main_config_file=@sysconfdir@/nagios.cfg + + + +# PHYSICAL HTML PATH +# This is the path where the HTML files for Nagios reside. This +# value is used to locate the logo images needed by the statusmap +# and statuswrl CGIs. + +physical_html_path=@datadir@ + + + +# URL HTML PATH +# This is the path portion of the URL that corresponds to the +# physical location of the Nagios HTML files (as defined above). +# This value is used by the CGIs to locate the online documentation +# and graphics. If you access the Nagios pages with an URL like +# http://www.myhost.com/nagios, this value should be '/nagios' +# (without the quotes). + +url_html_path=@htmurl@ + + + +# CONTEXT-SENSITIVE HELP +# This option determines whether or not a context-sensitive +# help icon will be displayed for most of the CGIs. +# Values: 0 = disables context-sensitive help +# 1 = enables context-sensitive help + +show_context_help=0 + + + +# PENDING STATES OPTION +# This option determines what states should be displayed in the web +# interface for hosts/services that have not yet been checked. +# Values: 0 = leave hosts/services that have not been check yet in their original state +# 1 = mark hosts/services that have not been checked yet as PENDING + +use_pending_states=1 + + + + +# AUTHENTICATION USAGE +# This option controls whether or not the CGIs will use any +# authentication when displaying host and service information, as +# well as committing commands to Nagios for processing. +# +# Read the HTML documentation to learn how the authorization works! +# +# NOTE: It is a really *bad* idea to disable authorization, unless +# you plan on removing the command CGI (cmd.cgi)! Failure to do +# so will leave you wide open to kiddies messing with Nagios and +# possibly hitting you with a denial of service attack by filling up +# your drive by continuously writing to your command file! +# +# Setting this value to 0 will cause the CGIs to *not* use +# authentication (bad idea), while any other value will make them +# use the authentication functions (the default). + +use_authentication=1 + + + + +# x509 CERT AUTHENTICATION +# When enabled, this option allows you to use x509 cert (SSL) +# authentication in the CGIs. This is an advanced option and should +# not be enabled unless you know what you're doing. + +use_ssl_authentication=0 + + + + +# DEFAULT USER +# Setting this variable will define a default user name that can +# access pages without authentication. This allows people within a +# secure domain (i.e., behind a firewall) to see the current status +# without authenticating. You may want to use this to avoid basic +# authentication if you are not using a secure server since basic +# authentication transmits passwords in the clear. +# +# Important: Do not define a default username unless you are +# running a secure web server and are sure that everyone who has +# access to the CGIs has been authenticated in some manner! If you +# define this variable, anyone who has not authenticated to the web +# server will inherit all rights you assign to this user! + +#default_user_name=guest + + + +# SYSTEM/PROCESS INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# have access to viewing the Nagios process information as +# provided by the Extended Information CGI (extinfo.cgi). By +# default, *no one* has access to this unless you choose to +# not use authorization. You may use an asterisk (*) to +# authorize any user who has authenticated to the web server. + +authorized_for_system_information=nagiosadmin + + + +# CONFIGURATION INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# can view ALL configuration information (hosts, commands, etc). +# By default, users can only view configuration information +# for the hosts and services they are contacts for. You may use +# an asterisk (*) to authorize any user who has authenticated +# to the web server. + +authorized_for_configuration_information=nagiosadmin + + + +# SYSTEM/PROCESS COMMAND ACCESS +# This option is a comma-delimited list of all usernames that +# can issue shutdown and restart commands to Nagios via the +# command CGI (cmd.cgi). Users in this list can also change +# the program mode to active or standby. By default, *no one* +# has access to this unless you choose to not use authorization. +# You may use an asterisk (*) to authorize any user who has +# authenticated to the web server. + +authorized_for_system_commands=nagiosadmin + + + +# GLOBAL HOST/SERVICE VIEW ACCESS +# These two options are comma-delimited lists of all usernames that +# can view information for all hosts and services that are being +# monitored. By default, users can only view information +# for hosts or services that they are contacts for (unless you +# you choose to not use authorization). You may use an asterisk (*) +# to authorize any user who has authenticated to the web server. + + +authorized_for_all_services=nagiosadmin +authorized_for_all_hosts=nagiosadmin + + + +# GLOBAL HOST/SERVICE COMMAND ACCESS +# These two options are comma-delimited lists of all usernames that +# can issue host or service related commands via the command +# CGI (cmd.cgi) for all hosts and services that are being monitored. +# By default, users can only issue commands for hosts or services +# that they are contacts for (unless you you choose to not use +# authorization). You may use an asterisk (*) to authorize any +# user who has authenticated to the web server. + +authorized_for_all_service_commands=nagiosadmin +authorized_for_all_host_commands=nagiosadmin + + + +# READ-ONLY USERS +# A comma-delimited list of usernames that have read-only rights in +# the CGIs. This will block any service or host commands normally shown +# on the extinfo CGI pages. It will also block comments from being shown +# to read-only users. + +#authorized_for_read_only=user1,user2 + + + + +# STATUSMAP BACKGROUND IMAGE +# This option allows you to specify an image to be used as a +# background in the statusmap CGI. It is assumed that the image +# resides in the HTML images path (i.e. /usr/local/nagios/share/images). +# This path is automatically determined by appending "/images" +# to the path specified by the 'physical_html_path' directive. +# Note: The image file may be in GIF, PNG, JPEG, or GD2 format. +# However, I recommend that you convert your image to GD2 format +# (uncompressed), as this will cause less CPU load when the CGI +# generates the image. + +#statusmap_background_image=smbackground.gd2 + + + + +# STATUSMAP TRANSPARENCY INDEX COLOR +# These options set the r,g,b values of the background color used the statusmap CGI, +# so normal browsers that can't show real png transparency set the desired color as +# a background color instead (to make it look pretty). +# Defaults to white: (R,G,B) = (255,255,255). + +#color_transparency_index_r=255 +#color_transparency_index_g=255 +#color_transparency_index_b=255 + + + + +# DEFAULT STATUSMAP LAYOUT METHOD +# This option allows you to specify the default layout method +# the statusmap CGI should use for drawing hosts. If you do +# not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 1 = Depth layers +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular +# 5 = Circular (Marked Up) + +default_statusmap_layout=5 + + + +# DEFAULT STATUSWRL LAYOUT METHOD +# This option allows you to specify the default layout method +# the statuswrl (VRML) CGI should use for drawing hosts. If you +# do not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular + +default_statuswrl_layout=4 + + + +# STATUSWRL INCLUDE +# This option allows you to include your own objects in the +# generated VRML world. It is assumed that the file +# resides in the HTML path (i.e. /usr/local/nagios/share). + +#statuswrl_include=myworld.wrl + + + +# PING SYNTAX +# This option determines what syntax should be used when +# attempting to ping a host from the WAP interface (using +# the statuswml CGI. You must include the full path to +# the ping binary, along with all required options. The +# $HOSTADDRESS$ macro is substituted with the address of +# the host before the command is executed. +# Please note that the syntax for the ping binary is +# notorious for being different on virtually ever *NIX +# OS and distribution, so you may have to tweak this to +# work on your system. + +ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$ + + + +# REFRESH RATE +# This option allows you to specify the refresh rate in seconds +# of various CGIs (status, statusmap, extinfo, and outages). + +refresh_rate=90 + +# DEFAULT PAGE LIMIT +# This option allows you to specify the default number of results +# displayed on the status.cgi. This number can be adjusted from +# within the UI after the initial page load. Setting this to 0 +# will show all results. + +result_limit=100 + + +# ESCAPE HTML TAGS +# This option determines whether HTML tags in host and service +# status output is escaped in the web interface. If enabled, +# your plugin output will not be able to contain clickable links. + +escape_html_tags=1 + + + + +# SOUND OPTIONS +# These options allow you to specify an optional audio file +# that should be played in your browser window when there are +# problems on the network. The audio files are used only in +# the status CGI. Only the sound for the most critical problem +# will be played. Order of importance (higher to lower) is as +# follows: unreachable hosts, down hosts, critical services, +# warning services, and unknown services. If there are no +# visible problems, the sound file optionally specified by +# 'normal_sound' variable will be played. +# +# +# = +# +# Note: All audio files must be placed in the /media subdirectory +# under the HTML path (i.e. /usr/local/nagios/share/media/). + +#host_unreachable_sound=hostdown.wav +#host_down_sound=hostdown.wav +#service_critical_sound=critical.wav +#service_warning_sound=warning.wav +#service_unknown_sound=warning.wav +#normal_sound=noproblem.wav + + + +# URL TARGET FRAMES +# These options determine the target frames in which notes and +# action URLs will open. + +action_url_target=_blank +notes_url_target=_blank + + + + +# LOCK AUTHOR NAMES OPTION +# This option determines whether users can change the author name +# when submitting comments, scheduling downtime. If disabled, the +# author names will be locked into their contact name, as defined in Nagios. +# Values: 0 = allow editing author names +# 1 = lock author names (disallow editing) + +lock_author_names=1 + + + + +# SPLUNK INTEGRATION OPTIONS +# These options allow you to enable integration with Splunk +# in the web interface. If enabled, you'll be presented with +# "Splunk It" links in various places in the CGIs (log file, +# alert history, host/service detail, etc). Useful if you're +# trying to research why a particular problem occurred. +# For more information on Splunk, visit http://www.splunk.com/ + +# This option determines whether the Splunk integration is enabled +# Values: 0 = disable Splunk integration +# 1 = enable Splunk integration + +#enable_splunk_integration=1 + + +# This option should be the URL used to access your instance of Splunk + +#splunk_url=http://127.0.0.1:8000/ + + + diff --git a/sample-config/httpd.conf.in b/sample-config/httpd.conf.in new file mode 100644 index 0000000..71d4fbb --- /dev/null +++ b/sample-config/httpd.conf.in @@ -0,0 +1,42 @@ +# SAMPLE CONFIG SNIPPETS FOR APACHE WEB SERVER +# Last Modified: 11-26-2005 +# +# This file contains examples of entries that need +# to be incorporated into your Apache web server +# configuration file. Customize the paths, etc. as +# needed to fit your system. + +ScriptAlias @cgiurl@ "@sbindir@" + + +# SSLRequireSSL + Options ExecCGI + AllowOverride None + Order allow,deny + Allow from all +# Order deny,allow +# Deny from all +# Allow from 127.0.0.1 + AuthName "Nagios Access" + AuthType Basic + AuthUserFile @sysconfdir@/htpasswd.users + Require valid-user + + +Alias @htmurl@ "@datadir@" + + +# SSLRequireSSL + Options None + AllowOverride None + Order allow,deny + Allow from all +# Order deny,allow +# Deny from all +# Allow from 127.0.0.1 + AuthName "Nagios Access" + AuthType Basic + AuthUserFile @sysconfdir@/htpasswd.users + Require valid-user + + diff --git a/sample-config/mrtg.cfg.in b/sample-config/mrtg.cfg.in new file mode 100644 index 0000000..3638fa0 --- /dev/null +++ b/sample-config/mrtg.cfg.in @@ -0,0 +1,180 @@ +################################################################### +# MRTG Graphs: Nagios @VERSION@ Statistics +# +# You can add the following entries to your MRTG config file to +# begin graphing several Nagios statistics which can be useful for +# debugging and trending purposes. The nagiostats binary (which is +# included as part of the Nagios distribution) is used to generate +# the data. +################################################################### + +# Service Latency and Execution Time +Target[nagios-a]: `@bindir@/nagiostats --mrtg --data=AVGACTSVCLAT,AVGACTSVCEXT,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-a]: 100000 +Title[nagios-a]: Average Service Check Latency and Execution Time +PageTop[nagios-a]:

    Average Service Check Latency and Execution Time

    +Options[nagios-a]: growright,gauge,nopercent +YLegend[nagios-a]: Milliseconds +ShortLegend[nagios-a]:   +LegendI[nagios-a]:  Latency: +LegendO[nagios-a]:  Execution Time: +Legend1[nagios-a]: Latency +Legend2[nagios-a]: Execution Time +Legend3[nagios-a]: Maximal 5 Minute Latency +Legend4[nagios-a]: Maximal 5 Minute Execution Time + + +# Service Percent State Change +Target[nagios-b]: `@bindir@/nagiostats --mrtg --data=AVGACTSVCPSC,AVGPSVSVCPSC,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-b]: 100 +Title[nagios-b]: Average Service State Change +PageTop[nagios-b]:

    Average Service State Change

    +Options[nagios-b]: growright,gauge,nopercent +YLegend[nagios-b]: Percent +ShortLegend[nagios-b]:   +LegendI[nagios-b]:  Active Check % Change: +LegendO[nagios-b]:  Passive Check % Change: +Legend1[nagios-b]: State Change +Legend2[nagios-b]: State Change +Legend3[nagios-b]: Maximal 5 Minute State Change +Legend4[nagios-b]: Maximal 5 Minute State Change + + +# Host Latency and Execution Time +Target[nagios-c]: `@bindir@/nagiostats --mrtg --data=AVGACTHSTLAT,AVGACTHSTEXT,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-c]: 100000 +Title[nagios-c]: Average Host Check Latency and Execution Time +PageTop[nagios-c]:

    Average Host Check Latency and Execution Time

    +Options[nagios-c]: growright,gauge,nopercent +YLegend[nagios-c]: Milliseconds +ShortLegend[nagios-c]:   +LegendI[nagios-c]:  Latency: +LegendO[nagios-c]:  Execution Time: +Legend1[nagios-c]: Latency +Legend2[nagios-c]: Execution Time +Legend3[nagios-c]: Maximal 5 Minute Latency +Legend4[nagios-c]: Maximal 5 Minute Execution Time + + +# Host Percent State Change +Target[nagios-d]: `@bindir@/nagiostats --mrtg --data=AVGACTHSTPSC,AVGPSVHSTPSC,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-d]: 100 +Title[nagios-d]: Average Host State Change +PageTop[nagios-d]:

    Average Host State Change

    +Options[nagios-d]: growright,gauge,nopercent +YLegend[nagios-d]: Percent +ShortLegend[nagios-d]:   +LegendI[nagios-d]:  Active Check % Change: +LegendO[nagios-d]:  Passive Check % Change: +Legend1[nagios-d]: State Change +Legend2[nagios-d]: State Change +Legend3[nagios-d]: Maximal 5 Minute State Change +Legend4[nagios-d]: Maximal 5 Minute State Change + + +# Hosts/Services Actively Checked +Target[nagios-e]: `@bindir@/nagiostats --mrtg --data=NUMHSTACTCHK5M,NUMSVCACTCHK5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-e]: 7000 +Title[nagios-e]: Hosts/Services Actively Checked +PageTop[nagios-e]:

    Hosts/Services Actively Checked

    +Options[nagios-e]: growright,gauge,nopercent +YLegend[nagios-e]: Total +ShortLegend[nagios-e]:   +LegendI[nagios-e]:  Hosts: +LegendO[nagios-e]:  Services: + + +# Hosts/Services Passively Checked +Target[nagios-f]: `@bindir@/nagiostats --mrtg --data=NUMHSTPSVCHK5M,NUMSVCPSVCHK5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-f]: 7000 +Title[nagios-f]: Hosts/Services Passively Checked +PageTop[nagios-f]:

    Hosts/Services Passively Checked

    +Options[nagios-f]: growright,gauge,nopercent +YLegend[nagios-f]: Total +ShortLegend[nagios-f]:   +LegendI[nagios-f]:  Hosts: +LegendO[nagios-f]:  Services: + + +# Used/Avail External Command Buffers +Target[nagios-g]: `@bindir@/nagiostats --mrtg --data=TOTCMDBUF,USEDCMDBUF,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-g]: 7000 +Title[nagios-g]: External Command Buffers +PageTop[nagios-g]:

    External Command Buffers

    +Options[nagios-g]: growright,gauge,nopercent +YLegend[nagios-g]: Buffers +ShortLegend[nagios-g]:   +LegendI[nagios-g]:  Total: +LegendO[nagios-g]:  Used: + + +# Active Host Checks +Target[nagios-i]: `@bindir@/nagiostats --mrtg --data=NUMSACTHSTCHECKS5M,NUMOACTHSTCHECKS5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-i]: 7000 +Title[nagios-i]: Active Host Checks +PageTop[nagios-i]:

    Active Host Checks

    +Options[nagios-i]: growright,gauge,nopercent +YLegend[nagios-i]: Checks +ShortLegend[nagios-i]:   +LegendI[nagios-i]:  Scheduled Checks: +LegendO[nagios-i]:  On-Demand Checks: + + +# Active Service Checks +Target[nagios-j]: `@bindir@/nagiostats --mrtg --data=NUMSACTSVCCHECKS5M,NUMOACTSVCCHECKS5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-j]: 7000 +Title[nagios-j]: Active Service Checks +PageTop[nagios-j]:

    Active Service Checks

    +Options[nagios-j]: growright,gauge,nopercent +YLegend[nagios-j]: Checks +ShortLegend[nagios-j]:   +LegendI[nagios-j]:  Scheduled Checks: +LegendO[nagios-j]:  On-Demand Checks: + + +# Passive Host/Service Checks +Target[nagios-k]: `@bindir@/nagiostats --mrtg --data=NUMPSVHSTCHECKS5M,NUMPSVSVCCHECKS5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-k]: 7000 +Title[nagios-k]: Passive Host/Service Checks +PageTop[nagios-k]:

    Passive Host/Service Checks

    +Options[nagios-k]: growright,gauge,nopercent +YLegend[nagios-k]: Checks +ShortLegend[nagios-k]:   +LegendI[nagios-k]:  Host Checks: +LegendO[nagios-k]:  Service Checks: + + +# Cached Host/Service Checks +Target[nagios-l]: `@bindir@/nagiostats --mrtg --data=NUMCACHEDHSTCHECKS5M,NUMCACHEDSVCCHECKS5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-l]: 7000 +Title[nagios-l]: Cached Host/Service Checks +PageTop[nagios-l]:

    Cached Host/Service Checks

    +Options[nagios-l]: growright,gauge,nopercent +YLegend[nagios-l]: Checks +ShortLegend[nagios-l]:   +LegendI[nagios-l]:  Host Checks: +LegendO[nagios-l]:  Service Checks: + + +# External Commands +Target[nagios-m]: `@bindir@/nagiostats --mrtg --data=NUMEXTCMDS5M,0,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-m]: 7000 +Title[nagios-m]: External Commands +PageTop[nagios-m]:

    External Commands

    +Options[nagios-m]: growright,gauge,nopercent +YLegend[nagios-m]: Commands +ShortLegend[nagios-m]:   +LegendI[nagios-m]:  Commands: +LegendO[nagios-m]:   + + +# Parallel/Service Host Checks +Target[nagios-n]: `@bindir@/nagiostats --mrtg --data=NUMPARHSTCHECKS5M,NUMSERHSTCHECKS5M,PROGRUNTIME,NAGIOSVERPID` +MaxBytes[nagios-n]: 7000 +Title[nagios-n]: Parallel/Serial Host Checks +PageTop[nagios-n]:

    Parallel/Serial Host Checks

    +Options[nagios-n]: growright,gauge,nopercent +YLegend[nagios-n]: Checks +ShortLegend[nagios-n]:   +LegendI[nagios-n]:  Parallel Checks: +LegendO[nagios-n]:  Serial Checks: diff --git a/sample-config/nagios.cfg.in b/sample-config/nagios.cfg.in new file mode 100644 index 0000000..1c2718e --- /dev/null +++ b/sample-config/nagios.cfg.in @@ -0,0 +1,1350 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios @VERSION@ +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=@localstatedir@/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# You can specify individual object config files as shown below: +cfg_file=@sysconfdir@/objects/commands.cfg +cfg_file=@sysconfdir@/objects/contacts.cfg +cfg_file=@sysconfdir@/objects/timeperiods.cfg +cfg_file=@sysconfdir@/objects/templates.cfg + +# Definitions for monitoring the local (Linux) host +cfg_file=@sysconfdir@/objects/localhost.cfg + +# Definitions for monitoring a Windows machine +#cfg_file=@sysconfdir@/objects/windows.cfg + +# Definitions for monitoring a router/switch +#cfg_file=@sysconfdir@/objects/switch.cfg + +# Definitions for monitoring a network printer +#cfg_file=@sysconfdir@/objects/printer.cfg + + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=@sysconfdir@/servers +#cfg_dir=@sysconfdir@/printers +#cfg_dir=@sysconfdir@/switches +#cfg_dir=@sysconfdir@/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=@localstatedir@/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=@localstatedir@/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=@sysconfdir@/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=@localstatedir@/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=@nagios_user@ + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=@nagios_grp@ + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=@localstatedir@/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=@lockfile@ + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=@localstatedir@/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=@TMPDIR@ + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=@localstatedir@/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=@CHECKRESULTDIR@ + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the retain_state_information +# variable is set to 1. + +state_retention_file=@localstatedir@/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESS EMPTY RESULTS +# THese options determine wether the core will process empty perfdata +# results or not. This is needed for distributed monitoring, and intentionally +# turned on by default. +# If you don't require empty perfdata - saving some cpu cycles +# on unwanted macro calculation - you can turn that off. Be careful! +# Values: 1 = enable, 0 = disable + +#host_perfdata_process_empty_results=1 +#service_perfdata_process_empty_results=1 + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# SERVICE CHECK TIMEOUT STATE +# This setting determines the state Nagios will report when a +# service check times out - that is does not respond within +# service_check_timeout seconds. This can be useful if a +# machine is running at too high a load and you do not want +# to consider a failed service check to be critical (the default). +# Valid settings are: +# c - Critical (default) +# u - Unknown +# w - Warning +# o - OK + +service_check_timeout_state=c + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=@bindir@/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=@nagios_user@@localhost +admin_pager=page@nagios_user@@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=@localstatedir@/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/sample-config/resource.cfg.in b/sample-config/resource.cfg.in new file mode 100644 index 0000000..5227bc2 --- /dev/null +++ b/sample-config/resource.cfg.in @@ -0,0 +1,34 @@ +########################################################################### +# +# RESOURCE.CFG - Sample Resource File for Nagios @VERSION@ +# +# Last Modified: 09-10-2003 +# +# You can define $USERx$ macros in this file, which can in turn be used +# in command definitions in your host config file(s). $USERx$ macros are +# useful for storing sensitive information such as usernames, passwords, +# etc. They are also handy for specifying the path to plugins and +# event handlers - if you decide to move the plugins or event handlers to +# a different directory in the future, you can just update one or two +# $USERx$ macros, instead of modifying a lot of command definitions. +# +# The CGIs will not attempt to read the contents of resource files, so +# you can set restrictive permissions (600 or 660) on them. +# +# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) +# +# Resource files may also be used to store configuration directives for +# external data sources like MySQL... +# +########################################################################### + +# Sets $USER1$ to be the path to the plugins +$USER1$=@libexecdir@ + +# Sets $USER2$ to be the path to event handlers +#$USER2$=@libexecdir@/eventhandlers + +# Store some usernames and passwords (hidden from the CGIs) +#$USER3$=someuser +#$USER4$=somepassword + diff --git a/sample-config/template-object/README b/sample-config/template-object/README new file mode 100644 index 0000000..557d09e --- /dev/null +++ b/sample-config/template-object/README @@ -0,0 +1,16 @@ +================================ +SAMPLE OBJECT CONFIG FILE README +================================ + +This directory contains sample object definition config files. +Sample config files have a .cfg extension. Ignore any files with +a .in extension, as they are templates used to generate the sample +config files. + +Please note that you can keep all of your object definitions in a +single file if you wish. You may also split them up into multiple +config files, as is done here. + +Read the 'Quickstart Installation Guide' in the HTML documentation +for instructions on how to install and use these sample config files. + diff --git a/sample-config/template-object/commands.cfg.in b/sample-config/template-object/commands.cfg.in new file mode 100644 index 0000000..acb3a4b --- /dev/null +++ b/sample-config/template-object/commands.cfg.in @@ -0,0 +1,240 @@ +############################################################################### +# COMMANDS.CFG - SAMPLE COMMAND DEFINITIONS FOR NAGIOS @VERSION@ +# +# Last Modified: 05-31-2007 +# +# NOTES: This config file provides you with some example command definitions +# that you can reference in host, service, and contact definitions. +# +# You don't need to keep commands in a separate file from your other +# object definitions. This has been done just to make things easier to +# understand. +# +############################################################################### + + +################################################################################ +# +# SAMPLE NOTIFICATION COMMANDS +# +# These are some example notification commands. They may or may not work on +# your system without modification. As an example, some systems will require +# you to use "/usr/bin/mailx" instead of "/usr/bin/mail" in the commands below. +# +################################################################################ + + +# 'notify-host-by-email' command definition +define command{ + command_name notify-host-by-email + command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | @MAIL_PROG@ -s "** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$ + } + +# 'notify-service-by-email' command definition +define command{ + command_name notify-service-by-email + command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$\n" | @MAIL_PROG@ -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$ + } + + + + + +################################################################################ +# +# SAMPLE HOST CHECK COMMANDS +# +################################################################################ + + +# This command checks to see if a host is "alive" by pinging it +# The check must result in a 100% packet loss or 5 second (5000ms) round trip +# average time to produce a critical error. +# Note: Five ICMP echo packets are sent (determined by the '-p 5' argument) + +# 'check-host-alive' command definition +define command{ + command_name check-host-alive + command_line $USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 5 + } + + + + +################################################################################ +# +# SAMPLE SERVICE CHECK COMMANDS +# +# These are some example service check commands. They may or may not work on +# your system, as they must be modified for your plugins. See the HTML +# documentation on the plugins for examples of how to configure command definitions. +# +# NOTE: The following 'check_local_...' functions are designed to monitor +# various metrics on the host that Nagios is running on (i.e. this one). +################################################################################ + +# 'check_local_disk' command definition +define command{ + command_name check_local_disk + command_line $USER1$/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$ + } + + +# 'check_local_load' command definition +define command{ + command_name check_local_load + command_line $USER1$/check_load -w $ARG1$ -c $ARG2$ + } + + +# 'check_local_procs' command definition +define command{ + command_name check_local_procs + command_line $USER1$/check_procs -w $ARG1$ -c $ARG2$ -s $ARG3$ + } + + +# 'check_local_users' command definition +define command{ + command_name check_local_users + command_line $USER1$/check_users -w $ARG1$ -c $ARG2$ + } + + +# 'check_local_swap' command definition +define command{ + command_name check_local_swap + command_line $USER1$/check_swap -w $ARG1$ -c $ARG2$ + } + + +# 'check_local_mrtgtraf' command definition +define command{ + command_name check_local_mrtgtraf + command_line $USER1$/check_mrtgtraf -F $ARG1$ -a $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ + } + + +################################################################################ +# NOTE: The following 'check_...' commands are used to monitor services on +# both local and remote hosts. +################################################################################ + +# 'check_ftp' command definition +define command{ + command_name check_ftp + command_line $USER1$/check_ftp -H $HOSTADDRESS$ $ARG1$ + } + + +# 'check_hpjd' command definition +define command{ + command_name check_hpjd + command_line $USER1$/check_hpjd -H $HOSTADDRESS$ $ARG1$ + } + + +# 'check_snmp' command definition +define command{ + command_name check_snmp + command_line $USER1$/check_snmp -H $HOSTADDRESS$ $ARG1$ + } + + +# 'check_http' command definition +define command{ + command_name check_http + command_line $USER1$/check_http -I $HOSTADDRESS$ $ARG1$ + } + + +# 'check_ssh' command definition +define command{ + command_name check_ssh + command_line $USER1$/check_ssh $ARG1$ $HOSTADDRESS$ + } + + +# 'check_dhcp' command definition +define command{ + command_name check_dhcp + command_line $USER1$/check_dhcp $ARG1$ + } + + +# 'check_ping' command definition +define command{ + command_name check_ping + command_line $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5 + } + + +# 'check_pop' command definition +define command{ + command_name check_pop + command_line $USER1$/check_pop -H $HOSTADDRESS$ $ARG1$ + } + + +# 'check_imap' command definition +define command{ + command_name check_imap + command_line $USER1$/check_imap -H $HOSTADDRESS$ $ARG1$ + } + + +# 'check_smtp' command definition +define command{ + command_name check_smtp + command_line $USER1$/check_smtp -H $HOSTADDRESS$ $ARG1$ + } + + +# 'check_tcp' command definition +define command{ + command_name check_tcp + command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$ $ARG2$ + } + + +# 'check_udp' command definition +define command{ + command_name check_udp + command_line $USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$ $ARG2$ + } + + +# 'check_nt' command definition +define command{ + command_name check_nt + command_line $USER1$/check_nt -H $HOSTADDRESS$ -p 12489 -v $ARG1$ $ARG2$ + } + + + +################################################################################ +# +# SAMPLE PERFORMANCE DATA COMMANDS +# +# These are sample performance data commands that can be used to send performance +# data output to two text files (one for hosts, another for services). If you +# plan on simply writing performance data out to a file, consider using the +# host_perfdata_file and service_perfdata_file options in the main config file. +# +################################################################################ + + +# 'process-host-perfdata' command definition +define command{ + command_name process-host-perfdata + command_line /usr/bin/printf "%b" "$LASTHOSTCHECK$\t$HOSTNAME$\t$HOSTSTATE$\t$HOSTATTEMPT$\t$HOSTSTATETYPE$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$\n" >> @localstatedir@/host-perfdata.out + } + + +# 'process-service-perfdata' command definition +define command{ + command_name process-service-perfdata + command_line /usr/bin/printf "%b" "$LASTSERVICECHECK$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATE$\t$SERVICEATTEMPT$\t$SERVICESTATETYPE$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$\n" >> @localstatedir@/service-perfdata.out + } + + diff --git a/sample-config/template-object/contacts.cfg.in b/sample-config/template-object/contacts.cfg.in new file mode 100644 index 0000000..bb6b7bf --- /dev/null +++ b/sample-config/template-object/contacts.cfg.in @@ -0,0 +1,55 @@ +############################################################################### +# CONTACTS.CFG - SAMPLE CONTACT/CONTACTGROUP DEFINITIONS +# +# Last Modified: 05-31-2007 +# +# NOTES: This config file provides you with some example contact and contact +# group definitions that you can reference in host and service +# definitions. +# +# You don't need to keep these definitions in a separate file from your +# other object definitions. This has been done just to make things +# easier to understand. +# +############################################################################### + + + +############################################################################### +############################################################################### +# +# CONTACTS +# +############################################################################### +############################################################################### + +# Just one contact defined by default - the Nagios admin (that's you) +# This contact definition inherits a lot of default values from the 'generic-contact' +# template which is defined elsewhere. + +define contact{ + contact_name nagiosadmin ; Short name of user + use generic-contact ; Inherit default values from generic-contact template (defined above) + alias Nagios Admin ; Full name of user + + email @nagios_user@@localhost ; <<***** CHANGE THIS TO YOUR EMAIL ADDRESS ****** + } + + + +############################################################################### +############################################################################### +# +# CONTACT GROUPS +# +############################################################################### +############################################################################### + +# We only have one contact in this simple configuration file, so there is +# no need to create more than one contact group. + +define contactgroup{ + contactgroup_name admins + alias Nagios Administrators + members nagiosadmin + } diff --git a/sample-config/template-object/localhost.cfg.in b/sample-config/template-object/localhost.cfg.in new file mode 100644 index 0000000..6882ced --- /dev/null +++ b/sample-config/template-object/localhost.cfg.in @@ -0,0 +1,157 @@ +############################################################################### +# LOCALHOST.CFG - SAMPLE OBJECT CONFIG FILE FOR MONITORING THIS MACHINE +# +# Last Modified: 05-31-2007 +# +# NOTE: This config file is intended to serve as an *extremely* simple +# example of how you can create configuration entries to monitor +# the local (Linux) machine. +# +############################################################################### + + + + +############################################################################### +############################################################################### +# +# HOST DEFINITION +# +############################################################################### +############################################################################### + +# Define a host for the local machine + +define host{ + use linux-server ; Name of host template to use + ; This host definition will inherit all variables that are defined + ; in (or inherited by) the linux-server host template definition. + host_name localhost + alias localhost + address 127.0.0.1 + } + + + +############################################################################### +############################################################################### +# +# HOST GROUP DEFINITION +# +############################################################################### +############################################################################### + +# Define an optional hostgroup for Linux machines + +define hostgroup{ + hostgroup_name linux-servers ; The name of the hostgroup + alias Linux Servers ; Long name of the group + members localhost ; Comma separated list of hosts that belong to this group + } + + + +############################################################################### +############################################################################### +# +# SERVICE DEFINITIONS +# +############################################################################### +############################################################################### + + +# Define a service to "ping" the local machine + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description PING + check_command check_ping!100.0,20%!500.0,60% + } + + +# Define a service to check the disk space of the root partition +# on the local machine. Warning if < 20% free, critical if +# < 10% free space on partition. + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description Root Partition + check_command check_local_disk!20%!10%!/ + } + + + +# Define a service to check the number of currently logged in +# users on the local machine. Warning if > 20 users, critical +# if > 50 users. + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description Current Users + check_command check_local_users!20!50 + } + + +# Define a service to check the number of currently running procs +# on the local machine. Warning if > 250 processes, critical if +# > 400 users. + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description Total Processes + check_command check_local_procs!250!400!RSZDT + } + + + +# Define a service to check the load on the local machine. + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description Current Load + check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0 + } + + + +# Define a service to check the swap usage the local machine. +# Critical if less than 10% of swap is free, warning if less than 20% is free + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description Swap Usage + check_command check_local_swap!20!10 + } + + + +# Define a service to check SSH on the local machine. +# Disable notifications for this service by default, as not all users may have SSH enabled. + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description SSH + check_command check_ssh + notifications_enabled 0 + } + + + +# Define a service to check HTTP on the local machine. +# Disable notifications for this service by default, as not all users may have HTTP enabled. + +define service{ + use local-service ; Name of service template to use + host_name localhost + service_description HTTP + check_command check_http + notifications_enabled 0 + } + diff --git a/sample-config/template-object/printer.cfg.in b/sample-config/template-object/printer.cfg.in new file mode 100644 index 0000000..1de8855 --- /dev/null +++ b/sample-config/template-object/printer.cfg.in @@ -0,0 +1,85 @@ +############################################################################### +# PRINTER.CFG - SAMPLE CONFIG FILE FOR MONITORING A NETWORK PRINTER +# +# Last Modified: 10-03-2007 +# +# NOTES: This config file assumes that you are using the sample configuration +# files that get installed with the Nagios quickstart guide. +# +############################################################################### + + + + +############################################################################### +############################################################################### +# +# HOST DEFINITIONS +# +############################################################################### +############################################################################### + +# Define a host for the printer we'll be monitoring +# Change the host_name, alias, and address to fit your situation + +define host{ + use generic-printer ; Inherit default values from a template + host_name hplj2605dn ; The name we're giving to this printer + alias HP LaserJet 2605dn ; A longer name associated with the printer + address 192.168.1.30 ; IP address of the printer + hostgroups network-printers ; Host groups this printer is associated with + } + + + + +############################################################################### +############################################################################### +# +# HOST GROUP DEFINITIONS +# +############################################################################### +############################################################################### + +# A hostgroup for network printers + +define hostgroup{ + hostgroup_name network-printers ; The name of the hostgroup + alias Network Printers ; Long name of the group + } + + + + +############################################################################### +############################################################################### +# +# SERVICE DEFINITIONS +# +############################################################################### +############################################################################### + +# Create a service for monitoring the status of the printer +# Change the host_name to match the name of the host you defined above +# If the printer has an SNMP community string other than "public", change the check_command directive to reflect that + +define service{ + use generic-service ; Inherit values from a template + host_name hplj2605dn ; The name of the host the service is associated with + service_description Printer Status ; The service description + check_command check_hpjd!-C public ; The command used to monitor the service + normal_check_interval 10 ; Check the service every 10 minutes under normal conditions + retry_check_interval 1 ; Re-check the service every minute until its final/hard state is determined + } + + +# Create a service for "pinging" the printer occassionally. Useful for monitoring RTA, packet loss, etc. + +define service{ + use generic-service + host_name hplj2605dn + service_description PING + check_command check_ping!3000.0,80%!5000.0,100% + normal_check_interval 10 + retry_check_interval 1 + } diff --git a/sample-config/template-object/switch.cfg.in b/sample-config/template-object/switch.cfg.in new file mode 100644 index 0000000..60c4db6 --- /dev/null +++ b/sample-config/template-object/switch.cfg.in @@ -0,0 +1,113 @@ +############################################################################### +# SWITCH.CFG - SAMPLE CONFIG FILE FOR MONITORING A SWITCH +# +# Last Modified: 10-03-2007 +# +# NOTES: This config file assumes that you are using the sample configuration +# files that get installed with the Nagios quickstart guide. +# +############################################################################### + + + + +############################################################################### +############################################################################### +# +# HOST DEFINITIONS +# +############################################################################### +############################################################################### + +# Define the switch that we'll be monitoring + +define host{ + use generic-switch ; Inherit default values from a template + host_name linksys-srw224p ; The name we're giving to this switch + alias Linksys SRW224P Switch ; A longer name associated with the switch + address 192.168.1.253 ; IP address of the switch + hostgroups switches ; Host groups this switch is associated with + } + + + + +############################################################################### +############################################################################### +# +# HOST GROUP DEFINITIONS +# +############################################################################### +############################################################################### + +# Create a new hostgroup for switches + +define hostgroup{ + hostgroup_name switches ; The name of the hostgroup + alias Network Switches ; Long name of the group + } + + + + +############################################################################### +############################################################################### +# +# SERVICE DEFINITIONS +# +############################################################################### +############################################################################### + +# Create a service to PING to switch + +define service{ + use generic-service ; Inherit values from a template + host_name linksys-srw224p ; The name of the host the service is associated with + service_description PING ; The service description + check_command check_ping!200.0,20%!600.0,60% ; The command used to monitor the service + normal_check_interval 5 ; Check the service every 5 minutes under normal conditions + retry_check_interval 1 ; Re-check the service every minute until its final/hard state is determined + } + + +# Monitor uptime via SNMP + +define service{ + use generic-service ; Inherit values from a template + host_name linksys-srw224p + service_description Uptime + check_command check_snmp!-C public -o sysUpTime.0 + } + + + +# Monitor Port 1 status via SNMP + +define service{ + use generic-service ; Inherit values from a template + host_name linksys-srw224p + service_description Port 1 Link Status + check_command check_snmp!-C public -o ifOperStatus.1 -r 1 -m RFC1213-MIB + } + + + +# Monitor bandwidth via MRTG logs + +define service{ + use generic-service ; Inherit values from a template + host_name linksys-srw224p + service_description Port 1 Bandwidth Usage + check_command check_local_mrtgtraf!/var/lib/mrtg/192.168.1.253_1.log!AVG!1000000,1000000!5000000,5000000!10 + } + + + + + + + + + + + diff --git a/sample-config/template-object/templates.cfg.in b/sample-config/template-object/templates.cfg.in new file mode 100644 index 0000000..16a980d --- /dev/null +++ b/sample-config/template-object/templates.cfg.in @@ -0,0 +1,190 @@ +############################################################################### +# TEMPLATES.CFG - SAMPLE OBJECT TEMPLATES +# +# Last Modified: 10-03-2007 +# +# NOTES: This config file provides you with some example object definition +# templates that are refered by other host, service, contact, etc. +# definitions in other config files. +# +# You don't need to keep these definitions in a separate file from your +# other object definitions. This has been done just to make things +# easier to understand. +# +############################################################################### + + + +############################################################################### +############################################################################### +# +# CONTACT TEMPLATES +# +############################################################################### +############################################################################### + +# Generic contact definition template - This is NOT a real contact, just a template! + +define contact{ + name generic-contact ; The name of this contact template + service_notification_period 24x7 ; service notifications can be sent anytime + host_notification_period 24x7 ; host notifications can be sent anytime + service_notification_options w,u,c,r,f,s ; send notifications for all service states, flapping events, and scheduled downtime events + host_notification_options d,u,r,f,s ; send notifications for all host states, flapping events, and scheduled downtime events + service_notification_commands notify-service-by-email ; send service notifications via email + host_notification_commands notify-host-by-email ; send host notifications via email + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL CONTACT, JUST A TEMPLATE! + } + + + + +############################################################################### +############################################################################### +# +# HOST TEMPLATES +# +############################################################################### +############################################################################### + +# Generic host definition template - This is NOT a real host, just a template! + +define host{ + name generic-host ; The name of this host template + notifications_enabled 1 ; Host notifications are enabled + event_handler_enabled 1 ; Host event handler is enabled + flap_detection_enabled 1 ; Flap detection is enabled + failure_prediction_enabled 1 ; Failure prediction is enabled + process_perf_data 1 ; Process performance data + retain_status_information 1 ; Retain status information across program restarts + retain_nonstatus_information 1 ; Retain non-status information across program restarts + notification_period 24x7 ; Send host notifications at any time + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE! + } + + +# Linux host definition template - This is NOT a real host, just a template! + +define host{ + name linux-server ; The name of this host template + use generic-host ; This template inherits other values from the generic-host template + check_period 24x7 ; By default, Linux hosts are checked round the clock + check_interval 5 ; Actively check the host every 5 minutes + retry_interval 1 ; Schedule host check retries at 1 minute intervals + max_check_attempts 10 ; Check each Linux host 10 times (max) + check_command check-host-alive ; Default command to check Linux hosts + notification_period workhours ; Linux admins hate to be woken up, so we only notify during the day + ; Note that the notification_period variable is being overridden from + ; the value that is inherited from the generic-host template! + notification_interval 120 ; Resend notifications every 2 hours + notification_options d,u,r ; Only send notifications for specific host states + contact_groups admins ; Notifications get sent to the admins by default + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE! + } + + + +# Windows host definition template - This is NOT a real host, just a template! + +define host{ + name windows-server ; The name of this host template + use generic-host ; Inherit default values from the generic-host template + check_period 24x7 ; By default, Windows servers are monitored round the clock + check_interval 5 ; Actively check the server every 5 minutes + retry_interval 1 ; Schedule host check retries at 1 minute intervals + max_check_attempts 10 ; Check each server 10 times (max) + check_command check-host-alive ; Default command to check if servers are "alive" + notification_period 24x7 ; Send notification out at any time - day or night + notification_interval 30 ; Resend notifications every 30 minutes + notification_options d,r ; Only send notifications for specific host states + contact_groups admins ; Notifications get sent to the admins by default + hostgroups windows-servers ; Host groups that Windows servers should be a member of + register 0 ; DONT REGISTER THIS - ITS JUST A TEMPLATE + } + + +# We define a generic printer template that can be used for most printers we monitor + +define host{ + name generic-printer ; The name of this host template + use generic-host ; Inherit default values from the generic-host template + check_period 24x7 ; By default, printers are monitored round the clock + check_interval 5 ; Actively check the printer every 5 minutes + retry_interval 1 ; Schedule host check retries at 1 minute intervals + max_check_attempts 10 ; Check each printer 10 times (max) + check_command check-host-alive ; Default command to check if printers are "alive" + notification_period workhours ; Printers are only used during the workday + notification_interval 30 ; Resend notifications every 30 minutes + notification_options d,r ; Only send notifications for specific host states + contact_groups admins ; Notifications get sent to the admins by default + register 0 ; DONT REGISTER THIS - ITS JUST A TEMPLATE + } + + +# Define a template for switches that we can reuse +define host{ + name generic-switch ; The name of this host template + use generic-host ; Inherit default values from the generic-host template + check_period 24x7 ; By default, switches are monitored round the clock + check_interval 5 ; Switches are checked every 5 minutes + retry_interval 1 ; Schedule host check retries at 1 minute intervals + max_check_attempts 10 ; Check each switch 10 times (max) + check_command check-host-alive ; Default command to check if routers are "alive" + notification_period 24x7 ; Send notifications at any time + notification_interval 30 ; Resend notifications every 30 minutes + notification_options d,r ; Only send notifications for specific host states + contact_groups admins ; Notifications get sent to the admins by default + register 0 ; DONT REGISTER THIS - ITS JUST A TEMPLATE + } + + + + +############################################################################### +############################################################################### +# +# SERVICE TEMPLATES +# +############################################################################### +############################################################################### + +# Generic service definition template - This is NOT a real service, just a template! + +define service{ + name generic-service ; The 'name' of this service template + active_checks_enabled 1 ; Active service checks are enabled + passive_checks_enabled 1 ; Passive service checks are enabled/accepted + parallelize_check 1 ; Active service checks should be parallelized (disabling this can lead to major performance problems) + obsess_over_service 1 ; We should obsess over this service (if necessary) + check_freshness 0 ; Default is to NOT check service 'freshness' + notifications_enabled 1 ; Service notifications are enabled + event_handler_enabled 1 ; Service event handler is enabled + flap_detection_enabled 1 ; Flap detection is enabled + failure_prediction_enabled 1 ; Failure prediction is enabled + process_perf_data 1 ; Process performance data + retain_status_information 1 ; Retain status information across program restarts + retain_nonstatus_information 1 ; Retain non-status information across program restarts + is_volatile 0 ; The service is not volatile + check_period 24x7 ; The service can be checked at any time of the day + max_check_attempts 3 ; Re-check the service up to 3 times in order to determine its final (hard) state + normal_check_interval 10 ; Check the service every 10 minutes under normal conditions + retry_check_interval 2 ; Re-check the service every two minutes until a hard state can be determined + contact_groups admins ; Notifications get sent out to everyone in the 'admins' group + notification_options w,u,c,r ; Send notifications about warning, unknown, critical, and recovery events + notification_interval 60 ; Re-notify about service problems every hour + notification_period 24x7 ; Notifications can be sent out at any time + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE! + } + + +# Local service definition template - This is NOT a real service, just a template! + +define service{ + name local-service ; The name of this service template + use generic-service ; Inherit default values from the generic-service definition + max_check_attempts 4 ; Re-check the service up to 4 times in order to determine its final (hard) state + normal_check_interval 5 ; Check the service every 5 minutes under normal conditions + retry_check_interval 1 ; Re-check the service every minute until a hard state can be determined + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE! + } + diff --git a/sample-config/template-object/timeperiods.cfg.in b/sample-config/template-object/timeperiods.cfg.in new file mode 100644 index 0000000..7f1802e --- /dev/null +++ b/sample-config/template-object/timeperiods.cfg.in @@ -0,0 +1,94 @@ +############################################################################### +# TIMEPERIODS.CFG - SAMPLE TIMEPERIOD DEFINITIONS +# +# Last Modified: 05-31-2007 +# +# NOTES: This config file provides you with some example timeperiod definitions +# that you can reference in host, service, contact, and dependency +# definitions. +# +# You don't need to keep timeperiods in a separate file from your other +# object definitions. This has been done just to make things easier to +# understand. +# +############################################################################### + + + +############################################################################### +############################################################################### +# +# TIME PERIODS +# +############################################################################### +############################################################################### + +# This defines a timeperiod where all times are valid for checks, +# notifications, etc. The classic "24x7" support nightmare. :-) +define timeperiod{ + timeperiod_name 24x7 + alias 24 Hours A Day, 7 Days A Week + sunday 00:00-24:00 + monday 00:00-24:00 + tuesday 00:00-24:00 + wednesday 00:00-24:00 + thursday 00:00-24:00 + friday 00:00-24:00 + saturday 00:00-24:00 + } + + +# 'workhours' timeperiod definition +define timeperiod{ + timeperiod_name workhours + alias Normal Work Hours + monday 09:00-17:00 + tuesday 09:00-17:00 + wednesday 09:00-17:00 + thursday 09:00-17:00 + friday 09:00-17:00 + } + + +# 'none' timeperiod definition +define timeperiod{ + timeperiod_name none + alias No Time Is A Good Time + } + + +# Some U.S. holidays +# Note: The timeranges for each holiday are meant to *exclude* the holidays from being +# treated as a valid time for notifications, etc. You probably don't want your pager +# going off on New Year's. Although you're employer might... :-) +define timeperiod{ + name us-holidays + timeperiod_name us-holidays + alias U.S. Holidays + + january 1 00:00-00:00 ; New Years + monday -1 may 00:00-00:00 ; Memorial Day (last Monday in May) + july 4 00:00-00:00 ; Independence Day + monday 1 september 00:00-00:00 ; Labor Day (first Monday in September) + thursday 4 november 00:00-00:00 ; Thanksgiving (4th Thursday in November) + december 25 00:00-00:00 ; Christmas + } + + +# This defines a modified "24x7" timeperiod that covers every day of the +# year, except for U.S. holidays (defined in the timeperiod above). +define timeperiod{ + timeperiod_name 24x7_sans_holidays + alias 24x7 Sans Holidays + + use us-holidays ; Get holiday exceptions from other timeperiod + + sunday 00:00-24:00 + monday 00:00-24:00 + tuesday 00:00-24:00 + wednesday 00:00-24:00 + thursday 00:00-24:00 + friday 00:00-24:00 + saturday 00:00-24:00 + } + diff --git a/sample-config/template-object/windows.cfg.in b/sample-config/template-object/windows.cfg.in new file mode 100644 index 0000000..264a63a --- /dev/null +++ b/sample-config/template-object/windows.cfg.in @@ -0,0 +1,145 @@ +############################################################################### +# WINDOWS.CFG - SAMPLE CONFIG FILE FOR MONITORING A WINDOWS MACHINE +# +# Last Modified: 06-13-2007 +# +# NOTES: This config file assumes that you are using the sample configuration +# files that get installed with the Nagios quickstart guide. +# +############################################################################### + + + + +############################################################################### +############################################################################### +# +# HOST DEFINITIONS +# +############################################################################### +############################################################################### + +# Define a host for the Windows machine we'll be monitoring +# Change the host_name, alias, and address to fit your situation + +define host{ + use windows-server ; Inherit default values from a template + host_name winserver ; The name we're giving to this host + alias My Windows Server ; A longer name associated with the host + address 192.168.1.2 ; IP address of the host + } + + + + +############################################################################### +############################################################################### +# +# HOST GROUP DEFINITIONS +# +############################################################################### +############################################################################### + + +# Define a hostgroup for Windows machines +# All hosts that use the windows-server template will automatically be a member of this group + +define hostgroup{ + hostgroup_name windows-servers ; The name of the hostgroup + alias Windows Servers ; Long name of the group + } + + + + +############################################################################### +############################################################################### +# +# SERVICE DEFINITIONS +# +############################################################################### +############################################################################### + + +# Create a service for monitoring the version of NSCLient++ that is installed +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description NSClient++ Version + check_command check_nt!CLIENTVERSION + } + + + +# Create a service for monitoring the uptime of the server +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description Uptime + check_command check_nt!UPTIME + } + + + +# Create a service for monitoring CPU load +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description CPU Load + check_command check_nt!CPULOAD!-l 5,80,90 + } + + + +# Create a service for monitoring memory usage +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description Memory Usage + check_command check_nt!MEMUSE!-w 80 -c 90 + } + + + +# Create a service for monitoring C:\ disk usage +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description C:\ Drive Space + check_command check_nt!USEDDISKSPACE!-l c -w 80 -c 90 + } + + + +# Create a service for monitoring the W3SVC service +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description W3SVC + check_command check_nt!SERVICESTATE!-d SHOWALL -l W3SVC + } + + + +# Create a service for monitoring the Explorer.exe process +# Change the host_name to match the name of the host you defined above + +define service{ + use generic-service + host_name winserver + service_description Explorer + check_command check_nt!PROCSTATE!-d SHOWALL -l Explorer.exe + } + diff --git a/subst.in b/subst.in new file mode 100755 index 0000000..a8e2c06 --- /dev/null +++ b/subst.in @@ -0,0 +1,52 @@ +#!/usr/bin/perl -w + +my ${exec_prefix}; +my ${prefix}; + +${prefix}="@prefix@"; +${exec_prefix}="@exec_prefix@"; +while ($f = shift @ARGV) { + + if (-x "/bin/mktemp") { + $TEMP = `/bin/mktemp $f.$$.XXXXXX`; + die 'Cannot make temporary file $TEMP' if($?); + chomp $TEMP; + } else { + $XXXXXX = rand; + $TEMP = "$f.$$.$XXXXXX"; + } + + open(IN,"<$f.in"); + open(OUT,">$TEMP") || die 'Cannot make temporary file $TEMP'; + + while () { + s|\@nagios_user\@|@nagios_user@|g; + s|\@nagios_grp\@|@nagios_grp@|g; + s|\@lockfile\@|@lockfile@|g; + s|\@libexecdir\@|@libexecdir@|g; # put all --with-vars before directories + s|\@localstatedir\@|@localstatedir@|g; + s|\@sysconfdir\@|@sysconfdir@|g; + s|\@TMPDIR\@|@TMPDIR@|g; + s|\@CHECKRESULTDIR\@|@CHECKRESULTDIR@|g; + s|\@datadir\@|@datadir@|g; + s|\@sbindir\@|@sbindir@|g; + s|\@bindir\@|@bindir@|g; + s|\@htmurl\@|@htmurl@|g; + s|\@cgiurl\@|@cgiurl@|g; + s|\@MAIL_PROG\@|@MAIL_PROG@|g; + s|\@VERSION\@|@VERSION@|g; + s|\$\{exec_prefix\}|@exec_prefix@|g; # must be next to last + s|\$\{prefix\}|@prefix@|g; # must be last + print OUT $_; + } + + close IN; + close OUT; + + if ((! -e $f) || (`diff $f $TEMP`)) { + `mv $TEMP $f`; + } else { + unlink $TEMP; + } + +} diff --git a/t-tap/.gitignore b/t-tap/.gitignore new file mode 100644 index 0000000..3c8db7f --- /dev/null +++ b/t-tap/.gitignore @@ -0,0 +1,10 @@ +test_events +test_logging +test_checks +test_nagios_config +test_timeperiods +test_xsddefault +test_commands +test_downtime +test_strtoul +*.dSYM diff --git a/t-tap/Makefile.in b/t-tap/Makefile.in new file mode 100644 index 0000000..2be4ae9 --- /dev/null +++ b/t-tap/Makefile.in @@ -0,0 +1,136 @@ +# Makefile for Nagios tests using libtap + + +# Source code directories +SRC_COMMON=../common +SRC_INCLUDE=../include +SRC_XDATA=../xdata +SRC_BASE=../base +SRC_CGI=../cgi +SRC_COMMON=../common + +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ -DNSCORE -I../include -I../tap/src + +TESTS = test_logging test_events test_timeperiods test_nagios_config +TESTS += test_xsddefault +TESTS += test_checks +TESTS += test_strtoul +TESTS += test_commands +TESTS += test_downtime + +XSD_OBJS = $(SRC_CGI)/statusdata-cgi.o $(SRC_CGI)/xstatusdata-cgi.o +XSD_OBJS += $(SRC_CGI)/objects-cgi.o $(SRC_CGI)/xobjects-cgi.o +XSD_OBJS += $(SRC_CGI)/comments-cgi.o $(SRC_CGI)/downtime-cgi.o +XSD_OBJS += $(SRC_CGI)/cgiutils.o $(SRC_CGI)/skiplist.o ../common/shared.o + +TP_OBJS = $(SRC_BASE)/utils.o $(SRC_BASE)/config.o $(SRC_BASE)/macros-base.o +TP_OBJS += $(SRC_BASE)/objects-base.o $(SRC_BASE)/xobjects-base.o +TP_OBJS += $(SRC_BASE)/skiplist.o ../common/shared.o + +CFG_OBJS = $(TP_OBJS) +CFG_OBJS += $(SRC_BASE)/comments-base.o $(SRC_BASE)/xcomments-base.o +CFG_OBJS += $(SRC_BASE)/downtime-base.o $(SRC_BASE)/xdowntime-base.o +CFG_OBJS += $(SRC_BASE)/retention-base.o $(SRC_BASE)/xretention-base.o + + +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@ + +TAPOBJ=../tap/src/tap.o $(SNPRINTF_O) + +all: $(TESTS) + +########## TESTS ########## + +test_logging: test_logging.o $(SRC_BASE)/logging.o $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_events: test_events.o $(SRC_BASE)/events.o $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(MATHLIBS) $(LIBS) + +test_checks: test_checks.o $(SRC_BASE)/checks.o $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(MATHLIBS) $(LIBS) + +test_commands: test_commands.o $(SRC_COMMON)/shared.o $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ + +test_downtime: test_downtime.o $(SRC_BASE)/downtime-base.o $(SRC_BASE)/xdowntime-base.o $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ + +test_freshness: test_freshness.o $(SRC_BASE)/freshness.o $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ + +test_nagios_config: test_nagios_config.o $(CFG_OBJS) $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ $(BROKER_LDFLAGS) $(LDFLAGS) $(MATHLIBS) $(SOCKETLIBS) $(THREADLIBS) $(BROKERLIBS) $(LIBS) + +test_timeperiods: test_timeperiods.o $(TP_OBJS) $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ $(BROKER_LDFLAGS) $(LDFLAGS) $(MATHLIBS) $(SOCKETLIBS) $(THREADLIBS) $(BROKERLIBS) $(LIBS) + +test_xsddefault: test_xsddefault.o $(XSD_OBJS) $(TAPOBJ) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_strtoul: test_strtoul.c + $(CC) $(CFLAGS) -o $@ test_strtoul.c $(TAPOBJ) + +test: $(TESTS) + HARNESS_PERL=./test_each.t perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map { "./$$_" } @ARGV)' $(TESTS) + +clean: + rm -f nagios nagiostats core *.o gmon.out + rm -f *~ *.*~ + +distclean: clean + rm -f perlxsi.c + rm -f Makefile + +devclean: distclean + diff --git a/t-tap/smallconfig/minimal.cfg b/t-tap/smallconfig/minimal.cfg new file mode 100644 index 0000000..0615efa --- /dev/null +++ b/t-tap/smallconfig/minimal.cfg @@ -0,0 +1,235 @@ +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none + hostgroups hostgroup1 +} + +define host { + host_name hostveryrecent + alias hostveryrecent test + address 192.168.1.1 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none + hostgroups hostgroup1 +} + +define hostgroup { + hostgroup_name hostgroup1 +} + +define hostgroup { + hostgroup_name hostgroup2 +} + +define service { + host_name host1 + service_description Dummy service + check_command check_me + max_check_attempts 3 + check_interval 32 + retry_interval 1 + check_period none + notification_interval 60 + notification_period none + contacts nagiosadmin +} + +define service { + host_name host1 + service_description Dummy service2 + check_command check_me + max_check_attempts 3 + check_interval 32 + retry_interval 1 + check_period none + notification_interval 60 + notification_period none + contacts nagiosadmin +} + +define service { + host_name host1 + service_description Uses important check command + check_command check_me!with some parameters + max_check_attempts 5 + check_interval 15 + retry_interval 1 + check_period none + notification_interval 65 + notification_period none + contacts nagiosadmin + use service-distributed +} + +define service { + name service-distributed + check_command !set_to_stale + register 0 +} + +define command { + command_name set_to_stale + command_line /usr/local/nagios/libexec/set_to_stale +} + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me +} + +define command { + command_name with_continuation_lines + command_line $USER1$/check_foo one\ + two +} + +define command { + command_name multiple_continuation_lines_with_spaces_intermingled + command_line \ + check_nrpe_arg!30!\ + check_fs_ping!/mnt/account-p,/mnt/prepro-p,/mnt/webapp-ssl,/mnt/rollout-p +} + +define timeperiod { + timeperiod_name none + alias Nothing +} + +define timeperiod { + timeperiod_name 24x7 + alias 24x7 base on weekdays + monday 00:00-24:00 + tuesday 00:00-24:00 + wednesday 00:00-24:00 + thursday 00:00-24:00 + friday 00:00-24:00 + saturday 00:00-24:00 + sunday 00:00-24:00 +} + +define timeperiod { + timeperiod_name sunday_only + alias Avoid time clock change hours + sunday 00:00-01:15,03:15-22:00 +} + +define timeperiod { + timeperiod_name weekly_complex + alias Complex weekly timeperiods + monday 01:15-23:15 + tuesday 01:15-23:15 + wednesday 01:15-23:15 + thursday 01:15-23:15 + friday 01:15-23:15 + saturday 00:00-22:00,23:00-24:00 + sunday 00:00-09:45,14:15-24:00 +} + + +define timeperiod{ + timeperiod_name Test_exclude + alias Test for exclude timeperiod + tuesday -1 - monday 1 16:30-24:00 + exclude myexclude + } + + +define timeperiod{ + timeperiod_name myexclude + alias myexclude + april 1 - august 16 00:00-24:00 + saturday -1 - monday 1 16:00-24:00 + } + +define timeperiod{ + timeperiod_name Test_exclude2 + alias Test2 for exclude timeperiod + tuesday 2 16:30-24:00 + exclude myexclude2 + } + +define timeperiod{ + timeperiod_name myexclude2 + alias myexclude2 + tuesday 00:00-23:58 + } + + +define timeperiod{ + timeperiod_name Test_exclude3 + alias Test3 for exclude timeperiod + tuesday 2 16:30-24:00 + exclude myexclude3 + } + +define timeperiod{ + timeperiod_name myexclude3 + alias myexclude3 + april 1 - august 16 00:00-24:00 + } + +define timeperiod{ + timeperiod_name Test_exclude4 + alias Test for exclude timeperiod + tuesday -1 - monday 1 16:30-24:00 + exclude myexclude4 + } + + +define timeperiod{ + timeperiod_name myexclude4 + alias myexclude4 + april 1 - august 16 00:00-24:00 + } + + + +define contact { + contact_name nagiosadmin + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none +} + +define contact { + contact_name second + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members nagiosadmin,second +} + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation +} + diff --git a/t-tap/smallconfig/nagios.cfg b/t-tap/smallconfig/nagios.cfg new file mode 100644 index 0000000..e538f9e --- /dev/null +++ b/t-tap/smallconfig/nagios.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=smallconfig/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=minimal.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=smallconfig/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=smallconfig/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=smallconfig/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=smallconfig/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=smallconfig/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=smallconfig/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=smallconfig/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=smallconfig + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=smallconfig + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=smallconfig + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=smallconfig/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=smallconfig/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t-tap/smallconfig/resource.cfg b/t-tap/smallconfig/resource.cfg new file mode 100644 index 0000000..153d8ca --- /dev/null +++ b/t-tap/smallconfig/resource.cfg @@ -0,0 +1 @@ +#Empty file diff --git a/t-tap/smallconfig/retention.dat b/t-tap/smallconfig/retention.dat new file mode 100644 index 0000000..2d35294 --- /dev/null +++ b/t-tap/smallconfig/retention.dat @@ -0,0 +1,208 @@ +######################################## +# NAGIOS STATE RETENTION FILE +# +# This is a test retention.dat file +######################################## +info { +created=1264459160 +version=3.2.0 +last_update_check=0 +update_available=0 +last_version=3.0.6 +new_version= +} +program { +modified_host_attributes=0 +modified_service_attributes=0 +enable_notifications=1 +active_service_checks_enabled=1 +passive_service_checks_enabled=1 +active_host_checks_enabled=1 +passive_host_checks_enabled=1 +enable_event_handlers=1 +obsess_over_services=0 +obsess_over_hosts=0 +check_service_freshness=1 +check_host_freshness=1 +enable_flap_detection=1 +enable_failure_prediction=1 +process_performance_data=1 +global_host_event_handler= +global_service_event_handler= +next_comment_id=100420 +next_downtime_id=100183 +next_event_id=1288 +next_problem_id=218 +next_notification_id=13494 +} +host { +host_name=host1 +modified_attributes=1 +check_command=check_host!-H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 1 +check_period=24x7 +notification_period=24x7 +event_handler= +has_been_checked=1 +check_execution_time=10.030 +check_latency=0.000 +check_type=0 +current_state=1 +last_state=2 +last_hard_state=2 +last_event_id=1204 +current_event_id=1275 +current_problem_id=41 +last_problem_id=0 +plugin_output=PING CRITICAL - Packet loss = 100% +long_plugin_output= +performance_data=rta=5000.000000ms;3000.000000;5000.000000;0.000000 pl=100%;80;100;0 +last_check=1264456433 +next_check=1264456444 +check_options=0 +current_attempt=1 +max_attempts=2 +normal_check_interval=0.000000 +retry_check_interval=0.000000 +state_type=1 +last_state_change=1264456444 +last_hard_state_change=1264456444 +last_time_up=1247509815 +last_time_down=1264456444 +last_time_unreachable=1264456432 +notified_on_down=1 +notified_on_unreachable=1 +last_notification=0 +current_notification_number=52 +current_notification_id=13392 +notifications_enabled=1 +problem_has_been_acknowledged=0 +acknowledgement_type=0 +active_checks_enabled=1 +passive_checks_enabled=1 +event_handler_enabled=0 +flap_detection_enabled=1 +failure_prediction_enabled=1 +process_performance_data=1 +obsess_over_host=0 +is_flapping=1 +percent_state_change=29.87 +check_flapping_recovery_notification=1 +state_history=1,1,1,1,2,2,1,2,2,1,1,1,1,1,1,1,2,2,2,2,1 +} +host { +host_name=doesnotexist +modified_attributes=1 +check_command=check_host!-H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 1 +check_period=24x7 +notification_period=24x7 +event_handler= +has_been_checked=1 +check_execution_time=10.030 +check_latency=0.000 +check_type=0 +current_state=1 +last_state=2 +last_hard_state=2 +last_event_id=1204 +current_event_id=1275 +current_problem_id=41 +last_problem_id=0 +plugin_output=PING CRITICAL - Packet loss = 100% +long_plugin_output= +performance_data=rta=5000.000000ms;3000.000000;5000.000000;0.000000 pl=100%;80;100;0 +last_check=1264456433 +next_check=1264456444 +check_options=0 +current_attempt=1 +max_attempts=2 +normal_check_interval=0.000000 +retry_check_interval=0.000000 +state_type=1 +last_state_change=1264456444 +last_hard_state_change=1264456444 +last_time_up=1247509815 +last_time_down=1264456444 +last_time_unreachable=1264456432 +notified_on_down=1 +notified_on_unreachable=1 +last_notification=0 +current_notification_number=52 +current_notification_id=13392 +notifications_enabled=1 +problem_has_been_acknowledged=0 +acknowledgement_type=0 +active_checks_enabled=1 +passive_checks_enabled=1 +event_handler_enabled=0 +flap_detection_enabled=1 +failure_prediction_enabled=1 +process_performance_data=1 +obsess_over_host=0 +is_flapping=1 +percent_state_change=29.87 +check_flapping_recovery_notification=1 +state_history=1,1,1,1,2,2,1,2,2,1,1,1,1,1,1,1,2,2,2,2,1 +} +hostcomment { +host_name=host1 +entry_type=3 +comment_id=418 +source=0 +persistent=1 +entry_time=1264451960 +expires=0 +expire_time=0 +author=(Nagios Process) +comment_data=Notifications for this host are being suppressed because it was detected as having been flapping between different states (34.5% change > 20.0% threshold). When the host state stabilizes and the flapping stops, notifications will be re-enabled. +} +servicecomment { +host_name=host1 +service_description=Dummy service +entry_type=3 +comment_id=419 +source=0 +persistent=1 +entry_time=1264451960 +expires=0 +expire_time=0 +author=(Nagios Process) +comment_data=Notifications for this service are being suppressed because it was detected as having been flapping between different states (40.3% change >= 20.0% threshold). When the service state stabilizes and the flapping stops, notifications will be re-enabled. +} +servicecomment { +host_name=host1 +service_description=Dummy service +entry_type=3 +comment_id=420 +source=0 +persistent=0 +entry_time=1264451960 +expires=0 +expire_time=0 +author=(Nagios Process) +comment_data=This is a non-persistent comment, to check is read correctly +} +hostdowntime { +host_name=host1 +downtime_id=1102 +entry_time=1280488503 +start_time=1980913033 +end_time=1980913033 +triggered_by=0 +fixed=1 +duration=7 +author=dferguson +comment=Test host downtime +} +servicedowntime { +host_name=host1 +service_description=Dummy service +downtime_id=1110 +entry_time=1280913033 +start_time=1980913033 +end_time=1980913041 +triggered_by=0 +fixed=1 +duration=8 +author=dferguson +comment=Test service downtime +} diff --git a/t-tap/stub_broker.c b/t-tap/stub_broker.c new file mode 100644 index 0000000..15c9824 --- /dev/null +++ b/t-tap/stub_broker.c @@ -0,0 +1,8 @@ +/* Stub file for routines from broker.c */ +void broker_downtime_data(int type, int flags, int attr, int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, struct timeval *timestamp) {} +void broker_adaptive_host_data(int type, int flags, int attr, host *hst, int command_type, unsigned long modattr, unsigned long modattrs, struct timeval *timestamp) {} +void broker_adaptive_program_data(int type, int flags, int attr, int command_type, unsigned long modhattr, unsigned long modhattrs, unsigned long modsattr, unsigned long modsattrs, struct timeval *timestamp) {} +void broker_adaptive_service_data(int type, int flags, int attr, service *svc, int command_type, unsigned long modattr, unsigned long modattrs, struct timeval *timestamp) {} +void broker_adaptive_contact_data(int type, int flags, int attr, contact *cntct, int command_type, unsigned long modattr, unsigned long modattrs, unsigned long modhattr, unsigned long modhattrs, unsigned long modsattr, unsigned long modsattrs, struct timeval *timestamp) {} +void broker_external_command(int type, int flags, int attr, int command_type, time_t entry_time, char *command_string, char *command_args, struct timeval *timestamp) {} +void broker_acknowledgement_data(int type, int flags, int attr, int acknowledgement_type, void *data, char *ack_author, char *ack_data, int subtype, int notify_contacts, int persistent_comment, struct timeval *timestamp) {} diff --git a/t-tap/stub_checks.c b/t-tap/stub_checks.c new file mode 100644 index 0000000..b7c101b --- /dev/null +++ b/t-tap/stub_checks.c @@ -0,0 +1,2 @@ +void schedule_host_check(host *hst, time_t check_time, int options) {} +void schedule_service_check(service *svc, time_t check_time, int options) {} diff --git a/t-tap/stub_comments.c b/t-tap/stub_comments.c new file mode 100644 index 0000000..0830343 --- /dev/null +++ b/t-tap/stub_comments.c @@ -0,0 +1,9 @@ +/* Stub file for comments.c */ +int delete_service_comment(unsigned long comment_id) {} +int delete_host_comment(unsigned long comment_id) {} +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 delete_service_acknowledgement_comments(service *svc) {} +int delete_host_acknowledgement_comments(host *hst) {} +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 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 delete_all_comments(int type, char *host_name, char *svc_description) {} diff --git a/t-tap/stub_downtime.c b/t-tap/stub_downtime.c new file mode 100644 index 0000000..7a6a1d1 --- /dev/null +++ b/t-tap/stub_downtime.c @@ -0,0 +1,4 @@ +/* Stub for common/downtime.c */ +int schedule_downtime(int type, char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *new_downtime_id) {} +int unschedule_downtime(int type, unsigned long downtime_id) {} +int check_pending_flex_host_downtime(host *hst) {} diff --git a/t-tap/stub_events.c b/t-tap/stub_events.c new file mode 100644 index 0000000..ae6e2fd --- /dev/null +++ b/t-tap/stub_events.c @@ -0,0 +1,3 @@ +/* Stub for base/events.c */ +int schedule_new_event(int event_type, int high_priority, time_t run_time, int recurring, unsigned long event_interval, void *timing_func, int compensate_for_time_change, void *event_data, void *event_args, int event_options) {} +void remove_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) {} diff --git a/t-tap/stub_flapping.c b/t-tap/stub_flapping.c new file mode 100644 index 0000000..9f859a5 --- /dev/null +++ b/t-tap/stub_flapping.c @@ -0,0 +1,7 @@ +/* Stub for base/flapping.c */ +void disable_service_flap_detection(service *svc) {} +void disable_host_flap_detection(host *hst) {} +void disable_flap_detection_routines(void) {} +void enable_flap_detection_routines(void) {} +void enable_service_flap_detection(service *svc) {} +void enable_host_flap_detection(host *hst) {} diff --git a/t-tap/stub_logging.c b/t-tap/stub_logging.c new file mode 100644 index 0000000..c11c150 --- /dev/null +++ b/t-tap/stub_logging.c @@ -0,0 +1,2 @@ +/* Stub for base/logging.c */ +int write_to_all_logs(char *buffer, unsigned long data_type) {} diff --git a/t-tap/stub_notifications.c b/t-tap/stub_notifications.c new file mode 100644 index 0000000..a0a1575 --- /dev/null +++ b/t-tap/stub_notifications.c @@ -0,0 +1,3 @@ +/* Stub for base/notifications.c */ +int service_notification(service *svc, int type, char *not_author, char *not_data, int options) {} +int host_notification(host *hst, int type, char *not_author, char *not_data, int options) {} diff --git a/t-tap/stub_objects.c b/t-tap/stub_objects.c new file mode 100644 index 0000000..f841b1b --- /dev/null +++ b/t-tap/stub_objects.c @@ -0,0 +1,9 @@ +/* Stub file for common/objects.c */ +service * find_service(char *host_name, char *svc_desc) {} +host * find_host(char *name) {} +hostgroup * find_hostgroup(char *name) {} +contactgroup * find_contactgroup(char *name) {} +servicegroup * find_servicegroup(char *name) {} +contact * find_contact(char *name) {} +command * find_command(char *name) {} +timeperiod * find_timeperiod(char *name) {} diff --git a/t-tap/stub_perfdata.c b/t-tap/stub_perfdata.c new file mode 100644 index 0000000..3561be5 --- /dev/null +++ b/t-tap/stub_perfdata.c @@ -0,0 +1 @@ +int update_host_performance_data(host *hst) {} diff --git a/t-tap/stub_sehandlers.c b/t-tap/stub_sehandlers.c new file mode 100644 index 0000000..9b48b23 --- /dev/null +++ b/t-tap/stub_sehandlers.c @@ -0,0 +1,2 @@ +int obsessive_compulsive_host_check_processor(host *hst) {} +int handle_host_event(host *hst) {} diff --git a/t-tap/stub_shared.c b/t-tap/stub_shared.c new file mode 100644 index 0000000..97d16e8 --- /dev/null +++ b/t-tap/stub_shared.c @@ -0,0 +1,2 @@ +/* Stub for common/shared.c */ +void get_datetime_string(time_t * raw_time, char *buffer, int buffer_length, int type) {} diff --git a/t-tap/stub_sretention.c b/t-tap/stub_sretention.c new file mode 100644 index 0000000..21fedfa --- /dev/null +++ b/t-tap/stub_sretention.c @@ -0,0 +1,2 @@ +int read_initial_state_information(void) {} +int save_state_information(int autosave) {} diff --git a/t-tap/stub_statusdata.c b/t-tap/stub_statusdata.c new file mode 100644 index 0000000..e0f8971 --- /dev/null +++ b/t-tap/stub_statusdata.c @@ -0,0 +1,5 @@ +/* Stub for common/statusdata.c */ +int update_service_status(service *svc, int aggregated_dump) {} +int update_host_status(host *hst, int aggregated_dump) {} +int update_program_status(int aggregated_dump) {} +int update_contact_status(contact *cntct, int aggregated_dump) {} diff --git a/t-tap/stub_utils.c b/t-tap/stub_utils.c new file mode 100644 index 0000000..85d2c6b --- /dev/null +++ b/t-tap/stub_utils.c @@ -0,0 +1,5 @@ +/* Stub for base/utils.c */ +void get_next_valid_time(time_t pref_time, time_t *valid_time, timeperiod *tperiod) {} +int update_check_stats(int check_type, time_t check_time) {} +int move_check_result_to_queue(char *checkresult_file) {} +int check_time_against_period(time_t test_time, timeperiod *tperiod) {} diff --git a/t-tap/stub_xdddefault.c b/t-tap/stub_xdddefault.c new file mode 100644 index 0000000..8b576fa --- /dev/null +++ b/t-tap/stub_xdddefault.c @@ -0,0 +1,7 @@ +/* Stub file for xdata/xddefault.c */ +int xdddefault_add_new_host_downtime(char *host_name, time_t entry_time, char *author, char *comment, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id) {} +int xdddefault_add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id) {} +int xdddefault_cleanup_downtime_data(char *main_config_file) {} +int xdddefault_delete_service_downtime(unsigned long downtime_id) {} +int xdddefault_delete_host_downtime(unsigned long downtime_id) {} +int xdddefault_initialize_downtime_data(char *main_config_file) {} diff --git a/t-tap/test-stubs.c b/t-tap/test-stubs.c new file mode 100644 index 0000000..3f374b9 --- /dev/null +++ b/t-tap/test-stubs.c @@ -0,0 +1,206 @@ +#ifndef NAGIOS_TEST_STUBS__ +#define NAGIOS_TEST_STUBS__ +#include "macros.h" + +/* give up the (fake) lock after 3 tries at getting it */ +int pthread_mutex_trylock(pthread_mutex_t *mutex) { + static int loops = 0; + if(loops < 3) { + loops++; + return -1; + } + loops = 0; + return 0; + } + +/* Loads of variables + stubbed functions */ +char *config_file = "etc/nagios.cfg"; +int test_scheduling; + +time_t program_start; +time_t event_start; +time_t last_command_check; + +int sigshutdown = FALSE; +int sigrestart = FALSE; + +double sleep_time; +int interval_length = 60; +int service_inter_check_delay_method; +int host_inter_check_delay_method; +int service_interleave_factor_method; +int max_host_check_spread; +int max_service_check_spread; + +int command_check_interval; +int check_reaper_interval; +int service_freshness_check_interval; +int host_freshness_check_interval; +int auto_rescheduling_interval; +int host_freshness_check_interval; +int auto_rescheduling_interval; +int auto_rescheduling_window; + +int check_external_commands; +int check_orphaned_services; +int check_orphaned_hosts; +int check_service_freshness; +int check_host_freshness; +int auto_reschedule_checks; + +int retain_state_information; +int retention_update_interval; + +int max_parallel_service_checks; +int currently_running_service_checks; + +int aggregate_status_updates; +int status_update_interval; + +int log_rotation_method; + +int service_check_timeout; + +int execute_service_checks = 1; +int execute_host_checks; + +int child_processes_fork_twice; + +int time_change_threshold; + + +host *host_list; +service *service_list; + +int check_for_expired_comment(unsigned long temp_long) {} +void broker_timed_event(int int1, int int2, int int3, timed_event *timed_event1, struct timeval *timeval1) {} +int check_for_expired_downtime(void) {} +int check_for_nagios_updates(int int1, int int2) {} +time_t get_next_service_notification_time(service *temp_service, time_t time_t1) {} +int save_state_information(int int1) {} +int check_for_external_commands(void) {} +int check_time_against_period(time_t time_t1, timeperiod *timeperiod) {} +time_t get_next_log_rotation_time(void) {} +int handle_scheduled_downtime_by_id(unsigned long long1) {} +#ifndef TEST_LOGGING +int log_host_event(host *hst) {} +int log_service_event_flag = 0; +int log_service_event(service *svc) { + log_service_event_flag++; + } +int rotate_log_file(time_t time_t1) {} +void logit(int int1, int int2, const char *fmt, ...) {} +#endif +time_t get_next_host_notification_time(host *temp_host, time_t time_t1) {} +void get_next_valid_time(time_t time_t1, time_t *time_t2, timeperiod *temp_timeperiod) {} + + +char *log_file = "var/nagios.log"; +char *temp_file = ""; +char *log_archive_path = "var"; +host *host_list = NULL; +service *service_list = NULL; +int use_syslog = 0; +int log_service_retries; +int log_initial_states; +unsigned long logging_options = NSLOG_PROCESS_INFO; +unsigned long syslog_options; +int verify_config; +int test_scheduling; +time_t last_log_rotation; +int log_rotation_method; +int daemon_mode = TRUE; +char *debug_file = ""; +int debug_level; +int debug_verbosity; +unsigned long max_debug_file_size; + +int grab_host_macros_r(nagios_macros *mac, host *hst) {} + +int grab_service_macros_r(nagios_macros *mac, service *svc) {} + +void broker_log_data(int a, int b, int c, char *d, unsigned long e, time_t f, struct timeval *g) {} + +int clear_volatile_macros_r(nagios_macros *mac) {} +int clear_service_macros_r(nagios_macros *mac) {} +int clear_host_macros_r(nagios_macros *mac) {} + +int process_macros(char *a, char **b, int c) {} +int process_macros_r(nagios_macros *mac, char *a, char **b, int c) {} + +int update_host_status(host *hst, int aggregated_dump) {} +int update_service_status(service *svc, int aggregated_dump) {} +int update_all_status_data(void) {} +char *check_result_path = NULL; +int process_check_result_queue(char *dirname) {} +service * find_service(char *host_name, char *svc_desc) {} +int delete_check_result_file(char *fname) {} +int free_check_result(check_result *info) {} +host * find_host(char *name) {} +int max_check_reaper_time = DEFAULT_MAX_REAPER_TIME; +check_result *read_check_result(void) {} +int broker_service_check(int type, int flags, int attr, service *svc, int check_type, struct timeval start_time, struct timeval end_time, char *cmd, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, struct timeval *timestamp) {} +int get_raw_command_line(command *a, char *b, char **c, int d) {} +int get_raw_command_line_r(nagios_macros *mac, command *a, char *b, char **c, int d) {} +check_result check_result_info; +char *temp_path; +int dbuf_init(dbuf *db, int chunk_size) {} +int update_check_stats(int check_type, time_t check_time) {} +int set_all_macro_environment_vars_r(nagios_macros *mac, int set) {} +int close_command_file(void) {} +void reset_sighandler(void) {} +void service_check_sighandler(int sig) {} +unsigned long max_debug_file_size = DEFAULT_MAX_DEBUG_FILE_SIZE; +int host_check_timeout = DEFAULT_HOST_CHECK_TIMEOUT; +int broker_host_check(int type, int flags, int attr, host *hst, int check_type, int state, int state_type, struct timeval start_time, struct timeval end_time, char *cmd, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, char *output, char *long_output, char *perfdata, struct timeval *timestamp) {} +char *escape_newlines(char *rawbuf) {} +int dbuf_strcat(dbuf *db, char *buf) {} +int dbuf_free(dbuf *db) {} +unsigned long next_event_id = 0L; +unsigned long next_problem_id = 0L; +int move_check_result_to_queue(char *checkresult_file) {} +int free_child_process_memory = -1; +void free_memory(nagios_macros *mac) {} +int accept_passive_service_checks = TRUE; +int log_passive_checks = TRUE; +int use_aggressive_host_checking = FALSE; +int handle_service_event(service *svc) {} +unsigned long cached_host_check_horizon = DEFAULT_CACHED_HOST_CHECK_HORIZON; +void check_for_service_flapping(service *svc, int update, int allow_flapstart_notification) {} +void check_for_host_flapping(host *hst, int update, int actual_check, int allow_flapstart_notification) {} +int service_notification(service *svc, int type, char *not_author, char *not_data, int options) {} +int obsess_over_services = FALSE; +int obsessive_compulsive_service_check_processor(service *svc) {} +int host_notification(host *hst, int type, char *not_author, char *not_data, int options) {} +int enable_predictive_service_dependency_checks = DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS; +servicedependency *get_first_servicedependency_by_dependent_service(char *host_name, char *svc_description, void **ptr) {} +servicedependency *get_next_servicedependency_by_dependent_service(char *host_name, char *svc_description, void **ptr) {} +int add_object_to_objectlist(objectlist **list, void *object_ptr) {} +int check_pending_flex_service_downtime(service *svc) {} +int compare_strings(char *val1a, char *val2a) {} +int update_service_performance_data(service *svc) {} +int free_objectlist(objectlist **temp_list) {} +unsigned long cached_service_check_horizon = DEFAULT_CACHED_SERVICE_CHECK_HORIZON; +timed_event *event_list_low = NULL; +timed_event *event_list_low_tail = NULL; +void remove_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) {} +void reschedule_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) {} +int process_passive_service_check(time_t check_time, char *host_name, char *svc_description, int return_code, char *output) {} +void process_passive_checks(void) {} +int soft_state_dependencies = FALSE; +int additional_freshness_latency = DEFAULT_ADDITIONAL_FRESHNESS_LATENCY; +hostdependency *get_first_hostdependency_by_dependent_host(char *host_name, void **ptr) { + /* Return NULL so check_host_dependencies returns back */ + return NULL; + } +hostdependency *get_next_hostdependency_by_dependent_host(char *host_name, void **ptr) {} +int currently_running_host_checks = 0; +int my_system_r(nagios_macros *mac, char *cmd, int timeout, int *early_timeout, double *exectime, char **output, int max_output_length) {} +void host_check_sighandler(int sig) {} +int accept_passive_host_checks = TRUE; +int passive_host_checks_are_soft = DEFAULT_PASSIVE_HOST_CHECKS_SOFT; +int translate_passive_host_checks = DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS; +int enable_predictive_host_dependency_checks = DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS; + + +#endif diff --git a/t-tap/test_checks.c b/t-tap/test_checks.c new file mode 100644 index 0000000..2f0024a --- /dev/null +++ b/t-tap/test_checks.c @@ -0,0 +1,411 @@ +/***************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* +*****************************************************************************/ + +#define NSCORE 1 +#include "config.h" +#include "comments.h" +#include "common.h" +#include "statusdata.h" +#include "downtime.h" +#include "macros.h" +#include "nagios.h" +#include "broker.h" +#include "perfdata.h" +#include "tap.h" +#include "test-stubs.c" +#include "stub_sehandlers.c" +#include "stub_comments.c" +#include "stub_perfdata.c" +#include "stub_downtime.c" +#include "../common/shared.c" + +int log_host_retries = 0; +int date_format; + +/* Test specific functions + variables */ +service *svc1 = NULL, *svc2 = NULL; +host *host1 = NULL; +int found_log_rechecking_host_when_service_wobbles = 0; +int found_log_run_async_host_check_3x = 0; +check_result *tmp_check_result; + +void setup_check_result() { + struct timeval start_time, finish_time; + start_time.tv_sec = 1234567890L; + start_time.tv_usec = 0L; + finish_time.tv_sec = 1234567891L; + finish_time.tv_usec = 0L; + + tmp_check_result = (check_result *)malloc(sizeof(check_result)); + tmp_check_result->check_type = SERVICE_CHECK_ACTIVE; + tmp_check_result->check_options = 0; + tmp_check_result->scheduled_check = TRUE; + tmp_check_result->reschedule_check = TRUE; + tmp_check_result->exited_ok = TRUE; + tmp_check_result->return_code = 0; + tmp_check_result->output = strdup("Fake result"); + tmp_check_result->latency = 0.6969; + tmp_check_result->start_time = start_time; + tmp_check_result->finish_time = finish_time; + } + +int c = 0; +int update_program_status(int aggregated_dump) { + c++; + /* printf ("# In the update_program_status hook: %d\n", c); */ + + /* Set this to break out of event_execution_loop */ + if(c > 10) { + sigshutdown = TRUE; + c = 0; + } + } +int log_debug_info(int level, int verbosity, const char *fmt, ...) { + va_list ap; + char *buffer = NULL; + + va_start(ap, fmt); + /* vprintf( fmt, ap ); */ + vasprintf(&buffer, fmt, ap); + if(strcmp(buffer, "Service wobbled between non-OK states, so we'll recheck the host state...\n") == 0) { + found_log_rechecking_host_when_service_wobbles++; + } + if(strcmp(buffer, "run_async_host_check_3x()\n") == 0) { + found_log_run_async_host_check_3x++; + } + free(buffer); + va_end(ap); + } + + +void +setup_objects(time_t time) { + timed_event *new_event = NULL; + + enable_predictive_service_dependency_checks = FALSE; + + host1 = (host *)calloc(1, sizeof(host)); + host1->name = strdup("Host1"); + host1->address = strdup("127.0.0.1"); + host1->retry_interval = 1; + host1->check_interval = 5; + host1->check_options = 0; + host1->state_type = SOFT_STATE; + host1->current_state = HOST_DOWN; + host1->has_been_checked = TRUE; + host1->last_check = time; + host1->next_check = time; + + /* First service is a normal one */ + svc1 = (service *)calloc(1, sizeof(service)); + svc1->host_name = strdup("Host1"); + svc1->host_ptr = host1; + svc1->description = strdup("Normal service"); + svc1->check_options = 0; + svc1->next_check = time; + svc1->state_type = SOFT_STATE; + svc1->current_state = STATE_CRITICAL; + svc1->retry_interval = 1; + svc1->check_interval = 5; + svc1->current_attempt = 1; + svc1->max_attempts = 4; + svc1->last_state_change = 0; + svc1->last_state_change = 0; + svc1->last_check = (time_t)1234560000; + svc1->host_problem_at_last_check = FALSE; + svc1->plugin_output = strdup("Initial state"); + svc1->last_hard_state_change = (time_t)1111111111; + + /* Second service .... to be configured! */ + svc2 = (service *)calloc(1, sizeof(service)); + svc2->host_name = strdup("Host1"); + svc2->description = strdup("To be nudged"); + svc2->check_options = 0; + svc2->next_check = time; + svc2->state_type = SOFT_STATE; + svc2->current_state = STATE_OK; + svc2->retry_interval = 1; + svc2->check_interval = 5; + + } + +int +main(int argc, char **argv) { + time_t now = 0L; + + + plan_tests(42); + + time(&now); + + + /* Test to confirm that if a service is warning, the notified_on_critical is reset */ + tmp_check_result = (check_result *)calloc(1, sizeof(check_result)); + tmp_check_result->host_name = strdup("host1"); + tmp_check_result->service_description = strdup("Normal service"); + tmp_check_result->object_check_type = SERVICE_CHECK; + tmp_check_result->check_type = SERVICE_CHECK_ACTIVE; + tmp_check_result->check_options = 0; + tmp_check_result->scheduled_check = TRUE; + tmp_check_result->reschedule_check = TRUE; + tmp_check_result->latency = 0.666; + tmp_check_result->start_time.tv_sec = 1234567890; + tmp_check_result->start_time.tv_usec = 56565; + tmp_check_result->finish_time.tv_sec = 1234567899; + tmp_check_result->finish_time.tv_usec = 45454; + tmp_check_result->early_timeout = 0; + tmp_check_result->exited_ok = TRUE; + tmp_check_result->return_code = 1; + tmp_check_result->output = strdup("Warning - check notified_on_critical reset"); + + setup_objects(now); + svc1->last_state = STATE_CRITICAL; + svc1->notified_on_critical = TRUE; + svc1->current_notification_number = 999; + svc1->last_notification = (time_t)11111; + svc1->next_notification = (time_t)22222; + svc1->no_more_notifications = TRUE; + + handle_async_service_check_result(svc1, tmp_check_result); + + /* This has been taken out because it is not required + ok( svc1->notified_on_critical==FALSE, "notified_on_critical reset" ); + */ + ok(svc1->last_notification == (time_t)0, "last notification reset due to state change"); + ok(svc1->next_notification == (time_t)0, "next notification reset due to state change"); + ok(svc1->no_more_notifications == FALSE, "no_more_notifications reset due to state change"); + ok(svc1->current_notification_number == 999, "notification number NOT reset"); + + /* Test case: + service that transitions from OK to CRITICAL (where its host is set to DOWN) will get set to a hard state + even though check attempts = 1 of 4 + */ + setup_objects((time_t) 1234567800L); + host1->current_state = HOST_DOWN; + svc1->current_state = STATE_OK; + svc1->state_type = HARD_STATE; + setup_check_result(); + tmp_check_result->return_code = STATE_CRITICAL; + tmp_check_result->output = strdup("CRITICAL failure"); + log_service_event_flag = 0; + + handle_async_service_check_result(svc1, tmp_check_result); + + ok(log_service_event_flag == 1, "log_service_event() was called"); + ok(svc1->last_hard_state_change == (time_t)1234567890, "Got last_hard_state_change time=%lu", svc1->last_hard_state_change); + ok(svc1->last_state_change == svc1->last_hard_state_change, "Got same last_state_change"); + ok(svc1->last_hard_state == 2, "Should save the last hard state as critical for next time"); + ok(svc1->host_problem_at_last_check == TRUE, "Got host_problem_at_last_check set to TRUE due to host failure - this needs to be saved otherwise extra alerts raised in subsequent runs"); + ok(svc1->state_type == HARD_STATE, "This should be a HARD state since the host is in a failure state"); + ok(svc1->current_attempt == 1, "Previous status was OK, so this failure should show current_attempt=1") || diag("Current attempt=%d", svc1->current_attempt); + + + + + + /* Test case: + OK -> WARNING 1/4 -> ack -> WARNING 2/4 -> OK transition + Tests that the ack is left for 2/4 + */ + setup_objects(now); + host1->current_state = HOST_UP; + host1->max_attempts = 4; + svc1->last_state = STATE_OK; + svc1->last_hard_state = STATE_OK; + svc1->current_state = STATE_OK; + svc1->state_type = SOFT_STATE; + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure"); + handle_async_service_check_result(svc1, tmp_check_result); + + ok(svc1->last_notification == (time_t)0, "last notification reset due to state change"); + ok(svc1->next_notification == (time_t)0, "next notification reset due to state change"); + ok(svc1->no_more_notifications == FALSE, "no_more_notifications reset due to state change"); + ok(svc1->current_notification_number == 0, "notification number reset"); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "No acks"); + + svc1->acknowledgement_type = ACKNOWLEDGEMENT_NORMAL; + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure"); + handle_async_service_check_result(svc1, tmp_check_result); + + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack left"); + + setup_check_result(); + tmp_check_result->return_code = STATE_OK; + tmp_check_result->output = strdup("Back to OK"); + handle_async_service_check_result(svc1, tmp_check_result); + + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "Ack reset to none"); + + + + + /* Test case: + OK -> WARNING 1/4 -> ack -> WARNING 2/4 -> WARNING 3/4 -> WARNING 4/4 -> WARNING 4/4 -> OK transition + Tests that the ack is not removed on hard state change + */ + setup_objects(now); + host1->current_state = HOST_UP; + host1->max_attempts = 4; + svc1->last_state = STATE_OK; + svc1->last_hard_state = STATE_OK; + svc1->current_state = STATE_OK; + svc1->state_type = SOFT_STATE; + svc1->current_attempt = 1; + + setup_check_result(); + tmp_check_result->return_code = STATE_OK; + tmp_check_result->output = strdup("Reset to OK"); + handle_async_service_check_result(svc1, tmp_check_result); + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure 1"); + handle_async_service_check_result(svc1, tmp_check_result); + + ok(svc1->state_type == SOFT_STATE, "Soft state"); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "No acks - testing transition to hard warning state"); + + svc1->acknowledgement_type = ACKNOWLEDGEMENT_NORMAL; + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure 2"); + handle_async_service_check_result(svc1, tmp_check_result); + ok(svc1->state_type == SOFT_STATE, "Soft state"); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack left"); + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure 3"); + handle_async_service_check_result(svc1, tmp_check_result); + ok(svc1->state_type == SOFT_STATE, "Soft state"); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack left"); + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure 4"); + handle_async_service_check_result(svc1, tmp_check_result); + ok(svc1->state_type == HARD_STATE, "Hard state"); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack left on hard failure"); + + setup_check_result(); + tmp_check_result->return_code = STATE_OK; + tmp_check_result->output = strdup("Back to OK"); + handle_async_service_check_result(svc1, tmp_check_result); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "Ack removed"); + + + + + /* Test case: + OK -> WARNING 1/1 -> ack -> WARNING -> OK transition + Tests that the ack is not removed on 2nd warning, but is on OK + */ + setup_objects(now); + host1->current_state = HOST_UP; + host1->max_attempts = 4; + svc1->last_state = STATE_OK; + svc1->last_hard_state = STATE_OK; + svc1->current_state = STATE_OK; + svc1->state_type = SOFT_STATE; + svc1->current_attempt = 1; + svc1->max_attempts = 2; + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure 1"); + + handle_async_service_check_result(svc1, tmp_check_result); + + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "No acks - testing transition to immediate hard then OK"); + + svc1->acknowledgement_type = ACKNOWLEDGEMENT_NORMAL; + + setup_check_result(); + tmp_check_result->return_code = STATE_WARNING; + tmp_check_result->output = strdup("WARNING failure 2"); + handle_async_service_check_result(svc1, tmp_check_result); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack left"); + + setup_check_result(); + tmp_check_result->return_code = STATE_OK; + tmp_check_result->output = strdup("Back to OK"); + handle_async_service_check_result(svc1, tmp_check_result); + ok(svc1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "Ack removed"); + + + /* Test case: + UP -> DOWN 1/4 -> ack -> DOWN 2/4 -> DOWN 3/4 -> DOWN 4/4 -> UP transition + Tests that the ack is not removed on 2nd DOWN, but is on UP + */ + setup_objects(now); + host1->current_state = HOST_UP; + host1->last_state = HOST_UP; + host1->last_hard_state = HOST_UP; + host1->state_type = SOFT_STATE; + host1->current_attempt = 1; + host1->max_attempts = 4; + host1->acknowledgement_type = ACKNOWLEDGEMENT_NONE; + host1->plugin_output = strdup(""); + host1->long_plugin_output = strdup(""); + host1->perf_data = strdup(""); + host1->host_check_command = strdup("Dummy command required"); + host1->accept_passive_host_checks = TRUE; + passive_host_checks_are_soft = TRUE; + setup_check_result(); + + tmp_check_result->return_code = STATE_CRITICAL; + tmp_check_result->output = strdup("DOWN failure 2"); + tmp_check_result->check_type = HOST_CHECK_PASSIVE; + handle_async_host_check_result_3x(host1, tmp_check_result); + ok(host1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "No ack set"); + ok(host1->current_attempt == 2, "Attempts right (not sure why this goes into 2 and not 1)") || diag("current_attempt=%d", host1->current_attempt); + ok(strcmp(host1->plugin_output, "DOWN failure 2") == 0, "output set") || diag("plugin_output=%s", host1->plugin_output); + + host1->acknowledgement_type = ACKNOWLEDGEMENT_NORMAL; + + tmp_check_result->output = strdup("DOWN failure 3"); + handle_async_host_check_result_3x(host1, tmp_check_result); + ok(host1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack should be retained as in soft state"); + ok(host1->current_attempt == 3, "Attempts incremented") || diag("current_attempt=%d", host1->current_attempt); + ok(strcmp(host1->plugin_output, "DOWN failure 3") == 0, "output set") || diag("plugin_output=%s", host1->plugin_output); + + + tmp_check_result->output = strdup("DOWN failure 4"); + handle_async_host_check_result_3x(host1, tmp_check_result); + ok(host1->acknowledgement_type == ACKNOWLEDGEMENT_NORMAL, "Ack should be retained as in soft state"); + ok(host1->current_attempt == 4, "Attempts incremented") || diag("current_attempt=%d", host1->current_attempt); + ok(strcmp(host1->plugin_output, "DOWN failure 4") == 0, "output set") || diag("plugin_output=%s", host1->plugin_output); + + + tmp_check_result->return_code = STATE_OK; + tmp_check_result->output = strdup("UP again"); + handle_async_host_check_result_3x(host1, tmp_check_result); + ok(host1->acknowledgement_type == ACKNOWLEDGEMENT_NONE, "Ack reset due to state change"); + ok(host1->current_attempt == 1, "Attempts reset") || diag("current_attempt=%d", host1->current_attempt); + ok(strcmp(host1->plugin_output, "UP again") == 0, "output set") || diag("plugin_output=%s", host1->plugin_output); + + + return exit_status(); + } + diff --git a/t-tap/test_commands.c b/t-tap/test_commands.c new file mode 100644 index 0000000..5b16ac9 --- /dev/null +++ b/t-tap/test_commands.c @@ -0,0 +1,212 @@ +/***************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* +*****************************************************************************/ + +#define NSCORE 1 +#include "config.h" +#include "common.h" +#include "nagios.h" +#include "../base/commands.c" +#include "stub_broker.c" +#include "stub_comments.c" +#include "stub_objects.c" +#include "stub_statusdata.c" +#include "stub_notifications.c" +#include "stub_events.c" +#include "stub_downtime.c" +#include "stub_flapping.c" +#include "stub_logging.c" +#include "stub_utils.c" +#include "stub_sretention.c" +#include "stub_checks.c" +#include "tap.h" + +void logit(int data_type, int display, const char *fmt, ...) {} +int log_debug_info(int level, int verbosity, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + /* vprintf( fmt, ap ); */ + va_end(ap); + } + +circular_buffer external_command_buffer; +time_t last_command_check; +int external_command_buffer_slots; +char *temp_path; +int date_format; +host *host_list; +service *service_list; +int accept_passive_service_checks; +time_t last_command_status_update; +int check_host_freshness; +int check_service_freshness; +int check_external_commands; +unsigned long modified_host_process_attributes; +unsigned long modified_service_process_attributes; +int enable_notifications; +int obsess_over_hosts; +int obsess_over_services; +int execute_service_checks; +int enable_event_handlers; +int accept_passive_host_checks; +int accept_passive_service_checks; +int enable_failure_prediction; +int process_performance_data; +int execute_host_checks; +int execute_service_checks; +char *global_service_event_handler; +command *global_service_event_handler_ptr; +char *global_host_event_handler; +command *global_host_event_handler_ptr; + +/* Catch lower calls through these stubs */ +time_t test_start_time = 0L; +char *test_hostname; +char *test_servicename; +char *test_comment = NULL; +int deleted = 1; +scheduled_downtime *find_host_downtime_by_name(char *hostname) {} +scheduled_downtime *find_host_service_downtime_by_name(char *hostname, char *service_description) {} +int delete_downtime_by_start_time_comment(time_t start_time, char *comment) { + test_start_time = start_time; + test_comment = comment; + return deleted; + } + +int delete_downtime_by_hostname_service_description_start_time_comment(char *hostname, char *service_description, time_t start_time, char *comment) { + test_hostname = hostname; + test_servicename = service_description; + test_start_time = start_time; + test_comment = comment; + return deleted; + } + +void reset_vars() { + test_start_time = 0L; + test_hostname = NULL; + test_servicename = NULL; + test_comment = NULL; + } + +hostgroup *temp_hostgroup = NULL; + +int +main() { + time_t now = 0L; + + plan_tests(62); + + ok(test_start_time == 0L, "Start time is empty"); + ok(test_comment == NULL, "And test_comment is blank"); + + ok(cmd_delete_downtime_by_start_time_comment(1, "1234567890;This is a comment") == OK, "cmd_delete_downtime_by_start_time_comment"); + ok(test_start_time == 1234567890L, "Start time called correctly"); + ok(strcmp(test_comment, "This is a comment") == 0, "comment set correctly"); + + ok(cmd_delete_downtime_by_start_time_comment(1, "") == ERROR, "cmd_delete_downtime_by_start_time_comment errors if no args sent"); + + ok(cmd_delete_downtime_by_start_time_comment(1, "1234;Comment;") == OK, "cmd_delete_downtime_by_start_time_comment"); + ok(test_start_time == 1234, "Silly start time parsed but will get rejected lower down"); + ok(strcmp(test_comment, "Comment;") == 0, "Comment with ; will get dropped: '%s' <--- not sure if this should be true or not", test_comment); + + ok(cmd_delete_downtime_by_start_time_comment(1, "1234;Comment with \n in it;") == OK, "cmd_delete_downtime_by_start_time_comment"); + ok(strcmp(test_comment, "Comment with ") == 0, "Comment truncated at \\n") || diag("comment=%s", test_comment); + + ok(cmd_delete_downtime_by_start_time_comment(1, ";") == ERROR, "cmd_delete_downtime_by_start_time_comment error due to no args"); + + test_start_time = 0L; + test_comment = "somethingelse"; + ok(cmd_delete_downtime_by_start_time_comment(1, "badtime") == ERROR, "cmd_delete_downtime_by_start_time_comment error due to bad time value"); + + ok(cmd_delete_downtime_by_start_time_comment(1, "123badtime;comment") == OK, "cmd_delete_downtime_by_start_time_comment"); + ok(test_start_time == 123L, "Partly bad start time is parsed, but that's an input problem"); + ok(strcmp(test_comment, "comment") == 0, "Comment"); + + ok(cmd_delete_downtime_by_start_time_comment(1, ";commentonly") == OK, "cmd_delete_downtime_by_start_time_comment"); + ok(test_start_time == 0L, "No start time, but comment is set"); + ok(strcmp(test_comment, "commentonly") == 0, "Comment"); + + deleted = 0; + ok(cmd_delete_downtime_by_start_time_comment(1, ";commentonly") == ERROR, "Got an error here because no items deleted"); + + + /* Test deletion of downtimes by name */ + ok(cmd_delete_downtime_by_host_name(1, "") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no args set"); + + ok(cmd_delete_downtime_by_host_name(1, ";svc;1234567890;Some comment") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 0, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(test_servicename == NULL, "servicename right"); + ok(test_comment == NULL, "comment right"); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;svc1;;") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 0, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(strcmp(test_servicename, "svc1") == 0, "servicename right"); + ok(test_comment == NULL, "comment right") || diag("comment=%s", test_comment); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;svc1") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 0, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(strcmp(test_servicename, "svc1") == 0, "servicename right"); + ok(test_comment == NULL, "comment right") || diag("comment=%s", test_comment); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;svc1;1234567;") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 1234567L, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(strcmp(test_servicename, "svc1") == 0, "servicename right"); + ok(test_comment == NULL, "comment right") || diag("comment=%s", test_comment); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;svc1;12345678") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 12345678L, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(strcmp(test_servicename, "svc1") == 0, "servicename right"); + ok(test_comment == NULL, "comment right") || diag("comment=%s", test_comment); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;;12345678;comment too") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 12345678, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(test_servicename == NULL, "servicename right") || diag("servicename=%s", test_servicename); + ok(strcmp(test_comment, "comment too") == 0, "comment right") || diag("comment=%s", test_comment); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;;12345678;") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 12345678, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(test_servicename == NULL, "servicename right") || diag("servicename=%s", test_servicename); + ok(test_comment == NULL, "comment right") || diag("comment=%s", test_comment); + + reset_vars(); + ok(cmd_delete_downtime_by_host_name(1, "host1;;;comment") == ERROR, "cmd_delete_downtime_by_start_time_comment - errors if no host name set"); + ok(test_start_time == 0L, "start time right"); + ok(strcmp(test_hostname, "host1") == 0, "hostname right"); + ok(test_servicename == NULL, "servicename right") || diag("servicename=%s", test_servicename); + ok(strcmp(test_comment, "comment") == 0, "comment right") || diag("comment=%s", test_comment); + + + + return exit_status(); + } + diff --git a/t-tap/test_downtime.c b/t-tap/test_downtime.c new file mode 100644 index 0000000..5bc1887 --- /dev/null +++ b/t-tap/test_downtime.c @@ -0,0 +1,179 @@ +/***************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* +*****************************************************************************/ + +#define NSCORE 1 +#include "config.h" +#include "common.h" +#include "nagios.h" +#include "downtime.h" +#include "stub_broker.c" +#include "stub_comments.c" +#include "stub_objects.c" +#include "stub_statusdata.c" +#include "stub_notifications.c" +#include "stub_shared.c" +#include "stub_events.c" +#include "tap.h" + +void logit(int data_type, int display, const char *fmt, ...) {} +int log_debug_info(int level, int verbosity, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + /* vprintf( fmt, ap ); */ + va_end(ap); + } + +timed_event *event_list_high = NULL; +timed_event *event_list_high_tail = NULL; + +unsigned long next_downtime_id = 1L; + +extern scheduled_downtime *scheduled_downtime_list; + +int +main(int argc, char **argv) { + time_t now = 0L; + time_t temp_start_time = 1234567890L; + time_t temp_end_time = 2134567890L; + unsigned long downtime_id = 0L; + scheduled_downtime *temp_downtime; + int i = 0; + + plan_tests(38); + + time(&now); + + schedule_downtime(HOST_DOWNTIME, "host1", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 1L, "Got host1 downtime: %lu", downtime_id); + schedule_downtime(HOST_DOWNTIME, "host2", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 2L, "Got host2 downtime: %lu", downtime_id); + schedule_downtime(HOST_DOWNTIME, "host3", NULL, temp_start_time, "user", "diff comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 3L, "Got host3 downtime: %lu", downtime_id); + schedule_downtime(HOST_DOWNTIME, "host4", NULL, temp_start_time, "user", "test comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 4L, "Got host4 downtime: %lu", downtime_id); + + schedule_downtime(SERVICE_DOWNTIME, "host1", "svc", temp_start_time, "user", "svc comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 5L, "Got host1::svc downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host2", "svc", temp_start_time, "user", "diff comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 6L, "Got host2::svc downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host3", "svc", temp_start_time, "user", "svc comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 7L, "Got host3::svc downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host4", "svc", temp_start_time, "user", "uniq comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 8L, "Got host4::svc downtime: %lu", downtime_id); + + for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} + ok(i == 8, "Got 8 downtimes: %d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, 0, NULL); + ok(i == 0, "No deletions") || diag("%d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, 0, NULL); + ok(i == 0, "No deletions"); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, temp_start_time, "test comment"); + ok(i == 2, "Deleted 2 downtimes"); + + for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} + ok(i == 6, "Got 6 downtimes left: %d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, temp_start_time + 200, "test comment"); + ok(i == 0, "Nothing matched, so 0 downtimes deleted"); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, temp_start_time + 1, NULL); + ok(i == 2, "Deleted 2 by start_time only: %d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, 0, "uniq comment"); + ok(i == 1, "Deleted 1 by unique comment: %d", i); + + for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) { + diag("downtime id: %d", temp_downtime->downtime_id); + } + ok(i == 3, "Got 3 downtimes left: %d", i); + + unschedule_downtime(HOST_DOWNTIME, 3); + unschedule_downtime(SERVICE_DOWNTIME, 5); + unschedule_downtime(SERVICE_DOWNTIME, 6); + + for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} + ok(i == 0, "No downtimes left"); + + + /* Set all downtimes up again */ + schedule_downtime(HOST_DOWNTIME, "host1", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 9L, "Got host1 downtime: %lu", downtime_id); + schedule_downtime(HOST_DOWNTIME, "host2", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 10L, "Got host2 downtime: %lu", downtime_id); + schedule_downtime(HOST_DOWNTIME, "host3", NULL, temp_start_time, "user", "diff comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 11L, "Got host3 downtime: %lu", downtime_id); + schedule_downtime(HOST_DOWNTIME, "host4", NULL, temp_start_time, "user", "test comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 12L, "Got host4 downtime: %lu", downtime_id); + + schedule_downtime(SERVICE_DOWNTIME, "host1", "svc", temp_start_time, "user", "svc comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 13L, "Got host1::svc downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host2", "svc", temp_start_time, "user", "diff comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 14L, "Got host2::svc downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host3", "svc", temp_start_time, "user", "svc comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 15L, "Got host3::svc downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host4", "svc", temp_start_time, "user", "uniq comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 16L, "Got host4::svc downtime: %lu", downtime_id); + + schedule_downtime(SERVICE_DOWNTIME, "host1", "svc2", temp_start_time, "user", "svc2 comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 17L, "Got host1::svc2 downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host2", "svc2", temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 18L, "Got host2::svc2 downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host3", "svc2", temp_start_time, "user", "svc2 comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 19L, "Got host3::svc2 downtime: %lu", downtime_id); + schedule_downtime(SERVICE_DOWNTIME, "host4", "svc2", temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); + ok(downtime_id == 20L, "Got host4::svc2 downtime: %lu", downtime_id); + + i = delete_downtime_by_hostname_service_description_start_time_comment("host2", NULL, 0, "test comment"); + ok(i == 2, "Deleted 2"); + + i = delete_downtime_by_hostname_service_description_start_time_comment("host1", "svc", 0, NULL); + ok(i == 1, "Deleted 1") || diag("Actually deleted: %d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment("host3", NULL, temp_start_time + 1, NULL); + ok(i == 2, "Deleted 2"); + + i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, "svc2", 0, NULL); + ok(i == 2, "Deleted 2") || diag("Actually deleted: %d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment("host4", NULL, 0, "test comment"); + ok(i == 1, "Deleted 1") || diag("Actually deleted: %d", i); + + i = delete_downtime_by_hostname_service_description_start_time_comment("host4", NULL, 0, "svc comment"); + ok(i == 0, "Deleted 0") || diag("Actually deleted: %d", i); + + for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) { + diag("downtime id: %d", temp_downtime->downtime_id); + } + ok(i == 4, "Got 4 downtimes left: %d", i); + + unschedule_downtime(HOST_DOWNTIME, 9); + unschedule_downtime(SERVICE_DOWNTIME, 14); + unschedule_downtime(SERVICE_DOWNTIME, 15); + unschedule_downtime(SERVICE_DOWNTIME, 16); + + for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} + ok(i == 0, "No downtimes left") || diag("Left: %d", i); + + + + return exit_status(); + } + diff --git a/t-tap/test_each.t b/t-tap/test_each.t new file mode 100755 index 0000000..79e1c53 --- /dev/null +++ b/t-tap/test_each.t @@ -0,0 +1,7 @@ +#!/usr/bin/perl +use Test::More; +$_ = shift @ARGV or die "Must specify a file"; +if (! -e "$_") { + plan skip_all => "$_ not compiled - please install tap library to test"; +} +system "./$_"; diff --git a/t-tap/test_events.c b/t-tap/test_events.c new file mode 100644 index 0000000..e71990e --- /dev/null +++ b/t-tap/test_events.c @@ -0,0 +1,319 @@ +/***************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* +*****************************************************************************/ + +#define NSCORE 1 +#include "config.h" +#include "common.h" +#include "downtime.h" +#include "comments.h" +#include "statusdata.h" +#include "nagios.h" +#include "broker.h" +#include "sretention.h" +#include "tap.h" + +char *config_file = "etc/nagios.cfg"; +int test_scheduling; + +time_t program_start; +time_t event_start; +time_t last_command_check; + +int sigshutdown = FALSE; +int sigrestart = FALSE; + +double sleep_time; +int interval_length = 60; +int service_inter_check_delay_method; +int host_inter_check_delay_method; +int service_interleave_factor_method; +int max_host_check_spread; +int max_service_check_spread; + +int command_check_interval; +int check_reaper_interval; +int service_freshness_check_interval; +int host_freshness_check_interval; +int auto_rescheduling_interval; +int host_freshness_check_interval; +int auto_rescheduling_interval; +int auto_rescheduling_window; + +int check_external_commands; +int check_orphaned_services; +int check_orphaned_hosts; +int check_service_freshness; +int check_host_freshness; +int auto_reschedule_checks; + +int retain_state_information; +int retention_update_interval; + +int max_parallel_service_checks; +int currently_running_service_checks; + +int aggregate_status_updates; +int status_update_interval; + +int log_rotation_method; + +int service_check_timeout; + +int execute_service_checks = 1; +int execute_host_checks; + +int child_processes_fork_twice; + +int time_change_threshold; + + +extern timed_event *event_list_low; +extern timed_event *event_list_low_tail; +extern timed_event *event_list_high; +extern timed_event *event_list_high_tail; + +host *host_list; +service *service_list; + +int check_for_expired_comment(unsigned long temp_long) {} +void broker_timed_event(int int1, int int2, int int3, timed_event *timed_event1, struct timeval *timeval1) {} +int perform_scheduled_host_check(host *temp_host, int int1, double double1) { + time_t now = 0L; + time(&now); + temp_host->last_check = now; + } +int check_for_expired_downtime(void) {} +int reap_check_results(void) {} +void check_host_result_freshness() {} +int check_for_nagios_updates(int int1, int int2) {} +time_t get_next_service_notification_time(service *temp_service, time_t time_t1) {} +int save_state_information(int int1) {} +void get_time_breakdown(unsigned long long1, int *int1, int *int2, int *int3, int *int4) {} +int check_for_external_commands(void) {} +void check_for_orphaned_hosts() {} +void check_service_result_freshness() {} +int check_time_against_period(time_t time_t1, timeperiod *timeperiod) {} +time_t get_next_log_rotation_time(void) {} +void check_for_orphaned_services() {} +int run_scheduled_service_check(service *service1, int int1, double double1) { + currently_running_service_checks++; + time_t now = 0L; + time(&now); + service1->last_check = now; + /* printf("Currently running service checks: %d\n", currently_running_service_checks); */ + } +int handle_scheduled_downtime_by_id(unsigned long long1) {} +int rotate_log_file(time_t time_t1) {} +time_t get_next_host_notification_time(host *temp_host, time_t time_t1) {} +void get_next_valid_time(time_t time_t1, time_t *time_t2, timeperiod *temp_timeperiod) {} +void logit(int int1, int int2, const char *fmt, ...) {} + +int c = 0; +int update_program_status(int aggregated_dump) { + c++; + /* printf ("# In the update_program_status hook: %d\n", c); */ + + /* Set this to break out of event_execution_loop */ + if(c > 10) { + sigshutdown = TRUE; + c = 0; + } + } +int update_service_status(service *svc, int aggregated_dump) {} +int update_all_status_data(void) {} +int log_debug_info(int level, int verbosity, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + /* vprintf( fmt, ap ); */ + va_end(ap); + } +int update_host_status(host *hst, int aggregated_dump) {} + +/* Test variables */ +service *svc1 = NULL, *svc2 = NULL, *svc3 = NULL; +host *host1 = NULL; + +void +setup_events(time_t time) { + timed_event *new_event = NULL; + + /* First service is a normal one */ + svc1 = (service *)malloc(sizeof(service)); + svc1->host_name = strdup("Host1"); + svc1->description = strdup("Normal service"); + svc1->check_options = 0; + svc1->next_check = time; + svc1->state_type = SOFT_STATE; + svc1->current_state = STATE_OK; + svc1->retry_interval = 1; + svc1->check_interval = 5; + + new_event = (timed_event *)malloc(sizeof(timed_event)); + new_event->event_type = EVENT_SERVICE_CHECK; + new_event->event_data = (void *)svc1; + new_event->event_args = (void *)NULL; + new_event->event_options = 0; + new_event->run_time = 0L; /* Straight away */ + new_event->recurring = FALSE; + new_event->event_interval = 0L; + new_event->timing_func = NULL; + new_event->compensate_for_time_change = TRUE; + reschedule_event(new_event, &event_list_low, &event_list_low_tail); + + /* Second service is one that will get nudged forward */ + svc2 = (service *)malloc(sizeof(service)); + svc2->host_name = strdup("Host1"); + svc2->description = strdup("To be nudged"); + svc2->check_options = 0; + svc2->next_check = time; + svc2->state_type = SOFT_STATE; + svc2->current_state = STATE_OK; + svc2->retry_interval = 1; + svc2->check_interval = 5; + + new_event = (timed_event *)malloc(sizeof(timed_event)); + new_event->event_type = EVENT_SERVICE_CHECK; + new_event->event_data = (void *)svc2; + new_event->event_args = (void *)NULL; + new_event->event_options = 0; + new_event->run_time = 0L; /* Straight away */ + new_event->recurring = FALSE; + new_event->event_interval = 0L; + new_event->timing_func = NULL; + new_event->compensate_for_time_change = TRUE; + reschedule_event(new_event, &event_list_low, &event_list_low_tail); + } + +void +setup_events_with_host(time_t time) { + timed_event *new_event = NULL; + + /* First service is a normal one */ + if(svc3 == NULL) + svc3 = (service *)malloc(sizeof(service)); + svc3->host_name = strdup("Host0"); + svc3->description = strdup("Normal service"); + svc3->check_options = 0; + svc3->next_check = time; + svc3->state_type = SOFT_STATE; + svc3->current_state = STATE_OK; + svc3->retry_interval = 1; + svc3->check_interval = 5; + + new_event = (timed_event *)malloc(sizeof(timed_event)); + new_event->event_type = EVENT_SERVICE_CHECK; + new_event->event_data = (void *)svc3; + new_event->event_args = (void *)NULL; + new_event->event_options = 0; + new_event->run_time = 0L; /* Straight away */ + new_event->recurring = FALSE; + new_event->event_interval = 0L; + new_event->timing_func = NULL; + new_event->compensate_for_time_change = TRUE; + reschedule_event(new_event, &event_list_low, &event_list_low_tail); + + if(host1 == NULL) + host1 = (host *)malloc(sizeof(host)); + host1->name = strdup("Host1"); + host1->address = strdup("127.0.0.1"); + host1->retry_interval = 1; + host1->check_interval = 5; + host1->check_options = 0; + host1->next_check = time; + new_event->recurring = TRUE; + host1->state_type = SOFT_STATE; + host1->current_state = STATE_OK; + + new_event = (timed_event *)malloc(sizeof(timed_event)); + new_event->event_type = EVENT_HOST_CHECK; + new_event->event_data = (void *)host1; + new_event->event_args = (void *)NULL; + new_event->event_options = 0; + new_event->run_time = 0L; /* Straight away */ + new_event->recurring = TRUE; + new_event->event_interval = 0L; + new_event->timing_func = NULL; + new_event->compensate_for_time_change = TRUE; + reschedule_event(new_event, &event_list_low, &event_list_low_tail); + } + +int +main(int argc, char **argv) { + time_t now = 0L; + + plan_tests(10); + + time(&now); + + currently_running_service_checks = 0; + max_parallel_service_checks = 1; + setup_events(now); + event_execution_loop(); + + ok(svc1->next_check == now, "svc1 has not had its next check time changed"); + printf("# Nudge amount: %d\n", svc2->next_check - now); + ok(svc2->next_check > now + 5 && svc2->next_check < now + 5 + 10, "svc2 has been nudged"); + + + sigshutdown = FALSE; + currently_running_service_checks = 0; + max_parallel_service_checks = 2; + setup_events(now); + event_execution_loop(); + ok(svc1->next_check == now, "svc1 has not had its next check time changed"); + printf("# Nudge amount: %d\n", svc2->next_check - now); + ok(svc2->next_check == now, "svc2 also has not changed, because can execute"); + + + /* This test should have both services moved forward due to not executing any service checks */ + /* Will make svc2 move forward by a retry_interval amount */ + execute_service_checks = 0; + sigshutdown = FALSE; + currently_running_service_checks = 0; + max_parallel_service_checks = 2; + setup_events(now); + svc2->current_state = STATE_CRITICAL; + event_execution_loop(); + ok(svc1->next_check == now + 300, "svc1 rescheduled ahead - normal interval"); + ok(svc2->next_check == now + 60, "svc2 rescheduled ahead - retry interval"); + + + /* Checking that a host check immediately following a service check + * correctly checks the host + */ + timed_event *temp_event = NULL; + while((temp_event = event_list_low) != NULL) { + remove_event(temp_event, &event_list_low, &event_list_low_tail); + } + + sigshutdown = FALSE; + currently_running_service_checks = 0; + max_parallel_service_checks = 2; + execute_service_checks = 0; + execute_host_checks = 1; + setup_events_with_host(now); + event_execution_loop(); + + ok(host1->last_check - now <= 2, "host1 was checked (within 2 seconds tolerance)") || diag("last_check:%lu now:%lu", host1->last_check, now); + ok(svc3->last_check == 0, "svc3 was skipped"); + ok(host1->next_check == now, "host1 rescheduled ahead - normal interval"); + ok(svc3->next_check == now + 300, "svc3 rescheduled ahead - normal interval"); + + return exit_status(); + } + diff --git a/t-tap/test_logging.c b/t-tap/test_logging.c new file mode 100644 index 0000000..63942ea --- /dev/null +++ b/t-tap/test_logging.c @@ -0,0 +1,89 @@ +/***************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* +*****************************************************************************/ + +#define NSCORE 1 +#include "config.h" +#include "nagios.h" +#include "objects.h" +#include "tap.h" +#include "../common/shared.c" + +#define TEST_LOGGING 1 +#include "test-stubs.c" + +int date_format; + +char *saved_source; +char *saved_dest; +int my_rename(char *source, char *dest) { + char *temp = "renamefailure"; + saved_source = strdup(source); + saved_dest = strdup(dest); + if(strcmp(source, "renamefailure") == 0) { + return ERROR; + } + return rename(source, dest); + } + +void update_program_status() {} + +int +main(int argc, char **argv) { + time_t rotation_time; + struct stat stat_info, stat_new; + char *log_filename_localtime = NULL; + char *temp_command = NULL; + struct tm *t; + + plan_tests(14); + + rotation_time = (time_t)1242949698; + t = localtime(&rotation_time); + + asprintf(&log_filename_localtime, "var/nagios-%02d-%02d-%d-%02d.log", t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour); + + log_rotation_method = 5; + ok(rotate_log_file(rotation_time) == ERROR, "Got error for a bad log_rotation_method"); + + log_file = "renamefailure"; + log_rotation_method = LOG_ROTATION_HOURLY; + ok(rotate_log_file(rotation_time) == ERROR, "Got an error with rename"); + ok(strcmp(saved_dest, log_filename_localtime) == 0, "Got an hourly rotation"); + + log_file = "var/nagios.log"; + log_rotation_method = LOG_ROTATION_HOURLY; + ok(system("cp var/nagios.log.dummy var/nagios.log") == 0, "Copied in dummy nagios.log for archiving"); + ok(rotate_log_file(rotation_time) == OK, "Log rotation should work happily"); + + ok(system("diff var/nagios.log var/nagios.log.expected > /dev/null") == 0, "Got correct contents of nagios.log"); + + asprintf(&temp_command, "diff var/nagios.log.dummy %s", log_filename_localtime); + ok(system(temp_command) == 0, "nagios log archived correctly"); + + unlink(log_filename_localtime); + ok(system("chmod 777 var/nagios.log") == 0, "Changed mode of nagios.log"); + ok(stat("var/nagios.log", &stat_info) == 0, "Got stat info for log file"); + ok(rotate_log_file(rotation_time) == OK, "Log rotate to check if mode is retained"); + ok(stat(log_filename_localtime, &stat_new) == 0, "Got new stat info for archived log file"); + ok(stat_info.st_mode == stat_new.st_mode, "Mode for archived file same as original log file"); + + ok(stat("var/nagios.log", &stat_new) == 0, "Got new stat info for new log file"); + ok(stat_info.st_mode == stat_new.st_mode, "Mode for new log file kept same as original log file"); + + return exit_status(); + } diff --git a/t-tap/test_nagios_config.c b/t-tap/test_nagios_config.c new file mode 100644 index 0000000..9ea9773 --- /dev/null +++ b/t-tap/test_nagios_config.c @@ -0,0 +1,385 @@ +/***************************************************************************** + * + * test_nagios_config.c - Test configuration loading + * + * Program: Nagios Core Testing + * License: GPL + * Copyright (c) 2009 Nagios Core Development Team and Community Contributors + * Copyright (c) 1999-2009 Ethan Galstad + * + * First Written: 10-08-2009, based on nagios.c + * Last Modified: 10-08-2009 + * + * Description: + * + * Tests Nagios configuration loading + * + * 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" +#include "tap.h" + +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; + +extern char *macro_x[MACRO_X_COUNT]; + +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 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 allow_empty_hostgroup_assignment = DEFAULT_ALLOW_EMPTY_HOSTGROUP_ASSIGNMENT; + +int check_for_updates = DEFAULT_CHECK_FOR_UPDATES; +int bare_update_check = DEFAULT_BARE_UPDATE_CHECK; +time_t last_update_check = 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; + +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 command_file_fd; +FILE *command_file_fp; +int command_file_created = FALSE; +unsigned long update_uid = 0L; + + +extern contact *contact_list; +extern contactgroup *contactgroup_list; +extern hostgroup *hostgroup_list; +extern command *command_list; +extern timeperiod *timeperiod_list; +extern serviceescalation *serviceescalation_list; +extern host *host_list; +extern char *xrddefault_retention_file; + +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; + + +/* Dummy variables */ +sched_info scheduling_info; +timed_event event_list_low; +timed_event event_list_high; +timed_event *event_list_high_tail = NULL; + + +/* Dummy functions */ +void logit(int data_type, int display, const char *fmt, ...) {} +int my_sendall(int s, char *buf, int *len, int timeout) {} +int write_to_log(char *buffer, unsigned long data_type, time_t *timestamp) {} +int log_debug_info(int level, int verbosity, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + /* vprintf( fmt, ap ); */ + va_end(ap); + } + +int neb_free_callback_list(void) {} +void broker_program_status(int type, int flags, int attr, struct timeval *timestamp) {} +int neb_deinit_modules(void) {} +void broker_program_state(int type, int flags, int attr, struct timeval *timestamp) {} +void broker_comment_data(int type, int flags, int attr, int comment_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, struct timeval *timestamp) {} +int neb_unload_all_modules(int flags, int reason) {} +int neb_add_module(char *filename, char *args, int should_be_loaded) {} +void broker_system_command(int type, int flags, int attr, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *cmd, char *output, struct timeval *timestamp) {} + +int schedule_new_event(int event_type, int high_priority, time_t run_time, int recurring, unsigned long event_interval, void *timing_func, int compensate_for_time_change, void *event_data, void *event_args, int event_options) {} +int my_tcp_connect(char *host_name, int port, int *sd, int timeout) {} +int my_recvall(int s, char *buf, int *len, int timeout) {} +int neb_free_module_list(void) {} +void remove_event(timed_event *event, timed_event **event_list, timed_event **event_list_tail) {} +void check_for_service_flapping(service *svc, int update, int allow_flapstart_notification) {} +int update_host_status(host *hst, int aggregated_dump) {} +int update_contact_status(contact *cntct, int aggregated_dump) {} +time_t get_next_service_notification_time(service *temp_service, time_t time_t1) {} +void broker_retention_data(int type, int flags, int attr, struct timeval *timestamp) {} +int host_notification(host *hst, int type, char *not_author, char *not_data, int options) {} +void broker_downtime_data(int type, int flags, int attr, int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, struct timeval *timestamp) {} +int update_service_status(service *svc, int aggregated_dump) {} +time_t get_next_host_notification_time(host *temp_host, time_t time_t1) {} +void check_for_host_flapping(host *hst, int update, int actual_check, int allow_flapstart_notification) {} +int service_notification(service *svc, int type, char *not_author, char *not_data, int options) {} + + +int main(int argc, char **argv) { + int result; + int error = FALSE; + char *buffer = NULL; + int display_license = FALSE; + int display_help = FALSE; + int c = 0; + struct tm *tm; + time_t now; + char datestring[256]; + host *temp_host = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_member = NULL; + + plan_tests(14); + + /* reset program variables */ + reset_variables(); + + printf("Reading configuration data...\n"); + + config_file = strdup("smallconfig/nagios.cfg"); + /* read in the configuration files (main config file, resource and object config files) */ + result = read_main_config_file(config_file); + ok(result == OK, "Read main configuration file okay - if fails, use nagios -v to check"); + + result = read_all_object_data(config_file); + ok(result == OK, "Read all object config files"); + + result = pre_flight_check(); + ok(result == OK, "Preflight check okay"); + + for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + c++; + //printf("Hostgroup=%s\n", temp_hostgroup->group_name); + } + ok(c == 2, "Found all hostgroups"); + + temp_hostgroup = find_hostgroup("hostgroup1"); + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + //printf("host pointer=%d\n", temp_member->host_ptr); + } + + temp_hostgroup = find_hostgroup("hostgroup2"); + for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { + //printf("host pointer=%d\n", temp_member->host_ptr); + } + + temp_host = find_host("host1"); + ok(temp_host->current_state == 0, "State is assumed OK on initial load"); + + xrddefault_retention_file = strdup("smallconfig/retention.dat"); + ok(xrddefault_read_state_information() == OK, "Reading retention data"); + + ok(temp_host->current_state == 1, "State changed due to retention file settings"); + + ok(find_host_comment(418) != NULL, "Found host comment id 418"); + ok(find_service_comment(419) != NULL, "Found service comment id 419"); + ok(find_service_comment(420) == NULL, "Did not find service comment id 420 as not persistent"); + ok(find_host_comment(1234567888) == NULL, "No such host comment"); + + ok(find_host_downtime(1102) != NULL, "Found host downtime id 1102"); + ok(find_service_downtime(1110) != NULL, "Found service downtime 1110"); + ok(find_host_downtime(1234567888) == NULL, "No such host downtime"); + + cleanup(); + + my_free(config_file); + + return exit_status(); + } + + diff --git a/t-tap/test_strtoul.c b/t-tap/test_strtoul.c new file mode 100644 index 0000000..2121e3a --- /dev/null +++ b/t-tap/test_strtoul.c @@ -0,0 +1,67 @@ +/***************************************************************************** +* +* test_strtoul.c - Test strtoul function for downtime +* +* Program: Nagios Core Testing +* License: GPL +* Copyright (c) 2009 Nagios Core Development Team and Community Contributors +* Copyright (c) 1999-2009 Ethan Galstad +* +* First Written: 12-Mov-2010 +* Last Modified: 12-Nov-2010 +* +* Description: +* +* Tests system strtoul - to ensure that it works as expected as some systems +* may differ in usage +* +* 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 +#include "tap.h" + +char *svr_hostname = "hostname"; +char *svr_fqdn = "hostname.domain.name"; +char *svr_ip = "192.168.1.1"; +char *svr_downtime_id = "1234"; +char *end_ptr = NULL; +unsigned long downtime_id = 0L; + +int main(int argc, char **argv) { + + plan_tests(8); + + downtime_id = strtoul(svr_hostname, &end_ptr, 10); + ok(downtime_id == 0, "hostname downtime_id is 0"); + ok(strlen(end_ptr) == 8, "hostname end_ptr is 8 chars"); + + downtime_id = strtoul(svr_fqdn, &end_ptr, 10); + ok(downtime_id == 0, "fqdn downtime_id is 0"); + ok(strlen(end_ptr) == 20, "fqdn end_ptr is 20 chars"); + + downtime_id = strtoul(svr_ip, &end_ptr, 10); + ok(downtime_id == 192, "ip downtime_id is 192"); + ok(strlen(end_ptr) == 8, "ip end_ptr is 8 chars"); + + downtime_id = strtoul(svr_downtime_id, &end_ptr, 10); + ok(downtime_id == 1234, "svr_downtime_id downtime_id is 1234"); + ok(strlen(end_ptr) == 0, "svr_downtime_id end_ptr is 0 chars"); + + return exit_status(); + } diff --git a/t-tap/test_timeperiods.c b/t-tap/test_timeperiods.c new file mode 100644 index 0000000..ded1771 --- /dev/null +++ b/t-tap/test_timeperiods.c @@ -0,0 +1,567 @@ +/***************************************************************************** + * + * test_timeperiod.c - Test timeperiod + * + * Program: Nagios Core Testing + * License: GPL + * Copyright (c) 2009 Nagios Core Development Team and Community Contributors + * Copyright (c) 1999-2009 Ethan Galstad + * + * First Written: 10-08-2009, based on nagios.c + * Last Modified: 10-08-2009 + * + * Description: + * + * Tests Nagios configuration loading + * + * 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" +#include "tap.h" + +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; + +extern char *macro_x[MACRO_X_COUNT]; + +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 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 allow_empty_hostgroup_assignment = DEFAULT_ALLOW_EMPTY_HOSTGROUP_ASSIGNMENT; + +int check_for_updates = DEFAULT_CHECK_FOR_UPDATES; +int bare_update_check = DEFAULT_BARE_UPDATE_CHECK; +time_t last_update_check = 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; + +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 command_file_fd; +FILE *command_file_fp; +int command_file_created = FALSE; +unsigned long update_uid = 0L; + + +extern contact *contact_list; +extern contactgroup *contactgroup_list; +extern hostgroup *hostgroup_list; +extern command *command_list; +extern timeperiod *timeperiod_list; +extern serviceescalation *serviceescalation_list; +extern host *host_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; + + +/* Dummy variables */ +sched_info scheduling_info; +timed_event event_list_low; +timed_event event_list_high; + +/* Dummy functions */ +void logit(int data_type, int display, const char *fmt, ...) {} +int my_sendall(int s, char *buf, int *len, int timeout) {} +void free_comment_data(void) {} +int write_to_log(char *buffer, unsigned long data_type, time_t *timestamp) {} +int log_debug_info(int level, int verbosity, const char *fmt, ...) {} + +int neb_free_callback_list(void) {} +void broker_program_status(int type, int flags, int attr, struct timeval *timestamp) {} +int neb_deinit_modules(void) {} +void broker_program_state(int type, int flags, int attr, struct timeval *timestamp) {} +void broker_comment_data(int type, int flags, int attr, int comment_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, struct timeval *timestamp) {} +int neb_unload_all_modules(int flags, int reason) {} +int neb_add_module(char *filename, char *args, int should_be_loaded) {} +void broker_system_command(int type, int flags, int attr, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *cmd, char *output, struct timeval *timestamp) {} + +int schedule_new_event(int event_type, int high_priority, time_t run_time, int recurring, unsigned long event_interval, void *timing_func, int compensate_for_time_change, void *event_data, void *event_args, int event_options) {} +int my_tcp_connect(char *host_name, int port, int *sd, int timeout) {} +int my_recvall(int s, char *buf, int *len, int timeout) {} +int neb_free_module_list(void) {} + +int main(int argc, char **argv) { + int result; + int error = FALSE; + char *buffer = NULL; + int display_license = FALSE; + int display_help = FALSE; + int c = 0; + struct tm *tm; + time_t current_time; + time_t test_time; + time_t saved_test_time; + time_t next_valid_time = 0L; + time_t chosen_valid_time = 0L; + char datestring[256]; + host *temp_host = NULL; + hostgroup *temp_hostgroup = NULL; + hostsmember *temp_member = NULL; + timeperiod *temp_timeperiod = NULL; + int is_valid_time = 0; + int iterations = 1000; + + plan_tests(6043); + + /* reset program variables */ + reset_variables(); + + printf("Reading configuration data...\n"); + + config_file = strdup("smallconfig/nagios.cfg"); + /* read in the configuration files (main config file, resource and object config files) */ + result = read_main_config_file(config_file); + ok(result == OK, "Read main configuration file okay - if fails, use nagios -v to check"); + + result = read_all_object_data(config_file); + ok(result == OK, "Read all object config files"); + + result = pre_flight_check(); + ok(result == OK, "Preflight check okay"); + + time(¤t_time); + test_time = current_time; + saved_test_time = current_time; + + temp_timeperiod = find_timeperiod("none"); + + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "No valid time because time period is empty"); + + get_next_valid_time(current_time, &next_valid_time, temp_timeperiod); + ok(current_time == next_valid_time, "There is no valid time due to timeperiod"); + + temp_timeperiod = find_timeperiod("24x7"); + + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Fine because 24x7"); + + get_next_valid_time(current_time, &next_valid_time, temp_timeperiod); + ok((next_valid_time - current_time) <= 2, "Next valid time should be the current_time, but with a 2 second tolerance"); + + + /* 2009-10-25 is the day when clocks go back an hour in Europe. Bug happens during 23:00 to 00:00 */ + /* This is 23:01:01 */ + saved_test_time = 1256511661; + saved_test_time = saved_test_time - (24 * 60 * 60); + + putenv("TZ=UTC"); + tzset(); + test_time = saved_test_time; + c = 0; + while(c < iterations) { + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Always OK for 24x7 with TZ=UTC, time_t=%lu", test_time); + chosen_valid_time = 0L; + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time"); + test_time += 1800; + c++; + } + + putenv("TZ=Europe/London"); + tzset(); + test_time = saved_test_time; + c = 0; + while(c < iterations) { + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Always OK for 24x7 with TZ=Europe/London, time_t=%lu", test_time); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time, time_t=%lu", test_time); + test_time += 1800; + c++; + } + + /* 2009-11-01 is the day when clocks go back an hour in America. Bug happens during 23:00 to 00:00 */ + /* This is 23:01:01 */ + saved_test_time = 1256511661; + saved_test_time = saved_test_time - (24 * 60 * 60); + + putenv("TZ=America/New_York"); + tzset(); + test_time = saved_test_time; + c = 0; + while(c < iterations) { + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Always OK for 24x7 with TZ=America/New_York, time_t=%lu", test_time); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time, time_t=%lu", test_time); + test_time += 1800; + c++; + } + + + + /* Tests around clock change going back for TZ=Europe/London. 1256511661 = Sun Oct + 25 23:01:01 2009 */ + /* A little trip to Paris*/ + putenv("TZ=Europe/Paris"); + tzset(); + + + /* Timeperiod exclude tests, from Jean Gabes */ + temp_timeperiod = find_timeperiod("Test_exclude"); + ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod"); + test_time = 1278939600; + /* printf("Testing at time %s", ctime(&test_time)); */ + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); + + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ + todo_start("Bug in exclude"); + ok(chosen_valid_time == 1288103400, "ME: Next valid time=Tue Oct 26 16:30:00 2010"); + todo_end(); + + + temp_timeperiod = find_timeperiod("Test_exclude2"); + ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 2"); + test_time = 1278939600; + /* printf("Testing at time %s", ctime(&test_time)); */ + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ + todo_start("Bug in exclude 2"); + ok(chosen_valid_time == 1279058340, "ME: Next valid time=Tue Jul 13 23:59:00 2010"); + todo_end(); + + + temp_timeperiod = find_timeperiod("Test_exclude3"); + ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 3"); + test_time = 1278939600; + /* printf("Testing at time %s", ctime(&test_time)); */ + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ + todo_start("Bug in exclude 3"); + ok(chosen_valid_time == 1284474600, "ME: Next valid time=Tue Sep 14 16:30:00 2010"); + todo_end(); + + + temp_timeperiod = find_timeperiod("Test_exclude4"); + ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 4"); + test_time = 1278939600; + /* printf("Testing at time %s", ctime(&test_time)); */ + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ + todo_start("Bug in exclude 3"); + ok(chosen_valid_time == 1283265000, "ME: Next valid time=Tue Aug 31 16:30:00 2010"); + todo_end(); + + + + + /* Back to New york */ + putenv("TZ=America/New_York"); + tzset(); + + + temp_timeperiod = find_timeperiod("sunday_only"); + ok(temp_timeperiod != NULL, "Testing Sunday 00:00-01:15,03:15-22:00"); + putenv("TZ=Europe/London"); + tzset(); + + + test_time = 1256421000; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "Sat Oct 24 22:50:00 2009 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1256425200, "Next valid time=Sun Oct 25 00:00:00 2009"); + + + test_time = 1256421661; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "Sat Oct 24 23:01:01 2009 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1256425200, "Next valid time=Sun Oct 25 00:00:00 2009"); + + test_time = 1256425400; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Sun Oct 25 00:03:20 2009 - true"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 00:03:20 2009"); + + test_time = 1256429700; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Sun Oct 25 01:15:00 2009 - true"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 01:15:00 2009"); + + test_time = 1256430400; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "Sun Oct 25 01:26:40 2009 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + todo_start("Is a bug in get_next_valid_time for a time that falls in the DST change hour period"); + ok(chosen_valid_time == 1256440500, "Next valid time=Sun Oct 25 03:15:00 2009") || printf("chosen_valid_time=%lu\n", chosen_valid_time); + todo_end(); + + test_time = 1256440500; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Sun Oct 25 03:15:00 2009 - true"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 03:15:00 2009"); + + test_time = 1256500000; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Sun Oct 25 19:46:40 2009 - true"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1256500000, "Next valid time=Sun Oct 25 19:46:40 2009"); + + test_time = 1256508000; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == OK, "Sun Oct 25 22:00:00 2009 - true"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1256508000, "Next valid time=Sun Oct 25 22:00:00 2009"); + + test_time = 1256508001; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "Sun Oct 25 22:00:01 2009 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1257033600, "Next valid time=Sun Nov 1 00:00:00 2009"); + + test_time = 1256513000; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "Sun Oct 25 23:23:20 2009 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1257033600, "Next valid time=Sun Nov 1 00:00:00 2009"); + + + + + temp_timeperiod = find_timeperiod("weekly_complex"); + ok(temp_timeperiod != NULL, "Testing complex weekly timeperiod definition"); + putenv("TZ=America/New_York"); + tzset(); + + test_time = 1268109420; + is_valid_time = check_time_against_period(test_time, temp_timeperiod); + ok(is_valid_time == ERROR, "Mon Mar 8 23:37:00 2010 - false"); + _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); + ok(chosen_valid_time == 1268115300, "Next valid time=Tue Mar 9 01:15:00 2010"); + + + + + + cleanup(); + + my_free(config_file); + + return exit_status(); + } + + diff --git a/t-tap/test_xsddefault.c b/t-tap/test_xsddefault.c new file mode 100644 index 0000000..c2d3204 --- /dev/null +++ b/t-tap/test_xsddefault.c @@ -0,0 +1,102 @@ +/***************************************************************************** + * + * test_xsddefault.c - Test configuration loading + * + * Program: Nagios Core Testing + * License: GPL + * Copyright (c) 2009-2010 Nagios Core Development Team and Community Contributors + * Copyright (c) 1999-2009 Ethan Galstad + * + * First Written: 06-01-2010, based on test_nagios_config.c + * + * Description: + * + * Tests Nagios status file reading + * + * 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. + * + *****************************************************************************/ + +/* Need these to get CGI mode */ +#undef NSCORE +#define NSCGI 1 +#include "../include/config.h" +#include "../include/common.h" +#include "../include/locations.h" +#include "../include/statusdata.h" +#include "../include/comments.h" +#include "../include/downtime.h" +#include "../include/macros.h" +#include "../include/skiplist.h" +#include "tap.h" + +extern comment *comment_list; +extern scheduled_downtime *scheduled_downtime_list; + +int main(int argc, char **argv) { + int result; + int c; + int last_id; + time_t last_time; + comment *temp_comment; + scheduled_downtime *temp_downtime; + + plan_tests(7); + + chdir("../t"); + + ok(system("cat var/status.dat > var/status-generated.dat") == 0, "New status.dat file"); + ok(system("bin/generate_downtimes 10 >> var/status-generated.dat") == 0, "Generated 10 downtimes"); + + result = xsddefault_read_status_data("etc/cgi-with-generated-status.cfg", 0); + ok(result == OK, "Read cgi status data okay"); + + temp_comment = comment_list; + last_id = 0; + c = 0; + result = OK; + while(temp_comment != NULL) { + c++; + if(temp_comment->comment_id <= last_id) { + result = ERROR; + break; + } + last_id = temp_comment->comment_id; + temp_comment = temp_comment->next; + } + ok(c == 12, "Got %d comments - expected 12", c); + ok(result == OK, "All comments in order"); + + temp_downtime = scheduled_downtime_list; + last_time = 0; + c = 0; + result = OK; + while(temp_downtime != NULL) { + c++; + if(temp_downtime->start_time < last_time) { + result = ERROR; + break; + } + last_time = temp_downtime->start_time; + temp_downtime = temp_downtime->next; + } + ok(c == 20, "Got %d downtimes - expected 20", c); + ok(result == OK, "All downtimes in order"); + + return exit_status(); + } + + diff --git a/t-tap/var/.gitignore b/t-tap/var/.gitignore new file mode 100644 index 0000000..146bee3 --- /dev/null +++ b/t-tap/var/.gitignore @@ -0,0 +1 @@ +nagios*.log diff --git a/t-tap/var/nagios.log.dummy b/t-tap/var/nagios.log.dummy new file mode 100644 index 0000000..b3ab4ea --- /dev/null +++ b/t-tap/var/nagios.log.dummy @@ -0,0 +1 @@ +This is a dummy nagios.log file. Will be archived diff --git a/t-tap/var/nagios.log.expected b/t-tap/var/nagios.log.expected new file mode 100644 index 0000000..77daddf --- /dev/null +++ b/t-tap/var/nagios.log.expected @@ -0,0 +1,2 @@ +[1242949698] LOG ROTATION: HOURLY +[1242949698] LOG VERSION: 2.0 diff --git a/t/610cgistatus.t b/t/610cgistatus.t new file mode 100644 index 0000000..e80b350 --- /dev/null +++ b/t/610cgistatus.t @@ -0,0 +1,43 @@ +#!/usr/bin/perl +# +# Checks for status.cgi + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $cgi = "$cgi_dir/status.cgi"; + +my $output; + +plan tests => 8; + +my $numhosts; + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REMOTE_USER=nagiosadmin REQUEST_METHOD=GET QUERY_STRING=host=all $cgi`; +like( $output, '/status.cgi\?host=all&sorttype=1&sortoption=1/', "Host value should be set to all if host=all passed in" ); + +# Bit of a hacky way to count number of hosts +$numhosts = grep /title=/, split("\n", $output); + +ok( $numhosts > 1, "Got $numhosts hosts, which is more than 1"); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REMOTE_USER=nagiosadmin REQUEST_METHOD=GET QUERY_STRING=host=host1 $cgi`; +like( $output, '/status.cgi\?host=host1&sorttype=1&sortoption=1/', "Host value should be set to specific host if passed in" ); +like( $output, '/1 Matching Service Entries Displayed/', "Found the one host" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REMOTE_USER=nagiosadmin REQUEST_METHOD=GET QUERY_STRING=host= $cgi`; +like( $output, '/status.cgi\?host=&sorttype=1&sortoption=1/', "Host value kept as blank if set to blank" ); +like( $output, '/0 Matching Service Entries Displayed/', "Got no hosts because looking for a blank name" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REMOTE_USER=nagiosadmin REQUEST_METHOD=GET $cgi`; +like( $output, '/status.cgi\?host=all&sorttype=1&sortoption=1/', "Host value should be set to all if nothing set initially" ); + +$_ = grep /title=/, split("\n", $output); +is( $_, $numhosts, "Same number of hosts" ); + diff --git a/t/611cgistatus-hosturgencies.t b/t/611cgistatus-hosturgencies.t new file mode 100644 index 0000000..598d266 --- /dev/null +++ b/t/611cgistatus-hosturgencies.t @@ -0,0 +1,33 @@ +#!/usr/bin/perl +# +# Checks for status.cgi + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $cgi = "$cgi_dir/status.cgi"; + +my $output; + +plan tests => 3; + +my $numhosts; + +# Host list sorted by name +$output = `NAGIOS_CGI_CONFIG=etc/cgi-hosturgencies.cfg REMOTE_USER=nagiosadmin REQUEST_METHOD=GET QUERY_STRING='hostgroup=all&style=hostdetail' $cgi`; +like( $output, '/>host1<.*>host2<.*>host3<.*>host4host4<.*>host1<.*>host2<.*>host3host2<.*>host3<.*>host4<.*>host1 1 ) } grep /\.cgi$/, readdir DIR; +closedir DIR; + +plan tests => scalar keys %cgis; + +# Remove these two because the output is different +my @todos = qw(statuswml.cgi statuswrl.cgi); + +TODO: { + local $TODO = "Output is different for these CGIs"; + foreach my $cgi (@todos) { + delete $cgis{$cgi}; + my $output = `NAGIOS_CGI_CONFIG=etc/cgi.nonexistant REQUEST_METHOD=GET $cgi_dir/$cgi`; + like( $output, "/Error: Could not open CGI config file 'etc/cgi.nonexistant' for reading/", "Found error for $cgi" ); + } +} + +foreach my $cgi (sort keys %cgis) { + my $output = `NAGIOS_CGI_CONFIG=etc/cgi.nonexistant REQUEST_METHOD=GET $cgi_dir/$cgi`; + like( $output, "/Error: Could not open CGI config file 'etc/cgi.nonexistant' for reading/", "Found error for $cgi" ); +} + diff --git a/t/616cginotification.t b/t/616cginotification.t new file mode 100644 index 0000000..0d3a75b --- /dev/null +++ b/t/616cginotification.t @@ -0,0 +1,34 @@ +#!/usr/bin/perl +# +# Checks for notifications.cgi + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $notifications_cgi = "$cgi_dir/notifications.cgi"; + +my $output; + +plan tests => 5; + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET $notifications_cgi`; +like( $output, "//", "Host value set to all if nothing set" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING=host=all $notifications_cgi`; +like( $output, "//", "Host value set to all if host=all set" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING=host=hostA $notifications_cgi`; +like( $output, "//", "Host value set to host in query string" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING=contact=all $notifications_cgi`; +like( $output, "//", "Contact value set to all from query string" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING=contact=fred $notifications_cgi`; +like( $output, "//", "Contact value set to fred from query string" ); + diff --git a/t/617statuswml.t b/t/617statuswml.t new file mode 100644 index 0000000..5d8148f --- /dev/null +++ b/t/617statuswml.t @@ -0,0 +1,39 @@ +#!/usr/bin/perl +# +# Checks for statuswml.cgi + +use warnings; +use strict; +use Test::More; + +# Useful for diagnostics, but not part of a core perl install +#use Test::LongString; + +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $statuswml = "$cgi_dir/statuswml.cgi"; + +my $output; +my $expected; + +plan tests => 5; + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING="ping=127.0.0.1%3Becho+this+should+not+get+here" $statuswml`; +unlike( $output, "/this should not get here/", "Check that security error does not exist" ); +like( $output, qr%

    Invalid host name/ip

    % ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING="traceroute=127.0.0.1%3Becho+this+should+not+get+here" $statuswml`; +unlike( $output, "/this should not get here/", "Check that security error does not exist" ); +like( $output, qr%

    Invalid host name/ip

    % ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING="ping=127.0.0.1" $statuswml`; +like( $output, qr%Results For Ping Of 127.0.0.1:
    %, "Works correctly for valid address for ping" ); + +# Don't run this test below, because it actually invokes traceroute +#$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING="traceroute=127.0.0.1" $statuswml`; +#like( $output, qr%Results For Traceroute To 127.0.0.1:
    %, "... and traceroute" ); + diff --git a/t/618cgisecurity.t b/t/618cgisecurity.t new file mode 100644 index 0000000..1f7d0cd --- /dev/null +++ b/t/618cgisecurity.t @@ -0,0 +1,23 @@ +#!/usr/bin/perl +# +# Check that you CGI security errors are fixed + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; + +plan 'no_plan'; + +my $output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING="layer=' style=xss:expression(alert('XSS')) '" $cgi_dir/statusmap.cgi`; +unlike( $output, qr/' style=xss:expression\(alert\('XSS'\)\) '/, "XSS injection not passed straight through" ); +like( $output, qr/' style=xss:expression(alert('XSS')) '/, "Expected escaping of quotes" ) || diag $output; + + +$output = `REMOTE_USER=nagiosadmin NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET QUERY_STRING="type=command&expand=" $cgi_dir/config.cgi`; +unlike( $output, qr//, "XSS injection not passed through" ) || diag ($output); diff --git a/t/620history.t b/t/620history.t new file mode 100644 index 0000000..39b96b7 --- /dev/null +++ b/t/620history.t @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use FindBin qw($Bin); + +use Test::More; + +eval "use Test::HTML::Lint"; +if ($@) { + plan skip_all => "Need Test::HTML::Lint"; +} + +eval "use Test::WWW::Mechanize::CGI"; +if ($@) { + plan skip_all => "Need Test::WWW::Mechanize::CGI"; +} + +my $lint; +eval '$lint = HTML::Lint->new( only_types => HTML::Lint::Error::STRUCTURE )'; + +plan tests => 3; + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; + +my $mech = Test::WWW::Mechanize::CGI->new; + +$mech->env( NAGIOS_CGI_CONFIG => "etc/cgi.cfg" ); +$mech->cgi_application("$cgi_dir/history.cgi"); + +$mech->get_ok("http://localhost/"); + +$mech->title_is("Nagios History"); + +html_ok( $lint, $mech->content, "HTML correct" ); + diff --git a/t/621extinfo.t b/t/621extinfo.t new file mode 100644 index 0000000..516c47c --- /dev/null +++ b/t/621extinfo.t @@ -0,0 +1,40 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use FindBin qw($Bin); + +use Test::More; + +eval "use Test::HTML::Lint"; +if ($@) { + plan skip_all => "Need Test::HTML::Lint"; +} + +eval "use Test::WWW::Mechanize::CGI"; +if ($@) { + plan skip_all => "Need Test::WWW::Mechanize::CGI"; +} + +my $lint; +eval '$lint = HTML::Lint->new( only_types => HTML::Lint::Error::STRUCTURE )'; + +plan tests => 3; + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; + +my $mech = Test::WWW::Mechanize::CGI->new; + +$mech->env( REMOTE_USER => "nagiosadmin" ); +$mech->env( NAGIOS_CGI_CONFIG => "etc/cgi.cfg" ); +$mech->cgi_application("$cgi_dir/extinfo.cgi"); + +$mech->get_ok("http://localhost/"); + +$mech->title_is("Extended Information"); + +html_ok( $lint, $mech->content, "HTML correct" ); + diff --git a/t/622extinfo-local.t b/t/622extinfo-local.t new file mode 100644 index 0000000..07a0dbd --- /dev/null +++ b/t/622extinfo-local.t @@ -0,0 +1,26 @@ +#!/usr/bin/perl +# +# Local Checks for extinfo.cgi + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $extinfo_cgi = "$cgi_dir/extinfo.cgi"; + +my $output; +my $remote_user = "REMOTE_USER=nagiosadmin"; + +plan tests => 2; + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET $remote_user $extinfo_cgi`; +like( $output, "/Process Information/", "extinfo.cgi without params show the process information" ); + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg REQUEST_METHOD=GET $remote_user QUERY_STRING='&type=1&host=host1' $extinfo_cgi`; +like( $output, "/Schedule downtime for all services on this host/", "extinfo.cgi allows us to set downtime for a host and all of his services" ); + diff --git a/t/623cmd-local.t b/t/623cmd-local.t new file mode 100644 index 0000000..8d0b76f --- /dev/null +++ b/t/623cmd-local.t @@ -0,0 +1,840 @@ +#!/usr/bin/perl +# +# Local Checks for cmd.cgi + +use warnings; +use strict; +use Test::More qw(no_plan); +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $local_cgi = "$cgi_dir/cmd.cgi"; + +my $output; + +my $cmd_typ = ''; +my $remote_user = 'REMOTE_USER=nagiosadmin'; + + + +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET $local_cgi`; +like( $output, "/

    Error: No command was specified

    /", "$local_cgi without params shows an error" ); + + +# Run many tests against commands which are not supportet by cmd.cgi +for (8, 18, 19, 31, 32, 53, 54, 69..77, 97, 98, 103..108, 115..120, 123..158, 161..169 ){ + $cmd_typ=$_; + $output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; + unlike( $output, "/You are requesting to execute an unknown command. Shame on you!/", "$local_cgi with cmd_typ=$cmd_typ results in an error" ); +} + +# Tests against command type '1' +$cmd_typ=1; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to add a host comment/", "$local_cgi with cmd_typ=$cmd_typ shows host comment form" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '2' +$cmd_typ=2; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to delete a host comment/", "$local_cgi with cmd_typ=$cmd_typ shows host comment form" ); +like( $output, "/Comment ID:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment ID field" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '3' +$cmd_typ=3; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to add a service comment/", "$local_cgi with cmd_typ=$cmd_typ shows service comment form" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '4' +$cmd_typ=4; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to delete a service comment/", "$local_cgi with cmd_typ=$cmd_typ shows service comment delete form" ); +like( $output, "/Comment ID:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment ID field" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '5' +$cmd_typ=5; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable active checks of a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows enable active service checks form" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '6' +$cmd_typ=6; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable active checks of a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows disable active service checks form" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '7' +$cmd_typ=7; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule a service check/", "$local_cgi with cmd_typ=$cmd_typ shows request service check form" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Check Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '9' +$cmd_typ=9; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to delay a service notification/", "$local_cgi with cmd_typ=$cmd_typ shows request to delay service notification" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Notification Delay \\(minutes from now\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Notification Delay form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '10' +$cmd_typ=10; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to delay a host notification/", "$local_cgi with cmd_typ=$cmd_typ shows request to delay host notification" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Notification Delay \\(minutes from now\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Notification Delay form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '11' +$cmd_typ=11; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notification/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notification" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '12' +$cmd_typ=12; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notification/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notification" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '13' +$cmd_typ=13; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to restart the Nagios process/", "$local_cgi with cmd_typ=$cmd_typ shows request to restart Nagios" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '14' +$cmd_typ=14; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to shutdown the Nagios process/", "$local_cgi with cmd_typ=$cmd_typ shows request to shutdown Nagios" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '15' +$cmd_typ=15; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable active checks of all services on a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable active checks of all services on a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '16' +$cmd_typ=16; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable active checks of all services on a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable active checks of all services on a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '17' +$cmd_typ=17; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule a check of all services for a host/", "$local_cgi with cmd_typ=$cmd_typ shows request check all services on a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Check Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + + +# Tests against command type '20' +$cmd_typ=20; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to delete all comments for a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to delete all comments for a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '21' +$cmd_typ=21; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to delete all comments for a service/", "$local_cgi with cmd_typ=$cmd_typ shows request to delete all comments for a service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '22' +$cmd_typ=22; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for a service/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for a service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '23' +$cmd_typ=23; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for a service/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for a service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '24' +$cmd_typ=24; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '25' +$cmd_typ=25; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '26' +$cmd_typ=26; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for all hosts and services beyond a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for all hosts and services beyond a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '27' +$cmd_typ=27; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for all hosts and services beyond a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for all hosts and services beyond a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '28' +$cmd_typ=28; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for all services on a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for all services on a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '29' +$cmd_typ=29; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for all services on a host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for all services on a host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '30' +$cmd_typ=30; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to submit a passive check result for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to submit passive check result for a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Check Result:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Result in form" ); +like( $output, "/Check Output:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Output in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + + +# Tests against command type '33' +$cmd_typ=33; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to acknowledge a host problem/", "$local_cgi with cmd_typ=$cmd_typ shows request to acknowledge a host problem" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Sticky Acknowledgement:/", "$local_cgi with cmd_typ=$cmd_typ allows Sticky Acknowledge in form" ); +like( $output, "/Send Notification:/", "$local_cgi with cmd_typ=$cmd_typ allows to send notification in form" ); +like( $output, "/Persistent Comment:/", "$local_cgi with cmd_typ=$cmd_typ allows to set Persistent Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '34' +$cmd_typ=34; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to acknowledge a service problem/", "$local_cgi with cmd_typ=$cmd_typ shows request to acknowledge a service problem" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Sticky Acknowledgement:/", "$local_cgi with cmd_typ=$cmd_typ allows Sticky Acknowledge in form" ); +like( $output, "/Send Notification:/", "$local_cgi with cmd_typ=$cmd_typ allows to send notification in form" ); +like( $output, "/Persistent Comment:/", "$local_cgi with cmd_typ=$cmd_typ allows to set Persistent Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '35' +$cmd_typ=35; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start executing active service checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to start executing system wide active service checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '36' +$cmd_typ=36; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop executing active service checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop executing system wide active service checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '37' +$cmd_typ=37; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start accepting passive service checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to start accepting executing system wide passive service checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '38' +$cmd_typ=38; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop accepting passive service checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop accepting system wide passive service checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '39' +$cmd_typ=39; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start accepting passive service checks for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to start accepting passive service checks for a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '40' +$cmd_typ=40; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop accepting passive service checks for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop accepting passive service checks for a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '41' +$cmd_typ=41; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable event handlers/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable system wide event handlers" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '42' +$cmd_typ=42; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable event handlers/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable system wide event handlers" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '43' +$cmd_typ=43; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable the event handler for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable event handler of a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '44' +$cmd_typ=44; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable the event handler for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable event handler of a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '45' +$cmd_typ=45; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable the event handler for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable event handler of a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '46' +$cmd_typ=46; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable the event handler for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable event handler of a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '47' +$cmd_typ=47; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable active checks of a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable active checks of a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '48' +$cmd_typ=48; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable active checks of a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable active checks of a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '49' +$cmd_typ=49; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start obsessing over service checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to start obsessing over service checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '50' +$cmd_typ=50; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop obsessing over service checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop obsessing over service checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '51' +$cmd_typ=51; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to remove a host acknowledgement/", "$local_cgi with cmd_typ=$cmd_typ shows request to remove a host acknowledgement" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + +# Tests against command type '52' +$cmd_typ=52; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to remove a service acknowledgement/", "$local_cgi with cmd_typ=$cmd_typ shows request to remove a service acknowledgement" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '55' +$cmd_typ=55; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for a particular Host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '56' +$cmd_typ=56; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for a particular Service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '57' +$cmd_typ=57; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable flap detection for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable flap detection for a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '58' +$cmd_typ=58; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable flap detection for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable flap detection for a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '59' +$cmd_typ=59; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable flap detection for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable flap detection for a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '60' +$cmd_typ=60; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable flap detection for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable flap detection for a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '61' +$cmd_typ=61; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable flap detection for hosts and services/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable flap detection for hosts and services" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '62' +$cmd_typ=62; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable flap detection for hosts and services/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable flap detection for hosts and services" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '63' +$cmd_typ=63; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for all services in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for all services in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '64' +$cmd_typ=64; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for all services in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for all services in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '65' +$cmd_typ=65; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for all hosts in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for all hosts in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '66' +$cmd_typ=66; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for all hosts in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for all hosts in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '67' +$cmd_typ=67; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable active checks of all services in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable active checks of all services in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '68' +$cmd_typ=68; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable active checks of all services in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable active checks of all services in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '78' +$cmd_typ=78; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to cancel scheduled downtime for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to cancel scheduled downtime for a particular host" ); +like( $output, "/Scheduled Downtime ID:/", "$local_cgi with cmd_typ=$cmd_typ requires Scheduled Downtime ID in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '79' +$cmd_typ=79; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to cancel scheduled downtime for a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to cancel scheduled downtime for a particular service" ); +like( $output, "/Scheduled Downtime ID:/", "$local_cgi with cmd_typ=$cmd_typ requires Scheduled Downtime ID in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '80' +$cmd_typ=80; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable failure prediction for hosts and service/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable failure prediction for hosts and service" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + + +# Tests against command type '81' +$cmd_typ=81; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable failure prediction for hosts and service/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable failure prediction for hosts and service" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '82' +$cmd_typ=82; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable performance data processing for hosts and services/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable performance data processing for hosts and services" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '83' +$cmd_typ=83; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable performance data processing for hosts and services/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable performance data processing for hosts and services" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '84' +$cmd_typ=84; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for all hosts in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for all hosts in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '85' +$cmd_typ=85; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for all services in a particular hostgroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for all services in a particular hostgroup" ); +like( $output, "/Hostgroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Hostgroup Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '86' +$cmd_typ=86; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for all services for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for all services for a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '87' +$cmd_typ=87; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to submit a passive check result for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to submit a passive check result for a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Check Result:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Result in form" ); +like( $output, "/Check Output:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Output in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '88' +$cmd_typ=88; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start executing host checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to start executing host checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '89' +$cmd_typ=89; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop executing host checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop executing host checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '90' +$cmd_typ=90; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start accepting passive host checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to start accepting passive host checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '91' +$cmd_typ=91; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop accepting passive host checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop accepting passive host checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '92' +$cmd_typ=92; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start accepting passive checks for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to start accepting passive checks for a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '93' +$cmd_typ=93; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop accepting passive checks for a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop accepting passive checks for a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '94' +$cmd_typ=94; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start obsessing over host checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to start obsessing over host checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '95' +$cmd_typ=95; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop obsessing over host checks/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop obsessing over host checks" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '96' +$cmd_typ=96; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule a host check/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule a host check" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Check Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Check Time in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '99' +$cmd_typ=99; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start obsessing over a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to start obsessing over a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '100' +$cmd_typ=100; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop obsessing over a particular service/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop obsessing over a particular service" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '101' +$cmd_typ=101; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to start obsessing over a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to start obsessing over a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '102' +$cmd_typ=102; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to stop obsessing over a particular host/", "$local_cgi with cmd_typ=$cmd_typ shows request to stop obsessing over a particular host" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '109' +$cmd_typ=109; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for all services in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for all services in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '110' +$cmd_typ=110; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for all services in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for all services in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '111' +$cmd_typ=111; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable notifications for all hosts in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable notifications for all hosts in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '112' +$cmd_typ=112; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable notifications for all hosts in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable notifications for all hosts in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '113' +$cmd_typ=113; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to enable active checks of all services in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to enable active checks of all services in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '114' +$cmd_typ=114; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to disable active checks of all services in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to disable active checks of all services in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '121' +$cmd_typ=121; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for all hosts in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for all hosts in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '122' +$cmd_typ=122; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to schedule downtime for all services in a particular servicegroup/", "$local_cgi with cmd_typ=$cmd_typ shows request to schedule downtime for all services in a particular servicegroup" ); +like( $output, "/Servicegroup Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Servicegroup Name in form" ); +like( $output, "/Start Time:/", "$local_cgi with cmd_typ=$cmd_typ requires Start Time in form" ); +like( $output, "/End Time:/", "$local_cgi with cmd_typ=$cmd_typ requires End Time in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '159' +$cmd_typ=159; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to send a custom host notification/", "$local_cgi with cmd_typ=$cmd_typ shows request to send a custom host notification" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + +# Tests against command type '160' +$cmd_typ=160; +$output = `NAGIOS_CGI_CONFIG=etc/cgi.cfg $remote_user REQUEST_METHOD=GET QUERY_STRING='cmd_typ=$cmd_typ' $local_cgi`; +like( $output, "/You are requesting to send a custom service notification/", "$local_cgi with cmd_typ=$cmd_typ shows request to send a custom service notification" ); +like( $output, "/Host Name:/", "$local_cgi with cmd_typ=$cmd_typ requires Host Name in form" ); +like( $output, "/Service:/", "$local_cgi with cmd_typ=$cmd_typ requires Service in form" ); +like( $output, "/Author \\(Your Name\\):/", "$local_cgi with cmd_typ=$cmd_typ requires Author Name in form" ); +like( $output, "/Comment:/", "$local_cgi with cmd_typ=$cmd_typ requires Comment in form" ); +unlike( $output, "/Sorry, but no information is available for this command./", "$local_cgi with cmd_typ=$cmd_typ has a command description" ); + + + diff --git a/t/660status-downtimes-comments.t b/t/660status-downtimes-comments.t new file mode 100644 index 0000000..c327ab8 --- /dev/null +++ b/t/660status-downtimes-comments.t @@ -0,0 +1,64 @@ +#!/usr/bin/perl +# +# Checks for status.cgi, with large number of comments and downtimes + +use warnings; +use strict; +use Test::More; + +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $cgi_dir = "$topdir/cgi"; +my $status_cgi = "$cgi_dir/status.cgi"; +my $extinfo_cgi = "$cgi_dir/extinfo.cgi"; +my $status_dat = "$Bin/var/status.dat"; +my $generated = "$Bin/var/status-generated.dat"; +my $generator = "$Bin/bin/generate_downtimes"; + +my $output; +my $expected; + + +my $iteration = 1; +my $iterations_max = shift @ARGV || 5; +my $copies; + +plan tests => 3 * $iterations_max; + +while($iteration <= $iterations_max) { + $copies = (10)**($iteration); + is( system("cat $status_dat > $generated"), 0, "New status.dat file" ); + is( system("$generator $copies >> $generated"), 0, "Generated $copies downtimes"); + my $num_comments = $copies + 1; + + my $start = time; + $output = `NAGIOS_CGI_CONFIG=etc/cgi-with-generated-status.cfg REQUEST_METHOD=GET REMOTE_USER=nagiosadmin QUERY_STRING="host=host1" $status_cgi`; + my $duration = time-$start; + like( $output, "/This service has $num_comments comments associated with it/", "Found $num_comments comments in HTML output from status.dat. Took $duration seconds" ); + + # This test is invalid - the comments displayed are in the order they are read + # As the test status.dat generator is in a random order, the output will also be in the same + # random order + # Check that the comments ids are sorted + #$output = `NAGIOS_CGI_CONFIG=etc/cgi-with-generated-status.cfg REQUEST_METHOD=GET REMOTE_USER=nagiosadmin QUERY_STRING="type=2&host=host1&service=Dummy+service" $extinfo_cgi`; + #check_decrementing_comment_ids(); + + $iteration++; +} + +sub check_decrementing_comment_ids { + my $last_id; + my @ids = $output =~ m//g; + while ($_ = shift @ids) { + unless (defined $last_id && $last_id > $_) { + fail("Comment ids out of order"); + return; + } + $last_id = $_; + } + ok( "All ids in order" ); +} + diff --git a/t/705nagiostats.t b/t/705nagiostats.t new file mode 100644 index 0000000..4974294 --- /dev/null +++ b/t/705nagiostats.t @@ -0,0 +1,28 @@ +#!/usr/bin/perl +# +# Checks nagiostats + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $nagiostats = "$topdir/base/nagiostats"; +my $etc = "$Bin/etc"; + +plan tests => 5; + +my $output = `$nagiostats -c "$etc/nagios-does-not-exit.cfg"`; +isnt( $?, 0, "Bad return code with no config file" ); +like( $output, "/Error processing config file/", "No config file" ); + +$output = `$nagiostats -c "$etc/nagios-no-status.cfg"`; +isnt( $?, 0, "Bad return code with no status file" ); +like( $output, "/Error reading status file 'var/status.dat.no.such.file': No such file or directory/", "No config file" ); + +$output = `$nagiostats -c "$etc/nagios-no-status.cfg" -m NUMHSTUP`; +isnt( $?, 0, "Bad return code with no status file in MRTG mode" ); + diff --git a/t/900-configparsing.t b/t/900-configparsing.t new file mode 100644 index 0000000..3548b3c --- /dev/null +++ b/t/900-configparsing.t @@ -0,0 +1,37 @@ +#!/usr/bin/perl +# +# Taking a known nagios configuration directory, will check that the objects.cache is as expected + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $nagios = "$topdir/base/nagios"; +my $etc = "$Bin/etc"; +my $precache = "$Bin/var/objects.precache"; + +plan tests => 2; + +my $output = `$nagios -v "$etc/nagios.cfg"`; +if ($? == 0) { + pass("Nagios validated test configuration successfully"); +} else { + fail("Nagios validation failed:\n$output"); +} + +system("$nagios -vp '$etc/nagios.cfg' > /dev/null") == 0 or die "Cannot create precached objects file"; +system("grep -v 'Created:' $precache > '$precache.generated'"); + +my $diff = "diff -u $precache.expected $precache.generated"; +my @output = `$diff`; +if ($? == 0) { + pass( "Nagios precached objects file matches expected" ); +} else { + fail( "Nagios precached objects discrepency!!!\nTest with: $diff\nCopy with: cp $precache.generated $precache.expected" ); + print "#$_" foreach @output; +} + diff --git a/t/910-noservice.t b/t/910-noservice.t new file mode 100644 index 0000000..0038196 --- /dev/null +++ b/t/910-noservice.t @@ -0,0 +1,20 @@ +#!/usr/bin/perl +# +# Check that no service gives the correct message + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $nagios = "$topdir/base/nagios"; +my $etc = "$Bin/etc"; +my $precache = "$Bin/var/objects.precache"; + +plan tests => 1; + +my $output = `$nagios -v "$etc/nagios-no-service.cfg"`; +like( $output, "/Error: There are no services defined!/", "Correct error for no services" ); diff --git a/t/920-nocontactgroup.t b/t/920-nocontactgroup.t new file mode 100644 index 0000000..c7005a6 --- /dev/null +++ b/t/920-nocontactgroup.t @@ -0,0 +1,20 @@ +#!/usr/bin/perl +# +# Check that no contactgroup gives the correct message + +use warnings; +use strict; +use Test::More qw(no_plan); +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $nagios = "$topdir/base/nagios"; +my $etc = "$Bin/etc"; +my $precache = "$Bin/var/objects.precache"; + + +my $output = `$nagios -v "$etc/nagios-no-contactgroup.cfg"`; +like( $output, "/Error: Could not find any contactgroup matching 'nonexistantone'/", "Correct error for no contactgroup" ); +isnt($?, 0, "And get return code error" ); diff --git a/t/930-emptygroups.t b/t/930-emptygroups.t new file mode 100644 index 0000000..2df2074 --- /dev/null +++ b/t/930-emptygroups.t @@ -0,0 +1,26 @@ +#!/usr/bin/perl +# +# Check that empty host/service groups pass verfication. +# Likely error on non-patched version: +# "Error: Host 'r' specified in host group 'generic-pc' is not defined anywhere!" + +use warnings; +use strict; +use Test::More; +use FindBin qw($Bin); + +chdir $Bin or die "Cannot chdir"; + +my $topdir = "$Bin/.."; +my $nagios = "$topdir/base/nagios"; +my $etc = "$Bin/etc"; + +plan tests => 1; + +my @output = `$nagios -v "$etc/nagios-empty-groups.cfg"`; +if ($? == 0) { + pass("Nagios validated empty host/service-group successfully"); +} else { + @output = grep(/^Error: .+$/g, @output); + fail("Nagios validation failed:\n@output"); +} diff --git a/t/Makefile.in b/t/Makefile.in new file mode 100644 index 0000000..d6697d2 --- /dev/null +++ b/t/Makefile.in @@ -0,0 +1,11 @@ +# Makefile for Nagios tests using perl + +all: + +test: + prove *.t + +clean: + +distclean: + diff --git a/t/bin/generate_downtimes b/t/bin/generate_downtimes new file mode 100755 index 0000000..3ba7f3e --- /dev/null +++ b/t/bin/generate_downtimes @@ -0,0 +1,84 @@ +#!/usr/bin/perl +# Prints to stdout lots of host and service downtimes + +use warnings; +use strict; + +my $max_iterations = shift @ARGV || 1000; + +my $hostname = "host1"; +my $servicename = "Dummy service"; + +my $servicecomment_id_start=1024; +my $servicecomment_ids = {}; + +my $downtime_id = 2596; +my $starttime = 1920000000; +my $downtime_template = <{ $id }; + $servicecomment_ids->{ $id } = 1; + return $id; +} diff --git a/t/etc/cgi-hosturgencies.cfg b/t/etc/cgi-hosturgencies.cfg new file mode 100644 index 0000000..3eeb96e --- /dev/null +++ b/t/etc/cgi-hosturgencies.cfg @@ -0,0 +1,332 @@ +################################################################# +# +# CGI.CFG - Sample CGI Configuration File for Nagios 3.1.0 +# +# Last Modified: 11-30-2008 +# +################################################################# + + +# MAIN CONFIGURATION FILE +# This tells the CGIs where to find your main configuration file. +# The CGIs will read the main and host config files for any other +# data they might need. + +main_config_file=etc/nagios-hosturgencies.cfg + + + +# PHYSICAL HTML PATH +# This is the path where the HTML files for Nagios reside. This +# value is used to locate the logo images needed by the statusmap +# and statuswrl CGIs. + +physical_html_path=/usr/local/nagios/share + + + +# URL HTML PATH +# This is the path portion of the URL that corresponds to the +# physical location of the Nagios HTML files (as defined above). +# This value is used by the CGIs to locate the online documentation +# and graphics. If you access the Nagios pages with an URL like +# http://www.myhost.com/nagios, this value should be '/nagios' +# (without the quotes). + +url_html_path=/nagios + + + +# CONTEXT-SENSITIVE HELP +# This option determines whether or not a context-sensitive +# help icon will be displayed for most of the CGIs. +# Values: 0 = disables context-sensitive help +# 1 = enables context-sensitive help + +show_context_help=0 + + + +# PENDING STATES OPTION +# This option determines what states should be displayed in the web +# interface for hosts/services that have not yet been checked. +# Values: 0 = leave hosts/services that have not been check yet in their original state +# 1 = mark hosts/services that have not been checked yet as PENDING + +use_pending_states=1 + + + + +# AUTHENTICATION USAGE +# This option controls whether or not the CGIs will use any +# authentication when displaying host and service information, as +# well as committing commands to Nagios for processing. +# +# Read the HTML documentation to learn how the authorization works! +# +# NOTE: It is a really *bad* idea to disable authorization, unless +# you plan on removing the command CGI (cmd.cgi)! Failure to do +# so will leave you wide open to kiddies messing with Nagios and +# possibly hitting you with a denial of service attack by filling up +# your drive by continuously writing to your command file! +# +# Setting this value to 0 will cause the CGIs to *not* use +# authentication (bad idea), while any other value will make them +# use the authentication functions (the default). + +use_authentication=1 + + + + +# x509 CERT AUTHENTICATION +# When enabled, this option allows you to use x509 cert (SSL) +# authentication in the CGIs. This is an advanced option and should +# not be enabled unless you know what you're doing. + +use_ssl_authentication=0 + + + + +# DEFAULT USER +# Setting this variable will define a default user name that can +# access pages without authentication. This allows people within a +# secure domain (i.e., behind a firewall) to see the current status +# without authenticating. You may want to use this to avoid basic +# authentication if you are not using a secure server since basic +# authentication transmits passwords in the clear. +# +# Important: Do not define a default username unless you are +# running a secure web server and are sure that everyone who has +# access to the CGIs has been authenticated in some manner! If you +# define this variable, anyone who has not authenticated to the web +# server will inherit all rights you assign to this user! + +#default_user_name=guest + + + +# SYSTEM/PROCESS INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# have access to viewing the Nagios process information as +# provided by the Extended Information CGI (extinfo.cgi). By +# default, *no one* has access to this unless you choose to +# not use authorization. You may use an asterisk (*) to +# authorize any user who has authenticated to the web server. + +authorized_for_system_information=nagiosadmin + + + +# CONFIGURATION INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# can view ALL configuration information (hosts, commands, etc). +# By default, users can only view configuration information +# for the hosts and services they are contacts for. You may use +# an asterisk (*) to authorize any user who has authenticated +# to the web server. + +authorized_for_configuration_information=nagiosadmin + + + +# SYSTEM/PROCESS COMMAND ACCESS +# This option is a comma-delimited list of all usernames that +# can issue shutdown and restart commands to Nagios via the +# command CGI (cmd.cgi). Users in this list can also change +# the program mode to active or standby. By default, *no one* +# has access to this unless you choose to not use authorization. +# You may use an asterisk (*) to authorize any user who has +# authenticated to the web server. + +authorized_for_system_commands=nagiosadmin + + + +# GLOBAL HOST/SERVICE VIEW ACCESS +# These two options are comma-delimited lists of all usernames that +# can view information for all hosts and services that are being +# monitored. By default, users can only view information +# for hosts or services that they are contacts for (unless you +# you choose to not use authorization). You may use an asterisk (*) +# to authorize any user who has authenticated to the web server. + + +authorized_for_all_services=nagiosadmin +authorized_for_all_hosts=nagiosadmin + + + +# GLOBAL HOST/SERVICE COMMAND ACCESS +# These two options are comma-delimited lists of all usernames that +# can issue host or service related commands via the command +# CGI (cmd.cgi) for all hosts and services that are being monitored. +# By default, users can only issue commands for hosts or services +# that they are contacts for (unless you you choose to not use +# authorization). You may use an asterisk (*) to authorize any +# user who has authenticated to the web server. + +authorized_for_all_service_commands=nagiosadmin +authorized_for_all_host_commands=nagiosadmin + + + + +# STATUSMAP BACKGROUND IMAGE +# This option allows you to specify an image to be used as a +# background in the statusmap CGI. It is assumed that the image +# resides in the HTML images path (i.e. /usr/local/nagios/share/images). +# This path is automatically determined by appending "/images" +# to the path specified by the 'physical_html_path' directive. +# Note: The image file may be in GIF, PNG, JPEG, or GD2 format. +# However, I recommend that you convert your image to GD2 format +# (uncompressed), as this will cause less CPU load when the CGI +# generates the image. + +#statusmap_background_image=smbackground.gd2 + + + +# DEFAULT STATUSMAP LAYOUT METHOD +# This option allows you to specify the default layout method +# the statusmap CGI should use for drawing hosts. If you do +# not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 1 = Depth layers +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular +# 5 = Circular (Marked Up) + +default_statusmap_layout=5 + + + +# DEFAULT STATUSWRL LAYOUT METHOD +# This option allows you to specify the default layout method +# the statuswrl (VRML) CGI should use for drawing hosts. If you +# do not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular + +default_statuswrl_layout=4 + + + +# STATUSWRL INCLUDE +# This option allows you to include your own objects in the +# generated VRML world. It is assumed that the file +# resides in the HTML path (i.e. /usr/local/nagios/share). + +#statuswrl_include=myworld.wrl + + + +# PING SYNTAX +# This option determines what syntax should be used when +# attempting to ping a host from the WAP interface (using +# the statuswml CGI. You must include the full path to +# the ping binary, along with all required options. The +# $HOSTADDRESS$ macro is substituted with the address of +# the host before the command is executed. +# Please note that the syntax for the ping binary is +# notorious for being different on virtually ever *NIX +# OS and distribution, so you may have to tweak this to +# work on your system. + +ping_syntax=echo -n -U -c 5 $HOSTADDRESS$ + + + +# REFRESH RATE +# This option allows you to specify the refresh rate in seconds +# of various CGIs (status, statusmap, extinfo, and outages). + +refresh_rate=90 + + + +# ESCAPE HTML TAGS +# This option determines whether HTML tags in host and service +# status output is escaped in the web interface. If enabled, +# your plugin output will not be able to contain clickable links. + +escape_html_tags=1 + + + + +# SOUND OPTIONS +# These options allow you to specify an optional audio file +# that should be played in your browser window when there are +# problems on the network. The audio files are used only in +# the status CGI. Only the sound for the most critical problem +# will be played. Order of importance (higher to lower) is as +# follows: unreachable hosts, down hosts, critical services, +# warning services, and unknown services. If there are no +# visible problems, the sound file optionally specified by +# 'normal_sound' variable will be played. +# +# +# = +# +# Note: All audio files must be placed in the /media subdirectory +# under the HTML path (i.e. /usr/local/nagios/share/media/). + +#host_unreachable_sound=hostdown.wav +#host_down_sound=hostdown.wav +#service_critical_sound=critical.wav +#service_warning_sound=warning.wav +#service_unknown_sound=warning.wav +#normal_sound=noproblem.wav + + + +# URL TARGET FRAMES +# These options determine the target frames in which notes and +# action URLs will open. + +action_url_target=_blank +notes_url_target=_blank + + + + +# LOCK AUTHOR NAMES OPTION +# This option determines whether users can change the author name +# when submitting comments, scheduling downtime. If disabled, the +# author names will be locked into their contact name, as defined in Nagios. +# Values: 0 = allow editing author names +# 1 = lock author names (disallow editing) + +lock_author_names=1 + + + + +# SPLUNK INTEGRATION OPTIONS +# These options allow you to enable integration with Splunk +# in the web interface. If enabled, you'll be presented with +# "Splunk It" links in various places in the CGIs (log file, +# alert history, host/service detail, etc). Useful if you're +# trying to research why a particular problem occurred. +# For more information on Splunk, visit http://www.splunk.com/ + +# This option determines whether the Splunk integration is enabled +# Values: 0 = disable Splunk integration +# 1 = enable Splunk integration + +#enable_splunk_integration=1 + + +# This option should be the URL used to access your instance of Splunk + +#splunk_url=http://127.0.0.1:8000/ + + diff --git a/t/etc/cgi-with-generated-status.cfg b/t/etc/cgi-with-generated-status.cfg new file mode 100644 index 0000000..9da610c --- /dev/null +++ b/t/etc/cgi-with-generated-status.cfg @@ -0,0 +1,332 @@ +################################################################# +# +# CGI.CFG - Sample CGI Configuration File for Nagios 3.1.0 +# +# Last Modified: 11-30-2008 +# +################################################################# + + +# MAIN CONFIGURATION FILE +# This tells the CGIs where to find your main configuration file. +# The CGIs will read the main and host config files for any other +# data they might need. + +main_config_file=etc/nagios-with-generated-status.cfg + + + +# PHYSICAL HTML PATH +# This is the path where the HTML files for Nagios reside. This +# value is used to locate the logo images needed by the statusmap +# and statuswrl CGIs. + +physical_html_path=/usr/local/nagios/share + + + +# URL HTML PATH +# This is the path portion of the URL that corresponds to the +# physical location of the Nagios HTML files (as defined above). +# This value is used by the CGIs to locate the online documentation +# and graphics. If you access the Nagios pages with an URL like +# http://www.myhost.com/nagios, this value should be '/nagios' +# (without the quotes). + +url_html_path=/nagios + + + +# CONTEXT-SENSITIVE HELP +# This option determines whether or not a context-sensitive +# help icon will be displayed for most of the CGIs. +# Values: 0 = disables context-sensitive help +# 1 = enables context-sensitive help + +show_context_help=0 + + + +# PENDING STATES OPTION +# This option determines what states should be displayed in the web +# interface for hosts/services that have not yet been checked. +# Values: 0 = leave hosts/services that have not been check yet in their original state +# 1 = mark hosts/services that have not been checked yet as PENDING + +use_pending_states=1 + + + + +# AUTHENTICATION USAGE +# This option controls whether or not the CGIs will use any +# authentication when displaying host and service information, as +# well as committing commands to Nagios for processing. +# +# Read the HTML documentation to learn how the authorization works! +# +# NOTE: It is a really *bad* idea to disable authorization, unless +# you plan on removing the command CGI (cmd.cgi)! Failure to do +# so will leave you wide open to kiddies messing with Nagios and +# possibly hitting you with a denial of service attack by filling up +# your drive by continuously writing to your command file! +# +# Setting this value to 0 will cause the CGIs to *not* use +# authentication (bad idea), while any other value will make them +# use the authentication functions (the default). + +use_authentication=1 + + + + +# x509 CERT AUTHENTICATION +# When enabled, this option allows you to use x509 cert (SSL) +# authentication in the CGIs. This is an advanced option and should +# not be enabled unless you know what you're doing. + +use_ssl_authentication=0 + + + + +# DEFAULT USER +# Setting this variable will define a default user name that can +# access pages without authentication. This allows people within a +# secure domain (i.e., behind a firewall) to see the current status +# without authenticating. You may want to use this to avoid basic +# authentication if you are not using a secure server since basic +# authentication transmits passwords in the clear. +# +# Important: Do not define a default username unless you are +# running a secure web server and are sure that everyone who has +# access to the CGIs has been authenticated in some manner! If you +# define this variable, anyone who has not authenticated to the web +# server will inherit all rights you assign to this user! + +#default_user_name=guest + + + +# SYSTEM/PROCESS INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# have access to viewing the Nagios process information as +# provided by the Extended Information CGI (extinfo.cgi). By +# default, *no one* has access to this unless you choose to +# not use authorization. You may use an asterisk (*) to +# authorize any user who has authenticated to the web server. + +authorized_for_system_information=nagiosadmin + + + +# CONFIGURATION INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# can view ALL configuration information (hosts, commands, etc). +# By default, users can only view configuration information +# for the hosts and services they are contacts for. You may use +# an asterisk (*) to authorize any user who has authenticated +# to the web server. + +authorized_for_configuration_information=nagiosadmin + + + +# SYSTEM/PROCESS COMMAND ACCESS +# This option is a comma-delimited list of all usernames that +# can issue shutdown and restart commands to Nagios via the +# command CGI (cmd.cgi). Users in this list can also change +# the program mode to active or standby. By default, *no one* +# has access to this unless you choose to not use authorization. +# You may use an asterisk (*) to authorize any user who has +# authenticated to the web server. + +authorized_for_system_commands=nagiosadmin + + + +# GLOBAL HOST/SERVICE VIEW ACCESS +# These two options are comma-delimited lists of all usernames that +# can view information for all hosts and services that are being +# monitored. By default, users can only view information +# for hosts or services that they are contacts for (unless you +# you choose to not use authorization). You may use an asterisk (*) +# to authorize any user who has authenticated to the web server. + + +authorized_for_all_services=nagiosadmin +authorized_for_all_hosts=nagiosadmin + + + +# GLOBAL HOST/SERVICE COMMAND ACCESS +# These two options are comma-delimited lists of all usernames that +# can issue host or service related commands via the command +# CGI (cmd.cgi) for all hosts and services that are being monitored. +# By default, users can only issue commands for hosts or services +# that they are contacts for (unless you you choose to not use +# authorization). You may use an asterisk (*) to authorize any +# user who has authenticated to the web server. + +authorized_for_all_service_commands=nagiosadmin +authorized_for_all_host_commands=nagiosadmin + + + + +# STATUSMAP BACKGROUND IMAGE +# This option allows you to specify an image to be used as a +# background in the statusmap CGI. It is assumed that the image +# resides in the HTML images path (i.e. /usr/local/nagios/share/images). +# This path is automatically determined by appending "/images" +# to the path specified by the 'physical_html_path' directive. +# Note: The image file may be in GIF, PNG, JPEG, or GD2 format. +# However, I recommend that you convert your image to GD2 format +# (uncompressed), as this will cause less CPU load when the CGI +# generates the image. + +#statusmap_background_image=smbackground.gd2 + + + +# DEFAULT STATUSMAP LAYOUT METHOD +# This option allows you to specify the default layout method +# the statusmap CGI should use for drawing hosts. If you do +# not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 1 = Depth layers +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular +# 5 = Circular (Marked Up) + +default_statusmap_layout=5 + + + +# DEFAULT STATUSWRL LAYOUT METHOD +# This option allows you to specify the default layout method +# the statuswrl (VRML) CGI should use for drawing hosts. If you +# do not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular + +default_statuswrl_layout=4 + + + +# STATUSWRL INCLUDE +# This option allows you to include your own objects in the +# generated VRML world. It is assumed that the file +# resides in the HTML path (i.e. /usr/local/nagios/share). + +#statuswrl_include=myworld.wrl + + + +# PING SYNTAX +# This option determines what syntax should be used when +# attempting to ping a host from the WAP interface (using +# the statuswml CGI. You must include the full path to +# the ping binary, along with all required options. The +# $HOSTADDRESS$ macro is substituted with the address of +# the host before the command is executed. +# Please note that the syntax for the ping binary is +# notorious for being different on virtually ever *NIX +# OS and distribution, so you may have to tweak this to +# work on your system. + +ping_syntax=echo -n -U -c 5 $HOSTADDRESS$ + + + +# REFRESH RATE +# This option allows you to specify the refresh rate in seconds +# of various CGIs (status, statusmap, extinfo, and outages). + +refresh_rate=90 + + + +# ESCAPE HTML TAGS +# This option determines whether HTML tags in host and service +# status output is escaped in the web interface. If enabled, +# your plugin output will not be able to contain clickable links. + +escape_html_tags=1 + + + + +# SOUND OPTIONS +# These options allow you to specify an optional audio file +# that should be played in your browser window when there are +# problems on the network. The audio files are used only in +# the status CGI. Only the sound for the most critical problem +# will be played. Order of importance (higher to lower) is as +# follows: unreachable hosts, down hosts, critical services, +# warning services, and unknown services. If there are no +# visible problems, the sound file optionally specified by +# 'normal_sound' variable will be played. +# +# +# = +# +# Note: All audio files must be placed in the /media subdirectory +# under the HTML path (i.e. /usr/local/nagios/share/media/). + +#host_unreachable_sound=hostdown.wav +#host_down_sound=hostdown.wav +#service_critical_sound=critical.wav +#service_warning_sound=warning.wav +#service_unknown_sound=warning.wav +#normal_sound=noproblem.wav + + + +# URL TARGET FRAMES +# These options determine the target frames in which notes and +# action URLs will open. + +action_url_target=_blank +notes_url_target=_blank + + + + +# LOCK AUTHOR NAMES OPTION +# This option determines whether users can change the author name +# when submitting comments, scheduling downtime. If disabled, the +# author names will be locked into their contact name, as defined in Nagios. +# Values: 0 = allow editing author names +# 1 = lock author names (disallow editing) + +lock_author_names=1 + + + + +# SPLUNK INTEGRATION OPTIONS +# These options allow you to enable integration with Splunk +# in the web interface. If enabled, you'll be presented with +# "Splunk It" links in various places in the CGIs (log file, +# alert history, host/service detail, etc). Useful if you're +# trying to research why a particular problem occurred. +# For more information on Splunk, visit http://www.splunk.com/ + +# This option determines whether the Splunk integration is enabled +# Values: 0 = disable Splunk integration +# 1 = enable Splunk integration + +#enable_splunk_integration=1 + + +# This option should be the URL used to access your instance of Splunk + +#splunk_url=http://127.0.0.1:8000/ + + diff --git a/t/etc/cgi.cfg b/t/etc/cgi.cfg new file mode 100644 index 0000000..a15825b --- /dev/null +++ b/t/etc/cgi.cfg @@ -0,0 +1,332 @@ +################################################################# +# +# CGI.CFG - Sample CGI Configuration File for Nagios 3.1.0 +# +# Last Modified: 11-30-2008 +# +################################################################# + + +# MAIN CONFIGURATION FILE +# This tells the CGIs where to find your main configuration file. +# The CGIs will read the main and host config files for any other +# data they might need. + +main_config_file=etc/nagios.cfg + + + +# PHYSICAL HTML PATH +# This is the path where the HTML files for Nagios reside. This +# value is used to locate the logo images needed by the statusmap +# and statuswrl CGIs. + +physical_html_path=/usr/local/nagios/share + + + +# URL HTML PATH +# This is the path portion of the URL that corresponds to the +# physical location of the Nagios HTML files (as defined above). +# This value is used by the CGIs to locate the online documentation +# and graphics. If you access the Nagios pages with an URL like +# http://www.myhost.com/nagios, this value should be '/nagios' +# (without the quotes). + +url_html_path=/nagios + + + +# CONTEXT-SENSITIVE HELP +# This option determines whether or not a context-sensitive +# help icon will be displayed for most of the CGIs. +# Values: 0 = disables context-sensitive help +# 1 = enables context-sensitive help + +show_context_help=0 + + + +# PENDING STATES OPTION +# This option determines what states should be displayed in the web +# interface for hosts/services that have not yet been checked. +# Values: 0 = leave hosts/services that have not been check yet in their original state +# 1 = mark hosts/services that have not been checked yet as PENDING + +use_pending_states=1 + + + + +# AUTHENTICATION USAGE +# This option controls whether or not the CGIs will use any +# authentication when displaying host and service information, as +# well as committing commands to Nagios for processing. +# +# Read the HTML documentation to learn how the authorization works! +# +# NOTE: It is a really *bad* idea to disable authorization, unless +# you plan on removing the command CGI (cmd.cgi)! Failure to do +# so will leave you wide open to kiddies messing with Nagios and +# possibly hitting you with a denial of service attack by filling up +# your drive by continuously writing to your command file! +# +# Setting this value to 0 will cause the CGIs to *not* use +# authentication (bad idea), while any other value will make them +# use the authentication functions (the default). + +use_authentication=1 + + + + +# x509 CERT AUTHENTICATION +# When enabled, this option allows you to use x509 cert (SSL) +# authentication in the CGIs. This is an advanced option and should +# not be enabled unless you know what you're doing. + +use_ssl_authentication=0 + + + + +# DEFAULT USER +# Setting this variable will define a default user name that can +# access pages without authentication. This allows people within a +# secure domain (i.e., behind a firewall) to see the current status +# without authenticating. You may want to use this to avoid basic +# authentication if you are not using a secure server since basic +# authentication transmits passwords in the clear. +# +# Important: Do not define a default username unless you are +# running a secure web server and are sure that everyone who has +# access to the CGIs has been authenticated in some manner! If you +# define this variable, anyone who has not authenticated to the web +# server will inherit all rights you assign to this user! + +#default_user_name=guest + + + +# SYSTEM/PROCESS INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# have access to viewing the Nagios process information as +# provided by the Extended Information CGI (extinfo.cgi). By +# default, *no one* has access to this unless you choose to +# not use authorization. You may use an asterisk (*) to +# authorize any user who has authenticated to the web server. + +authorized_for_system_information=nagiosadmin + + + +# CONFIGURATION INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# can view ALL configuration information (hosts, commands, etc). +# By default, users can only view configuration information +# for the hosts and services they are contacts for. You may use +# an asterisk (*) to authorize any user who has authenticated +# to the web server. + +authorized_for_configuration_information=nagiosadmin + + + +# SYSTEM/PROCESS COMMAND ACCESS +# This option is a comma-delimited list of all usernames that +# can issue shutdown and restart commands to Nagios via the +# command CGI (cmd.cgi). Users in this list can also change +# the program mode to active or standby. By default, *no one* +# has access to this unless you choose to not use authorization. +# You may use an asterisk (*) to authorize any user who has +# authenticated to the web server. + +authorized_for_system_commands=nagiosadmin + + + +# GLOBAL HOST/SERVICE VIEW ACCESS +# These two options are comma-delimited lists of all usernames that +# can view information for all hosts and services that are being +# monitored. By default, users can only view information +# for hosts or services that they are contacts for (unless you +# you choose to not use authorization). You may use an asterisk (*) +# to authorize any user who has authenticated to the web server. + + +authorized_for_all_services=nagiosadmin +authorized_for_all_hosts=nagiosadmin + + + +# GLOBAL HOST/SERVICE COMMAND ACCESS +# These two options are comma-delimited lists of all usernames that +# can issue host or service related commands via the command +# CGI (cmd.cgi) for all hosts and services that are being monitored. +# By default, users can only issue commands for hosts or services +# that they are contacts for (unless you you choose to not use +# authorization). You may use an asterisk (*) to authorize any +# user who has authenticated to the web server. + +authorized_for_all_service_commands=nagiosadmin +authorized_for_all_host_commands=nagiosadmin + + + + +# STATUSMAP BACKGROUND IMAGE +# This option allows you to specify an image to be used as a +# background in the statusmap CGI. It is assumed that the image +# resides in the HTML images path (i.e. /usr/local/nagios/share/images). +# This path is automatically determined by appending "/images" +# to the path specified by the 'physical_html_path' directive. +# Note: The image file may be in GIF, PNG, JPEG, or GD2 format. +# However, I recommend that you convert your image to GD2 format +# (uncompressed), as this will cause less CPU load when the CGI +# generates the image. + +#statusmap_background_image=smbackground.gd2 + + + +# DEFAULT STATUSMAP LAYOUT METHOD +# This option allows you to specify the default layout method +# the statusmap CGI should use for drawing hosts. If you do +# not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 1 = Depth layers +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular +# 5 = Circular (Marked Up) + +default_statusmap_layout=5 + + + +# DEFAULT STATUSWRL LAYOUT METHOD +# This option allows you to specify the default layout method +# the statuswrl (VRML) CGI should use for drawing hosts. If you +# do not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular + +default_statuswrl_layout=4 + + + +# STATUSWRL INCLUDE +# This option allows you to include your own objects in the +# generated VRML world. It is assumed that the file +# resides in the HTML path (i.e. /usr/local/nagios/share). + +#statuswrl_include=myworld.wrl + + + +# PING SYNTAX +# This option determines what syntax should be used when +# attempting to ping a host from the WAP interface (using +# the statuswml CGI. You must include the full path to +# the ping binary, along with all required options. The +# $HOSTADDRESS$ macro is substituted with the address of +# the host before the command is executed. +# Please note that the syntax for the ping binary is +# notorious for being different on virtually ever *NIX +# OS and distribution, so you may have to tweak this to +# work on your system. + +ping_syntax=echo -n -U -c 5 $HOSTADDRESS$ + + + +# REFRESH RATE +# This option allows you to specify the refresh rate in seconds +# of various CGIs (status, statusmap, extinfo, and outages). + +refresh_rate=90 + + + +# ESCAPE HTML TAGS +# This option determines whether HTML tags in host and service +# status output is escaped in the web interface. If enabled, +# your plugin output will not be able to contain clickable links. + +escape_html_tags=1 + + + + +# SOUND OPTIONS +# These options allow you to specify an optional audio file +# that should be played in your browser window when there are +# problems on the network. The audio files are used only in +# the status CGI. Only the sound for the most critical problem +# will be played. Order of importance (higher to lower) is as +# follows: unreachable hosts, down hosts, critical services, +# warning services, and unknown services. If there are no +# visible problems, the sound file optionally specified by +# 'normal_sound' variable will be played. +# +# +# = +# +# Note: All audio files must be placed in the /media subdirectory +# under the HTML path (i.e. /usr/local/nagios/share/media/). + +#host_unreachable_sound=hostdown.wav +#host_down_sound=hostdown.wav +#service_critical_sound=critical.wav +#service_warning_sound=warning.wav +#service_unknown_sound=warning.wav +#normal_sound=noproblem.wav + + + +# URL TARGET FRAMES +# These options determine the target frames in which notes and +# action URLs will open. + +action_url_target=_blank +notes_url_target=_blank + + + + +# LOCK AUTHOR NAMES OPTION +# This option determines whether users can change the author name +# when submitting comments, scheduling downtime. If disabled, the +# author names will be locked into their contact name, as defined in Nagios. +# Values: 0 = allow editing author names +# 1 = lock author names (disallow editing) + +lock_author_names=1 + + + + +# SPLUNK INTEGRATION OPTIONS +# These options allow you to enable integration with Splunk +# in the web interface. If enabled, you'll be presented with +# "Splunk It" links in various places in the CGIs (log file, +# alert history, host/service detail, etc). Useful if you're +# trying to research why a particular problem occurred. +# For more information on Splunk, visit http://www.splunk.com/ + +# This option determines whether the Splunk integration is enabled +# Values: 0 = disable Splunk integration +# 1 = enable Splunk integration + +#enable_splunk_integration=1 + + +# This option should be the URL used to access your instance of Splunk + +#splunk_url=http://127.0.0.1:8000/ + + diff --git a/t/etc/empty-groups-error.cfg b/t/etc/empty-groups-error.cfg new file mode 100644 index 0000000..4220276 --- /dev/null +++ b/t/etc/empty-groups-error.cfg @@ -0,0 +1,53 @@ +define command{ + command_name dummy + command_line /bin/true + } + +define timeperiod{ + timeperiod_name never + alias Never +} + +define contact{ + contact_name dude + host_notification_period never + host_notification_commands dummy + service_notification_period never + service_notification_commands dummy + } + +define host{ + host_name fake + alias Fake + address 127.0.0.1 + check_command dummy + check_period never + max_check_attempts 5 + contacts dude + } + +define service{ + name dummy-service + service_description Dummy Service + check_command dummy + check_period never + max_check_attempts 5 + notification_period never + contacts dude + host_name fake + } + +define hostgroup{ + hostgroup_name generic-pc + alias Generic PCs + } + +define host{ + name generic-host + hostgroups generic-pc + check_command dummy + check_period never + max_check_attempts 5 + contacts dude + register 0 + } diff --git a/t/etc/hosturgencies.cfg b/t/etc/hosturgencies.cfg new file mode 100644 index 0000000..53d9133 --- /dev/null +++ b/t/etc/hosturgencies.cfg @@ -0,0 +1,56 @@ +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define host { + host_name host2 + alias host2 test + address 192.168.2.2 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define host { + host_name host3 + alias host3 test + address 192.168.3.3 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define host { + host_name host4 + alias host4 test + address 192.168.4.4 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define service { + host_name host1,host2,host3,host4 + service_description Dummy service + check_command check_me + max_check_attempts 3 + check_interval 32 + retry_interval 1 + check_period none + notification_interval 60 + notification_period none + contacts nagiosadmin +} diff --git a/t/etc/minimal.cfg b/t/etc/minimal.cfg new file mode 100644 index 0000000..abdb600 --- /dev/null +++ b/t/etc/minimal.cfg @@ -0,0 +1,183 @@ +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define host { + host_name host2 + alias host2 test + address 192.168.2.2 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define host { + host_name host3 + alias host3 test + address 192.168.2.3 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none + hostgroups +hosts-with-master-service +} + +define hostgroup { + hostgroup_name hosts-with-master-service + alias Hosts running a master service +} + +define service { + host_name host1 + service_description Dummy service + check_command check_me + max_check_attempts 3 + check_interval 32 + retry_interval 1 + check_period none + notification_interval 60 + notification_period none + contacts nagiosadmin +} + +define service { + host_name host1,host2 + service_description Uses important check command + check_command check_me!with some parameters + max_check_attempts 5 + check_interval 15 + retry_interval 1 + check_period none + notification_interval 65 + notification_period none + contacts nagiosadmin + use service-distributed +} + +define service { + name service-distributed + check_command !set_to_stale + register 0 +} + +define service { + hostgroup_name hosts-with-master-service + service_description master-service + check_command check_me!master service + max_check_attempts 5 + check_interval 15 + retry_interval 1 + check_period none + notification_interval 65 + notification_period none + contacts nagiosadmin +} + +define service { + host_name host3 + service_description dependent-service + check_command check_me!dependent service + max_check_attempts 5 + check_interval 15 + retry_interval 1 + check_period none + notification_interval 65 + notification_period none + contacts nagiosadmin + servicegroups +services-depending-on-master-service +} + +define servicegroup { + servicegroup_name services-depending-on-master-service + alias Servicegroup for services depending on a "master" service on the same host +} + +define command { + command_name set_to_stale + command_line /usr/local/nagios/libexec/set_to_stale +} + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me +} + +define command { + command_name with_continuation_lines + command_line $USER1$/check_foo one\ + two +} + +define command { + command_name multiple_continuation_lines_with_spaces_intermingled + command_line \ + check_nrpe_arg!30!\ + check_fs_ping!/mnt/account-p,/mnt/prepro-p,/mnt/webapp-ssl,/mnt/rollout-p +} + +define timeperiod { + timeperiod_name none + alias Nothing +} + +define contact { + contact_name nagiosadmin + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none +} + +define contact { + contact_name second + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members nagiosadmin,second +} + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation +} + +define serviceescalation { + host_name * + service_description *,!Dummy service +} + +define servicedependency { + service_description master-service + dependent_servicegroup_name services-depending-on-master-service + execution_failure_criteria n + notification_failure_criteria c,u +} diff --git a/t/etc/nagios-empty-groups.cfg b/t/etc/nagios-empty-groups.cfg new file mode 100644 index 0000000..e6eafe8 --- /dev/null +++ b/t/etc/nagios-empty-groups.cfg @@ -0,0 +1,1305 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=empty-groups-error.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=var/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 diff --git a/t/etc/nagios-hosturgencies.cfg b/t/etc/nagios-hosturgencies.cfg new file mode 100644 index 0000000..ffc13ba --- /dev/null +++ b/t/etc/nagios-hosturgencies.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=hosturgencies.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache.hosturgencies + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache.hosturgencies + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=var/status-hosturgencies.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t/etc/nagios-no-contactgroup.cfg b/t/etc/nagios-no-contactgroup.cfg new file mode 100644 index 0000000..519d8f8 --- /dev/null +++ b/t/etc/nagios-no-contactgroup.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=/usr/local/nagios/var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=no-contactgroup-error.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=/usr/local/nagios/var/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=/usr/local/nagios/var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=/usr/local/nagios/var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=/usr/local/nagios/var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=/usr/local/nagios/var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=/usr/local/nagios/var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=/usr/local/nagios/var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t/etc/nagios-no-service.cfg b/t/etc/nagios-no-service.cfg new file mode 100644 index 0000000..a6fd60c --- /dev/null +++ b/t/etc/nagios-no-service.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=/usr/local/nagios/var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=no-service-error.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=/usr/local/nagios/var/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=/usr/local/nagios/var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=/usr/local/nagios/var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=/usr/local/nagios/var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=/usr/local/nagios/var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=/usr/local/nagios/var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=/usr/local/nagios/var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t/etc/nagios-no-status.cfg b/t/etc/nagios-no-status.cfg new file mode 100644 index 0000000..94a9fb6 --- /dev/null +++ b/t/etc/nagios-no-status.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=minimal.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=var/status.dat.no.such.file + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t/etc/nagios-with-generated-status.cfg b/t/etc/nagios-with-generated-status.cfg new file mode 100644 index 0000000..f438919 --- /dev/null +++ b/t/etc/nagios-with-generated-status.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=minimal.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=var/status-generated.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t/etc/nagios.cfg b/t/etc/nagios.cfg new file mode 100644 index 0000000..c5d2923 --- /dev/null +++ b/t/etc/nagios.cfg @@ -0,0 +1,1307 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 3.1.0 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-14-2008 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=var/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. + +# Note: A relative path here is relative to the location of the overall nagios.cfg file, +# not relative to the current directory +cfg_file=minimal.cfg + +# You can also tell Nagios to process all config files (with a .cfg +# extension) in a particular directory by using the cfg_dir +# directive as shown below: + +#cfg_dir=/usr/local/nagios/etc/servers +#cfg_dir=/usr/local/nagios/etc/printers +#cfg_dir=/usr/local/nagios/etc/switches +#cfg_dir=/usr/local/nagios/etc/routers + + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=var/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=var/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=etc/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=var/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=1 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=var/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=var/nagios.lock + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=var/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module= [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=var/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=var/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=var/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# CHECK FOR UPDATES +# This option determines whether Nagios will automatically check to +# see if new updates (releases) are available. It is recommend that you +# enable this option to ensure that you stay on top of the latest critical +# patches to Nagios. Nagios is critical to you - make sure you keep it in +# good shape. Nagios will check once a day for new updates. Data collected +# by Nagios Enterprises from the update check is processed in accordance +# with our privacy policy - see http://api.nagios.org for details. + +check_for_updates=1 + + + +# BARE UPDATE CHECK +# This option deterines what data Nagios will send to api.nagios.org when +# it checks for updates. By default, Nagios will send information on the +# current version of Nagios you have installed, as well as an indicator as +# to whether this was a new installation or not. Nagios Enterprises uses +# this data to determine the number of users running specific version of +# Nagios. Enable this option if you do not want this information to be sent. + +bare_update_check=0 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# +# SetEnv TZ "Australia/Brisbane" +# ... +# + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/local/nagios/bin/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=nagios@localhost +admin_pager=pagenagios@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=var/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/t/etc/no-contactgroup-error.cfg b/t/etc/no-contactgroup-error.cfg new file mode 100644 index 0000000..01dac44 --- /dev/null +++ b/t/etc/no-contactgroup-error.cfg @@ -0,0 +1,128 @@ +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define host { + host_name host2 + alias host2 test + address 192.168.2.2 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define service { + host_name host1 + service_description Dummy service + check_command check_me + max_check_attempts 3 + check_interval 32 + retry_interval 1 + check_period none + notification_interval 60 + notification_period none + contacts nagiosadmin +} + +define service { + host_name host1,host2 + service_description Uses important check command + check_command check_me!with some parameters + max_check_attempts 5 + check_interval 15 + retry_interval 1 + check_period none + notification_interval 65 + notification_period none + contacts nagiosadmin + use service-distributed +} + +define service { + name service-distributed + check_command !set_to_stale + register 0 +} + +define command { + command_name set_to_stale + command_line /usr/local/nagios/libexec/set_to_stale +} + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me +} + +define command { + command_name with_continuation_lines + command_line $USER1$/check_foo one\ + two +} + +define command { + command_name multiple_continuation_lines_with_spaces_intermingled + command_line \ + check_nrpe_arg!30!\ + check_fs_ping!/mnt/account-p,/mnt/prepro-p,/mnt/webapp-ssl,/mnt/rollout-p +} + +define timeperiod { + timeperiod_name none + alias Nothing +} + +define contact { + contact_name nagiosadmin + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none + contact_groups nonexistantone +} + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none +} + +define contact { + contact_name second + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members nagiosadmin,second +} + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation +} + +define serviceescalation { + host_name * + service_description *,!Dummy service +} diff --git a/t/etc/no-service-error.cfg b/t/etc/no-service-error.cfg new file mode 100644 index 0000000..df3a151 --- /dev/null +++ b/t/etc/no-service-error.cfg @@ -0,0 +1,61 @@ +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + max_check_attempts 2 + check_period none + contacts nagiosadmin + notification_interval 60 + notification_period none +} + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me +} + +define timeperiod { + timeperiod_name none + alias Nothing +} + +define contact { + contact_name nagiosadmin + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none +} + +define contact { + contact_name second + host_notifications_enabled 0 + service_notifications_enabled 0 + host_notification_period none + service_notification_period none + host_notification_options d,u,f,r,s + service_notification_options w,u,c,r,f,s + host_notification_commands notify-none + service_notification_commands notify-none +} + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members nagiosadmin,second +} + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation +} + diff --git a/t/etc/resource.cfg b/t/etc/resource.cfg new file mode 100644 index 0000000..153d8ca --- /dev/null +++ b/t/etc/resource.cfg @@ -0,0 +1 @@ +#Empty file diff --git a/t/var/.gitignore b/t/var/.gitignore new file mode 100644 index 0000000..de5cb46 --- /dev/null +++ b/t/var/.gitignore @@ -0,0 +1,2 @@ +objects.precache* +status-generated.dat diff --git a/t/var/nagios.log b/t/var/nagios.log new file mode 100644 index 0000000..9a79cd3 --- /dev/null +++ b/t/var/nagios.log @@ -0,0 +1,8 @@ +[1242341771] Nagios 3.1.0 starting... (PID=48448) +[1242341771] Local time is Thu May 14 23:56:11 BST 2009 +[1242341771] LOG VERSION: 2.0 +[1242341771] Error: Could not create external command file 'var/rw/nagios.cmd' as named pipe: (2) -> No such file or directory. If this file already exists and you are sure that another copy of Nagios is not running, you should delete this file. +[1242341771] Bailing out due to errors encountered while trying to initialize the external command file... (PID=48448) +[1242341791] Nagios 3.1.0 starting... (PID=48451) +[1242341791] Local time is Thu May 14 23:56:31 BST 2009 +[1242341791] LOG VERSION: 2.0 diff --git a/t/var/objects.cache b/t/var/objects.cache new file mode 100644 index 0000000..a661b7c --- /dev/null +++ b/t/var/objects.cache @@ -0,0 +1,197 @@ +######################################## +# NAGIOS OBJECT CACHE FILE +# +# THIS FILE IS AUTOMATICALLY GENERATED +# BY NAGIOS. DO NOT MODIFY THIS FILE! +# +# Created: Thu May 14 23:56:31 2009 +######################################## + +define timeperiod { + timeperiod_name none + alias Nothing + } + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me + } + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none + } + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members second,nagiosadmin + } + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation + } + +define contact { + contact_name nagiosadmin + service_notification_period none + host_notification_period none + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-none + host_notification_commands notify-none + host_notifications_enabled 0 + service_notifications_enabled 0 + can_submit_commands 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define contact { + contact_name second + service_notification_period none + host_notification_period none + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-none + host_notification_commands notify-none + host_notifications_enabled 0 + service_notifications_enabled 0 + can_submit_commands 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name host2 + alias host2 test + address 192.168.1.2 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host1 + service_description Dummy service + check_period none + check_command check_me + contacts nagiosadmin + notification_period none + initial_state o + check_interval 32.000000 + retry_interval 1.000000 + max_check_attempts 3 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host2 + service_description Dummy service + check_period none + check_command check_me + contacts nagiosadmin + notification_period none + initial_state o + check_interval 32.000000 + retry_interval 1.000000 + max_check_attempts 3 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + diff --git a/t/var/objects.cache.hosturgencies b/t/var/objects.cache.hosturgencies new file mode 100644 index 0000000..ddda905 --- /dev/null +++ b/t/var/objects.cache.hosturgencies @@ -0,0 +1,338 @@ +######################################## +# NAGIOS OBJECT CACHE FILE +# +# THIS FILE IS AUTOMATICALLY GENERATED +# BY NAGIOS. DO NOT MODIFY THIS FILE! +# +# Created: Mon Mar 21 20:09:19 2011 +######################################## + +define timeperiod { + timeperiod_name 24x7 + alias 24x7 base on weekdays + sunday 00:00-24:00 + monday 00:00-24:00 + tuesday 00:00-24:00 + wednesday 00:00-24:00 + thursday 00:00-24:00 + friday 00:00-24:00 + saturday 00:00-24:00 + } + +define timeperiod { + timeperiod_name Test_exclude + alias Test for exclude timeperiod + tuesday -1 - monday 1 16:30-24:00 + exclude myexclude + } + +define timeperiod { + timeperiod_name Test_exclude2 + alias Test2 for exclude timeperiod + tuesday 2 16:30-24:00 + exclude myexclude2 + } + +define timeperiod { + timeperiod_name Test_exclude3 + alias Test3 for exclude timeperiod + tuesday 2 16:30-24:00 + exclude myexclude3 + } + +define timeperiod { + timeperiod_name Test_exclude4 + alias Test for exclude timeperiod + tuesday -1 - monday 1 16:30-24:00 + exclude myexclude4 + } + +define timeperiod { + timeperiod_name myexclude + alias myexclude + april 1 - august 16 00:00-24:00 + saturday -1 - monday 1 16:00-24:00 + } + +define timeperiod { + timeperiod_name myexclude2 + alias myexclude2 + tuesday 00:00-23:58 + } + +define timeperiod { + timeperiod_name myexclude3 + alias myexclude3 + april 1 - august 16 00:00-24:00 + } + +define timeperiod { + timeperiod_name myexclude4 + alias myexclude4 + april 1 - august 16 00:00-24:00 + } + +define timeperiod { + timeperiod_name none + alias Nothing + } + +define timeperiod { + timeperiod_name sunday_only + alias Avoid time clock change hours + sunday 00:00-01:15,03:15-22:00 + } + +define timeperiod { + timeperiod_name weekly_complex + alias Complex weekly timeperiods + sunday 00:00-09:45,14:15-24:00 + monday 01:15-23:15 + tuesday 01:15-23:15 + wednesday 01:15-23:15 + thursday 01:15-23:15 + friday 01:15-23:15 + saturday 00:00-22:00,23:00-24:00 + } + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me + } + +define command { + command_name multiple_continuation_lines_with_spaces_intermingled + command_line check_nrpe_arg!30!check_fs_ping!/mnt/account-p,/mnt/prepro-p,/mnt/webapp-ssl,/mnt/rollout-p + } + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none + } + +define command { + command_name set_to_stale + command_line /usr/local/nagios/libexec/set_to_stale + } + +define command { + command_name with_continuation_lines + command_line $USER1$/check_foo onetwo + } + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members second,nagiosadmin + } + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation + } + +define hostgroup { + hostgroup_name hostgroup1 + members host1,hostveryrecent + } + +define hostgroup { + hostgroup_name hostgroup2 + } + +define contact { + contact_name nagiosadmin + service_notification_period none + host_notification_period none + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-none + host_notification_commands notify-none + host_notifications_enabled 0 + service_notifications_enabled 0 + can_submit_commands 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define contact { + contact_name second + service_notification_period none + host_notification_period none + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-none + host_notification_commands notify-none + host_notifications_enabled 0 + service_notifications_enabled 0 + can_submit_commands 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name hostveryrecent + alias hostveryrecent test + address 192.168.1.1 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host1 + service_description Dummy service + check_period none + check_command check_me + contacts nagiosadmin + notification_period none + initial_state o + check_interval 32.000000 + retry_interval 1.000000 + max_check_attempts 3 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host1 + service_description Dummy service2 + check_period none + check_command check_me + contacts nagiosadmin + notification_period none + initial_state o + check_interval 32.000000 + retry_interval 1.000000 + max_check_attempts 3 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host1 + service_description Uses important check command + check_period none + check_command set_to_stale + contacts nagiosadmin + notification_period none + initial_state o + check_interval 15.000000 + retry_interval 1.000000 + max_check_attempts 5 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 65.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + diff --git a/t/var/objects.precache.expected b/t/var/objects.precache.expected new file mode 100644 index 0000000..34da93d --- /dev/null +++ b/t/var/objects.precache.expected @@ -0,0 +1,411 @@ +######################################## +# NAGIOS OBJECT CACHE FILE +# +# THIS FILE IS AUTOMATICALLY GENERATED +# BY NAGIOS. DO NOT MODIFY THIS FILE! +# +######################################## + +define timeperiod { + timeperiod_name none + alias Nothing + } + +define command { + command_name check_me + command_line /usr/local/nagios/libexec/check_me + } + +define command { + command_name multiple_continuation_lines_with_spaces_intermingled + command_line check_nrpe_arg!30!check_fs_ping!/mnt/account-p,/mnt/prepro-p,/mnt/webapp-ssl,/mnt/rollout-p + } + +define command { + command_name notify-none + command_line /usr/local/nagios/notifications/notify-none + } + +define command { + command_name set_to_stale + command_line /usr/local/nagios/libexec/set_to_stale + } + +define command { + command_name with_continuation_lines + command_line $USER1$/check_foo onetwo + } + +define contactgroup { + contactgroup_name causetestfailure + alias This causes a test failure by having a comma separated list before the empty contactgroup + members second,nagiosadmin + } + +define contactgroup { + contactgroup_name empty + alias No members defined - this should pass validation + } + +define hostgroup { + hostgroup_name hosts-with-master-service + alias Hosts running a master service + members host3 + } + +define servicegroup { + servicegroup_name services-depending-on-master-service + alias Servicegroup for services depending on a "master" service on the same host + members host3,dependent-service + } + +define contact { + contact_name nagiosadmin + service_notification_period none + host_notification_period none + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-none + host_notification_commands notify-none + host_notifications_enabled 0 + service_notifications_enabled 0 + can_submit_commands 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define contact { + contact_name second + service_notification_period none + host_notification_period none + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-none + host_notification_commands notify-none + host_notifications_enabled 0 + service_notifications_enabled 0 + can_submit_commands 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name host1 + alias host1 test + address 192.168.1.1 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name host2 + alias host2 test + address 192.168.2.2 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define host { + host_name host3 + alias host3 test + address 192.168.2.3 + check_period none + contacts nagiosadmin + notification_period none + initial_state o + check_interval 5.000000 + retry_interval 1.000000 + max_check_attempts 2 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_host 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,d,u + freshness_threshold 0 + check_freshness 0 + notification_options d,u,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host1 + service_description Dummy service + check_period none + check_command check_me + contacts nagiosadmin + notification_period none + initial_state o + check_interval 32.000000 + retry_interval 1.000000 + max_check_attempts 3 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 60.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host1 + service_description Uses important check command + check_period none + check_command set_to_stale + contacts nagiosadmin + notification_period none + initial_state o + check_interval 15.000000 + retry_interval 1.000000 + max_check_attempts 5 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 65.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host2 + service_description Uses important check command + check_period none + check_command set_to_stale + contacts nagiosadmin + notification_period none + initial_state o + check_interval 15.000000 + retry_interval 1.000000 + max_check_attempts 5 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 65.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host3 + service_description dependent-service + check_period none + check_command check_me!dependent service + contacts nagiosadmin + notification_period none + initial_state o + check_interval 15.000000 + retry_interval 1.000000 + max_check_attempts 5 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 65.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define service { + host_name host3 + service_description master-service + check_period none + check_command check_me!master service + contacts nagiosadmin + notification_period none + initial_state o + check_interval 15.000000 + retry_interval 1.000000 + max_check_attempts 5 + is_volatile 0 + parallelize_check 1 + active_checks_enabled 1 + passive_checks_enabled 1 + obsess_over_service 1 + event_handler_enabled 1 + low_flap_threshold 0.000000 + high_flap_threshold 0.000000 + flap_detection_enabled 1 + flap_detection_options o,w,u,c + freshness_threshold 0 + check_freshness 0 + notification_options u,w,c,r,f,s + notifications_enabled 1 + notification_interval 65.000000 + first_notification_delay 0.000000 + stalking_options n + process_perf_data 1 + failure_prediction_enabled 1 + retain_status_information 1 + retain_nonstatus_information 1 + } + +define servicedependency { + host_name host3 + service_description master-service + dependent_host_name host3 + dependent_service_description dependent-service + inherits_parent 0 + notification_failure_options u,c + execution_failure_options n + } + +define serviceescalation { + host_name host1 + service_description Uses important check command + first_notification -2 + last_notification -2 + notification_interval 65.000000 + escalation_period none + escalation_options w,u,c,r + contacts nagiosadmin + } + +define serviceescalation { + host_name host2 + service_description Uses important check command + first_notification -2 + last_notification -2 + notification_interval 65.000000 + escalation_period none + escalation_options w,u,c,r + contacts nagiosadmin + } + +define serviceescalation { + host_name host3 + service_description dependent-service + first_notification -2 + last_notification -2 + notification_interval 65.000000 + escalation_period none + escalation_options w,u,c,r + contacts nagiosadmin + } + +define serviceescalation { + host_name host3 + service_description master-service + first_notification -2 + last_notification -2 + notification_interval 65.000000 + escalation_period none + escalation_options w,u,c,r + contacts nagiosadmin + } + diff --git a/t/var/spool/checkresults/.gitignore b/t/var/spool/checkresults/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/t/var/spool/checkresults/.gitignore @@ -0,0 +1 @@ +* diff --git a/t/var/status-hosturgencies.dat b/t/var/status-hosturgencies.dat new file mode 100644 index 0000000..dead32c --- /dev/null +++ b/t/var/status-hosturgencies.dat @@ -0,0 +1,577 @@ +######################################## +# NAGIOS STATUS FILE +# +# THIS FILE IS AUTOMATICALLY GENERATED +# BY NAGIOS. DO NOT MODIFY THIS FILE! +######################################## + +info { + created=1242341791 + version=3.1.0 + last_update_check=1242341791 + update_available=1 + last_version=3.1.0 + new_version=3.0.6 + } + +programstatus { + modified_host_attributes=0 + modified_service_attributes=0 + nagios_pid=48451 + daemon_mode=0 + program_start=1242341791 + last_command_check=0 + last_log_rotation=0 + enable_notifications=1 + active_service_checks_enabled=1 + passive_service_checks_enabled=1 + active_host_checks_enabled=1 + passive_host_checks_enabled=1 + enable_event_handlers=1 + obsess_over_services=0 + obsess_over_hosts=0 + check_service_freshness=1 + check_host_freshness=0 + enable_flap_detection=1 + enable_failure_prediction=1 + process_performance_data=0 + global_host_event_handler= + global_service_event_handler= + next_comment_id=1 + next_downtime_id=1 + next_event_id=1 + next_problem_id=0 + next_notification_id=1 + total_external_command_buffer_slots=4096 + used_external_command_buffer_slots=0 + high_external_command_buffer_slots=0 + active_scheduled_host_check_stats=0,0,0 + active_ondemand_host_check_stats=0,0,0 + passive_host_check_stats=0,0,0 + active_scheduled_service_check_stats=0,0,0 + active_ondemand_service_check_stats=0,0,0 + passive_service_check_stats=0,0,0 + cached_host_check_stats=0,0,0 + cached_service_check_stats=0,0,0 + external_command_stats=0,0,0 + parallel_host_check_stats=0,0,0 + serial_host_check_stats=0,0,0 + } + +hoststatus { + host_name=host1 + modified_attributes=0 + check_command= + check_period=none + notification_period=none + check_interval=5.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=1 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_attempt=1 + max_attempts=2 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_up=0 + last_time_down=0 + last_time_unreachable=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + current_notification_number=0 + current_notification_id=0 + notifications_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_host=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +hoststatus { + host_name=host2 + modified_attributes=0 + check_command= + check_period=none + notification_period=none + check_interval=5.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=1 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=1 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_attempt=1 + max_attempts=2 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_up=0 + last_time_down=0 + last_time_unreachable=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + current_notification_number=0 + current_notification_id=0 + notifications_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_host=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +hoststatus { + host_name=host3 + modified_attributes=0 + check_command= + check_period=none + notification_period=none + check_interval=5.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=1 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=2 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_attempt=1 + max_attempts=2 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_up=0 + last_time_down=0 + last_time_unreachable=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + current_notification_number=0 + current_notification_id=0 + notifications_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_host=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +hoststatus { + host_name=host4 + modified_attributes=0 + check_command= + check_period=none + notification_period=none + check_interval=5.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_attempt=1 + max_attempts=2 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_up=0 + last_time_down=0 + last_time_unreachable=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + current_notification_number=0 + current_notification_id=0 + notifications_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_host=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +servicestatus { + host_name=host1 + service_description=Dummy service + modified_attributes=0 + check_command=check_me + check_period=none + notification_period=none + check_interval=32.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + current_attempt=1 + max_attempts=3 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_ok=0 + last_time_warning=0 + last_time_unknown=0 + last_time_critical=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_notification_number=0 + current_notification_id=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + notifications_enabled=1 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_service=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +servicestatus { + host_name=host2 + service_description=Dummy service + modified_attributes=0 + check_command=check_me + check_period=none + notification_period=none + check_interval=32.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + current_attempt=1 + max_attempts=3 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_ok=0 + last_time_warning=0 + last_time_unknown=0 + last_time_critical=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_notification_number=0 + current_notification_id=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + notifications_enabled=1 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_service=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +servicestatus { + host_name=host3 + service_description=Dummy service + modified_attributes=0 + check_command=check_me + check_period=none + notification_period=none + check_interval=32.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + current_attempt=1 + max_attempts=3 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_ok=0 + last_time_warning=0 + last_time_unknown=0 + last_time_critical=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_notification_number=0 + current_notification_id=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + notifications_enabled=1 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_service=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +servicestatus { + host_name=host4 + service_description=Dummy service + modified_attributes=0 + check_command=check_me + check_period=none + notification_period=none + check_interval=32.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + current_attempt=1 + max_attempts=3 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_ok=0 + last_time_warning=0 + last_time_unknown=0 + last_time_critical=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_notification_number=0 + current_notification_id=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + notifications_enabled=1 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_service=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +contactstatus { + contact_name=nagiosadmin + modified_attributes=0 + modified_host_attributes=0 + modified_service_attributes=0 + host_notification_period=none + service_notification_period=none + last_host_notification=0 + last_service_notification=0 + host_notifications_enabled=0 + service_notifications_enabled=0 + } + +contactstatus { + contact_name=second + modified_attributes=0 + modified_host_attributes=0 + modified_service_attributes=0 + host_notification_period=none + service_notification_period=none + last_host_notification=0 + last_service_notification=0 + host_notifications_enabled=0 + service_notifications_enabled=0 + } + +hostcomment { + host_name=host1 + entry_type=1 + comment_id=1 + source=1 + persistent=1 + entry_time=1253110703 + expires=0 + expire_time=0 + author=Nagios Admin + comment_data=Test Comment + } + +servicecomment { + host_name=host1 + service_description=Dummy service + entry_type=1 + comment_id=2 + source=1 + persistent=1 + entry_time=1253108952 + expires=0 + expire_time=0 + author=Nagios Admin + comment_data=Test Comment + } + diff --git a/t/var/status.dat b/t/var/status.dat new file mode 100644 index 0000000..56e37cd --- /dev/null +++ b/t/var/status.dat @@ -0,0 +1,345 @@ +######################################## +# NAGIOS STATUS FILE +# +# THIS FILE IS AUTOMATICALLY GENERATED +# BY NAGIOS. DO NOT MODIFY THIS FILE! +######################################## + +info { + created=1242341791 + version=3.1.0 + last_update_check=1242341791 + update_available=1 + last_version=3.1.0 + new_version=3.0.6 + } + +programstatus { + modified_host_attributes=0 + modified_service_attributes=0 + nagios_pid=48451 + daemon_mode=0 + program_start=1242341791 + last_command_check=0 + last_log_rotation=0 + enable_notifications=1 + active_service_checks_enabled=1 + passive_service_checks_enabled=1 + active_host_checks_enabled=1 + passive_host_checks_enabled=1 + enable_event_handlers=1 + obsess_over_services=0 + obsess_over_hosts=0 + check_service_freshness=1 + check_host_freshness=0 + enable_flap_detection=1 + enable_failure_prediction=1 + process_performance_data=0 + global_host_event_handler= + global_service_event_handler= + next_comment_id=1 + next_downtime_id=1 + next_event_id=1 + next_problem_id=0 + next_notification_id=1 + total_external_command_buffer_slots=4096 + used_external_command_buffer_slots=0 + high_external_command_buffer_slots=0 + active_scheduled_host_check_stats=0,0,0 + active_ondemand_host_check_stats=0,0,0 + passive_host_check_stats=0,0,0 + active_scheduled_service_check_stats=0,0,0 + active_ondemand_service_check_stats=0,0,0 + passive_service_check_stats=0,0,0 + cached_host_check_stats=0,0,0 + cached_service_check_stats=0,0,0 + external_command_stats=0,0,0 + parallel_host_check_stats=0,0,0 + serial_host_check_stats=0,0,0 + } + +hoststatus { + host_name=host1 + modified_attributes=0 + check_command= + check_period=none + notification_period=none + check_interval=5.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_attempt=1 + max_attempts=2 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_up=0 + last_time_down=0 + last_time_unreachable=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + current_notification_number=0 + current_notification_id=0 + notifications_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_host=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +hoststatus { + host_name=host2 + modified_attributes=0 + check_command= + check_period=none + notification_period=none + check_interval=5.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_attempt=1 + max_attempts=2 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_up=0 + last_time_down=0 + last_time_unreachable=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + current_notification_number=0 + current_notification_id=0 + notifications_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_host=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +servicestatus { + host_name=host1 + service_description=Dummy service + modified_attributes=0 + check_command=check_me + check_period=none + notification_period=none + check_interval=32.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + current_attempt=1 + max_attempts=3 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_ok=0 + last_time_warning=0 + last_time_unknown=0 + last_time_critical=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_notification_number=0 + current_notification_id=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + notifications_enabled=1 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_service=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +servicestatus { + host_name=host2 + service_description=Dummy service + modified_attributes=0 + check_command=check_me + check_period=none + notification_period=none + check_interval=32.000000 + retry_interval=1.000000 + event_handler= + has_been_checked=0 + should_be_scheduled=0 + check_execution_time=0.000 + check_latency=0.000 + check_type=0 + current_state=0 + last_hard_state=0 + last_event_id=0 + current_event_id=0 + current_problem_id=0 + last_problem_id=0 + current_attempt=1 + max_attempts=3 + current_event_id=0 + last_event_id=0 + state_type=1 + last_state_change=0 + last_hard_state_change=0 + last_time_ok=0 + last_time_warning=0 + last_time_unknown=0 + last_time_critical=0 + plugin_output= + long_plugin_output= + performance_data= + last_check=0 + next_check=0 + check_options=0 + current_notification_number=0 + current_notification_id=0 + last_notification=0 + next_notification=0 + no_more_notifications=0 + notifications_enabled=1 + active_checks_enabled=1 + passive_checks_enabled=1 + event_handler_enabled=1 + problem_has_been_acknowledged=0 + acknowledgement_type=0 + flap_detection_enabled=1 + failure_prediction_enabled=1 + process_performance_data=1 + obsess_over_service=1 + last_update=1242341791 + is_flapping=0 + percent_state_change=0.00 + scheduled_downtime_depth=0 + } + +contactstatus { + contact_name=nagiosadmin + modified_attributes=0 + modified_host_attributes=0 + modified_service_attributes=0 + host_notification_period=none + service_notification_period=none + last_host_notification=0 + last_service_notification=0 + host_notifications_enabled=0 + service_notifications_enabled=0 + } + +contactstatus { + contact_name=second + modified_attributes=0 + modified_host_attributes=0 + modified_service_attributes=0 + host_notification_period=none + service_notification_period=none + last_host_notification=0 + last_service_notification=0 + host_notifications_enabled=0 + service_notifications_enabled=0 + } + +hostcomment { + host_name=host1 + entry_type=1 + comment_id=1 + source=1 + persistent=1 + entry_time=1253110703 + expires=0 + expire_time=0 + author=Nagios Admin + comment_data=Test Comment + } + +servicecomment { + host_name=host1 + service_description=Dummy service + entry_type=1 + comment_id=2 + source=1 + persistent=1 + entry_time=1253108952 + expires=0 + expire_time=0 + author=Nagios Admin + comment_data=Test Comment + } + diff --git a/tap/.gitignore b/tap/.gitignore new file mode 100644 index 0000000..da127e0 --- /dev/null +++ b/tap/.gitignore @@ -0,0 +1 @@ +libtool diff --git a/tap/INSTALL b/tap/INSTALL new file mode 100644 index 0000000..7f6479d --- /dev/null +++ b/tap/INSTALL @@ -0,0 +1,8 @@ +Quick Installation + + ./configure + make + make check + make install + +Run "configure --help" for additional options. diff --git a/tap/Makefile.am b/tap/Makefile.am new file mode 100644 index 0000000..728294c --- /dev/null +++ b/tap/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = src +SUBDIRS += tests + +prove: + prove -v -r diff --git a/tap/Makefile.in b/tap/Makefile.in new file mode 100644 index 0000000..370a0c3 --- /dev/null +++ b/tap/Makefile.in @@ -0,0 +1,578 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure INSTALL compile \ + config.guess config.sub depcomp install-sh ltmain.sh missing +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = src tests +all: all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ + check-am clean clean-generic clean-libtool clean-recursive \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic distclean-libtool distclean-recursive \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-generic \ + mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am uninstall-info-am + + +prove: + prove -v -r +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/README b/tap/README new file mode 100644 index 0000000..6c15be0 --- /dev/null +++ b/tap/README @@ -0,0 +1,11 @@ +NAME + tap -- write tests that implement the Test Anything Protocol + +SYNOPSIS + #include + +DESCRIPTION + The tap library provides functions for writing test scripts that produce + output consistent with the Test Anything Protocol. A test harness that + parses this protocol can run these tests and produce useful reports indi- + cating their success or failure. diff --git a/tap/README.nagios b/tap/README.nagios new file mode 100644 index 0000000..2581801 --- /dev/null +++ b/tap/README.nagios @@ -0,0 +1,3 @@ +This package has been included from http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap +into the Nagios distribution for testing Nagios functions + diff --git a/tap/aclocal.m4 b/tap/aclocal.m4 new file mode 100644 index 0000000..c7c523e --- /dev/null +++ b/tap/aclocal.m4 @@ -0,0 +1,6985 @@ +# generated automatically by aclocal 1.9.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.3])]) + +# AM_AUX_DIR_EXPAND + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 6 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# serial 7 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 11 + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# -*- Autoconf -*- + + +# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. + +# Copyright (C) 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- + +# serial 47 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* ) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + ;; + + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +#- set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case "$host_cpu" in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/${ac_tool_prefix}nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + esac + fi + done + IFS="$lt_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided and an installed libltdl is not found, it is +# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' +# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_builddir and top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# --------------- +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# -------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# +# Check for any special shared library compilation flags. +# +_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= +if test "$GCC" = no; then + case $host_os in + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' + ;; + esac +fi +if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then + AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) + _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no + fi +fi + + +# +# Check to make sure the static flag actually works. +# +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) + + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +# Report which librarie types wil actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cc + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case "$host_cpu" in + ia64*|hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + cxx) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sco*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDRT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + cxx) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $CC in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds" + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ +cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ +$echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds" + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4.2uw2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv5*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && break + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_MSG_RESULT([$SED]) +]) + diff --git a/tap/compile b/tap/compile new file mode 100755 index 0000000..3d21703 --- /dev/null +++ b/tap/compile @@ -0,0 +1,142 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2004-10-12.08 + +# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit 0 + ;; + -v | --v*) + echo "compile $scriptversion" + exit 0 + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/tap/config.guess b/tap/config.guess new file mode 100755 index 0000000..0e30d56 --- /dev/null +++ b/tap/config.guess @@ -0,0 +1,1407 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-07-02' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/FreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/tap/config.sub b/tap/config.sub new file mode 100755 index 0000000..9d7f733 --- /dev/null +++ b/tap/config.sub @@ -0,0 +1,1504 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-07-04' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/tap/configure b/tap/configure new file mode 100755 index 0000000..ab9c021 --- /dev/null +++ b/tap/configure @@ -0,0 +1,21388 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59 for tap 1.01. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +tagnames=${tagnames+${tagnames},}CXX + +tagnames=${tagnames+${tagnames},}F77 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='tap' +PACKAGE_TARNAME='tap' +PACKAGE_VERSION='1.01' +PACKAGE_STRING='tap 1.01' +PACKAGE_BUGREPORT='' + +ac_unique_file="src/tap.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP +ac_env_CXX_set=${CXX+set} +ac_env_CXX_value=$CXX +ac_cv_env_CXX_set=${CXX+set} +ac_cv_env_CXX_value=$CXX +ac_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_env_CXXFLAGS_value=$CXXFLAGS +ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_cv_env_CXXFLAGS_value=$CXXFLAGS +ac_env_CXXCPP_set=${CXXCPP+set} +ac_env_CXXCPP_value=$CXXCPP +ac_cv_env_CXXCPP_set=${CXXCPP+set} +ac_cv_env_CXXCPP_value=$CXXCPP +ac_env_F77_set=${F77+set} +ac_env_F77_value=$F77 +ac_cv_env_F77_set=${F77+set} +ac_cv_env_F77_value=$F77 +ac_env_FFLAGS_set=${FFLAGS+set} +ac_env_FFLAGS_value=$FFLAGS +ac_cv_env_FFLAGS_set=${FFLAGS+set} +ac_cv_env_FFLAGS_value=$FFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures tap 1.01 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of tap 1.01:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] + build shared libraries [default=yes] + --enable-static[=PKGS] + build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-tags[=TAGS] + include additional configurations [automatic] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +tap configure 1.01 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by tap $as_me 1.01, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + +am__api_version="1.9" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='tap' + VERSION='1.01' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi; + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi; + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi; + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && break + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done + +fi + +SED=$lt_cv_path_SED +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$CC -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/${ac_tool_prefix}nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + esac + fi + done + IFS="$lt_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +echo "${ECHO_T}$lt_cv_path_NM" >&6 +NM="$lt_cv_path_NM" + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump'. + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | kfreebsd*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case "$host_cpu" in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 3657 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +lt_cv_cc_needs_belf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +esac + +need_locks="$enable_libtool_lock" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tap lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CXX" && break +done +test -n "$ac_ct_CXX" || ac_ct_CXX="g++" + + CXX=$ac_ct_CXX +fi + + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cxx_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +echo "$as_me:$LINENO: result: $CXXCPP" >&5 +echo "${ECHO_T}$CXXCPP" >&6 +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +fi + + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_F77="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + echo "$as_me:$LINENO: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_F77="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_F77" && break +done + + F77=$ac_ct_F77 +fi + + +# Provide some information about the compiler. +echo "$as_me:5236:" \ + "checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 +ac_ext=$ac_save_ext +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_f77_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi + +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# find the maximum length of command line arguments +echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* ) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + ;; + + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 +else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +fi + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris* | sysv5*) + symcode='[BDRT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6 +if test "${lt_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +echo "${ECHO_T}$lt_cv_objdir" >&6 +objdir=$lt_cv_objdir + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + AR=$ac_ct_AR +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +enable_dlopen=no +enable_win32_dll=no + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# +# Check for any special shared library compilation flags. +# +lt_prog_cc_shlib= +if test "$GCC" = no; then + case $host_os in + sco3.2v5*) + lt_prog_cc_shlib='-belf' + ;; + esac +fi +if test -n "$lt_prog_cc_shlib"; then + { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5 +echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;} + if echo "$old_CC $old_CFLAGS " | grep "[ ]$lt_prog_cc_shlib[ ]" >/dev/null; then : + else + { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 +echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} + lt_cv_prog_cc_can_build_shared=no + fi +fi + + +# +# Check to make sure the static flag actually works. +# +echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_prog_compiler_static" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + else + lt_prog_compiler_static_works=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 + +if test x"$lt_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:6293: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:6297: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + linux*) + case $CC in + icc* | ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + sco3.2v5*) + lt_prog_compiler_pic='-Kpic' + lt_prog_compiler_static='-dn' + ;; + + solaris*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:6536: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:6540: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + lt_prog_compiler_pic_works=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 + +if test x"$lt_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:6596: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:6600: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag= + enable_shared_with_static_runtimes=no + archive_cmds= + archive_expsym_cmds= + old_archive_From_new_cmds= + old_archive_from_expsyms_cmds= + export_dynamic_flag_spec= + whole_archive_flag_spec= + thread_safe_flag_spec= + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + link_all_deplibs=unknown + hardcode_automatic=no + module_cmds= + module_expsym_cmds= + always_export_symbols=no + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds="$tmp_archive_cmds" + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ +cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ +$echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + else + archive_expsym_cmds="$tmp_archive_cmds" + fi + else + ld_shlibs=no + fi + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + + if test "$GCC" = yes; then + case $host_os in aix4.012|aix4.012.*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec=' ' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + ia64*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=no + hardcode_shlibpath_var=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + *) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld='-rpath $libdir' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +echo "${ECHO_T}$archive_cmds_need_lc" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.01* | freebsdelf3.01*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# Report which librarie types wil actually be built +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler \ + CC \ + LD \ + lt_prog_compiler_wl \ + lt_prog_compiler_pic \ + lt_prog_compiler_static \ + lt_prog_compiler_no_builtin_flag \ + export_dynamic_flag_spec \ + thread_safe_flag_spec \ + whole_archive_flag_spec \ + enable_shared_with_static_runtimes \ + old_archive_cmds \ + old_archive_from_new_cmds \ + predep_objects \ + postdep_objects \ + predeps \ + postdeps \ + compiler_lib_search_path \ + archive_cmds \ + archive_expsym_cmds \ + postinstall_cmds \ + postuninstall_cmds \ + old_archive_from_expsyms_cmds \ + allow_undefined_flag \ + no_undefined_flag \ + export_symbols_cmds \ + hardcode_libdir_flag_spec \ + hardcode_libdir_flag_spec_ld \ + hardcode_libdir_separator \ + hardcode_automatic \ + module_cmds \ + module_expsym_cmds \ + lt_cv_prog_compiler_c_o \ + exclude_expsyms \ + include_expsyms; do + + case $var in + old_archive_cmds | \ + old_archive_from_new_cmds | \ + archive_cmds | \ + archive_expsym_cmds | \ + module_cmds | \ + module_expsym_cmds | \ + old_archive_from_expsyms_cmds | \ + export_symbols_cmds | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + { echo "$as_me:$LINENO: creating $ofile" >&5 +echo "$as_me: creating $ofile" >&6;} + + cat <<__EOF__ >> "$cfgfile" +#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +# Check whether --with-tags or --without-tags was given. +if test "${with_tags+set}" = set; then + withval="$with_tags" + tagnames="$withval" +fi; + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} + else + { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 +echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} + fi + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in + "") ;; + *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 +echo "$as_me: error: invalid tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 +echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} + { (exit 1); exit 1; }; } + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_automatic_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +# Source file extension for C++ test sources. +ac_ext=cc + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +compiler_CXX=$CC +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +else + lt_prog_compiler_no_builtin_flag_CXX= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 +ld_shlibs_CXX=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes; then + case $host_os in aix4.012|aix4.012.*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_CXX=yes + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols_CXX=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX=' ' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + freebsd12*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs_CXX=no + ;; + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + gnu*) + ;; + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC) + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + hppa*64*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld_CXX='+b $libdir' + hardcode_libdir_separator_CXX=: + ;; + ia64*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + *) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case "$host_cpu" in + hppa*64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + *) + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC) + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case "$host_cpu" in + ia64*|hppa*64*) + archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + ;; + linux*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + cxx) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + mvs*) + case $cc_basename in + cxx) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + sco*) + archive_cmds_need_lc_CXX=no + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.0-5 | solaris2.0-5.*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + archive_cmds_need_lc_CXX=no + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; +esac +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +GCC_CXX="$GXX" +LD_CXX="$LD" + + +cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`" + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$rm -f confest.$objext + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + +lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + icpc) + # Intel C++ + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + cxx) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:11072: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:11076: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + lt_prog_compiler_pic_works_CXX=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 + +if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:11132: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:11136: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.01* | freebsdelf3.01*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || \ + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +echo "${ECHO_T}$hardcode_action_CXX" >&6 + +if test "$hardcode_action_CXX" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_CXX \ + CC_CXX \ + LD_CXX \ + lt_prog_compiler_wl_CXX \ + lt_prog_compiler_pic_CXX \ + lt_prog_compiler_static_CXX \ + lt_prog_compiler_no_builtin_flag_CXX \ + export_dynamic_flag_spec_CXX \ + thread_safe_flag_spec_CXX \ + whole_archive_flag_spec_CXX \ + enable_shared_with_static_runtimes_CXX \ + old_archive_cmds_CXX \ + old_archive_from_new_cmds_CXX \ + predep_objects_CXX \ + postdep_objects_CXX \ + predeps_CXX \ + postdeps_CXX \ + compiler_lib_search_path_CXX \ + archive_cmds_CXX \ + archive_expsym_cmds_CXX \ + postinstall_cmds_CXX \ + postuninstall_cmds_CXX \ + old_archive_from_expsyms_cmds_CXX \ + allow_undefined_flag_CXX \ + no_undefined_flag_CXX \ + export_symbols_cmds_CXX \ + hardcode_libdir_flag_spec_CXX \ + hardcode_libdir_flag_spec_ld_CXX \ + hardcode_libdir_separator_CXX \ + hardcode_automatic_CXX \ + module_cmds_CXX \ + module_expsym_cmds_CXX \ + lt_cv_prog_compiler_c_o_CXX \ + exclude_expsyms_CXX \ + include_expsyms_CXX; do + + case $var in + old_archive_cmds_CXX | \ + old_archive_from_new_cmds_CXX | \ + archive_cmds_CXX | \ + archive_expsym_cmds_CXX | \ + module_cmds_CXX | \ + module_expsym_cmds_CXX | \ + old_archive_from_expsyms_cmds_CXX | \ + export_symbols_cmds_CXX | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_CXX + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_CXX +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_CXX + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_CXX" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld + + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + + +archive_cmds_need_lc_F77=no +allow_undefined_flag_F77= +always_export_symbols_F77=no +archive_expsym_cmds_F77= +export_dynamic_flag_spec_F77= +hardcode_direct_F77=no +hardcode_libdir_flag_spec_F77= +hardcode_libdir_flag_spec_ld_F77= +hardcode_libdir_separator_F77= +hardcode_minus_L_F77=no +hardcode_automatic_F77=no +module_cmds_F77= +module_expsym_cmds_F77= +link_all_deplibs_F77=unknown +old_archive_cmds_F77=$old_archive_cmds +no_undefined_flag_F77= +whole_archive_flag_spec_F77= +enable_shared_with_static_runtimes_F77=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +objext_F77=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code=" subroutine t\n return\n end\n" + +# Code to be used in simple link tests +lt_simple_link_test_code=" program t\n end\n" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +compiler_F77=$CC +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + test "$enable_shared" = yes && enable_static=no + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +test "$ld_shlibs_F77" = no && can_build_shared=no + +GCC_F77="$G77" +LD_F77="$LD" + +lt_prog_compiler_wl_F77= +lt_prog_compiler_pic_F77= +lt_prog_compiler_static_F77= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_static_F77='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_F77='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_F77=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_F77=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_F77='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + else + lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_F77='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_F77='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + linux*) + case $CC in + icc* | ecc*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-static' + ;; + ccc*) + lt_prog_compiler_wl_F77='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_F77='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + + sco3.2v5*) + lt_prog_compiler_pic_F77='-Kpic' + lt_prog_compiler_static_F77='-dn' + ;; + + solaris*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sunos4*) + lt_prog_compiler_wl_F77='-Qoption ld ' + lt_prog_compiler_pic_F77='-PIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_F77='-Kconform_pic' + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + uts4*) + lt_prog_compiler_pic_F77='-pic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_F77"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_F77=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_F77" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:13428: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:13432: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + lt_prog_compiler_pic_works_F77=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 + +if test x"$lt_prog_compiler_pic_works_F77" = xyes; then + case $lt_prog_compiler_pic_F77 in + "" | " "*) ;; + *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; + esac +else + lt_prog_compiler_pic_F77= + lt_prog_compiler_can_build_shared_F77=no +fi + +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_F77= + ;; + *) + lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" + ;; +esac + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_F77=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:13488: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:13492: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + lt_cv_prog_compiler_c_o_F77=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_F77= + enable_shared_with_static_runtimes_F77=no + archive_cmds_F77= + archive_expsym_cmds_F77= + old_archive_From_new_cmds_F77= + old_archive_from_expsyms_cmds_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + thread_safe_flag_spec_F77= + hardcode_libdir_flag_spec_F77= + hardcode_libdir_flag_spec_ld_F77= + hardcode_libdir_separator_F77= + hardcode_direct_F77=no + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=unsupported + link_all_deplibs_F77=unknown + hardcode_automatic_F77=no + module_cmds_F77= + module_expsym_cmds_F77= + always_export_symbols_F77=no + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_F77= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_F77=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_F77=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_F77=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_F77='-L$libdir' + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=no + enable_shared_with_static_runtimes_F77=yes + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + sunos4*) + archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds_F77="$tmp_archive_cmds" + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ +cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ +$echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + else + archive_expsym_cmds_F77="$tmp_archive_cmds" + fi + else + ld_shlibs_F77=no + fi + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + + if test "$ld_shlibs_F77" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=yes + archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_F77=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_F77=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_F77='' + hardcode_direct_F77=yes + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + + if test "$GCC" = yes; then + case $host_os in aix4.012|aix4.012.*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_F77=yes + else + # We have old collect2 + hardcode_direct_F77=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_F77=yes + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_libdir_separator_F77= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_F77=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_F77='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_F77="-z nodefs" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_F77=' ${wl}-bernotok' + allow_undefined_flag_F77=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols_F77=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_F77=' ' + archive_cmds_need_lc_F77=yes + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_F77=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_F77=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_F77=' ' + allow_undefined_flag_F77=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_F77='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_F77=yes + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_F77=no + hardcode_direct_F77=no + hardcode_automatic_F77=yes + hardcode_shlibpath_var_F77=unsupported + whole_archive_flag_spec_F77='' + link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + freebsd1*) + ld_shlibs_F77=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu) + archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + ;; + ia64*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + *) + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + link_all_deplibs_F77=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + newsos6) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_shlibpath_var_F77=no + ;; + + openbsd*) + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + allow_undefined_flag_F77=unsupported + archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_F77='-rpath $libdir' + fi + hardcode_libdir_separator_F77=: + ;; + + sco3.2v5*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag_F77=' -z text' + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_shlibpath_var_F77=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs_F77=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_F77='$CC -r -o $output$reload_objs' + hardcode_direct_F77=no + ;; + motorola) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv4.3*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_F77=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + no_undefined_flag_F77='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv5*) + no_undefined_flag_F77=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec_F77= + hardcode_shlibpath_var_F77=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + *) + ld_shlibs_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 +echo "${ECHO_T}$ld_shlibs_F77" >&6 +test "$ld_shlibs_F77" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_F77" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_F77=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_F77 in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_F77 + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_F77 + allow_undefined_flag_F77= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_F77=no + else + archive_cmds_need_lc_F77=yes + fi + allow_undefined_flag_F77=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.01* | freebsdelf3.01*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_F77= +if test -n "$hardcode_libdir_flag_spec_F77" || \ + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_F77" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && + test "$hardcode_minus_L_F77" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_F77=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_F77=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_F77=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 +echo "${ECHO_T}$hardcode_action_F77" >&6 + +if test "$hardcode_action_F77" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_F77 \ + CC_F77 \ + LD_F77 \ + lt_prog_compiler_wl_F77 \ + lt_prog_compiler_pic_F77 \ + lt_prog_compiler_static_F77 \ + lt_prog_compiler_no_builtin_flag_F77 \ + export_dynamic_flag_spec_F77 \ + thread_safe_flag_spec_F77 \ + whole_archive_flag_spec_F77 \ + enable_shared_with_static_runtimes_F77 \ + old_archive_cmds_F77 \ + old_archive_from_new_cmds_F77 \ + predep_objects_F77 \ + postdep_objects_F77 \ + predeps_F77 \ + postdeps_F77 \ + compiler_lib_search_path_F77 \ + archive_cmds_F77 \ + archive_expsym_cmds_F77 \ + postinstall_cmds_F77 \ + postuninstall_cmds_F77 \ + old_archive_from_expsyms_cmds_F77 \ + allow_undefined_flag_F77 \ + no_undefined_flag_F77 \ + export_symbols_cmds_F77 \ + hardcode_libdir_flag_spec_F77 \ + hardcode_libdir_flag_spec_ld_F77 \ + hardcode_libdir_separator_F77 \ + hardcode_automatic_F77 \ + module_cmds_F77 \ + module_expsym_cmds_F77 \ + lt_cv_prog_compiler_c_o_F77 \ + exclude_expsyms_F77 \ + include_expsyms_F77; do + + case $var in + old_archive_cmds_F77 | \ + old_archive_from_new_cmds_F77 | \ + archive_cmds_F77 | \ + archive_expsym_cmds_F77 | \ + module_cmds_F77 | \ + module_expsym_cmds_F77 | \ + old_archive_from_expsyms_cmds_F77 | \ + export_symbols_cmds_F77 | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_F77 + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_compiler_F77 + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_F77 + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_F77 + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_F77 + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_F77 +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_F77 + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_F77 +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_F77 +archive_expsym_cmds=$lt_archive_expsym_cmds_F77 +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_F77 +module_expsym_cmds=$lt_module_expsym_cmds_F77 + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_F77 + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_F77 + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_F77 + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_F77 + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_F77 + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_F77 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_F77 + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_F77 + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_F77 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_F77 + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_F77" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_F77 + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_F77 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_F77 + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_F77 + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +objext_GCJ=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String argv) {}; }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +compiler_GCJ=$CC + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +archive_cmds_need_lc_GCJ=no + + +lt_prog_compiler_no_builtin_flag_GCJ= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15523: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:15527: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl_GCJ= +lt_prog_compiler_pic_GCJ= +lt_prog_compiler_static_GCJ= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_static_GCJ='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_GCJ='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_GCJ=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_GCJ=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_GCJ='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + else + lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case "$cc_basename" in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + linux*) + case $CC in + icc* | ecc*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-static' + ;; + ccc*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + sco3.2v5*) + lt_prog_compiler_pic_GCJ='-Kpic' + lt_prog_compiler_static_GCJ='-dn' + ;; + + solaris*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sunos4*) + lt_prog_compiler_wl_GCJ='-Qoption ld ' + lt_prog_compiler_pic_GCJ='-PIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_GCJ='-Kconform_pic' + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + uts4*) + lt_prog_compiler_pic_GCJ='-pic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_GCJ"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_GCJ=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_GCJ" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15766: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:15770: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + lt_prog_compiler_pic_works_GCJ=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 + +if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then + case $lt_prog_compiler_pic_GCJ in + "" | " "*) ;; + *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; + esac +else + lt_prog_compiler_pic_GCJ= + lt_prog_compiler_can_build_shared_GCJ=no +fi + +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_GCJ= + ;; + *) + lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" + ;; +esac + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_GCJ=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15826: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:15830: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + lt_cv_prog_compiler_c_o_GCJ=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_GCJ= + enable_shared_with_static_runtimes_GCJ=no + archive_cmds_GCJ= + archive_expsym_cmds_GCJ= + old_archive_From_new_cmds_GCJ= + old_archive_from_expsyms_cmds_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + thread_safe_flag_spec_GCJ= + hardcode_libdir_flag_spec_GCJ= + hardcode_libdir_flag_spec_ld_GCJ= + hardcode_libdir_separator_GCJ= + hardcode_direct_GCJ=no + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=unsupported + link_all_deplibs_GCJ=unknown + hardcode_automatic_GCJ=no + module_cmds_GCJ= + module_expsym_cmds_GCJ= + always_export_symbols_GCJ=no + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_GCJ= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_GCJ=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_GCJ=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_GCJ=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_GCJ='-L$libdir' + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=no + enable_shared_with_static_runtimes_GCJ=yes + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + sunos4*) + archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds_GCJ="$tmp_archive_cmds" + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ +cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ +$echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + else + archive_expsym_cmds_GCJ="$tmp_archive_cmds" + fi + else + ld_shlibs_GCJ=no + fi + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + + if test "$ld_shlibs_GCJ" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=yes + archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_GCJ=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_GCJ=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_GCJ='' + hardcode_direct_GCJ=yes + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + + if test "$GCC" = yes; then + case $host_os in aix4.012|aix4.012.*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_GCJ=yes + else + # We have old collect2 + hardcode_direct_GCJ=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_GCJ=yes + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_libdir_separator_GCJ= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_GCJ=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_GCJ='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_GCJ="-z nodefs" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_GCJ=' ${wl}-bernotok' + allow_undefined_flag_GCJ=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + always_export_symbols_GCJ=yes + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_GCJ=' ' + archive_cmds_need_lc_GCJ=yes + # This is similar to how AIX traditionally builds it's shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_GCJ=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_GCJ=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_GCJ=' ' + allow_undefined_flag_GCJ=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_GCJ='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_GCJ=yes + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_GCJ=no + hardcode_direct_GCJ=no + hardcode_automatic_GCJ=yes + hardcode_shlibpath_var_GCJ=unsupported + whole_archive_flag_spec_GCJ='' + link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case "$cc_basename" in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + freebsd1*) + ld_shlibs_GCJ=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu) + archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + ;; + ia64*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + *) + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + link_all_deplibs_GCJ=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + newsos6) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_shlibpath_var_GCJ=no + ;; + + openbsd*) + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + allow_undefined_flag_GCJ=unsupported + archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_GCJ='-rpath $libdir' + fi + hardcode_libdir_separator_GCJ=: + ;; + + sco3.2v5*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag_GCJ=' -z text' + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_shlibpath_var_GCJ=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs_GCJ=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_GCJ='$CC -r -o $output$reload_objs' + hardcode_direct_GCJ=no + ;; + motorola) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4.3*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_GCJ=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + no_undefined_flag_GCJ='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv5*) + no_undefined_flag_GCJ=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec_GCJ= + hardcode_shlibpath_var_GCJ=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + *) + ld_shlibs_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 +echo "${ECHO_T}$ld_shlibs_GCJ" >&6 +test "$ld_shlibs_GCJ" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_GCJ" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_GCJ=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_GCJ in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_GCJ + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ + allow_undefined_flag_GCJ= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_GCJ=no + else + archive_cmds_need_lc_GCJ=yes + fi + allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.01* | freebsdelf3.01*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_GCJ= +if test -n "$hardcode_libdir_flag_spec_GCJ" || \ + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_GCJ" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && + test "$hardcode_minus_L_GCJ" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_GCJ=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_GCJ=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_GCJ=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 +echo "${ECHO_T}$hardcode_action_GCJ" >&6 + +if test "$hardcode_action_GCJ" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_GCJ \ + CC_GCJ \ + LD_GCJ \ + lt_prog_compiler_wl_GCJ \ + lt_prog_compiler_pic_GCJ \ + lt_prog_compiler_static_GCJ \ + lt_prog_compiler_no_builtin_flag_GCJ \ + export_dynamic_flag_spec_GCJ \ + thread_safe_flag_spec_GCJ \ + whole_archive_flag_spec_GCJ \ + enable_shared_with_static_runtimes_GCJ \ + old_archive_cmds_GCJ \ + old_archive_from_new_cmds_GCJ \ + predep_objects_GCJ \ + postdep_objects_GCJ \ + predeps_GCJ \ + postdeps_GCJ \ + compiler_lib_search_path_GCJ \ + archive_cmds_GCJ \ + archive_expsym_cmds_GCJ \ + postinstall_cmds_GCJ \ + postuninstall_cmds_GCJ \ + old_archive_from_expsyms_cmds_GCJ \ + allow_undefined_flag_GCJ \ + no_undefined_flag_GCJ \ + export_symbols_cmds_GCJ \ + hardcode_libdir_flag_spec_GCJ \ + hardcode_libdir_flag_spec_ld_GCJ \ + hardcode_libdir_separator_GCJ \ + hardcode_automatic_GCJ \ + module_cmds_GCJ \ + module_expsym_cmds_GCJ \ + lt_cv_prog_compiler_c_o_GCJ \ + exclude_expsyms_GCJ \ + include_expsyms_GCJ; do + + case $var in + old_archive_cmds_GCJ | \ + old_archive_from_new_cmds_GCJ | \ + archive_cmds_GCJ | \ + archive_expsym_cmds_GCJ | \ + module_cmds_GCJ | \ + module_expsym_cmds_GCJ | \ + old_archive_from_expsyms_cmds_GCJ | \ + export_symbols_cmds_GCJ | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_GCJ + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_compiler_GCJ + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_GCJ + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_GCJ + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_GCJ + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_GCJ +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_GCJ + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_GCJ +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_GCJ +archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_GCJ +module_expsym_cmds=$lt_module_expsym_cmds_GCJ + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_GCJ + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_GCJ + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_GCJ + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_GCJ + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_GCJ + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_GCJ + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_GCJ + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_GCJ + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_GCJ + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_GCJ" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_GCJ + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_GCJ + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_GCJ + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_GCJ + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + RC) + + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +lt_cv_prog_compiler_c_o_RC=yes + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_RC \ + CC_RC \ + LD_RC \ + lt_prog_compiler_wl_RC \ + lt_prog_compiler_pic_RC \ + lt_prog_compiler_static_RC \ + lt_prog_compiler_no_builtin_flag_RC \ + export_dynamic_flag_spec_RC \ + thread_safe_flag_spec_RC \ + whole_archive_flag_spec_RC \ + enable_shared_with_static_runtimes_RC \ + old_archive_cmds_RC \ + old_archive_from_new_cmds_RC \ + predep_objects_RC \ + postdep_objects_RC \ + predeps_RC \ + postdeps_RC \ + compiler_lib_search_path_RC \ + archive_cmds_RC \ + archive_expsym_cmds_RC \ + postinstall_cmds_RC \ + postuninstall_cmds_RC \ + old_archive_from_expsyms_cmds_RC \ + allow_undefined_flag_RC \ + no_undefined_flag_RC \ + export_symbols_cmds_RC \ + hardcode_libdir_flag_spec_RC \ + hardcode_libdir_flag_spec_ld_RC \ + hardcode_libdir_separator_RC \ + hardcode_automatic_RC \ + module_cmds_RC \ + module_expsym_cmds_RC \ + lt_cv_prog_compiler_c_o_RC \ + exclude_expsyms_RC \ + include_expsyms_RC; do + + case $var in + old_archive_cmds_RC | \ + old_archive_from_new_cmds_RC | \ + archive_cmds_RC | \ + archive_expsym_cmds_RC | \ + module_cmds_RC | \ + module_expsym_cmds_RC | \ + old_archive_from_expsyms_cmds_RC | \ + export_symbols_cmds_RC | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_RC + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_RC + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_RC +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_RC + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_RC + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_RC + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_RC" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + ;; + + *) + { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 +echo "$as_me: error: Unsupported tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 +echo "$as_me: error: unable to update list of available tagged configurations." >&2;} + { (exit 1); exit 1; }; } + fi +fi + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + + + + + + + + + + + + + + + + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +# Checks for libraries +case "$host" in + *-*-*freebsd4*) + LDFLAGS="$LDFLAGS -pthread" + HAVE_LIBPTHREAD=1 + ;; + *) + +echo "$as_me:$LINENO: checking for main in -lpthread" >&5 +echo $ECHO_N "checking for main in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_main" >&6 +if test $ac_cv_lib_pthread_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREAD 1 +_ACEOF + + LIBS="-lpthread $LIBS" + +fi + + ;; +esac + +# Checks for header files +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tap lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in pthread.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tap lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + + +# Checks for library functions. + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6 +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case declares _doprnt. + For example, HP-UX 11i declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _doprnt + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char _doprnt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__doprnt) || defined (__stub____doprnt) +choke me +#else +char (*f) () = _doprnt; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != _doprnt; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func__doprnt=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6 +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + + +for ac_func in atexit +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + ac_config_files="$ac_config_files Makefile src/Makefile tests/Makefile tests/diag/Makefile tests/fail/Makefile tests/ok/Makefile tests/ok/ok-hash/Makefile tests/ok/ok-numeric/Makefile tests/ok/ok/Makefile tests/pass/Makefile tests/plan/Makefile tests/plan/no-tests/Makefile tests/plan/no_plan/Makefile tests/plan/not-enough-tests/Makefile tests/plan/sane/Makefile tests/plan/skip_all/Makefile tests/plan/too-many-plans/Makefile tests/plan/too-many-tests/Makefile tests/skip/Makefile tests/todo/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by tap $as_me 1.01, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +tap config.status 1.01 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; + "tests/diag/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/diag/Makefile" ;; + "tests/fail/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/fail/Makefile" ;; + "tests/ok/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/ok/Makefile" ;; + "tests/ok/ok-hash/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/ok/ok-hash/Makefile" ;; + "tests/ok/ok-numeric/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/ok/ok-numeric/Makefile" ;; + "tests/ok/ok/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/ok/ok/Makefile" ;; + "tests/pass/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/pass/Makefile" ;; + "tests/plan/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/Makefile" ;; + "tests/plan/no-tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/no-tests/Makefile" ;; + "tests/plan/no_plan/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/no_plan/Makefile" ;; + "tests/plan/not-enough-tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/not-enough-tests/Makefile" ;; + "tests/plan/sane/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/sane/Makefile" ;; + "tests/plan/skip_all/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/skip_all/Makefile" ;; + "tests/plan/too-many-plans/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/too-many-plans/Makefile" ;; + "tests/plan/too-many-tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/plan/too-many-tests/Makefile" ;; + "tests/skip/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/skip/Makefile" ;; + "tests/todo/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/todo/Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@mkdir_p@,$mkdir_p,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@am__leading_dot@,$am__leading_dot,;t t +s,@AMTAR@,$AMTAR,;t t +s,@am__tar@,$am__tar,;t t +s,@am__untar@,$am__untar,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@EGREP@,$EGREP,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@CXX@,$CXX,;t t +s,@CXXFLAGS@,$CXXFLAGS,;t t +s,@ac_ct_CXX@,$ac_ct_CXX,;t t +s,@CXXDEPMODE@,$CXXDEPMODE,;t t +s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t +s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t +s,@CXXCPP@,$CXXCPP,;t t +s,@F77@,$F77,;t t +s,@FFLAGS@,$FFLAGS,;t t +s,@ac_ct_F77@,$ac_ct_F77,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/tap/configure.in b/tap/configure.in new file mode 100644 index 0000000..4058adb --- /dev/null +++ b/tap/configure.in @@ -0,0 +1,52 @@ +AC_INIT(tap, 1.01) +AC_CONFIG_SRCDIR(src/tap.c) +AM_INIT_AUTOMAKE([foreign]) +AC_PROG_CC +AC_PROG_LIBTOOL +AC_PROG_INSTALL + +# Checks for libraries +case "$host" in + *-*-*freebsd4*) + LDFLAGS="$LDFLAGS -pthread" + HAVE_LIBPTHREAD=1 + ;; + *) + AC_CHECK_LIB(pthread, main) + ;; +esac + +# Checks for header files +AC_HEADER_STDC +AC_CHECK_HEADERS([stdlib.h]) +AC_CHECK_HEADERS([pthread.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +# Checks for library functions. +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([atexit]) + +AC_CONFIG_FILES([Makefile + src/Makefile + tests/Makefile + tests/diag/Makefile + tests/fail/Makefile + tests/ok/Makefile + tests/ok/ok-hash/Makefile + tests/ok/ok-numeric/Makefile + tests/ok/ok/Makefile + tests/pass/Makefile + tests/plan/Makefile + tests/plan/no-tests/Makefile + tests/plan/no_plan/Makefile + tests/plan/not-enough-tests/Makefile + tests/plan/sane/Makefile + tests/plan/skip_all/Makefile + tests/plan/too-many-plans/Makefile + tests/plan/too-many-tests/Makefile + tests/skip/Makefile + tests/todo/Makefile + ]) +AC_OUTPUT diff --git a/tap/depcomp b/tap/depcomp new file mode 100755 index 0000000..11e2d3b --- /dev/null +++ b/tap/depcomp @@ -0,0 +1,522 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2004-05-31.23 + +# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit 0 + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit 0 + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # Dependencies are output in .lo.d with libtool 1.4. + # With libtool 1.5 they are output both in $dir.libs/$base.o.d + # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the + # latter, because the former will be cleaned when $dir.libs is + # erased. + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir$base.o.d" + tmpdepfile3="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + tmpdepfile3="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + elif test -f "$tmpdepfile2"; then + tmpdepfile="$tmpdepfile2" + else + tmpdepfile="$tmpdepfile3" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/tap/install-sh b/tap/install-sh new file mode 100755 index 0000000..0b65ee8 --- /dev/null +++ b/tap/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2004-10-22.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit 0;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit 0;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/tap/ltmain.sh b/tap/ltmain.sh new file mode 100644 index 0000000..c888819 --- /dev/null +++ b/tap/ltmain.sh @@ -0,0 +1,6419 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.10 +TIMESTAMP=" (1.1220.2.130 2004/09/19 12:13:49)" + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes. +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () { + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` + if test "X$win32_nmres" = "Ximport" ; then + win32_libid_type="x86 archive import" + else + win32_libid_type="x86 archive static" + fi + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () { + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () { + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xdir="$my_gentop/$my_xlib" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$my_xdir"; then + exit $status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename $darwin_archive` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + # Remove the table of contents from the thin files. + $AR -d "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" __.SYMDEF 2>/dev/null || true + $AR -d "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" __.SYMDEF\ SORTED 2>/dev/null || true + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $AR -xo "${darwin_base_archive}" + rm "${darwin_base_archive}" + cd "$darwin_curdir" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f | xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + rm -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + (cd $my_xdir && $AR x $my_xabs) || exit $? + fi # $darwin_arches + fi # $run + ;; + *) + # We will extract separately just the conflicting names and we will + # no longer touch any unique names. It is faster to leave these + # extract automatically by $AR in one run. + $show "(cd $my_xdir && $AR x $my_xabs)" + $run eval "(cd \$my_xdir && $AR x \$my_xabs)" || exit $? + if ($AR t "$my_xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$my_xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$my_xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $my_xdir && $AR xN $i $my_xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$my_xdir && $AR xN $i \$my_xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2003 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $EXIT_SUCCESS + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $EXIT_SUCCESS + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $EXIT_SUCCESS + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) prevopt="--tag" prev=tag ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case "$arg_mode" in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit $EXIT_FAILURE + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd4*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + case $host in + *-*-freebsd*) + # Do not build the useless static library + build_old_libs=no + ;; + esac + continue + ;; + + # gcc -m* arguments should be passed to the linker via $compiler_flags + # in order to pass architecture information to the linker + # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo + # but this is not reliable with gcc because gcc may use -mfoo to + # select a different linker, different libraries, etc, while + # -Wl,-mfoo simply passes -mfoo to the linker. + -m*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + if test "$with_gcc" = "yes" ; then + compiler_flags="$compiler_flags $arg" + fi + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test "$status" -ne 0 && test ! -d "$output_objdir"; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5* ) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$save_output-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$save_output-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$save_output-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadale object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$save_output-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *-*-freebsd*) + # FreeBSD doesn't need this... + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + cwrappersource=`$echo ${objdir}/lt-${output}.c` + cwrapper=`$echo ${output}.exe` + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +#define HAVE_DOS_BASED_FILE_SYSTEM +#ifndef DIR_SEPARATOR_2 +#define DIR_SEPARATOR_2 '\\' +#endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +char * basename (const char *name); +char * fnqualify(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup ((char *) basename (argv[0])); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = fnqualify(argv[0]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +char * +basename (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha (name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return (char *) base; +} + +char * +fnqualify(const char *path) +{ + size_t size; + char *p; + char tmp[LT_PATHMAX + 1]; + + assert(path != NULL); + + /* Is it qualified already? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha (path[0]) && path[1] == ':') + return xstrdup (path); +#endif + if (IS_DIR_SEPARATOR (path[0])) + return xstrdup (path); + + /* prepend the current directory */ + /* doesn't handle '~' */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ + p = XMALLOC(char, size); + sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); + return p; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + # GNU ar 2.10+ was changed to match POSIX; thus no paths are + # encoded into archives. This makes 'ar r' malfunction in + # this piecewise linking case whenever conflicting object + # names appear in distinct ar calls; check, warn and compensate. + if (for obj in $save_oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2 + $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2 + AR_FLAGS=cq + fi + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + case $host in + *-*-freebsd*) + # Do not install the useless pseudo-library + ;; + *) + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + ;; + esac + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + save_umask=`umask` + umask 0077 + if $mkdir "$tmpdir"; then + umask $save_umask + else + umask $save_umask + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "----------------------------------------------------------------------" + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "----------------------------------------------------------------------" + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test "$mode" = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $EXIT_SUCCESS + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/tap/missing b/tap/missing new file mode 100755 index 0000000..64b5f90 --- /dev/null +++ b/tap/missing @@ -0,0 +1,353 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2004-09-07.08 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit 0 + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit 0 + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/tap/src/Makefile.am b/tap/src/Makefile.am new file mode 100644 index 0000000..c8c462e --- /dev/null +++ b/tap/src/Makefile.am @@ -0,0 +1,7 @@ +lib_LTLIBRARIES = libtap.la +libtap_la_SOURCES = tap.c tap.h + +man_MANS = tap.3 +EXTRA_DIST = $(man_MANS) + +include_HEADERS = tap.h diff --git a/tap/src/Makefile.in b/tap/src/Makefile.in new file mode 100644 index 0000000..20878ca --- /dev/null +++ b/tap/src/Makefile.in @@ -0,0 +1,526 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +SOURCES = $(libtap_la_SOURCES) + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(includedir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libtap_la_LIBADD = +am_libtap_la_OBJECTS = tap.lo +libtap_la_OBJECTS = $(am_libtap_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libtap_la_SOURCES) +DIST_SOURCES = $(libtap_la_SOURCES) +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(man_MANS) +includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +lib_LTLIBRARIES = libtap.la +libtap_la_SOURCES = tap.c tap.h +man_MANS = tap.3 +EXTRA_DIST = $(man_MANS) +include_HEADERS = tap.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libtap.la: $(libtap_la_OBJECTS) $(libtap_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libtap_la_LDFLAGS) $(libtap_la_OBJECTS) $(libtap_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tap.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-man3: $(man3_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man3dir)" || $(mkdir_p) "$(DESTDIR)$(man3dir)" + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \ + done +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 3*) ;; \ + *) ext='3' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man3dir)/$$inst"; \ + done +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(MANS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS install-man + +install-exec-am: install-libLTLIBRARIES + +install-info: install-info-am + +install-man: install-man3 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-info-am \ + uninstall-libLTLIBRARIES uninstall-man + +uninstall-man: uninstall-man3 + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-man3 install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-includeHEADERS uninstall-info-am \ + uninstall-libLTLIBRARIES uninstall-man uninstall-man3 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/src/tap.3 b/tap/src/tap.3 new file mode 100644 index 0000000..4b23c24 --- /dev/null +++ b/tap/src/tap.3 @@ -0,0 +1,368 @@ +.Dd December 20, 2004 +.Os +.Dt TAP 3 +.Sh NAME +.Nm tap +.Nd write tests that implement the Test Anything Protocol +.Sh SYNOPSIS +.In tap.h +.Sh DESCRIPTION +The +.Nm +library provides functions for writing test scripts that produce output +consistent with the Test Anything Protocol. A test harness that parses +this protocol can run these tests and produce useful reports indicating +their success or failure. +.Ss PRINTF STRINGS +In the descriptions that follow, for any function that takes as the +last two parameters +.Dq Fa char * , Fa ... +it can be assumed that the +.Fa char * +is a +.Fn printf +-like format string, and the optional arguments are values to be placed +in that string. +.Ss TEST PLANS +.Bl -tag -width indent +.It Xo +.Ft int +.Fn plan_tests "unsigned int" +.Xc +.It Xo +.Ft int +.Fn plan_no_plan "void" +.Xc +.It Xo +.Ft int +.Fn plan_skip_all "char *" "..." +.Xc +.El +.Pp +You must first specify a test plan. This indicates how many tests you +intend to run, and allows the test harness to notice if any tests were +missed, or if the test program exited prematurely. +.Pp +To do this, use +.Fn plan_tests , +which always returns 0. The function will cause your program to exit +prematurely if you specify 0 tests. +.Pp +In some situations you may not know how many tests you will be running, or +you are developing your test program, and do not want to update the +.Fn plan_tests +parameter every time you make a change. For those situations use +.Fn plan_no_plan . +It returns 0, and indicates to the test harness that an indeterminate number +of tests will be run. +.Pp +Both +.Fn plan_tests +and +.Fn plan_no_plan +will cause your test program to exit prematurely with a diagnostic +message if they are called more than once. +.Pp +If your test program detects at run time that some required functionality +is missing (for example, it relies on a database connection which is not +present, or a particular configuration option that has not been included +in the running kernel) use +.Fn plan_skip_all , +passing as parameters a string to display indicating the reason for skipping +the tests. +.Ss SIMPLE TESTS +.Bl -tag -width indent +.It Xo +.Ft unsigned int +.Fn ok "expression" "char *" "..." +.Xc +.It Xo +.Ft unsigned int +.Fn ok1 "expression" +.Xc +.It Xo +.Ft unsigned int +.Fn pass "char *" "..." +.Xc +.It Xo +.Ft unsigned int +.Fn fail "char *" "..." +.Xc +.El +.Pp +Tests are implemented as expressions checked by calls to the +.Fn ok +and +.Fn ok1 +macros. In both cases +.Fa expression +should evaluate to true if the test succeeded. +.Pp +.Fn ok +allows you to specify a name, or comment, describing the test which will +be included in the output. +.Fn ok1 +is for those times when the expression to be tested is self +explanatory and does not need an associated comment. In those cases +the test expression becomes the comment. +.Pp +These four calls are equivalent: +.Bd -literal -offset indent +int i = 5; + +ok(i == 5, "i equals 5"); /* Overly verbose */ +ok(i == 5, "i equals %d", i); /* Just to demonstrate printf-like + behaviour of the test name */ +ok(i == 5, "i == 5"); /* Needless repetition */ +ok1(i == 5); /* Just right */ +.Ed +.Pp +It is good practice to ensure that the test name describes the meaning +behind the test rather than what you are testing. Viz +.Bd -literal -offset indent +ok(db != NULL, "db is not NULL"); /* Not bad, but */ +ok(db != NULL, "Database conn. succeeded"); /* this is better */ +.Ed +.Pp +.Fn ok +and +.Fn ok1 +return 1 if the expression evaluated to true, and 0 if it evaluated to +false. This lets you chain calls from +.Fn ok +to +.Fn diag +to only produce diagnostic output if the test failed. For example, this +code will include diagnostic information about why the database connection +failed, but only if the test failed. +.Bd -literal -offset indent +ok(db != NULL, "Database conn. succeeded") || + diag("Database error code: %d", dberrno); +.Ed +.Pp +You also have +.Fn pass +and +.Fn fail . +From the Test::More documentation: +.Bd -literal -offset indent +Sometimes you just want to say that the tests have passed. +Usually the case is you've got some complicated condition +that is difficult to wedge into an ok(). In this case, +you can simply use pass() (to declare the test ok) or fail +(for not ok). + +Use these very, very, very sparingly. +.Ed +.Pp +These are synonyms for ok(1, ...) and ok(0, ...). +.Ss SKIPPING TESTS +.Bl -tag -width indent +.It Xo +.Ft int +.Fn skip "unsigned int" "char *" "..." +.Xc +.It Xo +.Fn skip_start "expression" "unsigned int" "char *" "..." +.Xc +.It Xo +.Sy skip_end +.Xc +.El +.Pp +Sets of tests can be skipped. Ordinarily you would do this because +the test can't be run in this particular testing environment. +.Pp +For example, suppose some tests should be run as root. If the test is +not being run as root then the tests should be skipped. In this +implementation, skipped tests are flagged as being ok, with a special +message indicating that they were skipped. It is your responsibility +to ensure that the number of tests skipped (the first parameter to +.Fn skip ) +is correct for the number of tests to skip. +.Pp +One way of implementing this is with a +.Dq do { } while(0); +loop, or an +.Dq if( ) { } else { } +construct, to ensure that there are no additional side effects from the +skipped tests. +.Bd -literal -offset indent +if(getuid() != 0) { + skip(1, "because test only works as root"); +} else { + ok(do_something_as_root() == 0, "Did something as root"); +} +.Ed +.Pp +Two macros are provided to assist with this. The previous example could +be re-written as follows. +.Bd -literal -offset indent +skip_start(getuid() != 0, 1, "because test only works as root"); + +ok(do_something_as_root() == 0, "Did something as root"); + +skip_end; /* It's a macro, no parentheses */ +.Ed +.Ss MARKING TESTS AS Dq TODO +.Bl -tag -width indent +.It Xo +.Ft void +.Fn todo_start "char *" "..." +.Xc +.It Xo +.Ft void +.Fn todo_end "void" +.Xc +.El +.Pp +Sets of tests can be flagged as being +.Dq TODO . +These are tests that you expect to fail, probably because you haven't +fixed a bug, or finished a new feature yet. These tests will still be +run, but with additional output that indicates that they are expected +to fail. Should a test start to succeed unexpectedly, tools like +.Xr prove 1 +will indicate this, and you can move the test out of the todo +block. This is much more useful than simply commenting out (or +.Dq #ifdef 0 ... #endif ) +the tests. +.Bd -literal -offset indent +todo_start("dwim() not returning true yet"); + +ok(dwim(), "Did what the user wanted"); + +todo_end(); +.Ed +.Pp +Should +.Fn dwim +ever start succeeding you will know about it as soon as you run the +tests. Note that +.Em unlike +the +.Fn skip_* +family, additional code between +.Fn todo_start +and +.Fn todo_end +.Em is +executed. +.Ss SKIP vs. TODO +From the Test::More documentation; +.Bd -literal -offset indent +If it's something the user might not be able to do, use SKIP. +This includes optional modules that aren't installed, running +under an OS that doesn't have some feature (like fork() or +symlinks), or maybe you need an Internet connection and one +isn't available. + +If it's something the programmer hasn't done yet, use TODO. +This is for any code you haven't written yet, or bugs you have +yet to fix, but want to put tests in your testing script +(always a good idea). +.Ed +.Ss DIAGNOSTIC OUTPUT +.Bl -tag -width indent +.It Xo +.Fr unsigned int +.Fn diag "char *" "..." +.Xc +.El +.Pp +If your tests need to produce diagnostic output, use +.Fn diag . +It ensures that the output will not be considered by the TAP test harness. +.Fn diag +adds the necessary trailing +.Dq \en +for you. +.Bd -literal -offset indent +diag("Expected return code 0, got return code %d", rcode); +.Ed +.Pp +.Fn diag +always returns 0. +.Ss EXIT STATUS +.Bl -tag -width indent +.It Xo +.Fr int +.Fn exit_status void +.Xc +.El +.Pp +For maximum compatability your test program should return a particular +exit code. This is calculated by +.Fn exit_status +so it is sufficient to always return from +.Fn main +with either +.Dq return exit_status(); +or +.Dq exit(exit_status()); +as appropriate. +.Sh EXAMPLES +The +.Pa tests +directory in the source distribution contains numerous tests of +.Nm +functionality, written using +.Nm . +Examine them for examples of how to construct test suites. +.Sh COMPATABILITY +.Nm +strives to be compatible with the Perl Test::More and Test::Harness +modules. The test suite verifies that +.Nm +is bug-for-bug compatible with their behaviour. This is why some +functions which would more naturally return nothing return constant +values. +.Pp +If the +.Lb libpthread +is found at compile time, +.Nm +.Em should +be thread safe. Indications to the contrary (and test cases that expose +incorrect behaviour) are very welcome. +.Sh SEE ALSO +.Xr Test::More 1 , +.Xr Test::Harness 1 , +.Xr prove 1 +.Sh STANDARDS +.Nm +requires a +.St -isoC-99 +compiler. Some of the +.Nm +functionality is implemented as variadic macros, and that functionality +was not formally codified until C99. Patches to use +.Nm +with earlier compilers that have their own implementation of variadic +macros will be gratefully received. +.Sh HISTORY +.Nm +was written to help improve the quality and coverage of the FreeBSD +regression test suite, and released in the hope that others find it +a useful tool to help improve the quality of their code. +.Sh AUTHORS +.An "Nik Clayton" Aq nik@ngo.org.uk , +.Aq nik@FreeBSD.org +.Pp +.Nm +would not exist without the efforts of +.An "Michael G Schwern" Aq schqern@pobox.com , +.An "Andy Lester" Aq andy@petdance.com , +and the countless others who have worked on the Perl QA programme. +.Sh BUGS +Ideally, running the tests would have no side effects on the behaviour +of the application you are testing. However, it is not always possible +to avoid them. The following side effects of using +.Nm +are known. +.Bl -bullet -offset indent +.It +stdout is set to unbuffered mode after calling any of the +.Fn plan_* +functions. +.El diff --git a/tap/src/tap.c b/tap/src/tap.c new file mode 100644 index 0000000..4ad647e --- /dev/null +++ b/tap/src/tap.c @@ -0,0 +1,425 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "tap.h" + +static int no_plan = 0; +static int skip_all = 0; +static int have_plan = 0; +static unsigned int test_count = 0; /* Number of tests that have been run */ +static unsigned int e_tests = 0; /* Expected number of tests to run */ +static unsigned int failures = 0; /* Number of tests that failed */ +static char *todo_msg = NULL; +static char *todo_msg_fixed = "libtap malloc issue"; +static int todo = 0; +static int test_died = 0; + +/* Encapsulate the pthread code in a conditional. In the absence of + libpthread the code does nothing */ +/* Ton: Remove LIBPTHREAD as locking occurs */ +#ifdef HAVE_LIBPTHREAD_REMOVED +#include +static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&M); +# define UNLOCK pthread_mutex_unlock(&M); +#else +# define LOCK +# define UNLOCK +#endif + +static void _expected_tests(unsigned int); +static void _tap_init(void); +static void _cleanup(void); + +/* + * Generate a test result. + * + * ok -- boolean, indicates whether or not the test passed. + * test_name -- the name of the test, may be NULL + * test_comment -- a comment to print afterwards, may be NULL + */ +unsigned int +_gen_result(int ok, const char *func, char *file, unsigned int line, + char *test_name, ...) { + va_list ap; + char *local_test_name = NULL; + char *c; + int name_is_digits; + + LOCK; + + test_count++; + + /* Start by taking the test name and performing any printf() + expansions on it */ + if(test_name != NULL) { + va_start(ap, test_name); + vasprintf(&local_test_name, test_name, ap); + va_end(ap); + + /* Make sure the test name contains more than digits + and spaces. Emit an error message and exit if it + does */ + if(local_test_name) { + name_is_digits = 1; + for(c = local_test_name; *c != '\0'; c++) { + if(!isdigit(*c) && !isspace(*c)) { + name_is_digits = 0; + break; + } + } + + if(name_is_digits) { + diag(" You named your test '%s'. You shouldn't use numbers for your test names.", local_test_name); + diag(" Very confusing."); + } + } + } + + if(!ok) { + printf("not "); + failures++; + } + + printf("ok %d", test_count); + + if(test_name != NULL) { + printf(" - "); + + /* Print the test name, escaping any '#' characters it + might contain */ + if(local_test_name != NULL) { + flockfile(stdout); + for(c = local_test_name; *c != '\0'; c++) { + if(*c == '#') + fputc('\\', stdout); + fputc((int)*c, stdout); + } + funlockfile(stdout); + } + else { /* vasprintf() failed, use a fixed message */ + printf("%s", todo_msg_fixed); + } + } + + /* If we're in a todo_start() block then flag the test as being + TODO. todo_msg should contain the message to print at this + point. If it's NULL then asprintf() failed, and we should + use the fixed message. + + This is not counted as a failure, so decrement the counter if + the test failed. */ + if(todo) { + printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); + if(!ok) + failures--; + } + + printf("\n"); + + if(!ok) + diag(" Failed %stest (%s:%s() at line %d)", + todo ? "(TODO) " : "", file, func, line); + + free(local_test_name); + + UNLOCK; + + /* We only care (when testing) that ok is positive, but here we + specifically only want to return 1 or 0 */ + return ok ? 1 : 0; + } + +/* + * Initialise the TAP library. Will only do so once, however many times it's + * called. + */ +void +_tap_init(void) { + static int run_once = 0; + + LOCK; + + if(!run_once) { + atexit(_cleanup); + + /* stdout needs to be unbuffered so that the output appears + in the same place relative to stderr output as it does + with Test::Harness */ + setbuf(stdout, 0); + run_once = 1; + } + + UNLOCK; + } + +/* + * Note that there's no plan. + */ +int +plan_no_plan(void) { + + LOCK; + + _tap_init(); + + if(have_plan != 0) { + fprintf(stderr, "You tried to plan twice!\n"); + test_died = 1; + UNLOCK; + exit(255); + } + + have_plan = 1; + no_plan = 1; + + UNLOCK; + + return 0; + } + +/* + * Note that the plan is to skip all tests + */ +int +plan_skip_all(char *reason) { + + LOCK; + + _tap_init(); + + skip_all = 1; + + printf("1..0"); + + if(reason != NULL) + printf(" # Skip %s", reason); + + printf("\n"); + + UNLOCK; + + exit(0); + } + +/* + * Note the number of tests that will be run. + */ +int +plan_tests(unsigned int tests) { + + LOCK; + + _tap_init(); + + if(have_plan != 0) { + fprintf(stderr, "You tried to plan twice!\n"); + test_died = 1; + UNLOCK; + exit(255); + } + + if(tests == 0) { + fprintf(stderr, "You said to run 0 tests! You've got to run something.\n"); + test_died = 1; + UNLOCK; + exit(255); + } + + have_plan = 1; + + _expected_tests(tests); + + UNLOCK; + + return 0; + } + +unsigned int +diag(char *fmt, ...) { + va_list ap; + + LOCK; + + fputs("# ", stderr); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fputs("\n", stderr); + + UNLOCK; + + return 0; + } + +void +_expected_tests(unsigned int tests) { + + LOCK; + + printf("1..%d\n", tests); + e_tests = tests; + + UNLOCK; + } + +int +skip(unsigned int n, char *fmt, ...) { + va_list ap; + char *skip_msg; + + LOCK; + + va_start(ap, fmt); + asprintf(&skip_msg, fmt, ap); + va_end(ap); + + while(n-- > 0) { + test_count++; + printf("ok %d # skip %s\n", test_count, + skip_msg != NULL ? + skip_msg : "libtap():malloc() failed"); + } + + free(skip_msg); + + UNLOCK; + + return 1; + } + +void +todo_start(char *fmt, ...) { + va_list ap; + + LOCK; + + va_start(ap, fmt); + vasprintf(&todo_msg, fmt, ap); + va_end(ap); + + todo = 1; + + UNLOCK; + } + +void +todo_end(void) { + + LOCK; + + todo = 0; + free(todo_msg); + + UNLOCK; + } + +int +exit_status(void) { + int r; + + LOCK; + + /* If there's no plan, just return the number of failures */ + if(no_plan || !have_plan) { + UNLOCK; + return failures; + } + + /* Ran too many tests? Return the number of tests that were run + that shouldn't have been */ + if(e_tests < test_count) { + r = test_count - e_tests; + UNLOCK; + return r; + } + + /* Return the number of tests that failed + the number of tests + that weren't run */ + r = failures + e_tests - test_count; + UNLOCK; + + return r; + } + +/* + * Cleanup at the end of the run, produce any final output that might be + * required. + */ +void +_cleanup(void) { + + LOCK; + + /* If plan_no_plan() wasn't called, and we don't have a plan, + and we're not skipping everything, then something happened + before we could produce any output */ + if(!no_plan && !have_plan && !skip_all) { + diag("Looks like your test died before it could output anything."); + UNLOCK; + return; + } + + if(test_died) { + diag("Looks like your test died just after %d.", test_count); + UNLOCK; + return; + } + + + /* No plan provided, but now we know how many tests were run, and can + print the header at the end */ + if(!skip_all && (no_plan || !have_plan)) { + printf("1..%d\n", test_count); + } + + if((have_plan && !no_plan) && e_tests < test_count) { + diag("Looks like you planned %d tests but ran %d extra.", + e_tests, test_count - e_tests); + UNLOCK; + return; + } + + if((have_plan || !no_plan) && e_tests > test_count) { + diag("Looks like you planned %d tests but only ran %d.", + e_tests, test_count); + UNLOCK; + return; + } + + if(failures) + diag("Looks like you failed %d tests of %d.", + failures, test_count); + + UNLOCK; + } diff --git a/tap/src/tap.h b/tap/src/tap.h new file mode 100644 index 0000000..e64f9d5 --- /dev/null +++ b/tap/src/tap.h @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* '## __VA_ARGS__' is a gcc'ism. C99 doesn't allow the token pasting + and requires the caller to add the final comma if they've ommitted + the optional arguments */ +#ifdef __GNUC__ +# define ok(e, test, ...) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, \ + test, ## __VA_ARGS__) : \ + _gen_result(0, __func__, __FILE__, __LINE__, \ + test, ## __VA_ARGS__)) + +# define ok1(e) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ + _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) + +# define pass(test, ...) ok(1, test, ## __VA_ARGS__); +# define fail(test, ...) ok(0, test, ## __VA_ARGS__); + +# define skip_start(test, n, fmt, ...) \ + do { \ + if((test)) { \ + skip(n, fmt, ## __VA_ARGS__); \ + continue; \ + } +#elif __STDC_VERSION__ >= 199901L /* __GNUC__ */ +# define ok(e, ...) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, \ + __VA_ARGS__) : \ + _gen_result(0, __func__, __FILE__, __LINE__, \ + __VA_ARGS__)) + +# define ok1(e) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ + _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) + +# define pass(...) ok(1, __VA_ARGS__); +# define fail(...) ok(0, __VA_ARGS__); + +# define skip_start(test, n, ...) \ + do { \ + if((test)) { \ + skip(n, __VA_ARGS__); \ + continue; \ + } +#else /* __STDC_VERSION__ */ +# error "Needs gcc or C99 compiler for variadic macros." +#endif /* __STDC_VERSION__ */ + +# define skip_end } while(0); + +unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...); + +int plan_no_plan(void); +int plan_skip_all(char *); +int plan_tests(unsigned int); + +unsigned int diag(char *, ...); + +int skip(unsigned int, char *, ...); + +void todo_start(char *, ...); +void todo_end(void); + +int exit_status(void); diff --git a/tap/tests/Makefile.am b/tap/tests/Makefile.am new file mode 100644 index 0000000..481a967 --- /dev/null +++ b/tap/tests/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS= diag +SUBDIRS+= fail +SUBDIRS+= ok +SUBDIRS+= pass +SUBDIRS+= plan +SUBDIRS+= skip +SUBDIRS+= todo diff --git a/tap/tests/Makefile.in b/tap/tests/Makefile.in new file mode 100644 index 0000000..82a8e5e --- /dev/null +++ b/tap/tests/Makefile.in @@ -0,0 +1,453 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = diag fail ok pass plan skip todo +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/README b/tap/tests/README new file mode 100644 index 0000000..a15fec2 --- /dev/null +++ b/tap/tests/README @@ -0,0 +1,12 @@ +Most of the tests follow the same pattern. + + * test.pl that uses Test::More, and demonstrates whatever functionality + that we're trying to test. This is the reference code. + + * test.c, which tests the libtap reimplementation of the same functionality. + + * test.t, which compiles the .c program, runs both test scripts, and then + diffs their output to make sure it's identical. + + Right now, test.t is identical in every directory. This sucks somewhat. + It should either be a symlink to a common script diff --git a/tap/tests/diag/Makefile.am b/tap/tests/diag/Makefile.am new file mode 100644 index 0000000..c1ccb75 --- /dev/null +++ b/tap/tests/diag/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/diag/Makefile.in b/tap/tests/diag/Makefile.in new file mode 100644 index 0000000..31fe058 --- /dev/null +++ b/tap/tests/diag/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/diag +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/diag/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/diag/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/diag/test.c b/tap/tests/diag/test.c new file mode 100644 index 0000000..bc0ec3a --- /dev/null +++ b/tap/tests/diag/test.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + plan_tests(2); + + rc = diag("A diagnostic message"); + diag("Returned: %d", rc); + + /* Make sure the failure is passed through */ + ok(1, "test 1") || diag("ok() failed, and shouldn't"); + ok(0, "test 2") || diag("ok() passed, and shouldn't"); + + return exit_status(); + } diff --git a/tap/tests/diag/test.pl b/tap/tests/diag/test.pl new file mode 100644 index 0000000..621dc27 --- /dev/null +++ b/tap/tests/diag/test.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +plan tests => 2; + +$rc = diag("A diagnostic message"); +diag("Returned: $rc"); + +ok(1, 'test 1') or diag "ok() failed, and shouldn't"; +ok(0, 'test 2') or diag "ok() passed, and shouldn't"; diff --git a/tap/tests/diag/test.t b/tap/tests/diag/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/diag/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/fail/Makefile.am b/tap/tests/fail/Makefile.am new file mode 100644 index 0000000..c1ccb75 --- /dev/null +++ b/tap/tests/fail/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/fail/Makefile.in b/tap/tests/fail/Makefile.in new file mode 100644 index 0000000..7063a6e --- /dev/null +++ b/tap/tests/fail/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/fail +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/fail/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/fail/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/fail/test.c b/tap/tests/fail/test.c new file mode 100644 index 0000000..929d8dd --- /dev/null +++ b/tap/tests/fail/test.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(2); + diag("Returned: %d", rc); + + rc = fail("test to fail"); + diag("Returned: %d", rc); + + rc = fail("test to fail %s", "with extra string"); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/fail/test.pl b/tap/tests/fail/test.pl new file mode 100644 index 0000000..73de1a7 --- /dev/null +++ b/tap/tests/fail/test.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 2; +diag("Returned: " . sprintf('%d', $rc)); + +$rc = fail('test to fail'); +diag("Returned: $rc"); + +$rc = fail('test to fail with extra string'); +diag("Returned: $rc"); diff --git a/tap/tests/fail/test.t b/tap/tests/fail/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/fail/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/ok/Makefile.am b/tap/tests/ok/Makefile.am new file mode 100644 index 0000000..c949748 --- /dev/null +++ b/tap/tests/ok/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = ok +SUBDIRS += ok-hash +SUBDIRS += ok-numeric diff --git a/tap/tests/ok/Makefile.in b/tap/tests/ok/Makefile.in new file mode 100644 index 0000000..febcce9 --- /dev/null +++ b/tap/tests/ok/Makefile.in @@ -0,0 +1,453 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/ok +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = ok ok-hash ok-numeric +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/ok/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/ok/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/ok/ok-hash/Makefile.am b/tap/tests/ok/ok-hash/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/ok/ok-hash/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/ok/ok-hash/Makefile.in b/tap/tests/ok/ok-hash/Makefile.in new file mode 100644 index 0000000..8c1d6b6 --- /dev/null +++ b/tap/tests/ok/ok-hash/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/ok/ok-hash +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/ok/ok-hash/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/ok/ok-hash/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/ok/ok-hash/test.c b/tap/tests/ok/ok-hash/test.c new file mode 100644 index 0000000..0aa8dbe --- /dev/null +++ b/tap/tests/ok/ok-hash/test.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(4); + diag("Returned: %d", rc); + + rc = ok(1, "Test with no hash"); + diag("Returned: %d", rc); + + rc = ok(1, "Test with one # hash"); + diag("Returned: %d", rc); + + rc = ok(1, "Test with # two # hashes"); + diag("Returned: %d", rc); + + rc = ok(1, "Test with ## back to back hashes"); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/ok/ok-hash/test.pl b/tap/tests/ok/ok-hash/test.pl new file mode 100644 index 0000000..306ddca --- /dev/null +++ b/tap/tests/ok/ok-hash/test.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 4; +diag("Returned: " . sprintf("%d", $rc)); + + +$rc = ok(1, 'Test with no hash'); +diag("Returned: $rc"); + +$rc = ok(1, 'Test with one # hash'); +diag("Returned: $rc"); + +$rc = ok(1, 'Test with # two # hashes'); +diag("Returned: $rc"); + +$rc = ok(1, 'Test with ## back to back hashes'); +diag("Returned: $rc"); diff --git a/tap/tests/ok/ok-hash/test.t b/tap/tests/ok/ok-hash/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/ok/ok-hash/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/ok/ok-numeric/Makefile.am b/tap/tests/ok/ok-numeric/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/ok/ok-numeric/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/ok/ok-numeric/Makefile.in b/tap/tests/ok/ok-numeric/Makefile.in new file mode 100644 index 0000000..ebdde5e --- /dev/null +++ b/tap/tests/ok/ok-numeric/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/ok/ok-numeric +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/ok/ok-numeric/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/ok/ok-numeric/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/ok/ok-numeric/test.c b/tap/tests/ok/ok-numeric/test.c new file mode 100644 index 0000000..06ccf51 --- /dev/null +++ b/tap/tests/ok/ok-numeric/test.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(3); + diag("Returned: %d", rc); + + rc = ok(1, "First test"); + diag("Returned: %d", rc); + + rc = ok(1, "1"); + diag("Returned: %d", rc); + + rc = ok(1, "Third test"); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/ok/ok-numeric/test.pl b/tap/tests/ok/ok-numeric/test.pl new file mode 100644 index 0000000..86f165f --- /dev/null +++ b/tap/tests/ok/ok-numeric/test.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 3; +diag("Returned: " . sprintf("%d", $rc)); + + +$rc = ok(1, 'First test'); +diag("Returned: $rc"); + +$rc = ok(1, '1'); +diag("Returned: $rc"); + +$rc = ok(1, 'Third test'); +diag("Returned: $rc"); diff --git a/tap/tests/ok/ok-numeric/test.t b/tap/tests/ok/ok-numeric/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/ok/ok-numeric/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/ok/ok/Makefile.am b/tap/tests/ok/ok/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/ok/ok/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/ok/ok/Makefile.in b/tap/tests/ok/ok/Makefile.in new file mode 100644 index 0000000..fa416e6 --- /dev/null +++ b/tap/tests/ok/ok/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/ok/ok +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/ok/ok/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/ok/ok/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/ok/ok/test.c b/tap/tests/ok/ok/test.c new file mode 100644 index 0000000..e689dfc --- /dev/null +++ b/tap/tests/ok/ok/test.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(5); + diag("Returned: %d", rc); + + rc = ok(1 == 1, "1 equals 1"); + diag("Returned: %d", rc); + + rc = ok(1 == 1, "1 equals %d", 1); + diag("Returned: %d", rc); + + rc = ok1(1 == 1); + diag("Returned: %d", rc); + + rc = ok(1 == 2, "1 equals 2"); + diag("Returned: %d", rc); + + rc = ok1(1 == 2); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/ok/ok/test.pl b/tap/tests/ok/ok/test.pl new file mode 100644 index 0000000..59f4181 --- /dev/null +++ b/tap/tests/ok/ok/test.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 5; +diag("Returned: " . sprintf("%d", $rc)); + + +$rc = ok(1 == 1, '1 equals 1'); # Test ok() passes when it should +diag("Returned: $rc"); + +$rc = ok(1 == 1, '1 equals 1'); # Used for %d testing in test.c +diag("Returned: $rc"); + +$rc = ok(1 == 1, '1 == 1'); # Test ok1() passes when it should +diag("Returned: $rc"); + +$rc = ok(1 == 2, '1 equals 2'); # Test ok() fails when it should +diag("Returned: $rc"); + +$rc = ok(1 == 2, '1 == 2'); # Test ok1() fails when it should +diag("Returned: $rc"); diff --git a/tap/tests/ok/ok/test.t b/tap/tests/ok/ok/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/ok/ok/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/pass/Makefile.am b/tap/tests/pass/Makefile.am new file mode 100644 index 0000000..c1ccb75 --- /dev/null +++ b/tap/tests/pass/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/pass/Makefile.in b/tap/tests/pass/Makefile.in new file mode 100644 index 0000000..8da84ed --- /dev/null +++ b/tap/tests/pass/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/pass +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/pass/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/pass/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/pass/test.c b/tap/tests/pass/test.c new file mode 100644 index 0000000..894bc8c --- /dev/null +++ b/tap/tests/pass/test.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(2); + diag("Returned: %d", rc); + + rc = pass("test to pass"); + diag("Returned: %d", rc); + + rc = pass("test to pass %s", "with extra string"); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/pass/test.pl b/tap/tests/pass/test.pl new file mode 100644 index 0000000..8abc92e --- /dev/null +++ b/tap/tests/pass/test.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 2; +diag("Returned: " . sprintf('%d', $rc)); + +$rc = pass('test to pass'); +diag("Returned: $rc"); + +$rc = pass('test to pass with extra string'); +diag("Returned: $rc"); diff --git a/tap/tests/pass/test.t b/tap/tests/pass/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/pass/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/Makefile.am b/tap/tests/plan/Makefile.am new file mode 100644 index 0000000..0724931 --- /dev/null +++ b/tap/tests/plan/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS = no-tests +SUBDIRS += no_plan +SUBDIRS += not-enough-tests +SUBDIRS += too-many-plans +SUBDIRS += too-many-tests +SUBDIRS += sane +SUBDIRS += skip_all diff --git a/tap/tests/plan/Makefile.in b/tap/tests/plan/Makefile.in new file mode 100644 index 0000000..9618174 --- /dev/null +++ b/tap/tests/plan/Makefile.in @@ -0,0 +1,454 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/plan +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = no-tests no_plan not-enough-tests too-many-plans \ + too-many-tests sane skip_all +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + clean clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive distclean distclean-generic distclean-libtool \ + distclean-recursive distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/no-tests/Makefile.am b/tap/tests/plan/no-tests/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/no-tests/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/no-tests/Makefile.in b/tap/tests/plan/no-tests/Makefile.in new file mode 100644 index 0000000..514f49b --- /dev/null +++ b/tap/tests/plan/no-tests/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/no-tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/no-tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/no-tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/no-tests/test.c b/tap/tests/plan/no-tests/test.c new file mode 100644 index 0000000..2ab85d8 --- /dev/null +++ b/tap/tests/plan/no-tests/test.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(0); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/no-tests/test.pl b/tap/tests/plan/no-tests/test.pl new file mode 100644 index 0000000..93d2b3b --- /dev/null +++ b/tap/tests/plan/no-tests/test.pl @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 0; +diag("Returned: " . sprintf("%d", $rc)); + +$rc = ok(1); +diag("Returned: $rc"); diff --git a/tap/tests/plan/no-tests/test.t b/tap/tests/plan/no-tests/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/plan/no-tests/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/no_plan/Makefile.am b/tap/tests/plan/no_plan/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/no_plan/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/no_plan/Makefile.in b/tap/tests/plan/no_plan/Makefile.in new file mode 100644 index 0000000..1d8d425 --- /dev/null +++ b/tap/tests/plan/no_plan/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/no_plan +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/no_plan/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/no_plan/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/no_plan/test.c b/tap/tests/plan/no_plan/test.c new file mode 100644 index 0000000..1cc2a41 --- /dev/null +++ b/tap/tests/plan/no_plan/test.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_no_plan(); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/no_plan/test.pl b/tap/tests/plan/no_plan/test.pl new file mode 100644 index 0000000..19e42b5 --- /dev/null +++ b/tap/tests/plan/no_plan/test.pl @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +my $rc = 0; + +use Test::More; + +$rc = plan qw(no_plan); +diag("Returned: " . sprintf("%d", $rc)); + +$rc = ok(1); +diag("Returned: $rc"); diff --git a/tap/tests/plan/no_plan/test.t b/tap/tests/plan/no_plan/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/plan/no_plan/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/not-enough-tests/Makefile.am b/tap/tests/plan/not-enough-tests/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/not-enough-tests/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/not-enough-tests/Makefile.in b/tap/tests/plan/not-enough-tests/Makefile.in new file mode 100644 index 0000000..767fb8d --- /dev/null +++ b/tap/tests/plan/not-enough-tests/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/not-enough-tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/not-enough-tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/not-enough-tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/not-enough-tests/test.c b/tap/tests/plan/not-enough-tests/test.c new file mode 100644 index 0000000..79a9545 --- /dev/null +++ b/tap/tests/plan/not-enough-tests/test.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(1); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/not-enough-tests/test.pl b/tap/tests/plan/not-enough-tests/test.pl new file mode 100644 index 0000000..73787a7 --- /dev/null +++ b/tap/tests/plan/not-enough-tests/test.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 1; +diag("Returned: " . sprintf("%d", $rc)); + +$rc = ok(1); +diag("Returned: $rc"); + +$rc = ok(1); +diag("Returned: $rc"); + +$rc = ok(1); +diag("Returned: $rc"); diff --git a/tap/tests/plan/not-enough-tests/test.t b/tap/tests/plan/not-enough-tests/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/plan/not-enough-tests/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/sane/Makefile.am b/tap/tests/plan/sane/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/sane/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/sane/Makefile.in b/tap/tests/plan/sane/Makefile.in new file mode 100644 index 0000000..b04c0ba --- /dev/null +++ b/tap/tests/plan/sane/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/sane +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/sane/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/sane/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/sane/test.c b/tap/tests/plan/sane/test.c new file mode 100644 index 0000000..4b83998 --- /dev/null +++ b/tap/tests/plan/sane/test.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(1); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/sane/test.pl b/tap/tests/plan/sane/test.pl new file mode 100644 index 0000000..35c4ef2 --- /dev/null +++ b/tap/tests/plan/sane/test.pl @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 1; +diag("Returned: " . sprintf("%d", $rc)); + +$rc = ok(1); +diag("Returned: $rc"); diff --git a/tap/tests/plan/sane/test.t b/tap/tests/plan/sane/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/plan/sane/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/skip_all/Makefile.am b/tap/tests/plan/skip_all/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/skip_all/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/skip_all/Makefile.in b/tap/tests/plan/skip_all/Makefile.in new file mode 100644 index 0000000..cace224 --- /dev/null +++ b/tap/tests/plan/skip_all/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/skip_all +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/skip_all/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/skip_all/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/skip_all/test.c b/tap/tests/plan/skip_all/test.c new file mode 100644 index 0000000..ee24ea3 --- /dev/null +++ b/tap/tests/plan/skip_all/test.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_skip_all("No good reason"); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/skip_all/test.pl b/tap/tests/plan/skip_all/test.pl new file mode 100644 index 0000000..3255572 --- /dev/null +++ b/tap/tests/plan/skip_all/test.pl @@ -0,0 +1,11 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan skip_all => "No good reason"; +diag("Returned: " . sprintf("%d", $rc)); diff --git a/tap/tests/plan/skip_all/test.t b/tap/tests/plan/skip_all/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/plan/skip_all/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/too-many-plans/Makefile.am b/tap/tests/plan/too-many-plans/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/too-many-plans/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/too-many-plans/Makefile.in b/tap/tests/plan/too-many-plans/Makefile.in new file mode 100644 index 0000000..ae3f5f3 --- /dev/null +++ b/tap/tests/plan/too-many-plans/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/too-many-plans +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/too-many-plans/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/too-many-plans/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/too-many-plans/test.c b/tap/tests/plan/too-many-plans/test.c new file mode 100644 index 0000000..7351643 --- /dev/null +++ b/tap/tests/plan/too-many-plans/test.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(1); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + rc = plan_tests(1); + diag("Returned: %d", rc); + + rc = ok(0, NULL); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/too-many-plans/test.pl b/tap/tests/plan/too-many-plans/test.pl new file mode 100644 index 0000000..893e5fc --- /dev/null +++ b/tap/tests/plan/too-many-plans/test.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 1; +diag("Returned: " . sprintf("%d", $rc)); + +$rc = ok(1); +diag("Returned: $rc"); + +$rc = plan tests => 1; +diag("Returned: $rc"); + +$rc = ok(0); +diag("Returned: $rc"); diff --git a/tap/tests/plan/too-many-plans/test.t b/tap/tests/plan/too-many-plans/test.t new file mode 100644 index 0000000..cd2acf7 --- /dev/null +++ b/tap/tests/plan/too-many-plans/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/twice!.*$/twice!/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/twice!.*$/twice!/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/plan/too-many-tests/Makefile.am b/tap/tests/plan/too-many-tests/Makefile.am new file mode 100644 index 0000000..91d880e --- /dev/null +++ b/tap/tests/plan/too-many-tests/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/plan/too-many-tests/Makefile.in b/tap/tests/plan/too-many-tests/Makefile.in new file mode 100644 index 0000000..f95b42c --- /dev/null +++ b/tap/tests/plan/too-many-tests/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/plan/too-many-tests +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../../src +test_LDFLAGS = -L../../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/plan/too-many-tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/plan/too-many-tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/plan/too-many-tests/test.c b/tap/tests/plan/too-many-tests/test.c new file mode 100644 index 0000000..5afdfab --- /dev/null +++ b/tap/tests/plan/too-many-tests/test.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + + rc = plan_tests(5); + diag("Returned: %d", rc); + + rc = ok(1, NULL); + diag("Returned: %d", rc); + + rc = ok(0, NULL); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/plan/too-many-tests/test.pl b/tap/tests/plan/too-many-tests/test.pl new file mode 100644 index 0000000..0a1666b --- /dev/null +++ b/tap/tests/plan/too-many-tests/test.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 5; +diag("Returned: " . sprintf("%d", $rc)); + +$rc = ok(1); +diag("Returned: $rc"); + +$rc = ok(0); +diag("Returned: $rc"); diff --git a/tap/tests/plan/too-many-tests/test.t b/tap/tests/plan/too-many-tests/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/plan/too-many-tests/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/skip/Makefile.am b/tap/tests/skip/Makefile.am new file mode 100644 index 0000000..c1ccb75 --- /dev/null +++ b/tap/tests/skip/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/skip/Makefile.in b/tap/tests/skip/Makefile.in new file mode 100644 index 0000000..75e026d --- /dev/null +++ b/tap/tests/skip/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/skip +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/skip/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/skip/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/skip/test.c b/tap/tests/skip/test.c new file mode 100644 index 0000000..97cae28 --- /dev/null +++ b/tap/tests/skip/test.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + unsigned int side_effect = 0; + + rc = plan_tests(4); + diag("Returned: %d", rc); + + rc = ok(1 == 1, "1 equals 1"); /* Should always work */ + diag("Returned: %d", rc); + + do { + if(1) { + rc = skip(1, "Testing skipping"); + continue; + } + + side_effect++; + + ok(side_effect == 1, "side_effect checked out"); + + } + while(0); + + diag("Returned: %d", rc); + + skip_start(1 == 1, 1, "Testing skipping #2"); + + side_effect++; + rc = ok(side_effect == 1, "side_effect checked out"); + diag("Returned: %d", rc); + + skip_end; + + rc = ok(side_effect == 0, "side_effect is %d", side_effect); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/skip/test.pl b/tap/tests/skip/test.pl new file mode 100644 index 0000000..dc29471 --- /dev/null +++ b/tap/tests/skip/test.pl @@ -0,0 +1,40 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 4; +diag("Returned: " . sprintf("%d", $rc)); + +my $side_effect = 0; # Check whether skipping has side effects + +$rc = ok(1 == 1, '1 equals 1'); # Test ok() passes when it should +diag("Returned: $rc"); + +# Start skipping +SKIP: { + $rc = skip "Testing skipping", 1; + + $side_effect++; + + $rc = ok($side_effect == 1, '$side_effect checked out'); +} + +diag("Returned: $rc"); + +SKIP: { + $rc = skip "Testing skipping #2", 1; + diag("Returned: $rc"); + + $side_effect++; + + $rc = ok($side_effect == 1, '$side_effect checked out'); + diag("Returned: $rc"); +} + +$rc = ok($side_effect == 0, "side_effect is $side_effect"); +diag("Returned: $rc"); diff --git a/tap/tests/skip/test.t b/tap/tests/skip/test.t new file mode 100644 index 0000000..bf0fe8f --- /dev/null +++ b/tap/tests/skip/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed test \(.*\)/# Failed test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tap/tests/todo/Makefile.am b/tap/tests/todo/Makefile.am new file mode 100644 index 0000000..c1ccb75 --- /dev/null +++ b/tap/tests/todo/Makefile.am @@ -0,0 +1,13 @@ + +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) + +EXTRA_DIST = $(TESTS) test.pl + +check_PROGRAMS = test + +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap + +CLEANFILES = test.o test.c.out test.pl.out diff --git a/tap/tests/todo/Makefile.in b/tap/tests/todo/Makefile.in new file mode 100644 index 0000000..37f233b --- /dev/null +++ b/tap/tests/todo/Makefile.in @@ -0,0 +1,512 @@ +# Makefile.in generated by automake 1.9.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SOURCES = test.c + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = tests/todo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +test_SOURCES = test.c +test_OBJECTS = test-test.$(OBJEXT) +test_DEPENDENCIES = +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = test.c +DIST_SOURCES = test.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +TESTS = test.t +TESTS_ENVIRONMENT = $(SHELL) +EXTRA_DIST = $(TESTS) test.pl +test_CFLAGS = -g -I../../src +test_LDFLAGS = -L../../src +test_LDADD = -ltap +CLEANFILES = test.o test.c.out test.pl.out +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/todo/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/todo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +test-test.o: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.o -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.o `test -f 'test.c' || echo '$(srcdir)/'`test.c + +test-test.obj: test.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -MT test-test.obj -MD -MP -MF "$(DEPDIR)/test-test.Tpo" -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/test-test.Tpo" "$(DEPDIR)/test-test.Po"; else rm -f "$(DEPDIR)/test-test.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test.c' object='test-test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_CFLAGS) $(CFLAGS) -c -o test-test.obj `if test -f 'test.c'; then $(CYGPATH_W) 'test.c'; else $(CYGPATH_W) '$(srcdir)/test.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tap/tests/todo/test.c b/tap/tests/todo/test.c new file mode 100644 index 0000000..ec3329a --- /dev/null +++ b/tap/tests/todo/test.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2004 Nik Clayton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "tap.h" + +int +main(int argc, char *argv[]) { + unsigned int rc = 0; + unsigned int side_effect = 0; + + rc = plan_tests(5); + diag("Returned: %d", rc); + + rc = ok(1 == 1, "1 equals 1"); /* Should always work */ + diag("Returned: %d", rc); + + todo_start("For testing purposes"); + + side_effect++; + + /* This test should fail */ + rc = ok(side_effect == 0, "side_effect checked out"); + diag("Returned: %d", rc); + + /* This test should unexpectedly succeed */ + rc = ok(side_effect == 1, "side_effect checked out"); + diag("Returned: %d", rc); + + todo_end(); + + todo_start("Testing printf() %s in todo_start()", "expansion"); + + rc = ok(0, "dummy test"); + diag("Returned: %d", rc); + + todo_end(); + + rc = ok(side_effect == 1, "side_effect is %d", side_effect); + diag("Returned: %d", rc); + + return exit_status(); + } diff --git a/tap/tests/todo/test.pl b/tap/tests/todo/test.pl new file mode 100644 index 0000000..2621e12 --- /dev/null +++ b/tap/tests/todo/test.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use Test::More; + +my $rc = 0; + +$rc = plan tests => 5; +diag("Returned: " . sprintf("%d", $rc)); + +my $side_effect = 0; # Check whether TODO has side effects + +$rc = ok(1 == 1, '1 equals 1'); # Test ok() passes when it should +diag("Returned: $rc"); + +# Start TODO tests +TODO: { + local $TODO = 'For testing purposes'; + + $side_effect++; + + # This test should fail + $rc = ok($side_effect == 0, 'side_effect checked out'); + diag("Returned: $rc"); + + # This test should unexpectedly succeed + $rc = ok($side_effect == 1, 'side_effect checked out'); + diag("Returned: $rc"); +} + +TODO: { + local $TODO = 'Testing printf() expansion in todo_start()'; + + $rc = ok(0, 'dummy test'); + diag("Returned: $rc"); +} + +$rc = ok($side_effect == 1, "side_effect is $side_effect"); +diag("Returned: $rc"); diff --git a/tap/tests/todo/test.t b/tap/tests/todo/test.t new file mode 100644 index 0000000..7dbb17b --- /dev/null +++ b/tap/tests/todo/test.t @@ -0,0 +1,29 @@ +#!/bin/sh + +cd `dirname $0` + +echo '1..2' + +make 2>&1 > /dev/null + +perl ./test.pl 2>&1 | sed -e 's/# Failed (TODO) test \(.*\)/# Failed (TODO) test ()/' > test.pl.out +perlstatus=$? + +./test 2>&1 | sed -e 's/# Failed (TODO) test \(.*\)/# Failed (TODO) test ()/' > test.c.out +cstatus=$? + +diff -u test.pl.out test.c.out + +if [ $? -eq 0 ]; then + echo 'ok 1 - output is identical' +else + echo 'not ok 1 - output is identical' +fi + +if [ $perlstatus -eq $cstatus ]; then + echo 'ok 2 - status code' +else + echo 'not ok 2 - status code' + echo "# perlstatus = $perlstatus" + echo "# cstatus = $cstatus" +fi diff --git a/tools/tinderbox_build b/tools/tinderbox_build new file mode 100755 index 0000000..01d9a8e --- /dev/null +++ b/tools/tinderbox_build @@ -0,0 +1,291 @@ +#!/usr/bin/perl +# tinderbox_build.pl +# This script builds the nagios code and then sends +# logs back to the master tinderbox server +# +# This script is based on mozilla-unix.pl which comes with tinderbox2 +# +# See http://tinderbox.nagios.org for more details + +require 5.000; + +use strict; +use Sys::Hostname; +use Cwd; +use Time::Local; + +my $Version = "1.0"; + +my $myhost = hostname; +chomp($myhost); +my ($host, $junk) = split(/\./, $myhost); + +my $BuildAdministrator = $ENV{TINDERBOX_BUILD_ADMIN} || "$ENV{'USER'}\@$myhost"; +my $TmpDir = $ENV{TMPDIR} || "/tmp"; + +#Default values of cmdline opts +my $ReportStatus = 0; # Do not send results to server + +# Set these to what makes sense for your system + +# Set these proper values for your tinderbox server +# Have the StrictHostKeyChecking=no so that a new host will automatically add hostkey without +# prompting. If host key changes, then will get error, so this should still be secure +my $Tinderbox_user = "tinderbox2"; +my $Tinderbox_server = 'tinderbox.nagios.org'; +my $Tinderbox_ssh_args = "-o StrictHostKeyChecking=no $Tinderbox_user\@$Tinderbox_server"; + +# These shouldn't really need to be changed +my $BuildTree = 'nagios'; +my $BuildName = ''; +my $ConfigureArgs = $ENV{CONFIGURE_ARGS}; + +my $OS = `uname -s`; +my $OSVer = `uname -r`; + +chop($OS, $OSVer); + +if ( $OS eq 'AIX' ) { + $OSVer = `uname -v`; + chop($OSVer); + $OSVer = $OSVer . "." . `uname -r`; + chop($OSVer); +} + +if ( $OS eq 'IRIX64' ) { + $OS = 'IRIX'; +} + +if ( $OS eq 'SCO_SV' ) { + $OS = 'SCOOS'; + $OSVer = '5.0'; +} + +if ( "$host" ne "" ) { + $BuildName = $host . ' '; +} +$BuildName .= $OS . ' ' . $OSVer; +$_ = $BuildName; +s/ /_/g; + +my $logfile = "$_.log"; + +sub BuildIt { + my ($fe, @felist, $EarlyExit, $LastTime); + + my $StartDir = getcwd(); + $LastTime = 0; + + print "Starting dir is : $StartDir\n"; + + my $EarlyExit = 0; + + chdir("$StartDir"); + + my $StartTime = time; + if (-e (my $file = "nagios-plugins.spec")) { + open F, $file; + while () { + if (/^Version: trunk-(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) { + $StartTime = timegm(0, $5, $4, $3, ($2 - 1), ($1 - 1900)); + last; + } + } + } + + print "Start time is $StartTime",$/; + + my $CurrentDir = getcwd(); + if ( $CurrentDir ne $StartDir ) { + print "startdir: $StartDir, curdir $CurrentDir\n"; + die "curdir != startdir"; + } + + unlink( "$logfile" ); + + print "opening $logfile\n"; + open( LOG, ">$logfile" ) || print "can't open $?\n"; + print LOG "current dir is -- $host:$CurrentDir\n"; + print LOG "Build Administrator is $BuildAdministrator\n"; + &PrintEnv; + + my $BuildStatus; + if (&configure) { + if (&make) { + if (&maketest) { + $BuildStatus = "success"; + } else { + $BuildStatus = "test_failed"; + } + } else { + $BuildStatus = "build_failed"; + } + } else { + $BuildStatus = "busted"; + } + + print LOG "\nBuild Status = $BuildStatus\n"; + + close(LOG); + chdir("$StartDir"); + +# TV: Leaving this in, because process mail program probably has some +# limitation retained + +# this fun line added on 2/5/98. do not remove. Translated to english, +# that's "take any line longer than 1000 characters, and split it into less +# than 1000 char lines. If any of the resulting lines is +# a dot on a line by itself, replace that with a blank line." +# This is to prevent cases where a . occurs in the log file. Sendmail +# interprets that as the end of the mail, and truncates the log before +# it gets to Tinderbox. (terry weismann, chris yeh) +# +# This was replaced by a perl 'port' of the above, writen by +# preed@netscape.com; good things: no need for system() call, and now it's +# all in perl, so we don't have to do OS checking like before. + + open(LOG, "$logfile") || die "Couldn't open logfile: $!\n"; + open(OUTLOG, ">${logfile}.last") || die "Couldn't open logfile: $!\n"; + + print OUTLOG $/; + print OUTLOG "tinderbox: tree: $BuildTree\n"; + print OUTLOG "tinderbox: builddate: $StartTime\n"; + print OUTLOG "tinderbox: status: $BuildStatus\n"; + print OUTLOG "tinderbox: build: $BuildName $fe\n"; + print OUTLOG "tinderbox: errorparser: unix\n"; + print OUTLOG "tinderbox: buildfamily: unix\n"; + print OUTLOG "tinderbox: END\n"; + print OUTLOG $/; + + while () { + my $q = 0; + + for (;;) { + my $val = $q * 1000; + my $Output = substr($_, $val, 1000); + + last if $Output eq undef; + + $Output =~ s/^\.$//g; + $Output =~ s/\n//g; + print OUTLOG "$Output\n"; + $q++; + } #EndFor + + } #EndWhile + + close(LOG); + close(OUTLOG); + + if ($ReportStatus) { + system( "ssh $Tinderbox_ssh_args tinderbox_receive < ${logfile}.last" ) + } else { + print <<"EOF" +Not sending logs to http://$Tinderbox_server +If you have SSH keys setup on the tinderbox server, you can manually send +with 'ssh $Tinderbox_ssh_args tinderbox_receive < ${logfile}.last' +EOF + } + + unlink("$logfile"); + print "Finished building for tinderbox",$/; + +} #EndSub-BuildIt + +sub ParseArgs { + my($i); + + $i = 0; + while( $i < @ARGV ) { + if ($ARGV[$i] eq '--version' || $ARGV[$i] eq '-v') { + die "$0: version $Version\n"; + } elsif ($ARGV[$i] eq '-y') { + $ReportStatus = 1; + } else { + &PrintUsage; + } + + $i++; + } #EndWhile + +} #EndSub-ParseArgs + +sub PrintUsage { + die "usage: $0 [-v | --version ] [-t do not send report to tinderbox server]\n"; +} + +sub PrintEnv { + my ($key); + foreach $key (keys %ENV) { + print LOG "$key = $ENV{$key}\n"; + print "$key = $ENV{$key}\n"; + } + + # Print the NPTest variables + if (-e "/var/tmp/NPTest.cache") { + open F, "/var/tmp/NPTest.cache"; + print LOG "NPTest variables:\n"; + print LOG ; + close F; + } + +} #EndSub-PrintEnv + +sub SetupPath { + my($Path); + $Path = $ENV{PATH}; + print "Path before: $Path\n"; + + # Don't alter path if we're building off a repository tree; + # SunOS make will be used only for snapshots and releases. + if ( $OS eq 'SunOS' && !( -e '.svn' || -e '.git' )) { + $ENV{'PATH'} = '/usr/ccs/bin:' . $ENV{'PATH'}; + } + + $Path = $ENV{PATH}; + print "Path After: $Path\n"; +} #EndSub-SetupPath + +sub configure { + # Configure + print LOG "./configure --enable-libtap $ConfigureArgs 2>&1\n"; + open (CONFIGURE, "./configure --enable-libtap $ConfigureArgs 2>&1 |") || die "../configure: $!\n"; + while () { + print $_; + print LOG $_; + } + close(CONFIGURE); + return ! $?; +} + +sub make { + # Building + print LOG "make nagios && make cgis 2>&1\n"; + open( MAKE, "make nagios && make cgis 2>&1 |"); + while ( ) { + print $_; + print LOG $_; + } + close( MAKE); + return ! $?; +} + +sub maketest { + # Tests + print LOG "LANG=C make test 2>&1\n"; + open( MAKE, "LANG=C make test 2>&1 |"); + while ( ) { + print $_; + print LOG $_; + } + close( MAKE); + my $rc = $?; + return ! $rc; +} + +# Main function +&ParseArgs; +&SetupPath; +&BuildIt; + +1; diff --git a/update-version b/update-version new file mode 100755 index 0000000..fb5041d --- /dev/null +++ b/update-version @@ -0,0 +1,77 @@ +#!/bin/sh + +# Get date (two formats) +if [ -n "$2" ]; then + LONGDATE=`date -d "$2" "+%B %d, %Y"` + SHORTDATE=`date -d "$2" "+%m-%d-%Y"` +else + LONGDATE=`date "+%B %d, %Y"` + SHORTDATE=`date "+%m-%d-%Y"` +fi + +# Current version number +CURRENTVERSION=3.5.1 + +# Last date +LASTDATE=08-30-2013 + +if [ "x$1" = "x" ] +then + echo "Usage: $0 [revision date]" + echo "" + echo "Run this script with the name of the new version (i.e \"2.0b1\") to" + echo "update version number and modification date in files." + echo "Use the \"newdate\" argument if you want to keep the current version" + echo "number and just update the modification date." + echo "" + echo "Current version=$CURRENTVERSION" + echo "Current Modification date=$LASTDATE" + echo "" + exit 1 +fi + +# Keep track of last version, as it is needed to update quickstart guide pages +lastversion=$CURRENTVERSION + +# What's the new version number (if any)? +newversion=$1 +if [ "x$newversion" = "xnewdate" ] +then + # No new version number, just a new version date + newversion=$CURRENTVERSION +fi + +# Update version number and release date in main PHP page +perl -i -p -e "s/>Version .*Version $newversion.*<\//releasedate\">$LONGDATE<\//;" html/main.php +perl -i -p -e "s/\?version=.*&product=/\?version=$newversion&product=/;" html/main.php +perl -i -p -e "s/$this_version=\".*\";/$this_version=\"$newversion\";/;" html/main.php + +# Update version number and release date in common code +perl -i -p -e "s/VERSION \".*\"/VERSION \"$newversion\"/;" include/common.h +perl -i -p -e "s/MODIFICATION_DATE \".*\"/MODIFICATION_DATE \"$SHORTDATE\"/;" include/common.h + +# Update version number and release date in main code +perl -i -p -e "s/Version: .*/Version: $newversion/;" base/nagios.c +perl -i -p -e "s/Last Modified: [0-9].*/Last Modified: $SHORTDATE/;" base/nagios.c +perl -i -p -e "s/Version: [0-9].*/Version: $newversion/;" base/nagiostats.c +perl -i -p -e "s/Last Modified: [0-9].*/Last Modified: $SHORTDATE/;" base/nagiostats.c + +# Update version number and release date in configure script and configure.in +perl -i -p -e "s/PKG_VERSION=.*/PKG_VERSION=\"$newversion\"/;" configure +perl -i -p -e "s/PKG_REL_DATE=.*\"/PKG_REL_DATE=\"$SHORTDATE\"/;" configure +perl -i -p -e "s/PKG_VERSION=.*/PKG_VERSION=\"$newversion\"/;" configure.in +perl -i -p -e "s/PKG_REL_DATE=.*\"/PKG_REL_DATE=\"$SHORTDATE\"/;" configure.in + +# Update RPM spec file with version number +perl -i -p -e "s/%define version .*/%define version $newversion/;" nagios.spec + +# Update quickstart guides with new version number +#perl -i -p -e "s/nagios-$lastversion/nagios-$newversion/;" html/docs/quickstart-fedora.html +#perl -i -p -e "s/nagios-$lastversion/nagios-$newversion/;" html/docs/quickstart-opensuse.html +#perl -i -p -e "s/nagios-$lastversion/nagios-$newversion/;" html/docs/quickstart-ubuntu.html + +# Update this file with version number and last date +perl -i -p -e "s/^CURRENTVERSION=.*/CURRENTVERSION=$newversion/;" update-version +perl -i -p -e "s/^LASTDATE=.*/LASTDATE=$SHORTDATE/;" update-version + diff --git a/xdata/.gitignore b/xdata/.gitignore new file mode 100644 index 0000000..cc00087 --- /dev/null +++ b/xdata/.gitignore @@ -0,0 +1,2 @@ +Makefile +*.o diff --git a/xdata/Makefile.in b/xdata/Makefile.in new file mode 100644 index 0000000..22993e8 --- /dev/null +++ b/xdata/Makefile.in @@ -0,0 +1,15 @@ +############################ +# Makefile for Nagios +# +# Last Modified: 04-08-2003 +############################ + +clean: + rm -f *.o + rm -f *~ + +distclean: clean + rm -f Makefile + +devclean: distclean + diff --git a/xdata/xcddefault.c b/xdata/xcddefault.c new file mode 100644 index 0000000..868cd13 --- /dev/null +++ b/xdata/xcddefault.c @@ -0,0 +1,186 @@ +/***************************************************************************** + * + * XCDDEFAULT.C - Default external comment data routines for Nagios + * + * Copyright (c) 2000-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 09-04-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. + * + *****************************************************************************/ + + +/*********** COMMON HEADER FILES ***********/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/locations.h" +#include "../include/comments.h" +#include "../include/macros.h" + +#ifdef NSCORE +#include "../include/objects.h" +#include "../include/nagios.h" +#endif + +#ifdef NSCGI +#include "../include/cgiutils.h" +#endif + + +/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ +#include "xcddefault.h" + + +#ifdef NSCORE +extern unsigned long next_comment_id; +extern comment *comment_list; +#endif + + + +#ifdef NSCORE + +/******************************************************************/ +/************ COMMENT INITIALIZATION/CLEANUP FUNCTIONS ************/ +/******************************************************************/ + + +/* initialize comment data */ +int xcddefault_initialize_comment_data(char *main_config_file) { + comment *temp_comment = NULL; + + /* find the new starting index for comment id if its missing*/ + if(next_comment_id == 0L) { + for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) { + if(temp_comment->comment_id >= next_comment_id) + next_comment_id = temp_comment->comment_id + 1; + } + } + + /* initialize next comment id if necessary */ + if(next_comment_id == 0L) + next_comment_id = 1; + + return OK; + } + + +/* removes invalid and old comments from the comment file */ +int xcddefault_cleanup_comment_data(char *main_config_file) { + + /* nothing to do anymore */ + + return OK; + } + + + + + +/******************************************************************/ +/***************** DEFAULT DATA OUTPUT FUNCTIONS ******************/ +/******************************************************************/ + + +/* adds a new host comment */ +int xcddefault_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) { + + /* find the next valid comment id */ + while(find_host_comment(next_comment_id) != NULL) + next_comment_id++; + + /* add comment to list in memory */ + add_host_comment(entry_type, host_name, entry_time, author_name, comment_data, next_comment_id, persistent, expires, expire_time, source); + + /* update comment file */ + xcddefault_save_comment_data(); + + /* return the id for the comment we are about to add (this happens in the main code) */ + if(comment_id != NULL) + *comment_id = next_comment_id; + + /* increment the comment id */ + next_comment_id++; + + return OK; + } + + +/* adds a new service comment */ +int xcddefault_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) { + + /* find the next valid comment id */ + while(find_service_comment(next_comment_id) != NULL) + next_comment_id++; + + /* add comment to list in memory */ + add_service_comment(entry_type, host_name, svc_description, entry_time, author_name, comment_data, next_comment_id, persistent, expires, expire_time, source); + + /* update comment file */ + xcddefault_save_comment_data(); + + /* return the id for the comment we are about to add (this happens in the main code) */ + if(comment_id != NULL) + *comment_id = next_comment_id; + + /* increment the comment id */ + next_comment_id++; + + return OK; + } + + + +/******************************************************************/ +/**************** COMMENT DELETION FUNCTIONS **********************/ +/******************************************************************/ + + +/* deletes a host comment */ +int xcddefault_delete_host_comment(unsigned long comment_id) { + + /* update comment file */ + xcddefault_save_comment_data(); + + return OK; + } + + +/* deletes a service comment */ +int xcddefault_delete_service_comment(unsigned long comment_id) { + + /* update comment file */ + xcddefault_save_comment_data(); + + return OK; + } + + + +/******************************************************************/ +/****************** COMMENT OUTPUT FUNCTIONS **********************/ +/******************************************************************/ + +/* writes comment data to file */ +int xcddefault_save_comment_data(void) { + + /* don't update the status file now (too inefficent), let aggregated status updates do it */ + return OK; + } + +#endif + diff --git a/xdata/xcddefault.h b/xdata/xcddefault.h new file mode 100644 index 0000000..cf6d72b --- /dev/null +++ b/xdata/xcddefault.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * + * XCDDEFAULT.H - Header file for default comment data routines + * + * Copyright (c) 2000-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-26-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _XCDDEFAULT_H +#define _XCDDEFAULT_H + +#ifdef NSCORE +int xcddefault_initialize_comment_data(char *); +int xcddefault_cleanup_comment_data(char *); +int xcddefault_save_comment_data(void); +int xcddefault_add_new_host_comment(int, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); +int xcddefault_add_new_service_comment(int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); +int xcddefault_delete_host_comment(unsigned long); +int xcddefault_delete_service_comment(unsigned long); +#endif + +#endif diff --git a/xdata/xdddefault.c b/xdata/xdddefault.c new file mode 100644 index 0000000..e6dc6c6 --- /dev/null +++ b/xdata/xdddefault.c @@ -0,0 +1,294 @@ +/***************************************************************************** + * + * XDDDEFAULT.C - Default scheduled downtime data routines for Nagios + * + * Copyright (c) 2001-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 09-04-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. + * + *****************************************************************************/ + + +/*********** COMMON HEADER FILES ***********/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/locations.h" +#include "../include/downtime.h" +#include "../include/macros.h" + +#ifdef NSCORE +#include "../include/objects.h" +#include "../include/nagios.h" +#endif + +#ifdef NSCGI +#include "../include/cgiutils.h" +#endif + + +/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ +#include "xdddefault.h" + + + +#ifdef NSCORE +extern unsigned long next_downtime_id; +extern scheduled_downtime *scheduled_downtime_list; +#endif + + + + +#ifdef NSCORE + + +/******************************************************************/ +/*********** DOWNTIME INITIALIZATION/CLEANUP FUNCTIONS ************/ +/******************************************************************/ + + +/* initialize downtime data */ +int xdddefault_initialize_downtime_data(char *main_config_file) { + scheduled_downtime *temp_downtime = NULL; + + /* clean up the old downtime data */ + xdddefault_validate_downtime_data(); + + /* find the new starting index for downtime id if its missing*/ + if(next_downtime_id == 0L) { + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + if(temp_downtime->downtime_id >= next_downtime_id) + next_downtime_id = temp_downtime->downtime_id + 1; + } + } + + /* initialize next downtime id if necessary */ + if(next_downtime_id == 0L) + next_downtime_id = 1; + + return OK; + } + + + +/* removes invalid and old downtime entries from the downtime file */ +int xdddefault_validate_downtime_data(void) { + scheduled_downtime *temp_downtime; + scheduled_downtime *next_downtime; + int update_file = FALSE; + int save = TRUE; + + /* remove stale downtimes */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { + + next_downtime = temp_downtime->next; + save = TRUE; + + /* delete downtimes with invalid host names */ + if(find_host(temp_downtime->host_name) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Deleting downtime with invalid host name: %s\n", + temp_downtime->host_name); + save = FALSE; + } + + /* delete downtimes with invalid service descriptions */ + if(temp_downtime->type == SERVICE_DOWNTIME && find_service(temp_downtime->host_name, temp_downtime->service_description) == NULL) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Deleting downtime with invalid service description: %s\n", + temp_downtime->service_description); + save = FALSE; + } + + /* delete fixed downtimes that have expired */ + if((TRUE == temp_downtime->fixed) && + (temp_downtime->end_time < time(NULL))) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Deleting fixed downtime that expired at: %lu\n", + temp_downtime->end_time); + save = FALSE; + } + + /* delete flexible downtimes that never started and have expired */ + if((FALSE == temp_downtime->fixed) && + (0 == temp_downtime->flex_downtime_start) && + (temp_downtime->end_time < time(NULL))) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Deleting flexible downtime that expired at: %lu\n", + temp_downtime->end_time); + save = FALSE; + } + + /* delete flexible downtimes that started but whose duration + has completed */ + if((FALSE == temp_downtime->fixed) && + (0 != temp_downtime->flex_downtime_start) && + ((temp_downtime->flex_downtime_start + temp_downtime->duration) + < time(NULL))) { + log_debug_info(DEBUGL_DOWNTIME, 1, + "Deleting flexible downtime whose duration ended at: %lu\n", + temp_downtime->flex_downtime_start + temp_downtime->duration); + save = FALSE; + } + + /* delete the downtime */ + if(save == FALSE) { + update_file = TRUE; + delete_downtime(temp_downtime->type, temp_downtime->downtime_id); + } + } + + /* remove triggered downtimes without valid parents */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { + + next_downtime = temp_downtime->next; + save = TRUE; + + if(temp_downtime->triggered_by == 0) + continue; + + if(find_host_downtime(temp_downtime->triggered_by) == NULL && find_service_downtime(temp_downtime->triggered_by) == NULL) + save = FALSE; + + /* delete the downtime */ + if(save == FALSE) { + update_file = TRUE; + delete_downtime(temp_downtime->type, temp_downtime->downtime_id); + } + } + + /* update downtime file */ + if(update_file == TRUE) + xdddefault_save_downtime_data(); + + return OK; + } + + + +/* removes invalid and old downtime entries from the downtime file */ +int xdddefault_cleanup_downtime_data(char *main_config_file) { + + /* we don't need to do any cleanup... */ + return OK; + } + + + +/******************************************************************/ +/************************ SAVE FUNCTIONS **************************/ +/******************************************************************/ + +/* adds a new scheduled host downtime entry */ +int xdddefault_add_new_host_downtime(char *host_name, time_t entry_time, char *author, char *comment, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent) { + + /* find the next valid downtime id */ + while(find_host_downtime(next_downtime_id) != NULL) + next_downtime_id++; + + /* add downtime to list in memory */ + add_host_downtime(host_name, entry_time, author, comment, start_time, (time_t)0, end_time, fixed, triggered_by, duration, next_downtime_id, is_in_effect, start_notification_sent); + + /* update downtime file */ + xdddefault_save_downtime_data(); + + /* return the id for the downtime we are about to add (this happens in the main code) */ + if(downtime_id != NULL) + *downtime_id = next_downtime_id; + + /* increment the downtime id */ + next_downtime_id++; + + return OK; + } + + + +/* adds a new scheduled service downtime entry */ +int xdddefault_add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent) { + + /* find the next valid downtime id */ + while(find_service_downtime(next_downtime_id) != NULL) + next_downtime_id++; + + /* add downtime to list in memory */ + add_service_downtime(host_name, service_description, entry_time, author, comment, start_time, (time_t)0, end_time, fixed, triggered_by, duration, next_downtime_id, is_in_effect, start_notification_sent); + + /* update downtime file */ + xdddefault_save_downtime_data(); + + /* return the id for the downtime we are about to add (this happens in the main code) */ + if(downtime_id != NULL) + *downtime_id = next_downtime_id; + + /* increment the downtime id */ + next_downtime_id++; + + return OK; + } + + +/******************************************************************/ +/********************** DELETION FUNCTIONS ************************/ +/******************************************************************/ + +/* deletes a scheduled host downtime entry */ +int xdddefault_delete_host_downtime(unsigned long downtime_id) { + int result; + + result = xdddefault_delete_downtime(HOST_DOWNTIME, downtime_id); + + return result; + } + + +/* deletes a scheduled service downtime entry */ +int xdddefault_delete_service_downtime(unsigned long downtime_id) { + int result; + + result = xdddefault_delete_downtime(SERVICE_DOWNTIME, downtime_id); + + return result; + } + + +/* deletes a scheduled host or service downtime entry */ +int xdddefault_delete_downtime(int type, unsigned long downtime_id) { + + /* rewrite the downtime file (downtime was already removed from memory) */ + xdddefault_save_downtime_data(); + + return OK; + } + + + +/******************************************************************/ +/****************** DOWNTIME OUTPUT FUNCTIONS *********************/ +/******************************************************************/ + +/* writes downtime data to file */ +int xdddefault_save_downtime_data(void) { + + /* don't update the status file now (too inefficent), let aggregated status updates do it */ + return OK; + } + +#endif + + diff --git a/xdata/xdddefault.h b/xdata/xdddefault.h new file mode 100644 index 0000000..fa5e708 --- /dev/null +++ b/xdata/xdddefault.h @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * XDDDEFAULT.H - Header file for default scheduled downtime data routines + * + * Copyright (c) 2001-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 03-01-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _XDDDEFAULT_H +#define _XDDDEFAULT_H + +#define XDDDEFAULT_NO_DATA 0 +#define XDDDEFAULT_INFO_DATA 1 +#define XDDDEFAULT_HOST_DATA 2 +#define XDDDEFAULT_SERVICE_DATA 3 + +#ifdef NSCORE +int xdddefault_initialize_downtime_data(char *); +int xdddefault_validate_downtime_data(void); +int xdddefault_cleanup_downtime_data(char *); + +int xdddefault_save_downtime_data(void); +int xdddefault_add_new_host_downtime(char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); +int xdddefault_add_new_service_downtime(char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); + +int xdddefault_delete_host_downtime(unsigned long); +int xdddefault_delete_service_downtime(unsigned long); +int xdddefault_delete_downtime(int, unsigned long); +#endif + +#endif diff --git a/xdata/xodtemplate.c b/xdata/xodtemplate.c new file mode 100644 index 0000000..58eac00 --- /dev/null +++ b/xdata/xodtemplate.c @@ -0,0 +1,13590 @@ +/***************************************************************************** + * + * XODTEMPLATE.C - Template-based object configuration data input routines + * + * Copyright (c) 2001-2009 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 01-01-2009 + * + * Description: + * + * Routines for parsing and resolving template-based object definitions. + * Basic steps involved in this in the daemon are as follows: + * + * 1) Read + * 2) Resolve + * 3) Duplicate + * 4) Recombobulate + * 5) Cache + * 7) Register + * 8) Cleanup + * + * The steps involved for the CGIs differ a bit, since they read the cached + * definitions which are already resolved, recombobulated and duplicated. In + * otherwords, they've already been "flattened"... + * + * 1) Read + * 2) Register + * 3) Cleanup + * + * + * 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/locations.h" +#include "../include/macros.h" +#include "../include/skiplist.h" + +/**** CORE OR CGI SPECIFIC HEADER FILES ****/ + +#ifdef NSCORE +#include "../include/nagios.h" +#endif + +#ifdef NSCGI +#include "../include/cgiutils.h" +#endif + +/**** DATA INPUT-SPECIFIC HEADER FILES ****/ + +#include "xodtemplate.h" + + +#ifdef NSCORE +extern int use_regexp_matches; +extern int use_true_regexp_matching; +extern int verify_config; +extern int test_scheduling; +extern int use_precached_objects; +#endif + +xodtemplate_timeperiod *xodtemplate_timeperiod_list = NULL; +xodtemplate_command *xodtemplate_command_list = NULL; +xodtemplate_contactgroup *xodtemplate_contactgroup_list = NULL; +xodtemplate_hostgroup *xodtemplate_hostgroup_list = NULL; +xodtemplate_servicegroup *xodtemplate_servicegroup_list = NULL; +xodtemplate_servicedependency *xodtemplate_servicedependency_list = NULL; +xodtemplate_serviceescalation *xodtemplate_serviceescalation_list = NULL; +xodtemplate_contact *xodtemplate_contact_list = NULL; +xodtemplate_host *xodtemplate_host_list = NULL; +xodtemplate_service *xodtemplate_service_list = NULL; +xodtemplate_hostdependency *xodtemplate_hostdependency_list = NULL; +xodtemplate_hostescalation *xodtemplate_hostescalation_list = NULL; +xodtemplate_hostextinfo *xodtemplate_hostextinfo_list = NULL; +xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list = NULL; + +xodtemplate_timeperiod *xodtemplate_timeperiod_list_tail = NULL; +xodtemplate_command *xodtemplate_command_list_tail = NULL; +xodtemplate_contactgroup *xodtemplate_contactgroup_list_tail = NULL; +xodtemplate_hostgroup *xodtemplate_hostgroup_list_tail = NULL; +xodtemplate_servicegroup *xodtemplate_servicegroup_list_tail = NULL; +xodtemplate_servicedependency *xodtemplate_servicedependency_list_tail = NULL; +xodtemplate_serviceescalation *xodtemplate_serviceescalation_list_tail = NULL; +xodtemplate_contact *xodtemplate_contact_list_tail = NULL; +xodtemplate_host *xodtemplate_host_list_tail = NULL; +xodtemplate_service *xodtemplate_service_list_tail = NULL; +xodtemplate_hostdependency *xodtemplate_hostdependency_list_tail = NULL; +xodtemplate_hostescalation *xodtemplate_hostescalation_list_tail = NULL; +xodtemplate_hostextinfo *xodtemplate_hostextinfo_list_tail = NULL; +xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list_tail = NULL; + + +skiplist *xobject_template_skiplists[NUM_XOBJECT_SKIPLISTS]; +skiplist *xobject_skiplists[NUM_XOBJECT_SKIPLISTS]; + + +void *xodtemplate_current_object = NULL; +int xodtemplate_current_object_type = XODTEMPLATE_NONE; + +int xodtemplate_current_config_file = 0; +char **xodtemplate_config_files = NULL; + +char *xodtemplate_cache_file = NULL; +char *xodtemplate_precache_file = NULL; + +int presorted_objects = FALSE; + +extern int allow_empty_hostgroup_assignment; + +/* + * Macro magic used to determine if a service is assigned + * via hostgroup_name or host_name. Those assigned via host_name + * take precedence. + */ +#define X_SERVICE_IS_FROM_HOSTGROUP (1 << 1) /* flag to know if service come from a hostgroup def, apply on srv->have_initial_state */ +#define xodtemplate_set_service_is_from_hostgroup(srv) \ + srv->have_initial_state |= X_SERVICE_IS_FROM_HOSTGROUP +#define xodtemplate_unset_service_is_from_hostgroup(srv) \ + srv->have_initial_state &= ~X_SERVICE_IS_FROM_HOSTGROUP +#define xodtemplate_is_service_is_from_hostgroup(srv) \ + ((srv->have_initial_state & X_SERVICE_IS_FROM_HOSTGROUP) != 0) + + + +/* returns the name of a numbered config file */ +static char *xodtemplate_config_file_name(int config_file) { + if(config_file <= xodtemplate_current_config_file) + return xodtemplate_config_files[config_file - 1]; + + return "?"; + } + + + +/******************************************************************/ +/************* TOP-LEVEL CONFIG DATA INPUT FUNCTION ***************/ +/******************************************************************/ + +/* process all config files - both core and CGIs pass in name of main config file */ +int xodtemplate_read_config_data(char *main_config_file, int options, int cache, int precache) { +#ifdef NSCORE + char *config_file = NULL; + char *config_base_dir = NULL; + char *input = NULL; + char *var = NULL; + char *val = NULL; + struct timeval tv[14]; + double runtime[14]; + mmapfile *thefile = NULL; +#endif + int result = OK; + + + if(main_config_file == NULL) { +#ifdef NSCORE + printf("Error: No main config file passed to object routines!\n"); +#endif + return ERROR; + } + + /* get variables from main config file */ + xodtemplate_grab_config_info(main_config_file); + + /* initialize variables */ + xodtemplate_timeperiod_list = NULL; + xodtemplate_command_list = NULL; + xodtemplate_contactgroup_list = NULL; + xodtemplate_hostgroup_list = NULL; + xodtemplate_servicegroup_list = NULL; + xodtemplate_servicedependency_list = NULL; + xodtemplate_serviceescalation_list = NULL; + xodtemplate_contact_list = NULL; + xodtemplate_host_list = NULL; + xodtemplate_service_list = NULL; + xodtemplate_hostdependency_list = NULL; + xodtemplate_hostescalation_list = NULL; + xodtemplate_hostextinfo_list = NULL; + xodtemplate_serviceextinfo_list = NULL; + + /* initialize skiplists */ + xodtemplate_init_xobject_skiplists(); + + xodtemplate_current_object = NULL; + xodtemplate_current_object_type = XODTEMPLATE_NONE; + + /* allocate memory for 256 config files (increased dynamically) */ + xodtemplate_current_config_file = 0; + xodtemplate_config_files = (char **)malloc(256 * sizeof(char **)); + if(xodtemplate_config_files == NULL) { +#ifdef NSCORE + printf("Unable to allocate memory!\n"); +#endif + return ERROR; + } + + /* are the objects we're reading already pre-sorted? */ + presorted_objects = FALSE; +#ifdef NSCORE + presorted_objects = (use_precached_objects == TRUE) ? TRUE : FALSE; +#endif + +#ifdef NSCORE + if(test_scheduling == TRUE) + gettimeofday(&tv[0], NULL); + + /* only process the precached object file as long as we're not regenerating it and we're not verifying the config */ + if(use_precached_objects == TRUE) + result = xodtemplate_process_config_file(xodtemplate_precache_file, options); + + /* process object config files normally... */ + else { + + /* determine the directory of the main config file */ + if((config_file = (char *)strdup(main_config_file)) == NULL) { + my_free(xodtemplate_config_files); +#ifdef NSCORE + printf("Unable to allocate memory!\n"); +#endif + return ERROR; + } + config_base_dir = (char *)strdup(dirname(config_file)); + my_free(config_file); + + /* open the main config file for reading (we need to find all the config files to read) */ + if((thefile = mmap_fopen(main_config_file)) == NULL) { + my_free(config_base_dir); + my_free(xodtemplate_config_files); +#ifdef NSCORE + printf("Unable to open main config file '%s'\n", main_config_file); +#endif + return ERROR; + } + + /* daemon reads all config files/dirs specified in the main config file */ + /* read in all lines from the main config file */ + while(1) { + + /* free memory */ + my_free(input); + + /* get the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + /* strip input */ + strip(input); + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == ';' || input[0] == '\x0') + continue; + + if((var = strtok(input, "=")) == NULL) + continue; + + if((val = strtok(NULL, "\n")) == NULL) + continue; + + /* process a single config file */ + if(!strcmp(var, "xodtemplate_config_file") || !strcmp(var, "cfg_file")) { + + if(config_base_dir != NULL && val[0] != '/') { + asprintf(&config_file, "%s/%s", config_base_dir, val); + } + else + config_file = strdup(val); + + /* process the config file... */ + result = xodtemplate_process_config_file(config_file, options); + + my_free(config_file); + + /* if there was an error processing the config file, break out of loop */ + if(result == ERROR) + break; + } + + /* process all files in a config directory */ + else if(!strcmp(var, "xodtemplate_config_dir") || !strcmp(var, "cfg_dir")) { + + if(config_base_dir != NULL && val[0] != '/') { + asprintf(&config_file, "%s/%s", config_base_dir, val); + } + else + config_file = strdup(val); + + /* strip trailing / if necessary */ + if(config_file != NULL && config_file[strlen(config_file) - 1] == '/') + config_file[strlen(config_file) - 1] = '\x0'; + + /* process the config directory... */ + result = xodtemplate_process_config_dir(config_file, options); + + my_free(config_file); + + /* if there was an error processing the config file, break out of loop */ + if(result == ERROR) + break; + } + } + + /* free memory and close the file */ + my_free(config_base_dir); + my_free(input); + mmap_fclose(thefile); + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[1], NULL); +#endif + +#ifdef NSCGI + /* CGIs process only one file - the cached objects file */ + result = xodtemplate_process_config_file(xodtemplate_cache_file, options); +#endif + +#ifdef NSCORE + + /* only perform intensive operations if we're not using the precached object file */ + if(use_precached_objects == FALSE) { + + /* resolve objects definitions */ + if(result == OK) + result = xodtemplate_resolve_objects(); + if(test_scheduling == TRUE) + gettimeofday(&tv[2], NULL); + + /* cleanup some additive inheritance stuff... */ + xodtemplate_clean_additive_strings(); + + /* do the meat and potatoes stuff... */ + if(result == OK) + result = xodtemplate_recombobulate_contactgroups(); + if(test_scheduling == TRUE) + gettimeofday(&tv[3], NULL); + + if(result == OK) + result = xodtemplate_recombobulate_hostgroups(); + if(test_scheduling == TRUE) + gettimeofday(&tv[4], NULL); + + if(result == OK) + result = xodtemplate_duplicate_services(); + if(test_scheduling == TRUE) + gettimeofday(&tv[5], NULL); + + if(result == OK) + result = xodtemplate_recombobulate_servicegroups(); + if(test_scheduling == TRUE) + gettimeofday(&tv[6], NULL); + + if(result == OK) + result = xodtemplate_duplicate_objects(); + if(test_scheduling == TRUE) + gettimeofday(&tv[7], NULL); + + /* NOTE: some missing defaults (notification options, etc.) are also applied here */ + if(result == OK) + result = xodtemplate_inherit_object_properties(); + if(test_scheduling == TRUE) + gettimeofday(&tv[8], NULL); + + if(result == OK) + result = xodtemplate_recombobulate_object_contacts(); + if(test_scheduling == TRUE) + gettimeofday(&tv[9], NULL); + + /* sort objects */ + if(result == OK) + result = xodtemplate_sort_objects(); + if(test_scheduling == TRUE) + gettimeofday(&tv[10], NULL); + } + + if(result == OK) { + + /* merge host/service extinfo definitions with host/service definitions */ + /* this will be removed in Nagios 4.x */ + xodtemplate_merge_extinfo_ojects(); + + /* cache object definitions for the CGIs and external apps */ + if(cache == TRUE) + xodtemplate_cache_objects(xodtemplate_cache_file); + + /* precache object definitions for future runs */ + if(precache == TRUE) + xodtemplate_cache_objects(xodtemplate_precache_file); + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[11], NULL); + +#endif + + /* register objects */ + if(result == OK) + result = xodtemplate_register_objects(); +#ifdef NSCORE + if(test_scheduling == TRUE) + gettimeofday(&tv[12], NULL); +#endif + + /* cleanup */ + xodtemplate_free_memory(); +#ifdef NSCORE + if(test_scheduling == TRUE) + gettimeofday(&tv[13], NULL); +#endif + + /* free memory */ + my_free(xodtemplate_cache_file); + my_free(xodtemplate_precache_file); + +#ifdef NSCORE + if(test_scheduling == TRUE) { + + runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + if(use_precached_objects == FALSE) { + runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0); + runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0); + runtime[3] = (double)((double)(tv[4].tv_sec - tv[3].tv_sec) + (double)((tv[4].tv_usec - tv[3].tv_usec) / 1000.0) / 1000.0); + runtime[4] = (double)((double)(tv[5].tv_sec - tv[4].tv_sec) + (double)((tv[5].tv_usec - tv[4].tv_usec) / 1000.0) / 1000.0); + runtime[5] = (double)((double)(tv[6].tv_sec - tv[5].tv_sec) + (double)((tv[6].tv_usec - tv[5].tv_usec) / 1000.0) / 1000.0); + runtime[6] = (double)((double)(tv[7].tv_sec - tv[6].tv_sec) + (double)((tv[7].tv_usec - tv[6].tv_usec) / 1000.0) / 1000.0); + runtime[7] = (double)((double)(tv[8].tv_sec - tv[7].tv_sec) + (double)((tv[8].tv_usec - tv[7].tv_usec) / 1000.0) / 1000.0); + runtime[8] = (double)((double)(tv[9].tv_sec - tv[8].tv_sec) + (double)((tv[9].tv_usec - tv[8].tv_usec) / 1000.0) / 1000.0); + runtime[9] = (double)((double)(tv[10].tv_sec - tv[9].tv_sec) + (double)((tv[10].tv_usec - tv[9].tv_usec) / 1000.0) / 1000.0); + runtime[10] = (double)((double)(tv[11].tv_sec - tv[10].tv_sec) + (double)((tv[11].tv_usec - tv[10].tv_usec) / 1000.0) / 1000.0); + runtime[11] = (double)((double)(tv[12].tv_sec - tv[11].tv_sec) + (double)((tv[12].tv_usec - tv[11].tv_usec) / 1000.0) / 1000.0); + } + else { + runtime[1] = 0.0; + runtime[2] = 0.0; + runtime[3] = 0.0; + runtime[4] = 0.0; + runtime[5] = 0.0; + runtime[6] = 0.0; + runtime[7] = 0.0; + runtime[8] = 0.0; + runtime[9] = 0.0; + runtime[10] = 0.0; + runtime[11] = (double)((double)(tv[12].tv_sec - tv[1].tv_sec) + (double)((tv[12].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0); + } + runtime[12] = (double)((double)(tv[13].tv_sec - tv[12].tv_sec) + (double)((tv[13].tv_usec - tv[12].tv_usec) / 1000.0) / 1000.0); + runtime[13] = (double)((double)(tv[13].tv_sec - tv[0].tv_sec) + (double)((tv[13].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + + printf("Timing information on object configuration processing is listed\n"); + printf("below. You can use this information to see if precaching your\n"); + printf("object configuration would be useful.\n\n"); + + printf("Object Config Source: %s\n\n", (use_precached_objects == TRUE) ? "Pre-cached config file" : "Config files (uncached)"); + + printf("OBJECT CONFIG PROCESSING TIMES (* = Potential for precache savings with -u option)\n"); + printf("----------------------------------\n"); + printf("Read: %.6lf sec\n", runtime[0]); + printf("Resolve: %.6lf sec *\n", runtime[1]); + printf("Recomb Contactgroups: %.6lf sec *\n", runtime[2]); + printf("Recomb Hostgroups: %.6lf sec *\n", runtime[3]); + printf("Dup Services: %.6lf sec *\n", runtime[4]); + printf("Recomb Servicegroups: %.6lf sec *\n", runtime[5]); + printf("Duplicate: %.6lf sec *\n", runtime[6]); + printf("Inherit: %.6lf sec *\n", runtime[7]); + printf("Recomb Contacts: %.6lf sec *\n", runtime[8]); + printf("Sort: %.6lf sec *\n", runtime[9]); + /* printf("Cache: %.6lf sec\n",runtime[10]);*/ + printf("Register: %.6lf sec\n", runtime[11]); + printf("Free: %.6lf sec\n", runtime[12]); + printf(" ============\n"); + printf("TOTAL: %.6lf sec ", runtime[13]); + if(use_precached_objects == FALSE) + printf("* = %.6lf sec (%.2f%%) estimated savings", runtime[13] - runtime[12] - runtime[11] - runtime[0], ((runtime[13] - runtime[12] - runtime[11] - runtime[0]) / runtime[13]) * 100.0); + printf("\n"); + printf("\n\n"); + } +#endif + + return result; + } + + + +/* grab config variable from main config file */ +int xodtemplate_grab_config_info(char *main_config_file) { + char *input = NULL; + char *var = NULL; + char *val = NULL; + mmapfile *thefile = NULL; +#ifdef NSCORE + nagios_macros *mac; +#endif + + /* open the main config file for reading */ + if((thefile = mmap_fopen(main_config_file)) == NULL) + return ERROR; + + /* read in all lines from the main config file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + /* strip input */ + strip(input); + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == ';' || input[0] == '\x0') + continue; + + if((var = strtok(input, "=")) == NULL) + continue; + + if((val = strtok(NULL, "\n")) == NULL) + continue; + + /* cached object file definition (overrides default location) */ + if(!strcmp(var, "object_cache_file")) + xodtemplate_cache_file = (char *)strdup(val); + + /* pre-cached object file definition */ + if(!strcmp(var, "precached_object_file")) + xodtemplate_precache_file = (char *)strdup(val); + } + + /* close the file */ + mmap_fclose(thefile); + + /* default locations */ + if(xodtemplate_cache_file == NULL) + xodtemplate_cache_file = (char *)strdup(DEFAULT_OBJECT_CACHE_FILE); + if(xodtemplate_precache_file == NULL) + xodtemplate_precache_file = (char *)strdup(DEFAULT_PRECACHED_OBJECT_FILE); + + /* make sure we have what we need */ + if(xodtemplate_cache_file == NULL || xodtemplate_precache_file == NULL) + return ERROR; + +#ifdef NSCORE + mac = get_global_macros(); + /* save the object cache file macro */ + my_free(mac->x[MACRO_OBJECTCACHEFILE]); + if((mac->x[MACRO_OBJECTCACHEFILE] = (char *)strdup(xodtemplate_cache_file))) + strip(mac->x[MACRO_OBJECTCACHEFILE]); +#endif + + return OK; + } + + + +/* process all files in a specific config directory */ +int xodtemplate_process_config_dir(char *dirname, int options) { + char file[MAX_FILENAME_LENGTH]; + DIR *dirp = NULL; + struct dirent *dirfile = NULL; + int result = OK; + register int x = 0; + struct stat stat_buf; + +#ifdef NSCORE + if(verify_config == TRUE) + printf("Processing object config directory '%s'...\n", dirname); +#endif + + /* open the directory for reading */ + dirp = opendir(dirname); + if(dirp == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not open config directory '%s' for reading.\n", dirname); + return ERROR; + } + + /* process all files in the directory... */ + while((dirfile = readdir(dirp)) != NULL) { + + /* skip hidden files and directories, and current and parent dir */ + if(dirfile->d_name[0] == '.') + continue; + + /* create /path/to/file */ + snprintf(file, sizeof(file), "%s/%s", dirname, dirfile->d_name); + file[sizeof(file) - 1] = '\x0'; + + /* process this if it's a non-hidden config file... */ + if(stat(file, &stat_buf) == -1) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open config directory member '%s' for reading.\n", file); + closedir(dirp); + return ERROR; + } + + switch(stat_buf.st_mode & S_IFMT) { + + case S_IFREG: + x = strlen(dirfile->d_name); + if(x <= 4 || strcmp(dirfile->d_name + (x - 4), ".cfg")) + break; + + /* process the config file */ + result = xodtemplate_process_config_file(file, options); + + if(result == ERROR) { + closedir(dirp); + return ERROR; + } + + break; + + case S_IFDIR: + /* recurse into subdirectories... */ + result = xodtemplate_process_config_dir(file, options); + + if(result == ERROR) { + closedir(dirp); + return ERROR; + } + + break; + + default: + /* everything else we ignore */ + break; + } + } + + closedir(dirp); + + return result; + } + + +/* process data in a specific config file */ +int xodtemplate_process_config_file(char *filename, int options) { + mmapfile *thefile = NULL; + char *input = NULL; + register int in_definition = FALSE; + register int current_line = 0; + int result = OK; + register int x = 0; + register int y = 0; + char *ptr = NULL; + + +#ifdef NSCORE + if(verify_config == TRUE) + printf("Processing object config file '%s'...\n", filename); +#endif + + /* save config file name */ + xodtemplate_config_files[xodtemplate_current_config_file++] = (char *)strdup(filename); + + /* reallocate memory for config files */ + if(!(xodtemplate_current_config_file % 256)) { + xodtemplate_config_files = (char **)realloc(xodtemplate_config_files, (xodtemplate_current_config_file + 256) * sizeof(char **)); + if(xodtemplate_config_files == NULL) + return ERROR; + } + + /* open the config file for reading */ + if((thefile = mmap_fopen(filename)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open config file '%s' for reading: %s\n", filename, strerror(errno)); + return ERROR; + } + + /* read in all lines from the config file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + current_line = thefile->current_line; + + /* grab data before comment delimiter - faster than a strtok() and strncpy()... */ + for(x = 0; input[x] != '\x0'; x++) { + if(input[x] == ';') { + if(x == 0) + break; + else if(input[x - 1] != '\\') + break; + } + } + input[x] = '\x0'; + + /* strip input */ + strip(input); + + /* skip empty lines */ + if(input[0] == '\x0' || input[0] == '#') + continue; + + /* this is the start of an object definition */ + if(strstr(input, "define") == input) { + + /* get the type of object we're defining... */ + for(x = 6; input[x] != '\x0'; x++) + if(input[x] != ' ' && input[x] != '\t') + break; + for(y = 0; input[x] != '\x0'; x++) { + if(input[x] == ' ' || input[x] == '\t' || input[x] == '{') + break; + else + input[y++] = input[x]; + } + input[y] = '\x0'; + + /* make sure an object type is specified... */ + if(input[0] == '\x0') { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: No object type specified in file '%s' on line %d.\n", filename, current_line); + result = ERROR; + break; + } + + /* check validity of object type */ + if(strcmp(input, "timeperiod") && strcmp(input, "command") && strcmp(input, "contact") && strcmp(input, "contactgroup") && strcmp(input, "host") && strcmp(input, "hostgroup") && strcmp(input, "servicegroup") && strcmp(input, "service") && strcmp(input, "servicedependency") && strcmp(input, "serviceescalation") && strcmp(input, "hostgroupescalation") && strcmp(input, "hostdependency") && strcmp(input, "hostescalation") && strcmp(input, "hostextinfo") && strcmp(input, "serviceextinfo")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid object definition type '%s' in file '%s' on line %d.\n", input, filename, current_line); + result = ERROR; + break; + } + + /* we're already in an object definition... */ + if(in_definition == TRUE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected start of object definition in file '%s' on line %d. Make sure you close preceding objects before starting a new one.\n", filename, current_line); + result = ERROR; + break; + } + + /* start a new definition */ + if(xodtemplate_begin_object_definition(input, options, xodtemplate_current_config_file, current_line) == ERROR) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add object definition in file '%s' on line %d.\n", filename, current_line); + result = ERROR; + break; + } + + in_definition = TRUE; + } + + /* we're currently inside an object definition */ + else if(in_definition == TRUE) { + + /* this is the close of an object definition */ + if(!strcmp(input, "}")) { + + in_definition = FALSE; + + /* close out current definition */ + if(xodtemplate_end_object_definition(options) == ERROR) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not complete object definition in file '%s' on line %d.\n", filename, current_line); + result = ERROR; + break; + } + } + + /* this is a directive inside an object definition */ + else { + + /* add directive to object definition */ + if(xodtemplate_add_object_property(input, options) == ERROR) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add object property in file '%s' on line %d.\n", filename, current_line); + result = ERROR; + break; + } + } + } + + /* include another file */ + else if(strstr(input, "include_file=") == input) { + + ptr = strtok(input, "="); + ptr = strtok(NULL, "\n"); + + if(ptr != NULL) { + result = xodtemplate_process_config_file(ptr, options); + if(result == ERROR) + break; + } + } + + /* include a directory */ + else if(strstr(input, "include_dir") == input) { + + ptr = strtok(input, "="); + ptr = strtok(NULL, "\n"); + + if(ptr != NULL) { + result = xodtemplate_process_config_dir(ptr, options); + if(result == ERROR) + break; + } + } + + /* unexpected token or statement */ + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected token or statement in file '%s' on line %d.\n", filename, current_line); + result = ERROR; + break; + } + } + + /* free memory and close file */ + my_free(input); + mmap_fclose(thefile); + + /* whoops - EOF while we were in the middle of an object definition... */ + if(in_definition == TRUE && result == OK) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected EOF in file '%s' on line %d - check for a missing closing bracket.\n", filename, current_line); + result = ERROR; + } + + return result; + } + + + + + +/******************************************************************/ +/***************** OBJECT DEFINITION FUNCTIONS ********************/ +/******************************************************************/ + +/* + * all objects start the same way, so we can get rid of quite + * a lot of code with this struct-offset-insensitive macro + */ +#define xod_begin_def(type) \ + do { \ + new_##type = (xodtemplate_##type *)calloc(1, sizeof(*new_##type)); \ + if (new_##type == NULL) \ + return ERROR; \ + new_##type->register_object=TRUE; \ + new_##type->_config_file=config_file; \ + new_##type->_start_line=start_line; \ + \ + /* precached object files are already sorted, so add to tail */ \ + if(presorted_objects==TRUE){ \ + \ + if(xodtemplate_##type##_list==NULL){ \ + xodtemplate_##type##_list=new_##type; \ + xodtemplate_##type##_list_tail=xodtemplate_##type##_list; \ + } else { \ + xodtemplate_##type##_list_tail->next=new_##type; \ + xodtemplate_##type##_list_tail=new_##type; \ + } \ + \ + /* update current object pointer */ \ + xodtemplate_current_object=xodtemplate_##type##_list_tail; \ + } else { \ + /* add new object to head of list in memory */ \ + new_##type->next=xodtemplate_##type##_list; \ + xodtemplate_##type##_list=new_##type; \ + \ + /* update current object pointer */ \ + xodtemplate_current_object=xodtemplate_##type##_list; \ + } \ + } while (0) + +/* starts a new object definition */ +int xodtemplate_begin_object_definition(char *input, int options, int config_file, int start_line) { + int result = OK; + xodtemplate_timeperiod *new_timeperiod = NULL; + xodtemplate_command *new_command = NULL; + xodtemplate_contactgroup *new_contactgroup = NULL; + xodtemplate_hostgroup *new_hostgroup = NULL; + xodtemplate_servicegroup *new_servicegroup = NULL; + xodtemplate_servicedependency *new_servicedependency = NULL; + xodtemplate_serviceescalation *new_serviceescalation = NULL; + xodtemplate_contact *new_contact = NULL; + xodtemplate_host *new_host = NULL; + xodtemplate_service *new_service = NULL; + xodtemplate_hostdependency *new_hostdependency = NULL; + xodtemplate_hostescalation *new_hostescalation = NULL; + xodtemplate_hostextinfo *new_hostextinfo = NULL; + xodtemplate_serviceextinfo *new_serviceextinfo = NULL; + + if(!strcmp(input, "service")) + xodtemplate_current_object_type = XODTEMPLATE_SERVICE; + else if(!strcmp(input, "host")) + xodtemplate_current_object_type = XODTEMPLATE_HOST; + else if(!strcmp(input, "command")) + xodtemplate_current_object_type = XODTEMPLATE_COMMAND; + else if(!strcmp(input, "contact")) + xodtemplate_current_object_type = XODTEMPLATE_CONTACT; + else if(!strcmp(input, "contactgroup")) + xodtemplate_current_object_type = XODTEMPLATE_CONTACTGROUP; + else if(!strcmp(input, "hostgroup")) + xodtemplate_current_object_type = XODTEMPLATE_HOSTGROUP; + else if(!strcmp(input, "servicegroup")) + xodtemplate_current_object_type = XODTEMPLATE_SERVICEGROUP; + else if(!strcmp(input, "timeperiod")) + xodtemplate_current_object_type = XODTEMPLATE_TIMEPERIOD; + else if(!strcmp(input, "servicedependency")) + xodtemplate_current_object_type = XODTEMPLATE_SERVICEDEPENDENCY; + else if(!strcmp(input, "serviceescalation")) + xodtemplate_current_object_type = XODTEMPLATE_SERVICEESCALATION; + else if(!strcmp(input, "hostdependency")) + xodtemplate_current_object_type = XODTEMPLATE_HOSTDEPENDENCY; + else if(!strcmp(input, "hostescalation")) + xodtemplate_current_object_type = XODTEMPLATE_HOSTESCALATION; + else if(!strcmp(input, "hostextinfo")) + xodtemplate_current_object_type = XODTEMPLATE_HOSTEXTINFO; + else if(!strcmp(input, "serviceextinfo")) + xodtemplate_current_object_type = XODTEMPLATE_SERVICEEXTINFO; + else + return ERROR; + + + /* check to see if we should process this type of object */ + switch(xodtemplate_current_object_type) { + case XODTEMPLATE_TIMEPERIOD: + if(!(options & READ_TIMEPERIODS)) + return OK; + break; + case XODTEMPLATE_COMMAND: + if(!(options & READ_COMMANDS)) + return OK; + break; + case XODTEMPLATE_CONTACT: + if(!(options & READ_CONTACTS)) + return OK; + break; + case XODTEMPLATE_CONTACTGROUP: + if(!(options & READ_CONTACTGROUPS)) + return OK; + break; + case XODTEMPLATE_HOST: + if(!(options & READ_HOSTS)) + return OK; + break; + case XODTEMPLATE_HOSTGROUP: + if(!(options & READ_HOSTGROUPS)) + return OK; + break; + case XODTEMPLATE_SERVICEGROUP: + if(!(options & READ_SERVICEGROUPS)) + return OK; + break; + case XODTEMPLATE_SERVICE: + if(!(options & READ_SERVICES)) + return OK; + break; + case XODTEMPLATE_SERVICEDEPENDENCY: + if(!(options & READ_SERVICEDEPENDENCIES)) + return OK; + break; + case XODTEMPLATE_SERVICEESCALATION: + if(!(options & READ_SERVICEESCALATIONS)) + return OK; + break; + case XODTEMPLATE_HOSTDEPENDENCY: + if(!(options & READ_HOSTDEPENDENCIES)) + return OK; + break; + case XODTEMPLATE_HOSTESCALATION: + if(!(options & READ_HOSTESCALATIONS)) + return OK; + break; + case XODTEMPLATE_HOSTEXTINFO: + if(!(options & READ_HOSTEXTINFO)) + return OK; + break; + case XODTEMPLATE_SERVICEEXTINFO: + if(!(options & READ_SERVICEEXTINFO)) + return OK; + break; + default: + return ERROR; + break; + } + + + + /* add a new (blank) object */ + switch(xodtemplate_current_object_type) { + + case XODTEMPLATE_TIMEPERIOD: + xod_begin_def(timeperiod); + break; + + case XODTEMPLATE_COMMAND: + xod_begin_def(command); + break; + + case XODTEMPLATE_CONTACTGROUP: + xod_begin_def(contactgroup); + break; + + case XODTEMPLATE_HOSTGROUP: + xod_begin_def(hostgroup); + break; + + case XODTEMPLATE_SERVICEGROUP: + xod_begin_def(servicegroup); + break; + + case XODTEMPLATE_SERVICEDEPENDENCY: + xod_begin_def(servicedependency); + break; + + case XODTEMPLATE_SERVICEESCALATION: + xod_begin_def(serviceescalation); + new_serviceescalation->first_notification = -2; + new_serviceescalation->last_notification = -2; + break; + + case XODTEMPLATE_CONTACT: + xod_begin_def(contact); + + new_contact->host_notifications_enabled = TRUE; + new_contact->service_notifications_enabled = TRUE; + new_contact->can_submit_commands = TRUE; + new_contact->retain_status_information = TRUE; + new_contact->retain_nonstatus_information = TRUE; + break; + + case XODTEMPLATE_HOST: + xod_begin_def(host); + new_host->check_interval = 5.0; + new_host->retry_interval = 1.0; + new_host->active_checks_enabled = TRUE; + new_host->passive_checks_enabled = TRUE; + new_host->obsess_over_host = TRUE; + new_host->max_check_attempts = -2; + new_host->event_handler_enabled = TRUE; + new_host->flap_detection_enabled = TRUE; + new_host->flap_detection_on_up = TRUE; + new_host->flap_detection_on_down = TRUE; + new_host->flap_detection_on_unreachable = TRUE; + new_host->notifications_enabled = TRUE; + new_host->notification_interval = 30.0; + new_host->process_perf_data = TRUE; + new_host->failure_prediction_enabled = TRUE; + new_host->x_2d = -1; + new_host->y_2d = -1; + new_host->retain_status_information = TRUE; + new_host->retain_nonstatus_information = TRUE; + break; + + case XODTEMPLATE_SERVICE: + xod_begin_def(service); + + new_service->initial_state = STATE_OK; + new_service->max_check_attempts = -2; + new_service->check_interval = 5.0; + new_service->retry_interval = 1.0; + new_service->active_checks_enabled = TRUE; + new_service->passive_checks_enabled = TRUE; + new_service->parallelize_check = TRUE; + new_service->obsess_over_service = TRUE; + new_service->event_handler_enabled = TRUE; + new_service->flap_detection_enabled = TRUE; + new_service->flap_detection_on_ok = TRUE; + new_service->flap_detection_on_warning = TRUE; + new_service->flap_detection_on_unknown = TRUE; + new_service->flap_detection_on_critical = TRUE; + new_service->notifications_enabled = TRUE; + new_service->notification_interval = 30.0; + new_service->process_perf_data = TRUE; + new_service->failure_prediction_enabled = TRUE; + new_service->retain_status_information = TRUE; + new_service->retain_nonstatus_information = TRUE; + + /* true service, so is not from host group, must be set AFTER have_initial_state*/ + xodtemplate_unset_service_is_from_hostgroup(new_service); + break; + + case XODTEMPLATE_HOSTDEPENDENCY: + xod_begin_def(hostdependency); + break; + + case XODTEMPLATE_HOSTESCALATION: + xod_begin_def(hostescalation); + new_hostescalation->first_notification = -2; + new_hostescalation->last_notification = -2; + break; + + case XODTEMPLATE_HOSTEXTINFO: + xod_begin_def(hostextinfo); + + new_hostextinfo->x_2d = -1; + new_hostextinfo->y_2d = -1; + break; + + case XODTEMPLATE_SERVICEEXTINFO: + xod_begin_def(serviceextinfo); + break; + + default: + return ERROR; + break; + } + + return result; + } +#undef xod_begin_def /* we don't need this anymore */ + + +/* adds a property to an object definition */ +int xodtemplate_add_object_property(char *input, int options) { + int result = OK; + char *variable = NULL; + char *value = NULL; + char *temp_ptr = NULL; + char *customvarname = NULL; + char *customvarvalue = NULL; + xodtemplate_timeperiod *temp_timeperiod = NULL; + xodtemplate_command *temp_command = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_contact *temp_contact = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + xodtemplate_hostextinfo *temp_hostextinfo = NULL; + xodtemplate_serviceextinfo *temp_serviceextinfo = NULL; + register int x = 0; + register int y = 0; + int force_skiplists = FALSE; + + + /* should some object definitions be added to skiplists immediately? */ +#ifdef NSCORE + if(use_precached_objects == TRUE) + force_skiplists = TRUE; +#else + force_skiplists = TRUE; +#endif + + /* check to see if we should process this type of object */ + switch(xodtemplate_current_object_type) { + case XODTEMPLATE_TIMEPERIOD: + if(!(options & READ_TIMEPERIODS)) + return OK; + break; + case XODTEMPLATE_COMMAND: + if(!(options & READ_COMMANDS)) + return OK; + break; + case XODTEMPLATE_CONTACT: + if(!(options & READ_CONTACTS)) + return OK; + break; + case XODTEMPLATE_CONTACTGROUP: + if(!(options & READ_CONTACTGROUPS)) + return OK; + break; + case XODTEMPLATE_HOST: + if(!(options & READ_HOSTS)) + return OK; + break; + case XODTEMPLATE_HOSTGROUP: + if(!(options & READ_HOSTGROUPS)) + return OK; + break; + case XODTEMPLATE_SERVICEGROUP: + if(!(options & READ_SERVICEGROUPS)) + return OK; + break; + case XODTEMPLATE_SERVICE: + if(!(options & READ_SERVICES)) + return OK; + break; + case XODTEMPLATE_SERVICEDEPENDENCY: + if(!(options & READ_SERVICEDEPENDENCIES)) + return OK; + break; + case XODTEMPLATE_SERVICEESCALATION: + if(!(options & READ_SERVICEESCALATIONS)) + return OK; + break; + case XODTEMPLATE_HOSTDEPENDENCY: + if(!(options & READ_HOSTDEPENDENCIES)) + return OK; + break; + case XODTEMPLATE_HOSTESCALATION: + if(!(options & READ_HOSTESCALATIONS)) + return OK; + break; + case XODTEMPLATE_HOSTEXTINFO: + if(!(options & READ_HOSTEXTINFO)) + return OK; + break; + case XODTEMPLATE_SERVICEEXTINFO: + if(!(options & READ_SERVICEEXTINFO)) + return OK; + break; + default: + return ERROR; + break; + } + + /* get variable name */ + if((variable = (char *)strdup(input)) == NULL) + return ERROR; + /* trim at first whitespace occurance */ + for(x = 0, y = 0; variable[x] != '\x0'; x++) { + if(variable[x] == ' ' || variable[x] == '\t') + break; + y++; + } + variable[y] = '\x0'; + + /* get variable value */ + if((value = (char *)strdup(input + x)) == NULL) { + my_free(variable); + return ERROR; + } + strip(value); + + + switch(xodtemplate_current_object_type) { + + case XODTEMPLATE_TIMEPERIOD: + + temp_timeperiod = (xodtemplate_timeperiod *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_timeperiod->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_timeperiod->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add timeperiod to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_TIMEPERIOD_SKIPLIST], (void *)temp_timeperiod); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for timeperiod '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_timeperiod->_config_file), temp_timeperiod->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "timeperiod_name")) { + if((temp_timeperiod->timeperiod_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add timeperiod to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_TIMEPERIOD_SKIPLIST], (void *)temp_timeperiod); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for timeperiod '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_timeperiod->_config_file), temp_timeperiod->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "alias")) { + if((temp_timeperiod->alias = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "exclude")) { + if((temp_timeperiod->exclusions = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "register")) + temp_timeperiod->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else if(xodtemplate_parse_timeperiod_directive(temp_timeperiod, variable, value) == OK) + result = OK; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid timeperiod object directive '%s'.\n", variable); + return ERROR; + } + break; + + + + case XODTEMPLATE_COMMAND: + + temp_command = (xodtemplate_command *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_command->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_command->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add command to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_COMMAND_SKIPLIST], (void *)temp_command); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for command '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_command->_config_file), temp_command->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "command_name")) { + if((temp_command->command_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add command to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_COMMAND_SKIPLIST], (void *)temp_command); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for command '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_command->_config_file), temp_command->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "command_line")) { + if((temp_command->command_line = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "register")) + temp_command->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid command object directive '%s'.\n", variable); + return ERROR; + } + + break; + + case XODTEMPLATE_CONTACTGROUP: + + temp_contactgroup = (xodtemplate_contactgroup *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_contactgroup->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_contactgroup->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add contactgroup to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_CONTACTGROUP_SKIPLIST], (void *)temp_contactgroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contactgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "contactgroup_name")) { + if((temp_contactgroup->contactgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add contactgroup to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], (void *)temp_contactgroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contactgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "alias")) { + if((temp_contactgroup->alias = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "members")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(temp_contactgroup->members == NULL) + temp_contactgroup->members = (char *)strdup(value); + else { + temp_contactgroup->members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(value) + 2); + if(temp_contactgroup->members != NULL) { + strcat(temp_contactgroup->members, ","); + strcat(temp_contactgroup->members, value); + } + } + if(temp_contactgroup->members == NULL) + result = ERROR; + } + temp_contactgroup->have_members = TRUE; + } + else if(!strcmp(variable, "contactgroup_members")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(temp_contactgroup->contactgroup_members == NULL) + temp_contactgroup->contactgroup_members = (char *)strdup(value); + else { + temp_contactgroup->contactgroup_members = (char *)realloc(temp_contactgroup->contactgroup_members, strlen(temp_contactgroup->contactgroup_members) + strlen(value) + 2); + if(temp_contactgroup->contactgroup_members != NULL) { + strcat(temp_contactgroup->contactgroup_members, ","); + strcat(temp_contactgroup->contactgroup_members, value); + } + } + if(temp_contactgroup->contactgroup_members == NULL) + result = ERROR; + } + temp_contactgroup->have_contactgroup_members = TRUE; + } + else if(!strcmp(variable, "register")) + temp_contactgroup->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid contactgroup object directive '%s'.\n", variable); + return ERROR; + } + + break; + + case XODTEMPLATE_HOSTGROUP: + + temp_hostgroup = (xodtemplate_hostgroup *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_hostgroup->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_hostgroup->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add hostgroup to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_HOSTGROUP_SKIPLIST], (void *)temp_hostgroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for hostgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "hostgroup_name")) { + if((temp_hostgroup->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add hostgroup to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_HOSTGROUP_SKIPLIST], (void *)temp_hostgroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for hostgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "alias")) { + if((temp_hostgroup->alias = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "members")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(temp_hostgroup->members == NULL) + temp_hostgroup->members = (char *)strdup(value); + else { + temp_hostgroup->members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(value) + 2); + if(temp_hostgroup->members != NULL) { + strcat(temp_hostgroup->members, ","); + strcat(temp_hostgroup->members, value); + } + } + if(temp_hostgroup->members == NULL) + result = ERROR; + } + temp_hostgroup->have_members = TRUE; + } + else if(!strcmp(variable, "hostgroup_members")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(temp_hostgroup->hostgroup_members == NULL) + temp_hostgroup->hostgroup_members = (char *)strdup(value); + else { + temp_hostgroup->hostgroup_members = (char *)realloc(temp_hostgroup->hostgroup_members, strlen(temp_hostgroup->hostgroup_members) + strlen(value) + 2); + if(temp_hostgroup->hostgroup_members != NULL) { + strcat(temp_hostgroup->hostgroup_members, ","); + strcat(temp_hostgroup->hostgroup_members, value); + } + } + if(temp_hostgroup->hostgroup_members == NULL) + result = ERROR; + } + temp_hostgroup->have_hostgroup_members = TRUE; + } + else if(!strcmp(variable, "notes")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostgroup->notes = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostgroup->have_notes = TRUE; + } + else if(!strcmp(variable, "notes_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostgroup->notes_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostgroup->have_notes_url = TRUE; + } + else if(!strcmp(variable, "action_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostgroup->action_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostgroup->have_action_url = TRUE; + } + else if(!strcmp(variable, "register")) + temp_hostgroup->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostgroup object directive '%s'.\n", variable); + return ERROR; + } + + break; + + + case XODTEMPLATE_SERVICEGROUP: + + temp_servicegroup = (xodtemplate_servicegroup *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_servicegroup->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_servicegroup->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add servicegroup to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_SERVICEGROUP_SKIPLIST], (void *)temp_servicegroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for servicegroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "servicegroup_name")) { + if((temp_servicegroup->servicegroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add servicegroup to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], (void *)temp_servicegroup); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for servicegroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "alias")) { + if((temp_servicegroup->alias = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "members")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(temp_servicegroup->members == NULL) + temp_servicegroup->members = (char *)strdup(value); + else { + temp_servicegroup->members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(value) + 2); + if(temp_servicegroup->members != NULL) { + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, value); + } + } + if(temp_servicegroup->members == NULL) + result = ERROR; + } + temp_servicegroup->have_members = TRUE; + } + else if(!strcmp(variable, "servicegroup_members")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(temp_servicegroup->servicegroup_members == NULL) + temp_servicegroup->servicegroup_members = (char *)strdup(value); + else { + temp_servicegroup->servicegroup_members = (char *)realloc(temp_servicegroup->servicegroup_members, strlen(temp_servicegroup->servicegroup_members) + strlen(value) + 2); + if(temp_servicegroup->servicegroup_members != NULL) { + strcat(temp_servicegroup->servicegroup_members, ","); + strcat(temp_servicegroup->servicegroup_members, value); + } + } + if(temp_servicegroup->servicegroup_members == NULL) + result = ERROR; + } + temp_servicegroup->have_servicegroup_members = TRUE; + } + else if(!strcmp(variable, "notes")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicegroup->notes = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicegroup->have_notes = TRUE; + } + else if(!strcmp(variable, "notes_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicegroup->notes_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicegroup->have_notes_url = TRUE; + } + else if(!strcmp(variable, "action_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicegroup->action_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicegroup->have_action_url = TRUE; + } + else if(!strcmp(variable, "register")) + temp_servicegroup->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid servicegroup object directive '%s'.\n", variable); + return ERROR; + } + + break; + + + case XODTEMPLATE_SERVICEDEPENDENCY: + + temp_servicedependency = (xodtemplate_servicedependency *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_servicedependency->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_servicedependency->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add dependency to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service dependency '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "servicegroup") || !strcmp(variable, "servicegroups") || !strcmp(variable, "servicegroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->servicegroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_servicegroup_name = TRUE; + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "host") || !strcmp(variable, "host_name") || !strcmp(variable, "master_host") || !strcmp(variable, "master_host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_host_name = TRUE; + } + else if(!strcmp(variable, "description") || !strcmp(variable, "service_description") || !strcmp(variable, "master_description") || !strcmp(variable, "master_service_description")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->service_description = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_service_description = TRUE; + } + else if(!strcmp(variable, "dependent_servicegroup") || !strcmp(variable, "dependent_servicegroups") || !strcmp(variable, "dependent_servicegroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->dependent_servicegroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_dependent_servicegroup_name = TRUE; + } + else if(!strcmp(variable, "dependent_hostgroup") || !strcmp(variable, "dependent_hostgroups") || !strcmp(variable, "dependent_hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->dependent_hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_dependent_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "dependent_host") || !strcmp(variable, "dependent_host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->dependent_host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_dependent_host_name = TRUE; + + /* NOTE: dependencies are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE && temp_servicedependency->dependent_host_name != NULL && temp_servicedependency->dependent_service_description != NULL) { + /* add servicedependency to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "dependent_description") || !strcmp(variable, "dependent_service_description")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->dependent_service_description = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_dependent_service_description = TRUE; + + /* NOTE: dependencies are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE && temp_servicedependency->dependent_host_name != NULL && temp_servicedependency->dependent_service_description != NULL) { + /* add servicedependency to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "dependency_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_servicedependency->dependency_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_servicedependency->have_dependency_period = TRUE; + } + else if(!strcmp(variable, "inherits_parent")) { + temp_servicedependency->inherits_parent = (atoi(value) > 0) ? TRUE : FALSE; + temp_servicedependency->have_inherits_parent = TRUE; + } + else if(!strcmp(variable, "execution_failure_options") || !strcmp(variable, "execution_failure_criteria")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok")) + temp_servicedependency->fail_execute_on_ok = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_servicedependency->fail_execute_on_unknown = TRUE; + else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_servicedependency->fail_execute_on_warning = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_servicedependency->fail_execute_on_critical = TRUE; + else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending")) + temp_servicedependency->fail_execute_on_pending = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_servicedependency->fail_execute_on_ok = FALSE; + temp_servicedependency->fail_execute_on_unknown = FALSE; + temp_servicedependency->fail_execute_on_warning = FALSE; + temp_servicedependency->fail_execute_on_critical = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_servicedependency->fail_execute_on_ok = TRUE; + temp_servicedependency->fail_execute_on_unknown = TRUE; + temp_servicedependency->fail_execute_on_warning = TRUE; + temp_servicedependency->fail_execute_on_critical = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid execution dependency option '%s' in servicedependency definition.\n", temp_ptr); + return ERROR; + } + } + temp_servicedependency->have_execution_dependency_options = TRUE; + } + else if(!strcmp(variable, "notification_failure_options") || !strcmp(variable, "notification_failure_criteria")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok")) + temp_servicedependency->fail_notify_on_ok = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_servicedependency->fail_notify_on_unknown = TRUE; + else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_servicedependency->fail_notify_on_warning = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_servicedependency->fail_notify_on_critical = TRUE; + else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending")) + temp_servicedependency->fail_notify_on_pending = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_servicedependency->fail_notify_on_ok = FALSE; + temp_servicedependency->fail_notify_on_unknown = FALSE; + temp_servicedependency->fail_notify_on_warning = FALSE; + temp_servicedependency->fail_notify_on_critical = FALSE; + temp_servicedependency->fail_notify_on_pending = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_servicedependency->fail_notify_on_ok = TRUE; + temp_servicedependency->fail_notify_on_unknown = TRUE; + temp_servicedependency->fail_notify_on_warning = TRUE; + temp_servicedependency->fail_notify_on_critical = TRUE; + temp_servicedependency->fail_notify_on_pending = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification dependency option '%s' in servicedependency definition.\n", temp_ptr); + return ERROR; + } + } + temp_servicedependency->have_notification_dependency_options = TRUE; + } + else if(!strcmp(variable, "register")) + temp_servicedependency->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid servicedependency object directive '%s'.\n", variable); + return ERROR; + } + + break; + + + case XODTEMPLATE_SERVICEESCALATION: + + temp_serviceescalation = (xodtemplate_serviceescalation *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_serviceescalation->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_serviceescalation->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add escalation to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service escalation '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "host") || !strcmp(variable, "host_name")) { + + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_host_name = TRUE; + + /* NOTE: escalations are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE && temp_serviceescalation->host_name != NULL && temp_serviceescalation->service_description != NULL) { + /* add serviceescalation to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "description") || !strcmp(variable, "service_description")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->service_description = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_service_description = TRUE; + + /* NOTE: escalations are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE && temp_serviceescalation->host_name != NULL && temp_serviceescalation->service_description != NULL) { + /* add serviceescalation to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "servicegroup") || !strcmp(variable, "servicegroups") || !strcmp(variable, "servicegroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->servicegroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_servicegroup_name = TRUE; + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "contact_groups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->contact_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_contact_groups = TRUE; + } + else if(!strcmp(variable, "contacts")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->contacts = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_contacts = TRUE; + } + else if(!strcmp(variable, "escalation_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceescalation->escalation_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceescalation->have_escalation_period = TRUE; + } + else if(!strcmp(variable, "first_notification")) { + temp_serviceescalation->first_notification = atoi(value); + temp_serviceescalation->have_first_notification = TRUE; + } + else if(!strcmp(variable, "last_notification")) { + temp_serviceescalation->last_notification = atoi(value); + temp_serviceescalation->have_last_notification = TRUE; + } + else if(!strcmp(variable, "notification_interval")) { + temp_serviceescalation->notification_interval = strtod(value, NULL); + temp_serviceescalation->have_notification_interval = TRUE; + } + else if(!strcmp(variable, "escalation_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_serviceescalation->escalate_on_warning = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_serviceescalation->escalate_on_unknown = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_serviceescalation->escalate_on_critical = TRUE; + else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery")) + temp_serviceescalation->escalate_on_recovery = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_serviceescalation->escalate_on_warning = FALSE; + temp_serviceescalation->escalate_on_unknown = FALSE; + temp_serviceescalation->escalate_on_critical = FALSE; + temp_serviceescalation->escalate_on_recovery = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_serviceescalation->escalate_on_warning = TRUE; + temp_serviceescalation->escalate_on_unknown = TRUE; + temp_serviceescalation->escalate_on_critical = TRUE; + temp_serviceescalation->escalate_on_recovery = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid escalation option '%s' in serviceescalation definition.\n", temp_ptr); + return ERROR; + } + } + temp_serviceescalation->have_escalation_options = TRUE; + } + else if(!strcmp(variable, "register")) + temp_serviceescalation->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid serviceescalation object directive '%s'.\n", variable); + return ERROR; + } + + break; + + + case XODTEMPLATE_CONTACT: + + temp_contact = (xodtemplate_contact *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_contact->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_contact->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add contact to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_CONTACT_SKIPLIST], (void *)temp_contact); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contact '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contact->_config_file), temp_contact->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "contact_name")) { + if((temp_contact->contact_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add contact to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_CONTACT_SKIPLIST], (void *)temp_contact); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contact '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contact->_config_file), temp_contact->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "alias")) { + if((temp_contact->alias = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "contact_groups") || !strcmp(variable, "contactgroups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->contact_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_contact_groups = TRUE; + } + else if(!strcmp(variable, "email")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->email = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_email = TRUE; + } + else if(!strcmp(variable, "pager")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->pager = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_pager = TRUE; + } + else if(strstr(variable, "address") == variable) { + x = atoi(variable + 7); + if(x < 1 || x > MAX_XODTEMPLATE_CONTACT_ADDRESSES) + result = ERROR; + else if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->address[x - 1] = (char *)strdup(value)) == NULL) + result = ERROR; + } + if(result == OK) + temp_contact->have_address[x - 1] = TRUE; + } + else if(!strcmp(variable, "host_notification_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->host_notification_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_host_notification_period = TRUE; + } + else if(!strcmp(variable, "host_notification_commands")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->host_notification_commands = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_host_notification_commands = TRUE; + } + else if(!strcmp(variable, "service_notification_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->service_notification_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_service_notification_period = TRUE; + } + else if(!strcmp(variable, "service_notification_commands")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_contact->service_notification_commands = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_contact->have_service_notification_commands = TRUE; + } + else if(!strcmp(variable, "host_notification_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_contact->notify_on_host_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_contact->notify_on_host_unreachable = TRUE; + else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery")) + temp_contact->notify_on_host_recovery = TRUE; + else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping")) + temp_contact->notify_on_host_flapping = TRUE; + else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime")) + temp_contact->notify_on_host_downtime = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_contact->notify_on_host_down = FALSE; + temp_contact->notify_on_host_unreachable = FALSE; + temp_contact->notify_on_host_recovery = FALSE; + temp_contact->notify_on_host_flapping = FALSE; + temp_contact->notify_on_host_downtime = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_contact->notify_on_host_down = TRUE; + temp_contact->notify_on_host_unreachable = TRUE; + temp_contact->notify_on_host_recovery = TRUE; + temp_contact->notify_on_host_flapping = TRUE; + temp_contact->notify_on_host_downtime = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid host notification option '%s' in contact definition.\n", temp_ptr); + return ERROR; + } + } + temp_contact->have_host_notification_options = TRUE; + } + else if(!strcmp(variable, "service_notification_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_contact->notify_on_service_unknown = TRUE; + else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_contact->notify_on_service_warning = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_contact->notify_on_service_critical = TRUE; + else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery")) + temp_contact->notify_on_service_recovery = TRUE; + else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping")) + temp_contact->notify_on_service_flapping = TRUE; + else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime")) + temp_contact->notify_on_service_downtime = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_contact->notify_on_service_unknown = FALSE; + temp_contact->notify_on_service_warning = FALSE; + temp_contact->notify_on_service_critical = FALSE; + temp_contact->notify_on_service_recovery = FALSE; + temp_contact->notify_on_service_flapping = FALSE; + temp_contact->notify_on_service_downtime = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_contact->notify_on_service_unknown = TRUE; + temp_contact->notify_on_service_warning = TRUE; + temp_contact->notify_on_service_critical = TRUE; + temp_contact->notify_on_service_recovery = TRUE; + temp_contact->notify_on_service_flapping = TRUE; + temp_contact->notify_on_service_downtime = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid service notification option '%s' in contact definition.\n", temp_ptr); + return ERROR; + } + } + temp_contact->have_service_notification_options = TRUE; + } + else if(!strcmp(variable, "host_notifications_enabled")) { + temp_contact->host_notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_contact->have_host_notifications_enabled = TRUE; + } + else if(!strcmp(variable, "service_notifications_enabled")) { + temp_contact->service_notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_contact->have_service_notifications_enabled = TRUE; + } + else if(!strcmp(variable, "can_submit_commands")) { + temp_contact->can_submit_commands = (atoi(value) > 0) ? TRUE : FALSE; + temp_contact->have_can_submit_commands = TRUE; + } + else if(!strcmp(variable, "retain_status_information")) { + temp_contact->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE; + temp_contact->have_retain_status_information = TRUE; + } + else if(!strcmp(variable, "retain_nonstatus_information")) { + temp_contact->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE; + temp_contact->have_retain_nonstatus_information = TRUE; + } + else if(!strcmp(variable, "register")) + temp_contact->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else if(variable[0] == '_') { + + /* get the variable name */ + customvarname = (char *)strdup(variable + 1); + + /* make sure we have a variable name */ + if(customvarname == NULL || !strcmp(customvarname, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n"); + my_free(customvarname); + return ERROR; + } + + /* get the variable value */ + if(strcmp(value, XODTEMPLATE_NULL)) + customvarvalue = (char *)strdup(value); + else + customvarvalue = NULL; + + /* add the custom variable */ + if(xodtemplate_add_custom_variable_to_contact(temp_contact, customvarname, customvarvalue) == NULL) { + my_free(customvarname); + my_free(customvarvalue); + return ERROR; + } + + /* free memory */ + my_free(customvarname); + my_free(customvarvalue); + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid contact object directive '%s'.\n", variable); + return ERROR; + } + + break; + + + case XODTEMPLATE_HOST: + + temp_host = (xodtemplate_host *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_host->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_host->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add host to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_HOST_SKIPLIST], (void *)temp_host); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "host_name")) { + if((temp_host->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add host to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_HOST_SKIPLIST], (void *)temp_host); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "display_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->display_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_display_name = TRUE; + } + else if(!strcmp(variable, "alias")) { + if((temp_host->alias = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "address")) { + if((temp_host->address = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "parents")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->parents = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_parents = TRUE; + } + else if(!strcmp(variable, "host_groups") || !strcmp(variable, "hostgroups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->host_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_host_groups = TRUE; + } + else if(!strcmp(variable, "contact_groups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->contact_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_contact_groups = TRUE; + } + else if(!strcmp(variable, "contacts")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->contacts = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_contacts = TRUE; + } + else if(!strcmp(variable, "notification_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->notification_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_notification_period = TRUE; + } + else if(!strcmp(variable, "check_command")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->check_command = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_check_command = TRUE; + } + else if(!strcmp(variable, "check_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->check_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_check_period = TRUE; + } + else if(!strcmp(variable, "event_handler")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->event_handler = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_event_handler = TRUE; + } + else if(!strcmp(variable, "failure_prediction_options")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->failure_prediction_options = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_failure_prediction_options = TRUE; + } + else if(!strcmp(variable, "notes")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->notes = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_notes = TRUE; + } + else if(!strcmp(variable, "notes_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->notes_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_notes_url = TRUE; + } + else if(!strcmp(variable, "action_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->action_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_action_url = TRUE; + } + else if(!strcmp(variable, "icon_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->icon_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_icon_image = TRUE; + } + else if(!strcmp(variable, "icon_image_alt")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->icon_image_alt = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_icon_image_alt = TRUE; + } + else if(!strcmp(variable, "vrml_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->vrml_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_vrml_image = TRUE; + } + else if(!strcmp(variable, "gd2_image") || !strcmp(variable, "statusmap_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_host->statusmap_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_host->have_statusmap_image = TRUE; + } + else if(!strcmp(variable, "initial_state")) { + if(!strcmp(value, "o") || !strcmp(value, "up")) + temp_host->initial_state = 0; /* HOST_UP */ + else if(!strcmp(value, "d") || !strcmp(value, "down")) + temp_host->initial_state = 1; /* HOST_DOWN */ + else if(!strcmp(value, "u") || !strcmp(value, "unreachable")) + temp_host->initial_state = 2; /* HOST_UNREACHABLE */ + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid initial state '%s' in host definition.\n", value); + result = ERROR; + } + temp_host->have_initial_state = TRUE; + } + else if(!strcmp(variable, "check_interval") || !strcmp(variable, "normal_check_interval")) { + temp_host->check_interval = strtod(value, NULL); + temp_host->have_check_interval = TRUE; + } + else if(!strcmp(variable, "retry_interval") || !strcmp(variable, "retry_check_interval")) { + temp_host->retry_interval = strtod(value, NULL); + temp_host->have_retry_interval = TRUE; + } + else if(!strcmp(variable, "max_check_attempts")) { + temp_host->max_check_attempts = atoi(value); + temp_host->have_max_check_attempts = TRUE; + } + else if(!strcmp(variable, "checks_enabled") || !strcmp(variable, "active_checks_enabled")) { + temp_host->active_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_active_checks_enabled = TRUE; + } + else if(!strcmp(variable, "passive_checks_enabled")) { + temp_host->passive_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_passive_checks_enabled = TRUE; + } + else if(!strcmp(variable, "event_handler_enabled")) { + temp_host->event_handler_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_event_handler_enabled = TRUE; + } + else if(!strcmp(variable, "check_freshness")) { + temp_host->check_freshness = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_check_freshness = TRUE; + } + else if(!strcmp(variable, "freshness_threshold")) { + temp_host->freshness_threshold = atoi(value); + temp_host->have_freshness_threshold = TRUE; + } + else if(!strcmp(variable, "low_flap_threshold")) { + temp_host->low_flap_threshold = strtod(value, NULL); + temp_host->have_low_flap_threshold = TRUE; + } + else if(!strcmp(variable, "high_flap_threshold")) { + temp_host->high_flap_threshold = strtod(value, NULL); + temp_host->have_high_flap_threshold = TRUE; + } + else if(!strcmp(variable, "flap_detection_enabled")) { + temp_host->flap_detection_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_flap_detection_enabled = TRUE; + } + else if(!strcmp(variable, "flap_detection_options")) { + + /* user is specifying something, so discard defaults... */ + temp_host->flap_detection_on_up = FALSE; + temp_host->flap_detection_on_down = FALSE; + temp_host->flap_detection_on_unreachable = FALSE; + + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up")) + temp_host->flap_detection_on_up = TRUE; + else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_host->flap_detection_on_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_host->flap_detection_on_unreachable = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_host->flap_detection_on_up = FALSE; + temp_host->flap_detection_on_down = FALSE; + temp_host->flap_detection_on_unreachable = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_host->flap_detection_on_up = TRUE; + temp_host->flap_detection_on_down = TRUE; + temp_host->flap_detection_on_unreachable = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid flap detection option '%s' in host definition.\n", temp_ptr); + result = ERROR; + } + } + temp_host->have_flap_detection_options = TRUE; + } + else if(!strcmp(variable, "notification_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_host->notify_on_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_host->notify_on_unreachable = TRUE; + else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery")) + temp_host->notify_on_recovery = TRUE; + else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping")) + temp_host->notify_on_flapping = TRUE; + else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime")) + temp_host->notify_on_downtime = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_host->notify_on_down = FALSE; + temp_host->notify_on_unreachable = FALSE; + temp_host->notify_on_recovery = FALSE; + temp_host->notify_on_flapping = FALSE; + temp_host->notify_on_downtime = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_host->notify_on_down = TRUE; + temp_host->notify_on_unreachable = TRUE; + temp_host->notify_on_recovery = TRUE; + temp_host->notify_on_flapping = TRUE; + temp_host->notify_on_downtime = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification option '%s' in host definition.\n", temp_ptr); + result = ERROR; + } + } + temp_host->have_notification_options = TRUE; + } + else if(!strcmp(variable, "notifications_enabled")) { + temp_host->notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_notifications_enabled = TRUE; + } + else if(!strcmp(variable, "notification_interval")) { + temp_host->notification_interval = strtod(value, NULL); + temp_host->have_notification_interval = TRUE; + } + else if(!strcmp(variable, "first_notification_delay")) { + temp_host->first_notification_delay = strtod(value, NULL); + temp_host->have_first_notification_delay = TRUE; + } + else if(!strcmp(variable, "stalking_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up")) + temp_host->stalk_on_up = TRUE; + else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_host->stalk_on_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_host->stalk_on_unreachable = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_host->stalk_on_up = FALSE; + temp_host->stalk_on_down = FALSE; + temp_host->stalk_on_unreachable = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_host->stalk_on_up = TRUE; + temp_host->stalk_on_down = TRUE; + temp_host->stalk_on_unreachable = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid stalking option '%s' in host definition.\n", temp_ptr); + result = ERROR; + } + } + temp_host->have_stalking_options = TRUE; + } + else if(!strcmp(variable, "process_perf_data")) { + temp_host->process_perf_data = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_process_perf_data = TRUE; + } + else if(!strcmp(variable, "failure_prediction_enabled")) { + temp_host->failure_prediction_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_failure_prediction_enabled = TRUE; + } + else if(!strcmp(variable, "2d_coords")) { + if((temp_ptr = strtok(value, ", ")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in host definition.\n", temp_ptr); + return ERROR; + } + temp_host->x_2d = atoi(temp_ptr); + if((temp_ptr = strtok(NULL, ", ")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in host definition.\n", temp_ptr); + return ERROR; + } + temp_host->y_2d = atoi(temp_ptr); + temp_host->have_2d_coords = TRUE; + } + else if(!strcmp(variable, "3d_coords")) { + if((temp_ptr = strtok(value, ", ")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr); + return ERROR; + } + temp_host->x_3d = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ", ")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr); + return ERROR; + } + temp_host->y_3d = strtod(temp_ptr, NULL); + if((temp_ptr = strtok(NULL, ", ")) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr); + return ERROR; + } + temp_host->z_3d = strtod(temp_ptr, NULL); + temp_host->have_3d_coords = TRUE; + } + else if(!strcmp(variable, "obsess_over_host")) { + temp_host->obsess_over_host = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_obsess_over_host = TRUE; + } + else if(!strcmp(variable, "retain_status_information")) { + temp_host->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_retain_status_information = TRUE; + } + else if(!strcmp(variable, "retain_nonstatus_information")) { + temp_host->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE; + temp_host->have_retain_nonstatus_information = TRUE; + } + else if(!strcmp(variable, "register")) + temp_host->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else if(variable[0] == '_') { + + /* get the variable name */ + customvarname = (char *)strdup(variable + 1); + + /* make sure we have a variable name */ + if(customvarname == NULL || !strcmp(customvarname, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n"); + my_free(customvarname); + return ERROR; + } + + /* get the variable value */ + customvarvalue = NULL; + if(strcmp(value, XODTEMPLATE_NULL)) + customvarvalue = (char *)strdup(value); + + /* add the custom variable */ + if(xodtemplate_add_custom_variable_to_host(temp_host, customvarname, customvarvalue) == NULL) { + my_free(customvarname); + my_free(customvarvalue); + return ERROR; + } + + /* free memory */ + my_free(customvarname); + my_free(customvarvalue); + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid host object directive '%s'.\n", variable); + return ERROR; + } + + break; + + case XODTEMPLATE_SERVICE: + + temp_service = (xodtemplate_service *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_service->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_service->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add service to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "host") || !strcmp(variable, "hosts") || !strcmp(variable, "host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_host_name = TRUE; + + /* NOTE: services are added to the skiplist in xodtemplate_duplicate_services(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE && temp_service->host_name != NULL && temp_service->service_description != NULL) { + /* add service to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "service_description") || !strcmp(variable, "description")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->service_description = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_service_description = TRUE; + + /* NOTE: services are added to the skiplist in xodtemplate_duplicate_services(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE && temp_service->host_name != NULL && temp_service->service_description != NULL) { + /* add service to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "display_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->display_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_display_name = TRUE; + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "service_groups") || !strcmp(variable, "servicegroups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->service_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_service_groups = TRUE; + } + else if(!strcmp(variable, "check_command")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if(value[0] == '!') { + temp_service->have_important_check_command = TRUE; + temp_ptr = value + 1; + } + else + temp_ptr = value; + if((temp_service->check_command = (char *)strdup(temp_ptr)) == NULL) + result = ERROR; + } + temp_service->have_check_command = TRUE; + } + else if(!strcmp(variable, "check_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->check_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_check_period = TRUE; + } + else if(!strcmp(variable, "event_handler")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->event_handler = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_event_handler = TRUE; + } + else if(!strcmp(variable, "notification_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->notification_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_notification_period = TRUE; + } + else if(!strcmp(variable, "contact_groups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->contact_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_contact_groups = TRUE; + } + else if(!strcmp(variable, "contacts")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->contacts = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_contacts = TRUE; + } + else if(!strcmp(variable, "failure_prediction_options")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->failure_prediction_options = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_failure_prediction_options = TRUE; + } + else if(!strcmp(variable, "notes")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->notes = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_notes = TRUE; + } + else if(!strcmp(variable, "notes_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->notes_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_notes_url = TRUE; + } + else if(!strcmp(variable, "action_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->action_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_action_url = TRUE; + } + else if(!strcmp(variable, "icon_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->icon_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_icon_image = TRUE; + } + else if(!strcmp(variable, "icon_image_alt")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_service->icon_image_alt = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_service->have_icon_image_alt = TRUE; + } + else if(!strcmp(variable, "initial_state")) { + if(!strcmp(value, "o") || !strcmp(value, "ok")) + temp_service->initial_state = STATE_OK; + else if(!strcmp(value, "w") || !strcmp(value, "warning")) + temp_service->initial_state = STATE_WARNING; + else if(!strcmp(value, "u") || !strcmp(value, "unknown")) + temp_service->initial_state = STATE_UNKNOWN; + else if(!strcmp(value, "c") || !strcmp(value, "critical")) + temp_service->initial_state = STATE_CRITICAL; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid initial state '%s' in service definition.\n", value); + result = ERROR; + } + temp_service->have_initial_state = TRUE; + } + else if(!strcmp(variable, "max_check_attempts")) { + temp_service->max_check_attempts = atoi(value); + temp_service->have_max_check_attempts = TRUE; + } + else if(!strcmp(variable, "check_interval") || !strcmp(variable, "normal_check_interval")) { + temp_service->check_interval = strtod(value, NULL); + temp_service->have_check_interval = TRUE; + } + else if(!strcmp(variable, "retry_interval") || !strcmp(variable, "retry_check_interval")) { + temp_service->retry_interval = strtod(value, NULL); + temp_service->have_retry_interval = TRUE; + } + else if(!strcmp(variable, "active_checks_enabled")) { + temp_service->active_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_active_checks_enabled = TRUE; + } + else if(!strcmp(variable, "passive_checks_enabled")) { + temp_service->passive_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_passive_checks_enabled = TRUE; + } + else if(!strcmp(variable, "parallelize_check")) { + temp_service->parallelize_check = atoi(value); + temp_service->have_parallelize_check = TRUE; + } + else if(!strcmp(variable, "is_volatile")) { + temp_service->is_volatile = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_is_volatile = TRUE; + } + else if(!strcmp(variable, "obsess_over_service")) { + temp_service->obsess_over_service = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_obsess_over_service = TRUE; + } + else if(!strcmp(variable, "event_handler_enabled")) { + temp_service->event_handler_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_event_handler_enabled = TRUE; + } + else if(!strcmp(variable, "check_freshness")) { + temp_service->check_freshness = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_check_freshness = TRUE; + } + else if(!strcmp(variable, "freshness_threshold")) { + temp_service->freshness_threshold = atoi(value); + temp_service->have_freshness_threshold = TRUE; + } + else if(!strcmp(variable, "low_flap_threshold")) { + temp_service->low_flap_threshold = strtod(value, NULL); + temp_service->have_low_flap_threshold = TRUE; + } + else if(!strcmp(variable, "high_flap_threshold")) { + temp_service->high_flap_threshold = strtod(value, NULL); + temp_service->have_high_flap_threshold = TRUE; + } + else if(!strcmp(variable, "flap_detection_enabled")) { + temp_service->flap_detection_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_flap_detection_enabled = TRUE; + } + else if(!strcmp(variable, "flap_detection_options")) { + + /* user is specifying something, so discard defaults... */ + temp_service->flap_detection_on_ok = FALSE; + temp_service->flap_detection_on_warning = FALSE; + temp_service->flap_detection_on_unknown = FALSE; + temp_service->flap_detection_on_critical = FALSE; + + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok")) + temp_service->flap_detection_on_ok = TRUE; + else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_service->flap_detection_on_warning = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_service->flap_detection_on_unknown = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_service->flap_detection_on_critical = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_service->flap_detection_on_ok = FALSE; + temp_service->flap_detection_on_warning = FALSE; + temp_service->flap_detection_on_unknown = FALSE; + temp_service->flap_detection_on_critical = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_service->flap_detection_on_ok = TRUE; + temp_service->flap_detection_on_warning = TRUE; + temp_service->flap_detection_on_unknown = TRUE; + temp_service->flap_detection_on_critical = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid flap detection option '%s' in service definition.\n", temp_ptr); + return ERROR; + } + } + temp_service->have_flap_detection_options = TRUE; + } + else if(!strcmp(variable, "notification_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_service->notify_on_unknown = TRUE; + else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_service->notify_on_warning = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_service->notify_on_critical = TRUE; + else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery")) + temp_service->notify_on_recovery = TRUE; + else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping")) + temp_service->notify_on_flapping = TRUE; + else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime")) + temp_service->notify_on_downtime = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_service->notify_on_unknown = FALSE; + temp_service->notify_on_warning = FALSE; + temp_service->notify_on_critical = FALSE; + temp_service->notify_on_recovery = FALSE; + temp_service->notify_on_flapping = FALSE; + temp_service->notify_on_downtime = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_service->notify_on_unknown = TRUE; + temp_service->notify_on_warning = TRUE; + temp_service->notify_on_critical = TRUE; + temp_service->notify_on_recovery = TRUE; + temp_service->notify_on_flapping = TRUE; + temp_service->notify_on_downtime = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification option '%s' in service definition.\n", temp_ptr); + return ERROR; + } + } + temp_service->have_notification_options = TRUE; + } + else if(!strcmp(variable, "notifications_enabled")) { + temp_service->notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_notifications_enabled = TRUE; + } + else if(!strcmp(variable, "notification_interval")) { + temp_service->notification_interval = strtod(value, NULL); + temp_service->have_notification_interval = TRUE; + } + else if(!strcmp(variable, "first_notification_delay")) { + temp_service->first_notification_delay = strtod(value, NULL); + temp_service->have_first_notification_delay = TRUE; + } + else if(!strcmp(variable, "stalking_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok")) + temp_service->stalk_on_ok = TRUE; + else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning")) + temp_service->stalk_on_warning = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown")) + temp_service->stalk_on_unknown = TRUE; + else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical")) + temp_service->stalk_on_critical = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_service->stalk_on_ok = FALSE; + temp_service->stalk_on_warning = FALSE; + temp_service->stalk_on_unknown = FALSE; + temp_service->stalk_on_critical = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_service->stalk_on_ok = TRUE; + temp_service->stalk_on_warning = TRUE; + temp_service->stalk_on_unknown = TRUE; + temp_service->stalk_on_critical = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid stalking option '%s' in service definition.\n", temp_ptr); + return ERROR; + } + } + temp_service->have_stalking_options = TRUE; + } + else if(!strcmp(variable, "process_perf_data")) { + temp_service->process_perf_data = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_process_perf_data = TRUE; + } + else if(!strcmp(variable, "failure_prediction_enabled")) { + temp_service->failure_prediction_enabled = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_failure_prediction_enabled = TRUE; + } + else if(!strcmp(variable, "retain_status_information")) { + temp_service->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_retain_status_information = TRUE; + } + else if(!strcmp(variable, "retain_nonstatus_information")) { + temp_service->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE; + temp_service->have_retain_nonstatus_information = TRUE; + } + else if(!strcmp(variable, "register")) + temp_service->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else if(variable[0] == '_') { + + /* get the variable name */ + customvarname = (char *)strdup(variable + 1); + + /* make sure we have a variable name */ + if(customvarname == NULL || !strcmp(customvarname, "")) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n"); + my_free(customvarname); + return ERROR; + } + + /* get the variable value */ + if(strcmp(value, XODTEMPLATE_NULL)) + customvarvalue = (char *)strdup(value); + else + customvarvalue = NULL; + + /* add the custom variable */ + if(xodtemplate_add_custom_variable_to_service(temp_service, customvarname, customvarvalue) == NULL) { + my_free(customvarname); + my_free(customvarvalue); + return ERROR; + } + + /* free memory */ + my_free(customvarname); + my_free(customvarvalue); + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid service object directive '%s'.\n", variable); + return ERROR; + } + + break; + + case XODTEMPLATE_HOSTDEPENDENCY: + + temp_hostdependency = (xodtemplate_hostdependency *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_hostdependency->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_hostdependency->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add dependency to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host dependency '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostdependency->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostdependency->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "host") || !strcmp(variable, "host_name") || !strcmp(variable, "master_host") || !strcmp(variable, "master_host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostdependency->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostdependency->have_host_name = TRUE; + } + else if(!strcmp(variable, "dependent_hostgroup") || !strcmp(variable, "dependent_hostgroups") || !strcmp(variable, "dependent_hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostdependency->dependent_hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostdependency->have_dependent_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "dependent_host") || !strcmp(variable, "dependent_host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostdependency->dependent_host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostdependency->have_dependent_host_name = TRUE; + + /* NOTE: dependencies are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE) { + /* add hostdependency to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "dependency_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostdependency->dependency_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostdependency->have_dependency_period = TRUE; + } + else if(!strcmp(variable, "inherits_parent")) { + temp_hostdependency->inherits_parent = (atoi(value) > 0) ? TRUE : FALSE; + temp_hostdependency->have_inherits_parent = TRUE; + } + else if(!strcmp(variable, "notification_failure_options") || !strcmp(variable, "notification_failure_criteria")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up")) + temp_hostdependency->fail_notify_on_up = TRUE; + else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_hostdependency->fail_notify_on_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_hostdependency->fail_notify_on_unreachable = TRUE; + else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending")) + temp_hostdependency->fail_notify_on_pending = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_hostdependency->fail_notify_on_up = FALSE; + temp_hostdependency->fail_notify_on_down = FALSE; + temp_hostdependency->fail_notify_on_unreachable = FALSE; + temp_hostdependency->fail_notify_on_pending = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_hostdependency->fail_notify_on_up = TRUE; + temp_hostdependency->fail_notify_on_down = TRUE; + temp_hostdependency->fail_notify_on_unreachable = TRUE; + temp_hostdependency->fail_notify_on_pending = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification dependency option '%s' in hostdependency definition.\n", temp_ptr); + return ERROR; + } + } + temp_hostdependency->have_notification_dependency_options = TRUE; + } + else if(!strcmp(variable, "execution_failure_options") || !strcmp(variable, "execution_failure_criteria")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up")) + temp_hostdependency->fail_execute_on_up = TRUE; + else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_hostdependency->fail_execute_on_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_hostdependency->fail_execute_on_unreachable = TRUE; + else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending")) + temp_hostdependency->fail_execute_on_pending = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_hostdependency->fail_execute_on_up = FALSE; + temp_hostdependency->fail_execute_on_down = FALSE; + temp_hostdependency->fail_execute_on_unreachable = FALSE; + temp_hostdependency->fail_execute_on_pending = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_hostdependency->fail_execute_on_up = TRUE; + temp_hostdependency->fail_execute_on_down = TRUE; + temp_hostdependency->fail_execute_on_unreachable = TRUE; + temp_hostdependency->fail_execute_on_pending = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid execution dependency option '%s' in hostdependency definition.\n", temp_ptr); + return ERROR; + } + } + temp_hostdependency->have_execution_dependency_options = TRUE; + } + else if(!strcmp(variable, "register")) + temp_hostdependency->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostdependency object directive '%s'.\n", variable); + return ERROR; + } + + break; + + + case XODTEMPLATE_HOSTESCALATION: + + temp_hostescalation = (xodtemplate_hostescalation *)xodtemplate_current_object; + + if(!strcmp(variable, "use")) { + if((temp_hostescalation->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_hostescalation->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add escalation to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host escalation '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostescalation->_config_file), temp_hostescalation->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostescalation->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostescalation->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "host") || !strcmp(variable, "host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostescalation->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostescalation->have_host_name = TRUE; + + /* NOTE: escalations are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */ + if(result == OK && force_skiplists == TRUE) { + /* add hostescalation to template skiplist for fast searches */ + result = skiplist_insert(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "contact_groups")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostescalation->contact_groups = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostescalation->have_contact_groups = TRUE; + } + else if(!strcmp(variable, "contacts")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostescalation->contacts = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostescalation->have_contacts = TRUE; + } + else if(!strcmp(variable, "escalation_period")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostescalation->escalation_period = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostescalation->have_escalation_period = TRUE; + } + else if(!strcmp(variable, "first_notification")) { + temp_hostescalation->first_notification = atoi(value); + temp_hostescalation->have_first_notification = TRUE; + } + else if(!strcmp(variable, "last_notification")) { + temp_hostescalation->last_notification = atoi(value); + temp_hostescalation->have_last_notification = TRUE; + } + else if(!strcmp(variable, "notification_interval")) { + temp_hostescalation->notification_interval = strtod(value, NULL); + temp_hostescalation->have_notification_interval = TRUE; + } + else if(!strcmp(variable, "escalation_options")) { + for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) { + if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down")) + temp_hostescalation->escalate_on_down = TRUE; + else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable")) + temp_hostescalation->escalate_on_unreachable = TRUE; + else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery")) + temp_hostescalation->escalate_on_recovery = TRUE; + else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) { + temp_hostescalation->escalate_on_down = FALSE; + temp_hostescalation->escalate_on_unreachable = FALSE; + temp_hostescalation->escalate_on_recovery = FALSE; + } + else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) { + temp_hostescalation->escalate_on_down = TRUE; + temp_hostescalation->escalate_on_unreachable = TRUE; + temp_hostescalation->escalate_on_recovery = TRUE; + } + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid escalation option '%s' in hostescalation definition.\n", temp_ptr); + return ERROR; + } + } + temp_hostescalation->have_escalation_options = TRUE; + } + else if(!strcmp(variable, "register")) + temp_hostescalation->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostescalation object directive '%s'.\n", variable); + return ERROR; + } + + break; + + case XODTEMPLATE_HOSTEXTINFO: + + temp_hostextinfo = xodtemplate_hostextinfo_list; + + if(!strcmp(variable, "use")) { + if((temp_hostextinfo->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_hostextinfo->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_HOSTEXTINFO_SKIPLIST], (void *)temp_hostextinfo); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for extended host info '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostextinfo->_config_file), temp_hostextinfo->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_host_name = TRUE; + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "notes")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->notes = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_notes = TRUE; + } + else if(!strcmp(variable, "notes_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->notes_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_notes_url = TRUE; + } + else if(!strcmp(variable, "action_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->action_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_action_url = TRUE; + } + else if(!strcmp(variable, "icon_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->icon_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_icon_image = TRUE; + } + else if(!strcmp(variable, "icon_image_alt")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->icon_image_alt = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_icon_image_alt = TRUE; + } + else if(!strcmp(variable, "vrml_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->vrml_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_vrml_image = TRUE; + } + else if(!strcmp(variable, "gd2_image") || !strcmp(variable, "statusmap_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_hostextinfo->statusmap_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_hostextinfo->have_statusmap_image = TRUE; + } + else if(!strcmp(variable, "2d_coords")) { + temp_ptr = strtok(value, ", "); + if(temp_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in extended host info definition.\n", temp_ptr); + return ERROR; + } + temp_hostextinfo->x_2d = atoi(temp_ptr); + temp_ptr = strtok(NULL, ", "); + if(temp_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in extended host info definition.\n", temp_ptr); + return ERROR; + } + temp_hostextinfo->y_2d = atoi(temp_ptr); + temp_hostextinfo->have_2d_coords = TRUE; + } + else if(!strcmp(variable, "3d_coords")) { + temp_ptr = strtok(value, ", "); + if(temp_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr); + return ERROR; + } + temp_hostextinfo->x_3d = strtod(temp_ptr, NULL); + temp_ptr = strtok(NULL, ", "); + if(temp_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr); + return ERROR; + } + temp_hostextinfo->y_3d = strtod(temp_ptr, NULL); + temp_ptr = strtok(NULL, ", "); + if(temp_ptr == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr); + return ERROR; + } + temp_hostextinfo->z_3d = strtod(temp_ptr, NULL); + temp_hostextinfo->have_3d_coords = TRUE; + } + else if(!strcmp(variable, "register")) + temp_hostextinfo->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostextinfo object directive '%s'.\n", variable); + return ERROR; + } + + break; + + case XODTEMPLATE_SERVICEEXTINFO: + + temp_serviceextinfo = xodtemplate_serviceextinfo_list; + + if(!strcmp(variable, "use")) { + if((temp_serviceextinfo->template = (char *)strdup(value)) == NULL) + result = ERROR; + } + else if(!strcmp(variable, "name")) { + + if((temp_serviceextinfo->name = (char *)strdup(value)) == NULL) + result = ERROR; + + if(result == OK) { + /* add to template skiplist for fast searches */ + result = skiplist_insert(xobject_template_skiplists[X_SERVICEEXTINFO_SKIPLIST], (void *)temp_serviceextinfo); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for extended service info '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_serviceextinfo->_config_file), temp_serviceextinfo->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + } + else if(!strcmp(variable, "host_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->host_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_host_name = TRUE; + } + else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroup_name")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->hostgroup_name = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_hostgroup_name = TRUE; + } + else if(!strcmp(variable, "service_description")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->service_description = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_service_description = TRUE; + } + else if(!strcmp(variable, "notes")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->notes = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_notes = TRUE; + } + else if(!strcmp(variable, "notes_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->notes_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_notes_url = TRUE; + } + else if(!strcmp(variable, "action_url")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->action_url = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_action_url = TRUE; + } + else if(!strcmp(variable, "icon_image")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->icon_image = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_icon_image = TRUE; + } + else if(!strcmp(variable, "icon_image_alt")) { + if(strcmp(value, XODTEMPLATE_NULL)) { + if((temp_serviceextinfo->icon_image_alt = (char *)strdup(value)) == NULL) + result = ERROR; + } + temp_serviceextinfo->have_icon_image_alt = TRUE; + } + else if(!strcmp(variable, "register")) + temp_serviceextinfo->register_object = (atoi(value) > 0) ? TRUE : FALSE; + else { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid serviceextinfo object directive '%s'.\n", variable); + return ERROR; + } + + break; + + default: + return ERROR; + break; + } + + /* free memory */ + my_free(variable); + my_free(value); + + return result; + } + + + +/* completes an object definition */ +int xodtemplate_end_object_definition(int options) { + int result = OK; + + + xodtemplate_current_object = NULL; + xodtemplate_current_object_type = XODTEMPLATE_NONE; + + return result; + } + + + +/* adds a custom variable to a host */ +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_host(xodtemplate_host *hst, char *varname, char *varvalue) { + + return xodtemplate_add_custom_variable_to_object(&hst->custom_variables, varname, varvalue); + } + + + +/* adds a custom variable to a service */ +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_service(xodtemplate_service *svc, char *varname, char *varvalue) { + + return xodtemplate_add_custom_variable_to_object(&svc->custom_variables, varname, varvalue); + } + + + +/* adds a custom variable to a contact */ +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_contact(xodtemplate_contact *cntct, char *varname, char *varvalue) { + + return xodtemplate_add_custom_variable_to_object(&cntct->custom_variables, varname, varvalue); + } + + + +/* adds a custom variable to an object */ +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_object(xodtemplate_customvariablesmember **object_ptr, char *varname, char *varvalue) { + xodtemplate_customvariablesmember *new_customvariablesmember = NULL; + register int x = 0; + + /* make sure we have the data we need */ + if(object_ptr == NULL) + return NULL; + + if(varname == NULL || !strcmp(varname, "")) + return NULL; + + /* allocate memory for a new member */ + if((new_customvariablesmember = malloc(sizeof(xodtemplate_customvariablesmember))) == NULL) + return NULL; + if((new_customvariablesmember->variable_name = (char *)strdup(varname)) == NULL) { + my_free(new_customvariablesmember); + return NULL; + } + if(varvalue) { + if((new_customvariablesmember->variable_value = (char *)strdup(varvalue)) == NULL) { + my_free(new_customvariablesmember->variable_name); + my_free(new_customvariablesmember); + return NULL; + } + } + else + new_customvariablesmember->variable_value = NULL; + + /* convert varname to all uppercase (saves CPU time during macro functions) */ + for(x = 0; new_customvariablesmember->variable_name[x] != '\x0'; x++) + new_customvariablesmember->variable_name[x] = toupper(new_customvariablesmember->variable_name[x]); + + /* add the new member to the head of the member list */ + new_customvariablesmember->next = *object_ptr; + *object_ptr = new_customvariablesmember; + + return new_customvariablesmember; + } + + + +/* parses a timeperod directive... :-) */ +int xodtemplate_parse_timeperiod_directive(xodtemplate_timeperiod *tperiod, char *var, char *val) { + char *input = NULL; + char temp_buffer[5][MAX_INPUT_BUFFER] = {"", "", "", "", ""}; + int items = 0; + int result = OK; + + int syear = 0; + int smon = 0; + int smday = 0; + int swday = 0; + int swday_offset = 0; + int eyear = 0; + int emon = 0; + int emday = 0; + int ewday = 0; + int ewday_offset = 0; + int skip_interval = 0; + + /* make sure we've got the reqs */ + if(tperiod == NULL || var == NULL || val == NULL) + return ERROR; + + /* we'll need the full (unsplit) input later */ + if((input = (char *)malloc(strlen(var) + strlen(val) + 2)) == NULL) + return ERROR; + strcpy(input, var); + strcat(input, " "); + strcat(input, val); + + if(0) + return OK; + + /* calendar dates */ + else if((items = sscanf(input, "%4d-%2d-%2d - %4d-%2d-%2d / %d %[0-9:, -]", &syear, &smon, &smday, &eyear, &emon, &emday, &skip_interval, temp_buffer[0])) == 8) { + /* add timerange exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, skip_interval, temp_buffer[0]) == NULL) + result = ERROR; + } + + else if((items = sscanf(input, "%4d-%2d-%2d / %d %[0-9:, -]", &syear, &smon, &smday, &skip_interval, temp_buffer[0])) == 5) { + eyear = syear; + emon = smon; + emday = smday; + /* add timerange exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, skip_interval, temp_buffer[0]) == NULL) + result = ERROR; + } + + else if((items = sscanf(input, "%4d-%2d-%2d - %4d-%2d-%2d %[0-9:, -]", &syear, &smon, &smday, &eyear, &emon, &emday, temp_buffer[0])) == 7) { + /* add timerange exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, 0, temp_buffer[0]) == NULL) + result = ERROR; + } + + else if((items = sscanf(input, "%4d-%2d-%2d %[0-9:, -]", &syear, &smon, &smday, temp_buffer[0])) == 4) { + eyear = syear; + emon = smon; + emday = smday; + /* add timerange exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, 0, temp_buffer[0]) == NULL) + result = ERROR; + } + + /* other types... */ + else if((items = sscanf(input, "%[a-z] %d %[a-z] - %[a-z] %d %[a-z] / %d %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2], &ewday_offset, temp_buffer[3], &skip_interval, temp_buffer[4])) == 8) { + /* wednesday 1 january - thursday 2 july / 3 */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[2], &ewday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[3], &emon)) == OK) { + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_WEEK_DAY, 0, smon, 0, swday, swday_offset, 0, emon, 0, ewday, ewday_offset, skip_interval, temp_buffer[4]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d - %[a-z] %d / %d %[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1], &emday, &skip_interval, temp_buffer[2])) == 6) { + /* february 1 - march 15 / 3 */ + /* monday 2 - thursday 3 / 2 */ + /* day 4 - day 6 / 2 */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[1], &ewday)) == OK) { + /* monday 2 - thursday 3 / 2 */ + swday_offset = smday; + ewday_offset = emday; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, skip_interval, temp_buffer[2]) == NULL) + result = ERROR; + } + else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &emon)) == OK) { + /* february 1 - march 15 / 3 */ + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, skip_interval, temp_buffer[2]) == NULL) + result = ERROR; + } + else if(!strcmp(temp_buffer[0], "day") && !strcmp(temp_buffer[1], "day")) { + /* day 4 - 6 / 2 */ + /* add timeperiod exception */ + result = OK; + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, skip_interval, temp_buffer[2]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d - %d / %d %[0-9:, -]", temp_buffer[0], &smday, &emday, &skip_interval, temp_buffer[1])) == 5) { + /* february 1 - 15 / 3 */ + /* monday 2 - 3 / 2 */ + /* day 1 - 25 / 4 */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) { + /* thursday 2 - 4 */ + swday_offset = smday; + ewday = swday; + ewday_offset = emday; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, skip_interval, temp_buffer[1]) == NULL) + result = ERROR; + } + else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) { + /* february 3 - 5 */ + emon = smon; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, skip_interval, temp_buffer[1]) == NULL) + result = ERROR; + } + else if(!strcmp(temp_buffer[0], "day")) { + /* day 1 - 4 */ + /* add timeperiod exception */ + result = OK; + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, skip_interval, temp_buffer[1]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d %[a-z] - %[a-z] %d %[a-z] %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2], &ewday_offset, temp_buffer[3], temp_buffer[4])) == 7) { + /* wednesday 1 january - thursday 2 july */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[2], &ewday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[3], &emon)) == OK) { + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_WEEK_DAY, 0, smon, 0, swday, swday_offset, 0, emon, 0, ewday, ewday_offset, 0, temp_buffer[4]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d - %d %[0-9:, -]", temp_buffer[0], &smday, &emday, temp_buffer[1])) == 4) { + /* february 3 - 5 */ + /* thursday 2 - 4 */ + /* day 1 - 4 */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) { + /* thursday 2 - 4 */ + swday_offset = smday; + ewday = swday; + ewday_offset = emday; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, 0, temp_buffer[1]) == NULL) + result = ERROR; + } + else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) { + /* february 3 - 5 */ + emon = smon; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, 0, temp_buffer[1]) == NULL) + result = ERROR; + } + else if(!strcmp(temp_buffer[0], "day")) { + /* day 1 - 4 */ + /* add timeperiod exception */ + result = OK; + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, 0, temp_buffer[1]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d - %[a-z] %d %[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1], &emday, temp_buffer[2])) == 5) { + /* february 1 - march 15 */ + /* monday 2 - thursday 3 */ + /* day 1 - day 5 */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[1], &ewday)) == OK) { + /* monday 2 - thursday 3 */ + swday_offset = smday; + ewday_offset = emday; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, 0, temp_buffer[2]) == NULL) + result = ERROR; + } + else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &emon)) == OK) { + /* february 1 - march 15 */ + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, 0, temp_buffer[2]) == NULL) + result = ERROR; + } + else if(!strcmp(temp_buffer[0], "day") && !strcmp(temp_buffer[1], "day")) { + /* day 1 - day 5 */ + /* add timeperiod exception */ + result = OK; + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, 0, temp_buffer[2]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d%*[ \t]%[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1])) == 3) { + /* february 3 */ + /* thursday 2 */ + /* day 1 */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) { + /* thursday 2 */ + swday_offset = smday; + ewday = swday; + ewday_offset = swday_offset; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, 0, temp_buffer[1]) == NULL) + result = ERROR; + } + else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) { + /* february 3 */ + emon = smon; + emday = smday; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, 0, temp_buffer[1]) == NULL) + result = ERROR; + } + else if(!strcmp(temp_buffer[0], "day")) { + /* day 1 */ + emday = smday; + /* add timeperiod exception */ + result = OK; + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, 0, temp_buffer[1]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %d %[a-z] %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2])) == 4) { + /* thursday 3 february */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK) { + emon = smon; + ewday = swday; + ewday_offset = swday_offset; + /* add timeperiod exception */ + if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_WEEK_DAY, 0, smon, 0, swday, swday_offset, 0, emon, 0, ewday, ewday_offset, 0, temp_buffer[2]) == NULL) + result = ERROR; + } + } + + else if((items = sscanf(input, "%[a-z] %[0-9:, -]", temp_buffer[0], temp_buffer[1])) == 2) { + /* monday */ + if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) { + /* add normal weekday timerange */ + if((tperiod->timeranges[swday] = (char *)strdup(temp_buffer[1])) == NULL) + result = ERROR; + } + } + + else + result = ERROR; + +#ifdef NSCORE + if(result == ERROR) { + printf("Error: Could not parse timeperiod directive '%s'!\n", input); + } +#endif + + /* free memory */ + my_free(input); + + return result; + } + + + +/* add a new exception to a timeperiod */ +xodtemplate_daterange *xodtemplate_add_exception_to_timeperiod(xodtemplate_timeperiod *period, int type, int syear, int smon, int smday, int swday, int swday_offset, int eyear, int emon, int emday, int ewday, int ewday_offset, int skip_interval, char *timeranges) { + xodtemplate_daterange *new_daterange = NULL; + + /* make sure we have the data we need */ + if(period == NULL || timeranges == NULL) + return NULL; + + /* allocate memory for the date range range */ + if((new_daterange = malloc(sizeof(xodtemplate_daterange))) == NULL) + return NULL; + + new_daterange->next = NULL; + + new_daterange->type = type; + new_daterange->syear = syear; + new_daterange->smon = smon; + new_daterange->smday = smday; + new_daterange->swday = swday; + new_daterange->swday_offset = swday_offset; + new_daterange->eyear = eyear; + new_daterange->emon = emon; + new_daterange->emday = emday; + new_daterange->ewday = ewday; + new_daterange->ewday_offset = ewday_offset; + new_daterange->skip_interval = skip_interval; + new_daterange->timeranges = (char *)strdup(timeranges); + + /* add the new date range to the head of the range list for this exception type */ + new_daterange->next = period->exceptions[type]; + period->exceptions[type] = new_daterange; + + return new_daterange; + } + + + +int xodtemplate_get_month_from_string(char *str, int *month) { + char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}; + int x = 0; + + if(str == NULL || month == NULL) + return ERROR; + + for(x = 0; x < 12; x++) { + if(!strcmp(str, months[x])) { + *month = x; + return OK; + } + } + + return ERROR; + } + + + + +int xodtemplate_get_weekday_from_string(char *str, int *weekday) { + char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}; + int x = 0; + + if(str == NULL || weekday == NULL) + return ERROR; + + for(x = 0; x < 7; x++) { + if(!strcmp(str, days[x])) { + *weekday = x; + return OK; + } + } + + return ERROR; + } + + + +/******************************************************************/ +/***************** OBJECT DUPLICATION FUNCTIONS *******************/ +/******************************************************************/ + +#ifdef NSCORE + +/* duplicates service definitions */ +int xodtemplate_duplicate_services(void) { + int result = OK; + xodtemplate_service *temp_service = NULL; + xodtemplate_memberlist *temp_memberlist = NULL; + xodtemplate_memberlist *temp_rejectlist = NULL; + xodtemplate_memberlist *this_memberlist = NULL; + char *host_name = NULL; + int first_item = FALSE; + + + /****** DUPLICATE SERVICE DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* skip service definitions without enough data */ + if(temp_service->hostgroup_name == NULL && temp_service->host_name == NULL) + continue; + + /* If hostgroup is not null and hostgroup has no members, check to see if */ + /* allow_empty_hostgroup_assignment is set to 1 - if it is, continue without error */ + if(temp_service->hostgroup_name != NULL) { + if(xodtemplate_expand_hostgroups(&temp_memberlist, &temp_rejectlist, temp_service->hostgroup_name, temp_service->_config_file, temp_service->_start_line) == ERROR) { + return ERROR; + } + else { + xodtemplate_free_memberlist(&temp_rejectlist); + if(temp_memberlist != NULL) { + xodtemplate_free_memberlist(&temp_memberlist); + } + else { + /* User is ok with hostgroup -> service mappings with no hosts */ + if(allow_empty_hostgroup_assignment == 1) { + continue; + } + } + } + } + + /* skip services that shouldn't be registered */ + if(temp_service->register_object == FALSE) + continue; + + /* get list of hosts */ + temp_memberlist = xodtemplate_expand_hostgroups_and_hosts(temp_service->hostgroup_name, temp_service->host_name, temp_service->_config_file, temp_service->_start_line); + if(temp_memberlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in service (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + return ERROR; + } + + /* add a copy of the service for every host in the hostgroup/host name list */ + first_item = TRUE; + for(this_memberlist = temp_memberlist; this_memberlist != NULL; this_memberlist = this_memberlist->next) { + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_service->host_name); + temp_service->host_name = (char *)strdup(this_memberlist->name1); + if(temp_service->host_name == NULL) { + xodtemplate_free_memberlist(&temp_memberlist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service definition */ + result = xodtemplate_duplicate_service(temp_service, this_memberlist->name1); + + /* exit on error */ + if(result == ERROR) { + my_free(host_name); + return ERROR; + } + } + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&temp_memberlist); + } + + + /***************************************/ + /* SKIPLIST STUFF FOR FAST SORT/SEARCH */ + /***************************************/ + + /* First loop for single host service definition*/ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* skip services that shouldn't be registered */ + if(temp_service->register_object == FALSE) + continue; + + /* skip service definitions without enough data */ + if(temp_service->host_name == NULL || temp_service->service_description == NULL) + continue; + + if(xodtemplate_is_service_is_from_hostgroup(temp_service)) { + continue; + } + + + result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' on host '%s' (config file '%s', starting on line %d)\n", temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + + + /* second loop for host group service definition*/ + /* add services to skiplist for fast searches */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* skip services that shouldn't be registered */ + if(temp_service->register_object == FALSE) + continue; + + /* skip service definitions without enough data */ + if(temp_service->host_name == NULL || temp_service->service_description == NULL) + continue; + + if(!xodtemplate_is_service_is_from_hostgroup(temp_service)) { + continue; + } + /*The flag X_SERVICE_IS_FROM_HOSTGROUP is set, unset it*/ + xodtemplate_unset_service_is_from_hostgroup(temp_service); + + result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service); + switch(result) { + case SKIPLIST_ERROR_DUPLICATE: + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' on host '%s' (config file '%s', starting on line %d)\n", temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + result = ERROR; + break; + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + + return OK; + } + + + +/* duplicates object definitions */ +int xodtemplate_duplicate_objects(void) { + int result = OK; + xodtemplate_hostescalation *temp_hostescalation = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_hostextinfo *temp_hostextinfo = NULL; + xodtemplate_serviceextinfo *temp_serviceextinfo = NULL; + + xodtemplate_memberlist *master_hostlist = NULL, *dependent_hostlist = NULL; + xodtemplate_memberlist *master_servicelist = NULL, *dependent_servicelist = NULL; + xodtemplate_memberlist *temp_masterhost = NULL, *temp_dependenthost = NULL; + xodtemplate_memberlist *temp_masterservice = NULL, *temp_dependentservice = NULL; + + char *service_descriptions = NULL; + int first_item = FALSE; + int same_host_servicedependency = FALSE; + + + /*************************************/ + /* SERVICES ARE DUPLICATED ELSEWHERE */ + /*************************************/ + + + /****** DUPLICATE HOST ESCALATION DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ + for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) { + + /* skip host escalation definitions without enough data */ + if(temp_hostescalation->hostgroup_name == NULL && temp_hostescalation->host_name == NULL) + continue; + + /* get list of hosts */ + master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostescalation->hostgroup_name, temp_hostescalation->host_name, temp_hostescalation->_config_file, temp_hostescalation->_start_line); + if(master_hostlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in host escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostescalation->_config_file), temp_hostescalation->_start_line); + return ERROR; + } + + /* add a copy of the hostescalation for every host in the hostgroup/host name list */ + first_item = TRUE; + for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) { + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_hostescalation->host_name); + temp_hostescalation->host_name = (char *)strdup(temp_masterhost->name1); + if(temp_hostescalation->host_name == NULL) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate hostescalation definition */ + result = xodtemplate_duplicate_hostescalation(temp_hostescalation, temp_masterhost->name1); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + } + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&master_hostlist); + } + + + /****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + + /* skip service escalation definitions without enough data */ + if(temp_serviceescalation->hostgroup_name == NULL && temp_serviceescalation->host_name == NULL) + continue; + + /* get list of hosts */ + master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_serviceescalation->hostgroup_name, temp_serviceescalation->host_name, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line); + if(master_hostlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line); + return ERROR; + } + + /* duplicate service escalation entries */ + first_item = TRUE; + for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) { + + /* if this is the first duplication,use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_serviceescalation->host_name); + temp_serviceescalation->host_name = (char *)strdup(temp_masterhost->name1); + if(temp_serviceescalation->host_name == NULL) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service escalation definition */ + result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, temp_masterhost->name1, temp_serviceescalation->service_description); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + } + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&master_hostlist); + } + + + /****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH MULTIPLE DESCRIPTIONS ******/ + /* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + + /* skip serviceescalations without enough data */ + if(temp_serviceescalation->service_description == NULL || temp_serviceescalation->host_name == NULL) + continue; + + /* get list of services */ + master_servicelist = xodtemplate_expand_servicegroups_and_services(NULL, temp_serviceescalation->host_name, temp_serviceescalation->service_description, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line); + if(master_servicelist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand services specified in service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line); + return ERROR; + } + + /* duplicate service escalation entries */ + first_item = TRUE; + for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) { + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_serviceescalation->service_description); + temp_serviceescalation->service_description = (char *)strdup(temp_masterservice->name2); + if(temp_serviceescalation->service_description == NULL) { + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service escalation definition */ + result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, temp_serviceescalation->host_name, temp_masterservice->name2); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + } + + /* free memory we used for service list */ + xodtemplate_free_memberlist(&master_servicelist); + } + + + + /****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH SERVICEGROUPS ******/ + /* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + + /* skip serviceescalations without enough data */ + if(temp_serviceescalation->servicegroup_name == NULL) + continue; + + /* get list of services */ + master_servicelist = xodtemplate_expand_servicegroups_and_services(temp_serviceescalation->servicegroup_name, NULL, NULL, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line); + if(master_servicelist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand servicegroups specified in service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line); + return ERROR; + } + + /* duplicate service escalation entries */ + first_item = TRUE; + for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) { + + /* if this is the first duplication, use the existing entry if possible */ + if(first_item == TRUE && temp_serviceescalation->host_name == NULL && temp_serviceescalation->service_description == NULL) { + + my_free(temp_serviceescalation->host_name); + temp_serviceescalation->host_name = (char *)strdup(temp_masterservice->name1); + + my_free(temp_serviceescalation->service_description); + temp_serviceescalation->service_description = (char *)strdup(temp_masterservice->name2); + + if(temp_serviceescalation->host_name == NULL || temp_serviceescalation->service_description == NULL) { + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service escalation definition */ + result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, temp_masterservice->name1, temp_masterservice->name2); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + } + + /* free memory we used for service list */ + xodtemplate_free_memberlist(&master_servicelist); + } + + + /****** DUPLICATE HOST DEPENDENCY DEFINITIONS WITH MULTIPLE HOSTGROUP AND/OR HOST NAMES (MASTER AND DEPENDENT) ******/ + for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) { + + /* skip host dependencies without enough data */ + if(temp_hostdependency->hostgroup_name == NULL && temp_hostdependency->dependent_hostgroup_name == NULL && temp_hostdependency->host_name == NULL && temp_hostdependency->dependent_host_name == NULL) + continue; + + /* get list of master host names */ + master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->hostgroup_name, temp_hostdependency->host_name, temp_hostdependency->_config_file, temp_hostdependency->_start_line); + if(master_hostlist == NULL && allow_empty_hostgroup_assignment == 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master hostgroups and/or hosts specified in host dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line); + return ERROR; + } + + /* get list of dependent host names */ + dependent_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->dependent_hostgroup_name, temp_hostdependency->dependent_host_name, temp_hostdependency->_config_file, temp_hostdependency->_start_line); + if(dependent_hostlist == NULL && allow_empty_hostgroup_assignment == 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent hostgroups and/or hosts specified in host dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line); + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + + /* duplicate the dependency definitions */ + first_item = TRUE; + for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) { + + for(temp_dependenthost = dependent_hostlist; temp_dependenthost != NULL; temp_dependenthost = temp_dependenthost->next) { + + /* temp=master, this=dep */ + + /* existing definition gets first names */ + if(first_item == TRUE) { + my_free(temp_hostdependency->host_name); + my_free(temp_hostdependency->dependent_host_name); + temp_hostdependency->host_name = (char *)strdup(temp_masterhost->name1); + temp_hostdependency->dependent_host_name = (char *)strdup(temp_dependenthost->name1); + first_item = FALSE; + continue; + } + else + result = xodtemplate_duplicate_hostdependency(temp_hostdependency, temp_masterhost->name1, temp_dependenthost->name1); + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_hostlist); + xodtemplate_free_memberlist(&dependent_hostlist); + return ERROR; + } + } + } + + /* free memory used to store host lists */ + xodtemplate_free_memberlist(&master_hostlist); + xodtemplate_free_memberlist(&dependent_hostlist); + } + + + + /****** PROCESS SERVICE DEPENDENCIES WITH MASTER SERVICEGROUPS *****/ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + + /* skip templates */ + if(temp_servicedependency->register_object == 0) + continue; + + /* expand master servicegroups into a list of services */ + if(temp_servicedependency->servicegroup_name) { + + master_servicelist = xodtemplate_expand_servicegroups_and_services(temp_servicedependency->servicegroup_name, NULL, NULL, temp_servicedependency->_config_file, temp_servicedependency->_start_line); + if(master_servicelist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master servicegroups specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + return ERROR; + } + + /* if dependency also has master host, hostgroup, and/or service, we must split that off to another definition */ + if(temp_servicedependency->host_name != NULL || temp_servicedependency->hostgroup_name != NULL || temp_servicedependency->service_description != NULL) { + + /* duplicate everything except master servicegroup */ + xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, temp_servicedependency->hostgroup_name, NULL, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name); + + /* clear values in this definition */ + temp_servicedependency->have_host_name = FALSE; + temp_servicedependency->have_service_description = FALSE; + temp_servicedependency->have_hostgroup_name = FALSE; + my_free(temp_servicedependency->host_name); + my_free(temp_servicedependency->service_description); + my_free(temp_servicedependency->hostgroup_name); + } + + /* duplicate service dependency entries */ + first_item = TRUE; + for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) { + + /* just in case */ + if(temp_masterservice->name1 == NULL || temp_masterservice->name2 == NULL) + continue; + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_servicedependency->host_name); + temp_servicedependency->host_name = (char *)strdup(temp_masterservice->name1); + + my_free(temp_servicedependency->service_description); + temp_servicedependency->service_description = (char *)strdup(temp_masterservice->name2); + + /* clear the master servicegroup */ + temp_servicedependency->have_servicegroup_name = FALSE; + my_free(temp_servicedependency->servicegroup_name); + + if(temp_servicedependency->host_name == NULL || temp_servicedependency->service_description == NULL) { + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service dependency definition */ + result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_masterservice->name1, temp_masterservice->name2, NULL, NULL, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + } + + /* free memory we used for service list */ + xodtemplate_free_memberlist(&master_servicelist); + } + } + + + /****** PROCESS SERVICE DEPENDENCY MASTER HOSTS/HOSTGROUPS/SERVICES *****/ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + + /* skip templates */ + if(temp_servicedependency->register_object == 0) + continue; + + /* expand master hosts/hostgroups into a list of host names */ + if(temp_servicedependency->host_name != NULL || temp_servicedependency->hostgroup_name != NULL) { + +#ifdef DEBUG_SERVICE_DEPENDENCIES + printf("1a) H: %s HG: %s SD: %s\n", temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->service_description); +#endif + + master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_servicedependency->hostgroup_name, temp_servicedependency->host_name, temp_servicedependency->_config_file, temp_servicedependency->_start_line); + if(master_hostlist == NULL && allow_empty_hostgroup_assignment == 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master hostgroups and/or hosts specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + return ERROR; + } + + /* save service descriptions for later */ + if(temp_servicedependency->service_description) + service_descriptions = (char *)strdup(temp_servicedependency->service_description); + + /* for each host, expand master services */ + first_item = TRUE; + for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) { + + master_servicelist = xodtemplate_expand_servicegroups_and_services(NULL, temp_masterhost->name1, service_descriptions, temp_servicedependency->_config_file, temp_servicedependency->_start_line); + if(master_servicelist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master services specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + return ERROR; + } + + /* duplicate service dependency entries */ + for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) { + + /* just in case */ + if(temp_masterservice->name1 == NULL || temp_masterservice->name2 == NULL) + continue; + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_servicedependency->host_name); + temp_servicedependency->host_name = (char *)strdup(temp_masterhost->name1); + + my_free(temp_servicedependency->service_description); + temp_servicedependency->service_description = (char *)strdup(temp_masterservice->name2); + + if(temp_servicedependency->host_name == NULL || temp_servicedependency->service_description == NULL) { + xodtemplate_free_memberlist(&master_hostlist); + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service dependency definition */ + result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_masterhost->name1, temp_masterservice->name2, NULL, NULL, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_hostlist); + xodtemplate_free_memberlist(&master_servicelist); + return ERROR; + } + } + + /* free memory we used for service list */ + xodtemplate_free_memberlist(&master_servicelist); + } + + /* free service descriptions */ + my_free(service_descriptions); + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&master_hostlist); + } + } + + +#ifdef DEBUG_SERVICE_DEPENDENCIES + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + printf("1**) H: %s HG: %s SG: %s SD: %s DH: %s DHG: %s DSG: %s DSD: %s\n", temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->service_description, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name, temp_servicedependency->dependent_service_description); + } + printf("\n"); +#endif + + + /****** PROCESS SERVICE DEPENDENCIES WITH DEPENDENT SERVICEGROUPS *****/ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + + /* skip templates */ + if(temp_servicedependency->register_object == 0) + continue; + + /* expand dependent servicegroups into a list of services */ + if(temp_servicedependency->dependent_servicegroup_name) { + + dependent_servicelist = xodtemplate_expand_servicegroups_and_services(temp_servicedependency->dependent_servicegroup_name, NULL, NULL, temp_servicedependency->_config_file, temp_servicedependency->_start_line); + if(dependent_servicelist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent servicegroups specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + return ERROR; + } + + /* if dependency also has dependent host, hostgroup, and/or service, we must split that off to another definition */ + if(temp_servicedependency->dependent_host_name != NULL || temp_servicedependency->dependent_hostgroup_name != NULL || temp_servicedependency->dependent_service_description != NULL) { + + /* duplicate everything except dependent servicegroup */ + xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, NULL); + + /* clear values in this definition */ + temp_servicedependency->have_dependent_host_name = FALSE; + temp_servicedependency->have_dependent_service_description = FALSE; + temp_servicedependency->have_dependent_hostgroup_name = FALSE; + my_free(temp_servicedependency->dependent_host_name); + my_free(temp_servicedependency->dependent_service_description); + my_free(temp_servicedependency->dependent_hostgroup_name); + } + + /* Detected same host servicegroups dependencies */ + same_host_servicedependency = FALSE; + if(temp_servicedependency->host_name == NULL && temp_servicedependency->hostgroup_name == NULL) + same_host_servicedependency = TRUE; + + /* duplicate service dependency entries */ + first_item = TRUE; + for(temp_dependentservice = dependent_servicelist; temp_dependentservice != NULL; temp_dependentservice = temp_dependentservice->next) { + + /* just in case */ + if(temp_dependentservice->name1 == NULL || temp_dependentservice->name2 == NULL) + continue; + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_servicedependency->dependent_host_name); + temp_servicedependency->dependent_host_name = (char *)strdup(temp_dependentservice->name1); + + my_free(temp_servicedependency->dependent_service_description); + temp_servicedependency->dependent_service_description = (char *)strdup(temp_dependentservice->name2); + + /* Same host servicegroups dependencies: Use dependentservice host_name for master host_name */ + if(same_host_servicedependency == TRUE) + temp_servicedependency->host_name = (char*)strdup(temp_dependentservice->name1); + + /* clear the dependent servicegroup */ + temp_servicedependency->have_dependent_servicegroup_name = FALSE; + my_free(temp_servicedependency->dependent_servicegroup_name); + + if(temp_servicedependency->dependent_host_name == NULL || temp_servicedependency->dependent_service_description == NULL) { + xodtemplate_free_memberlist(&dependent_servicelist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service dependency definition */ + /* Same host servicegroups dependencies: Use dependentservice host_name for master host_name instead of undefined (not yet) master host_name */ + if(same_host_servicedependency == TRUE) + result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_dependentservice->name1, temp_servicedependency->service_description, NULL, NULL, temp_dependentservice->name1, temp_dependentservice->name2, NULL, NULL); + else + result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, NULL, NULL, temp_dependentservice->name1, temp_dependentservice->name2, NULL, NULL); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&dependent_servicelist); + return ERROR; + } + } + + /* free memory we used for service list */ + xodtemplate_free_memberlist(&dependent_servicelist); + } + } + + +#ifdef DEBUG_SERVICE_DEPENDENCIES + printf("\n"); + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + printf("2**) H: %s HG: %s SG: %s SD: %s DH: %s DHG: %s DSG: %s DSD: %s\n", temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->service_description, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name, temp_servicedependency->dependent_service_description); + } +#endif + + + /****** PROCESS SERVICE DEPENDENCY DEPENDENT HOSTS/HOSTGROUPS/SERVICES *****/ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + + /* skip templates */ + if(temp_servicedependency->register_object == 0) + continue; + + /* ADDED 02/04/2007 - special case for "same host" dependencies */ + if(temp_servicedependency->dependent_host_name == NULL && temp_servicedependency->dependent_hostgroup_name == NULL) { + if(temp_servicedependency->host_name) + temp_servicedependency->dependent_host_name = (char *)strdup(temp_servicedependency->host_name); + } + + /* expand dependent hosts/hostgroups into a list of host names */ + if(temp_servicedependency->dependent_host_name != NULL || temp_servicedependency->dependent_hostgroup_name != NULL) { + + dependent_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_host_name, temp_servicedependency->_config_file, temp_servicedependency->_start_line); + if(dependent_hostlist == NULL && allow_empty_hostgroup_assignment == 0) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent hostgroups and/or hosts specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + return ERROR; + } + + /* save service descriptions for later */ + if(temp_servicedependency->dependent_service_description) + service_descriptions = (char *)strdup(temp_servicedependency->dependent_service_description); + + /* for each host, expand dependent services */ + first_item = TRUE; + for(temp_dependenthost = dependent_hostlist; temp_dependenthost != NULL; temp_dependenthost = temp_dependenthost->next) { + + dependent_servicelist = xodtemplate_expand_servicegroups_and_services(NULL, temp_dependenthost->name1, service_descriptions, temp_servicedependency->_config_file, temp_servicedependency->_start_line); + if(dependent_servicelist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent services specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line); + return ERROR; + } + + /* duplicate service dependency entries */ + for(temp_dependentservice = dependent_servicelist; temp_dependentservice != NULL; temp_dependentservice = temp_dependentservice->next) { + + /* just in case */ + if(temp_dependentservice->name1 == NULL || temp_dependentservice->name2 == NULL) + continue; + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_servicedependency->dependent_host_name); + temp_servicedependency->dependent_host_name = (char *)strdup(temp_dependentservice->name1); + + my_free(temp_servicedependency->dependent_service_description); + temp_servicedependency->dependent_service_description = (char *)strdup(temp_dependentservice->name2); + + if(temp_servicedependency->dependent_host_name == NULL || temp_servicedependency->dependent_service_description == NULL) { + xodtemplate_free_memberlist(&dependent_servicelist); + xodtemplate_free_memberlist(&dependent_hostlist); + return ERROR; + } + + first_item = FALSE; + continue; + } + + /* duplicate service dependency definition */ + result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, NULL, NULL, temp_dependentservice->name1, temp_dependentservice->name2, NULL, NULL); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&dependent_servicelist); + xodtemplate_free_memberlist(&dependent_hostlist); + return ERROR; + } + } + + /* free memory we used for service list */ + xodtemplate_free_memberlist(&dependent_servicelist); + } + + /* free service descriptions */ + my_free(service_descriptions); + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&dependent_hostlist); + } + } + + +#ifdef DEBUG_SERVICE_DEPENDENCIES + printf("\n"); + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + printf("3**) MAS: %s/%s DEP: %s/%s\n", temp_servicedependency->host_name, temp_servicedependency->service_description, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description); + } +#endif + + + /****** DUPLICATE HOSTEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ + for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) { + + /* skip definitions without enough data */ + if(temp_hostextinfo->hostgroup_name == NULL && temp_hostextinfo->host_name == NULL) + continue; + + /* get list of hosts */ + master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostextinfo->hostgroup_name, temp_hostextinfo->host_name, temp_hostextinfo->_config_file, temp_hostextinfo->_start_line); + if(master_hostlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in extended host info (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostextinfo->_config_file), temp_hostextinfo->_start_line); + return ERROR; + } + + /* add a copy of the definition for every host in the hostgroup/host name list */ + first_item = TRUE; + for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) { + + /* if this is the first duplication, use the existing entry */ + if(first_item == TRUE) { + + my_free(temp_hostextinfo->host_name); + temp_hostextinfo->host_name = (char *)strdup(temp_masterhost->name1); + if(temp_hostextinfo->host_name == NULL) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + first_item = FALSE; + continue; + } + + /* duplicate hostextinfo definition */ + result = xodtemplate_duplicate_hostextinfo(temp_hostextinfo, temp_masterhost->name1); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + } + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&master_hostlist); + } + + + /****** DUPLICATE SERVICEEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ + for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) { + + /* skip definitions without enough data */ + if(temp_serviceextinfo->hostgroup_name == NULL && temp_serviceextinfo->host_name == NULL) + continue; + + /* get list of hosts */ + master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_serviceextinfo->hostgroup_name, temp_serviceextinfo->host_name, temp_serviceextinfo->_config_file, temp_serviceextinfo->_start_line); + if(master_hostlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in extended service info (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceextinfo->_config_file), temp_serviceextinfo->_start_line); + return ERROR; + } + + /* add a copy of the definition for every host in the hostgroup/host name list */ + first_item = TRUE; + for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) { + + /* existing definition gets first host name */ + if(first_item == TRUE) { + my_free(temp_serviceextinfo->host_name); + temp_serviceextinfo->host_name = (char *)strdup(temp_masterhost->name1); + if(temp_serviceextinfo->host_name == NULL) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + first_item = FALSE; + continue; + } + + /* duplicate serviceextinfo definition */ + result = xodtemplate_duplicate_serviceextinfo(temp_serviceextinfo, temp_masterhost->name1); + + /* exit on error */ + if(result == ERROR) { + xodtemplate_free_memberlist(&master_hostlist); + return ERROR; + } + } + + /* free memory we used for host list */ + xodtemplate_free_memberlist(&master_hostlist); + } + + + /***************************************/ + /* SKIPLIST STUFF FOR FAST SORT/SEARCH */ + /***************************************/ + + /* host escalations */ + for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) { + + /* skip escalations that shouldn't be registered */ + if(temp_hostescalation->register_object == FALSE) + continue; + + /* skip escalation definitions without enough data */ + if(temp_hostescalation->host_name == NULL) + continue; + + result = skiplist_insert(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + + /* service escalations */ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + + /* skip escalations that shouldn't be registered */ + if(temp_serviceescalation->register_object == FALSE) + continue; + + /* skip escalation definitions without enough data */ + if(temp_serviceescalation->host_name == NULL || temp_serviceescalation->service_description == NULL) + continue; + + result = skiplist_insert(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + + /* host dependencies */ + for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) { + + /* skip dependencys that shouldn't be registered */ + if(temp_hostdependency->register_object == FALSE) + continue; + + /* skip dependency definitions without enough data */ + if(temp_hostdependency->host_name == NULL) + continue; + + result = skiplist_insert(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + + /* service dependencies */ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + + /* skip dependencys that shouldn't be registered */ + if(temp_servicedependency->register_object == FALSE) + continue; + + /* skip dependency definitions without enough data */ + if(temp_servicedependency->dependent_host_name == NULL || temp_servicedependency->dependent_service_description == NULL) + continue; + + result = skiplist_insert(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency); + switch(result) { + case SKIPLIST_OK: + result = OK; + break; + default: + result = ERROR; + break; + } + } + + /* host extinfo */ + /* NOT NEEDED */ + + /* service extinfo */ + /* NOT NEEDED */ + + return OK; + } + + + +/* duplicates a service definition (with a new host name) */ +int xodtemplate_duplicate_service(xodtemplate_service *temp_service, char *host_name) { + xodtemplate_service *new_service = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + int error = FALSE; + + /* allocate zero'd out memory for a new service definition */ + new_service = (xodtemplate_service *)calloc(1, sizeof(xodtemplate_service)); + if(new_service == NULL) + return ERROR; + + /* standard items */ + new_service->has_been_resolved = temp_service->has_been_resolved; + new_service->register_object = temp_service->register_object; + new_service->_config_file = temp_service->_config_file; + new_service->_start_line = temp_service->_start_line; + /*tag service apply on host group*/ + xodtemplate_set_service_is_from_hostgroup(new_service); + + /* string defaults */ + new_service->have_hostgroup_name = temp_service->have_hostgroup_name; + new_service->have_host_name = temp_service->have_host_name; + new_service->have_service_description = temp_service->have_service_description; + new_service->have_display_name = temp_service->have_display_name; + new_service->have_service_groups = temp_service->have_service_groups; + new_service->have_check_command = temp_service->have_check_command; + new_service->have_check_period = temp_service->have_check_period; + new_service->have_event_handler = temp_service->have_event_handler; + new_service->have_notification_period = temp_service->have_notification_period; + new_service->have_contact_groups = temp_service->have_contact_groups; + new_service->have_contacts = temp_service->have_contacts; + new_service->have_failure_prediction_options = temp_service->have_failure_prediction_options; + new_service->have_notes = temp_service->have_notes; + new_service->have_notes_url = temp_service->have_notes_url; + new_service->have_action_url = temp_service->have_action_url; + new_service->have_icon_image = temp_service->have_icon_image; + new_service->have_icon_image_alt = temp_service->have_icon_image_alt; + + /* allocate memory for and copy string members of service definition (host name provided, DO NOT duplicate hostgroup member!)*/ + if(temp_service->host_name != NULL && (new_service->host_name = (char *)strdup(host_name)) == NULL) + error = TRUE; + if(temp_service->template != NULL && (new_service->template = (char *)strdup(temp_service->template)) == NULL) + error = TRUE; + if(temp_service->name != NULL && (new_service->name = (char *)strdup(temp_service->name)) == NULL) + error = TRUE; + if(temp_service->service_description != NULL && (new_service->service_description = (char *)strdup(temp_service->service_description)) == NULL) + error = TRUE; + if(temp_service->display_name != NULL && (new_service->display_name = (char *)strdup(temp_service->display_name)) == NULL) + error = TRUE; + if(temp_service->service_groups != NULL && (new_service->service_groups = (char *)strdup(temp_service->service_groups)) == NULL) + error = TRUE; + if(temp_service->check_command != NULL && (new_service->check_command = (char *)strdup(temp_service->check_command)) == NULL) + error = TRUE; + if(temp_service->check_period != NULL && (new_service->check_period = (char *)strdup(temp_service->check_period)) == NULL) + error = TRUE; + if(temp_service->event_handler != NULL && (new_service->event_handler = (char *)strdup(temp_service->event_handler)) == NULL) + error = TRUE; + if(temp_service->notification_period != NULL && (new_service->notification_period = (char *)strdup(temp_service->notification_period)) == NULL) + error = TRUE; + if(temp_service->contact_groups != NULL && (new_service->contact_groups = (char *)strdup(temp_service->contact_groups)) == NULL) + error = TRUE; + if(temp_service->contacts != NULL && (new_service->contacts = (char *)strdup(temp_service->contacts)) == NULL) + error = TRUE; + if(temp_service->failure_prediction_options != NULL && (new_service->failure_prediction_options = (char *)strdup(temp_service->failure_prediction_options)) == NULL) + error = TRUE; + if(temp_service->notes != NULL && (new_service->notes = (char *)strdup(temp_service->notes)) == NULL) + error = TRUE; + if(temp_service->notes_url != NULL && (new_service->notes_url = (char *)strdup(temp_service->notes_url)) == NULL) + error = TRUE; + if(temp_service->action_url != NULL && (new_service->action_url = (char *)strdup(temp_service->action_url)) == NULL) + error = TRUE; + if(temp_service->icon_image != NULL && (new_service->icon_image = (char *)strdup(temp_service->icon_image)) == NULL) + error = TRUE; + if(temp_service->icon_image_alt != NULL && (new_service->icon_image_alt = (char *)strdup(temp_service->icon_image_alt)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_service->host_name); + my_free(new_service->template); + my_free(new_service->name); + my_free(new_service->service_description); + my_free(new_service->display_name); + my_free(new_service->service_groups); + my_free(new_service->check_command); + my_free(new_service->check_period); + my_free(new_service->event_handler); + my_free(new_service->notification_period); + my_free(new_service->contact_groups); + my_free(new_service->contacts); + my_free(new_service->failure_prediction_options); + my_free(new_service->notes); + my_free(new_service->notes_url); + my_free(new_service->action_url); + my_free(new_service->icon_image); + my_free(new_service->icon_image_alt); + my_free(new_service); + return ERROR; + } + + /* duplicate custom variables */ + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) + xodtemplate_add_custom_variable_to_service(new_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value); + + /* duplicate non-string members */ + new_service->initial_state = temp_service->initial_state; + new_service->max_check_attempts = temp_service->max_check_attempts; + new_service->have_max_check_attempts = temp_service->have_max_check_attempts; + new_service->check_interval = temp_service->check_interval; + new_service->have_check_interval = temp_service->have_check_interval; + new_service->retry_interval = temp_service->retry_interval; + new_service->have_retry_interval = temp_service->have_retry_interval; + new_service->active_checks_enabled = temp_service->active_checks_enabled; + new_service->have_active_checks_enabled = temp_service->have_active_checks_enabled; + new_service->passive_checks_enabled = temp_service->passive_checks_enabled; + new_service->have_passive_checks_enabled = temp_service->have_passive_checks_enabled; + new_service->parallelize_check = temp_service->parallelize_check; + new_service->have_parallelize_check = temp_service->have_parallelize_check; + new_service->is_volatile = temp_service->is_volatile; + new_service->have_is_volatile = temp_service->have_is_volatile; + new_service->obsess_over_service = temp_service->obsess_over_service; + new_service->have_obsess_over_service = temp_service->have_obsess_over_service; + new_service->event_handler_enabled = temp_service->event_handler_enabled; + new_service->have_event_handler_enabled = temp_service->have_event_handler_enabled; + new_service->check_freshness = temp_service->check_freshness; + new_service->have_check_freshness = temp_service->have_check_freshness; + new_service->freshness_threshold = temp_service->freshness_threshold; + new_service->have_freshness_threshold = temp_service->have_freshness_threshold; + new_service->flap_detection_enabled = temp_service->flap_detection_enabled; + new_service->have_flap_detection_enabled = temp_service->have_flap_detection_enabled; + new_service->low_flap_threshold = temp_service->low_flap_threshold; + new_service->have_low_flap_threshold = temp_service->have_low_flap_threshold; + new_service->high_flap_threshold = temp_service->high_flap_threshold; + new_service->have_high_flap_threshold = temp_service->have_high_flap_threshold; + new_service->flap_detection_on_ok = temp_service->flap_detection_on_ok; + new_service->flap_detection_on_warning = temp_service->flap_detection_on_warning; + new_service->flap_detection_on_unknown = temp_service->flap_detection_on_unknown; + new_service->flap_detection_on_critical = temp_service->flap_detection_on_critical; + new_service->have_flap_detection_options = temp_service->have_flap_detection_options; + new_service->notify_on_unknown = temp_service->notify_on_unknown; + new_service->notify_on_warning = temp_service->notify_on_warning; + new_service->notify_on_critical = temp_service->notify_on_critical; + new_service->notify_on_recovery = temp_service->notify_on_recovery; + new_service->notify_on_flapping = temp_service->notify_on_flapping; + new_service->notify_on_downtime = temp_service->notify_on_downtime; + new_service->have_notification_options = temp_service->have_notification_options; + new_service->notifications_enabled = temp_service->notifications_enabled; + new_service->have_notifications_enabled = temp_service->have_notifications_enabled; + new_service->notification_interval = temp_service->notification_interval; + new_service->have_notification_interval = temp_service->have_notification_interval; + new_service->first_notification_delay = temp_service->first_notification_delay; + new_service->have_first_notification_delay = temp_service->have_first_notification_delay; + new_service->stalk_on_ok = temp_service->stalk_on_ok; + new_service->stalk_on_unknown = temp_service->stalk_on_unknown; + new_service->stalk_on_warning = temp_service->stalk_on_warning; + new_service->stalk_on_critical = temp_service->stalk_on_critical; + new_service->have_stalking_options = temp_service->have_stalking_options; + new_service->process_perf_data = temp_service->process_perf_data; + new_service->have_process_perf_data = temp_service->have_process_perf_data; + new_service->failure_prediction_enabled = temp_service->failure_prediction_enabled; + new_service->have_failure_prediction_enabled = temp_service->have_failure_prediction_enabled; + new_service->retain_status_information = temp_service->retain_status_information; + new_service->have_retain_status_information = temp_service->have_retain_status_information; + new_service->retain_nonstatus_information = temp_service->retain_nonstatus_information; + new_service->have_retain_nonstatus_information = temp_service->have_retain_nonstatus_information; + + /* add new service to head of list in memory */ + new_service->next = xodtemplate_service_list; + xodtemplate_service_list = new_service; + + return OK; + } + + + + +/* duplicates a host escalation definition (with a new host name) */ +int xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation *temp_hostescalation, char *host_name) { + xodtemplate_hostescalation *new_hostescalation = NULL; + int error = FALSE; + + + /* allocate zero'd out memory for a new host escalation definition */ + new_hostescalation = (xodtemplate_hostescalation *)calloc(1, sizeof(xodtemplate_hostescalation)); + if(new_hostescalation == NULL) + return ERROR; + + /* standard items */ + new_hostescalation->has_been_resolved = temp_hostescalation->has_been_resolved; + new_hostescalation->register_object = temp_hostescalation->register_object; + new_hostescalation->_config_file = temp_hostescalation->_config_file; + new_hostescalation->_start_line = temp_hostescalation->_start_line; + + /* string defaults */ + new_hostescalation->have_hostgroup_name = temp_hostescalation->have_hostgroup_name; + new_hostescalation->have_host_name = (host_name) ? TRUE : FALSE; + new_hostescalation->have_contact_groups = temp_hostescalation->have_contact_groups; + new_hostescalation->have_contacts = temp_hostescalation->have_contacts; + new_hostescalation->have_escalation_period = temp_hostescalation->have_escalation_period; + + /* allocate memory for and copy string members of hostescalation definition */ + if(host_name != NULL && (new_hostescalation->host_name = (char *)strdup(host_name)) == NULL) + error = TRUE; + + if(temp_hostescalation->template != NULL && (new_hostescalation->template = (char *)strdup(temp_hostescalation->template)) == NULL) + error = TRUE; + if(temp_hostescalation->name != NULL && (new_hostescalation->name = (char *)strdup(temp_hostescalation->name)) == NULL) + error = TRUE; + if(temp_hostescalation->contact_groups != NULL && (new_hostescalation->contact_groups = (char *)strdup(temp_hostescalation->contact_groups)) == NULL) + error = TRUE; + if(temp_hostescalation->contacts != NULL && (new_hostescalation->contacts = (char *)strdup(temp_hostescalation->contacts)) == NULL) + error = TRUE; + if(temp_hostescalation->escalation_period != NULL && (new_hostescalation->escalation_period = (char *)strdup(temp_hostescalation->escalation_period)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_hostescalation->escalation_period); + my_free(new_hostescalation->contact_groups); + my_free(new_hostescalation->contacts); + my_free(new_hostescalation->host_name); + my_free(new_hostescalation->template); + my_free(new_hostescalation->name); + my_free(new_hostescalation); + return ERROR; + } + + /* duplicate non-string members */ + new_hostescalation->first_notification = temp_hostescalation->first_notification; + new_hostescalation->last_notification = temp_hostescalation->last_notification; + new_hostescalation->have_first_notification = temp_hostescalation->have_first_notification; + new_hostescalation->have_last_notification = temp_hostescalation->have_last_notification; + new_hostescalation->notification_interval = temp_hostescalation->notification_interval; + new_hostescalation->have_notification_interval = temp_hostescalation->have_notification_interval; + new_hostescalation->escalate_on_down = temp_hostescalation->escalate_on_down; + new_hostescalation->escalate_on_unreachable = temp_hostescalation->escalate_on_unreachable; + new_hostescalation->escalate_on_recovery = temp_hostescalation->escalate_on_recovery; + new_hostescalation->have_escalation_options = temp_hostescalation->have_escalation_options; + + /* add new hostescalation to head of list in memory */ + new_hostescalation->next = xodtemplate_hostescalation_list; + xodtemplate_hostescalation_list = new_hostescalation; + + return OK; + } + + + +/* duplicates a service escalation definition (with a new host name and/or service description) */ +int xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation *temp_serviceescalation, char *host_name, char *svc_description) { + xodtemplate_serviceescalation *new_serviceescalation = NULL; + int error = FALSE; + + /* allocate zero'd out memory for a new service escalation definition */ + new_serviceescalation = (xodtemplate_serviceescalation *)calloc(1, sizeof(xodtemplate_serviceescalation)); + if(new_serviceescalation == NULL) + return ERROR; + + /* standard items */ + new_serviceescalation->has_been_resolved = temp_serviceescalation->has_been_resolved; + new_serviceescalation->register_object = temp_serviceescalation->register_object; + new_serviceescalation->_config_file = temp_serviceescalation->_config_file; + new_serviceescalation->_start_line = temp_serviceescalation->_start_line; + + /* string defaults */ + new_serviceescalation->have_servicegroup_name = FALSE; + new_serviceescalation->have_hostgroup_name = FALSE; + new_serviceescalation->have_host_name = (host_name) ? TRUE : FALSE; + new_serviceescalation->have_service_description = (svc_description) ? TRUE : FALSE; + new_serviceescalation->have_contact_groups = temp_serviceescalation->have_contact_groups; + new_serviceescalation->have_contacts = temp_serviceescalation->have_contacts; + new_serviceescalation->have_escalation_period = temp_serviceescalation->have_escalation_period; + + /* allocate memory for and copy string members of serviceescalation definition */ + if(host_name != NULL && (new_serviceescalation->host_name = (char *)strdup(host_name)) == NULL) + error = TRUE; + if(svc_description != NULL && (new_serviceescalation->service_description = (char *)strdup(svc_description)) == NULL) + error = TRUE; + + if(temp_serviceescalation->template != NULL && (new_serviceescalation->template = (char *)strdup(temp_serviceescalation->template)) == NULL) + error = TRUE; + if(temp_serviceescalation->name != NULL && (new_serviceescalation->name = (char *)strdup(temp_serviceescalation->name)) == NULL) + error = TRUE; + if(temp_serviceescalation->contact_groups != NULL && (new_serviceescalation->contact_groups = (char *)strdup(temp_serviceescalation->contact_groups)) == NULL) + error = TRUE; + if(temp_serviceescalation->contacts != NULL && (new_serviceescalation->contacts = (char *)strdup(temp_serviceescalation->contacts)) == NULL) + error = TRUE; + if(temp_serviceescalation->escalation_period != NULL && (new_serviceescalation->escalation_period = (char *)strdup(temp_serviceescalation->escalation_period)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_serviceescalation->host_name); + my_free(new_serviceescalation->service_description); + my_free(new_serviceescalation->contact_groups); + my_free(new_serviceescalation->contacts); + my_free(new_serviceescalation->escalation_period); + my_free(new_serviceescalation->template); + my_free(new_serviceescalation->name); + my_free(new_serviceescalation); + return ERROR; + } + + /* duplicate non-string members */ + new_serviceescalation->first_notification = temp_serviceescalation->first_notification; + new_serviceescalation->last_notification = temp_serviceescalation->last_notification; + new_serviceescalation->have_first_notification = temp_serviceescalation->have_first_notification; + new_serviceescalation->have_last_notification = temp_serviceescalation->have_last_notification; + new_serviceescalation->notification_interval = temp_serviceescalation->notification_interval; + new_serviceescalation->have_notification_interval = temp_serviceescalation->have_notification_interval; + new_serviceescalation->escalate_on_warning = temp_serviceescalation->escalate_on_warning; + new_serviceescalation->escalate_on_unknown = temp_serviceescalation->escalate_on_unknown; + new_serviceescalation->escalate_on_critical = temp_serviceescalation->escalate_on_critical; + new_serviceescalation->escalate_on_recovery = temp_serviceescalation->escalate_on_recovery; + new_serviceescalation->have_escalation_options = temp_serviceescalation->have_escalation_options; + + /* add new serviceescalation to head of list in memory */ + new_serviceescalation->next = xodtemplate_serviceescalation_list; + xodtemplate_serviceescalation_list = new_serviceescalation; + + return OK; + } + + + +/* duplicates a host dependency definition (with master and dependent host names) */ +int xodtemplate_duplicate_hostdependency(xodtemplate_hostdependency *temp_hostdependency, char *master_host_name, char *dependent_host_name) { + xodtemplate_hostdependency *new_hostdependency = NULL; + int error = FALSE; + + /* allocate memory for a new host dependency definition */ + new_hostdependency = (xodtemplate_hostdependency *)calloc(1, sizeof(xodtemplate_hostdependency)); + if(new_hostdependency == NULL) + return ERROR; + + /* standard items */ + new_hostdependency->has_been_resolved = temp_hostdependency->has_been_resolved; + new_hostdependency->register_object = temp_hostdependency->register_object; + new_hostdependency->_config_file = temp_hostdependency->_config_file; + new_hostdependency->_start_line = temp_hostdependency->_start_line; + + /* string defaults */ + new_hostdependency->have_hostgroup_name = FALSE; + new_hostdependency->have_dependent_hostgroup_name = FALSE; + new_hostdependency->have_host_name = temp_hostdependency->have_host_name; + new_hostdependency->have_dependent_host_name = temp_hostdependency->have_dependent_host_name; + new_hostdependency->have_dependency_period = temp_hostdependency->have_dependency_period; + + /* allocate memory for and copy string members of hostdependency definition */ + if(master_host_name != NULL && (new_hostdependency->host_name = (char *)strdup(master_host_name)) == NULL) + error = TRUE; + if(dependent_host_name != NULL && (new_hostdependency->dependent_host_name = (char *)strdup(dependent_host_name)) == NULL) + error = TRUE; + + if(temp_hostdependency->dependency_period != NULL && (new_hostdependency->dependency_period = (char *)strdup(temp_hostdependency->dependency_period)) == NULL) + error = TRUE; + if(temp_hostdependency->template != NULL && (new_hostdependency->template = (char *)strdup(temp_hostdependency->template)) == NULL) + error = TRUE; + if(temp_hostdependency->name != NULL && (new_hostdependency->name = (char *)strdup(temp_hostdependency->name)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_hostdependency->dependent_host_name); + my_free(new_hostdependency->host_name); + my_free(new_hostdependency->template); + my_free(new_hostdependency->name); + my_free(new_hostdependency); + return ERROR; + } + + /* duplicate non-string members */ + new_hostdependency->fail_notify_on_up = temp_hostdependency->fail_notify_on_up; + new_hostdependency->fail_notify_on_down = temp_hostdependency->fail_notify_on_down; + new_hostdependency->fail_notify_on_unreachable = temp_hostdependency->fail_notify_on_unreachable; + new_hostdependency->fail_notify_on_pending = temp_hostdependency->fail_notify_on_pending; + new_hostdependency->have_notification_dependency_options = temp_hostdependency->have_notification_dependency_options; + new_hostdependency->fail_execute_on_up = temp_hostdependency->fail_execute_on_up; + new_hostdependency->fail_execute_on_down = temp_hostdependency->fail_execute_on_down; + new_hostdependency->fail_execute_on_unreachable = temp_hostdependency->fail_execute_on_unreachable; + new_hostdependency->fail_execute_on_pending = temp_hostdependency->fail_execute_on_pending; + new_hostdependency->have_execution_dependency_options = temp_hostdependency->have_execution_dependency_options; + new_hostdependency->inherits_parent = temp_hostdependency->inherits_parent; + new_hostdependency->have_inherits_parent = temp_hostdependency->have_inherits_parent; + + /* add new hostdependency to head of list in memory */ + new_hostdependency->next = xodtemplate_hostdependency_list; + xodtemplate_hostdependency_list = new_hostdependency; + + return OK; + } + + + +/* duplicates a service dependency definition */ +int xodtemplate_duplicate_servicedependency(xodtemplate_servicedependency *temp_servicedependency, char *master_host_name, char *master_service_description, char *master_hostgroup_name, char *master_servicegroup_name, char *dependent_host_name, char *dependent_service_description, char *dependent_hostgroup_name, char *dependent_servicegroup_name) { + xodtemplate_servicedependency *new_servicedependency = NULL; + int error = FALSE; + + /* allocate memory for a new service dependency definition */ + new_servicedependency = (xodtemplate_servicedependency *)calloc(1, sizeof(xodtemplate_servicedependency)); + if(new_servicedependency == NULL) + return ERROR; + + /* standard items */ + new_servicedependency->has_been_resolved = temp_servicedependency->has_been_resolved; + new_servicedependency->register_object = temp_servicedependency->register_object; + new_servicedependency->_config_file = temp_servicedependency->_config_file; + new_servicedependency->_start_line = temp_servicedependency->_start_line; + + /* string defaults */ + new_servicedependency->have_host_name = (master_host_name) ? TRUE : FALSE; + new_servicedependency->have_service_description = (master_service_description) ? TRUE : FALSE; + new_servicedependency->have_hostgroup_name = (master_hostgroup_name) ? TRUE : FALSE; + new_servicedependency->have_servicegroup_name = (master_servicegroup_name) ? TRUE : FALSE; + + new_servicedependency->have_dependent_host_name = (dependent_host_name) ? TRUE : FALSE; + new_servicedependency->have_dependent_service_description = (dependent_service_description) ? TRUE : FALSE; + new_servicedependency->have_dependent_hostgroup_name = (dependent_hostgroup_name) ? TRUE : FALSE; + new_servicedependency->have_dependent_servicegroup_name = (dependent_servicegroup_name) ? TRUE : FALSE; + + new_servicedependency->have_dependency_period = temp_servicedependency->have_dependency_period; + + /* duplicate strings */ + if(master_host_name != NULL && (new_servicedependency->host_name = (char *)strdup(master_host_name)) == NULL) + error = TRUE; + if(master_service_description != NULL && (new_servicedependency->service_description = (char *)strdup(master_service_description)) == NULL) + error = TRUE; + if(master_hostgroup_name != NULL && (new_servicedependency->hostgroup_name = (char *)strdup(master_hostgroup_name)) == NULL) + error = TRUE; + if(master_servicegroup_name != NULL && (new_servicedependency->servicegroup_name = (char *)strdup(master_servicegroup_name)) == NULL) + error = TRUE; + if(dependent_host_name != NULL && (new_servicedependency->dependent_host_name = (char *)strdup(dependent_host_name)) == NULL) + error = TRUE; + if(dependent_service_description != NULL && (new_servicedependency->dependent_service_description = (char *)strdup(dependent_service_description)) == NULL) + error = TRUE; + if(dependent_hostgroup_name != NULL && (new_servicedependency->dependent_hostgroup_name = (char *)strdup(dependent_hostgroup_name)) == NULL) + error = TRUE; + if(dependent_servicegroup_name != NULL && (new_servicedependency->dependent_servicegroup_name = (char *)strdup(dependent_servicegroup_name)) == NULL) + error = TRUE; + + if(temp_servicedependency->dependency_period != NULL && (new_servicedependency->dependency_period = (char *)strdup(temp_servicedependency->dependency_period)) == NULL) + error = TRUE; + if(temp_servicedependency->template != NULL && (new_servicedependency->template = (char *)strdup(temp_servicedependency->template)) == NULL) + error = TRUE; + if(temp_servicedependency->name != NULL && (new_servicedependency->name = (char *)strdup(temp_servicedependency->name)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_servicedependency->host_name); + my_free(new_servicedependency->service_description); + my_free(new_servicedependency->hostgroup_name); + my_free(new_servicedependency->servicegroup_name); + my_free(new_servicedependency->dependent_host_name); + my_free(new_servicedependency->dependent_service_description); + my_free(new_servicedependency->dependent_hostgroup_name); + my_free(new_servicedependency->dependent_servicegroup_name); + my_free(new_servicedependency->dependency_period); + my_free(new_servicedependency->template); + my_free(new_servicedependency->name); + my_free(new_servicedependency); + return ERROR; + } + + /* duplicate non-string members */ + new_servicedependency->fail_notify_on_ok = temp_servicedependency->fail_notify_on_ok; + new_servicedependency->fail_notify_on_unknown = temp_servicedependency->fail_notify_on_unknown; + new_servicedependency->fail_notify_on_warning = temp_servicedependency->fail_notify_on_warning; + new_servicedependency->fail_notify_on_critical = temp_servicedependency->fail_notify_on_critical; + new_servicedependency->fail_notify_on_pending = temp_servicedependency->fail_notify_on_pending; + new_servicedependency->have_notification_dependency_options = temp_servicedependency->have_notification_dependency_options; + new_servicedependency->fail_execute_on_ok = temp_servicedependency->fail_execute_on_ok; + new_servicedependency->fail_execute_on_unknown = temp_servicedependency->fail_execute_on_unknown; + new_servicedependency->fail_execute_on_warning = temp_servicedependency->fail_execute_on_warning; + new_servicedependency->fail_execute_on_critical = temp_servicedependency->fail_execute_on_critical; + new_servicedependency->fail_execute_on_pending = temp_servicedependency->fail_execute_on_pending; + new_servicedependency->have_execution_dependency_options = temp_servicedependency->have_execution_dependency_options; + new_servicedependency->inherits_parent = temp_servicedependency->inherits_parent; + new_servicedependency->have_inherits_parent = temp_servicedependency->have_inherits_parent; + + /* add new servicedependency to head of list in memory */ + new_servicedependency->next = xodtemplate_servicedependency_list; + xodtemplate_servicedependency_list = new_servicedependency; + + return OK; + } + + + +/* duplicates a hostextinfo object definition */ +int xodtemplate_duplicate_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo, char *host_name) { + xodtemplate_hostextinfo *new_hostextinfo = NULL; + int error = FALSE; + + /* allocate zero'd out memory for a new hostextinfo object */ + new_hostextinfo = (xodtemplate_hostextinfo *)calloc(1, sizeof(xodtemplate_hostextinfo)); + if(new_hostextinfo == NULL) + return ERROR; + + /* standard items */ + new_hostextinfo->has_been_resolved = this_hostextinfo->has_been_resolved; + new_hostextinfo->register_object = this_hostextinfo->register_object; + new_hostextinfo->_config_file = this_hostextinfo->_config_file; + new_hostextinfo->_start_line = this_hostextinfo->_start_line; + + /* string defaults */ + new_hostextinfo->have_host_name = this_hostextinfo->have_host_name; + new_hostextinfo->have_hostgroup_name = this_hostextinfo->have_hostgroup_name; + new_hostextinfo->have_notes = this_hostextinfo->have_notes; + new_hostextinfo->have_notes_url = this_hostextinfo->have_notes_url; + new_hostextinfo->have_action_url = this_hostextinfo->have_action_url; + new_hostextinfo->have_icon_image = this_hostextinfo->have_icon_image; + new_hostextinfo->have_icon_image_alt = this_hostextinfo->have_icon_image_alt; + new_hostextinfo->have_vrml_image = this_hostextinfo->have_vrml_image; + new_hostextinfo->have_statusmap_image = this_hostextinfo->have_statusmap_image; + + /* duplicate strings (host_name member is passed in) */ + if(host_name != NULL && (new_hostextinfo->host_name = (char *)strdup(host_name)) == NULL) + error = TRUE; + if(this_hostextinfo->template != NULL && (new_hostextinfo->template = (char *)strdup(this_hostextinfo->template)) == NULL) + error = TRUE; + if(this_hostextinfo->name != NULL && (new_hostextinfo->name = (char *)strdup(this_hostextinfo->name)) == NULL) + error = TRUE; + if(this_hostextinfo->notes != NULL && (new_hostextinfo->notes = (char *)strdup(this_hostextinfo->notes)) == NULL) + error = TRUE; + if(this_hostextinfo->notes_url != NULL && (new_hostextinfo->notes_url = (char *)strdup(this_hostextinfo->notes_url)) == NULL) + error = TRUE; + if(this_hostextinfo->action_url != NULL && (new_hostextinfo->action_url = (char *)strdup(this_hostextinfo->action_url)) == NULL) + error = TRUE; + if(this_hostextinfo->icon_image != NULL && (new_hostextinfo->icon_image = (char *)strdup(this_hostextinfo->icon_image)) == NULL) + error = TRUE; + if(this_hostextinfo->icon_image_alt != NULL && (new_hostextinfo->icon_image_alt = (char *)strdup(this_hostextinfo->icon_image_alt)) == NULL) + error = TRUE; + if(this_hostextinfo->vrml_image != NULL && (new_hostextinfo->vrml_image = (char *)strdup(this_hostextinfo->vrml_image)) == NULL) + error = TRUE; + if(this_hostextinfo->statusmap_image != NULL && (new_hostextinfo->statusmap_image = (char *)strdup(this_hostextinfo->statusmap_image)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_hostextinfo->host_name); + my_free(new_hostextinfo->template); + my_free(new_hostextinfo->name); + my_free(new_hostextinfo->notes); + my_free(new_hostextinfo->notes_url); + my_free(new_hostextinfo->action_url); + my_free(new_hostextinfo->icon_image); + my_free(new_hostextinfo->icon_image_alt); + my_free(new_hostextinfo->vrml_image); + my_free(new_hostextinfo->statusmap_image); + my_free(new_hostextinfo); + return ERROR; + } + + /* duplicate non-string members */ + new_hostextinfo->x_2d = this_hostextinfo->x_2d; + new_hostextinfo->y_2d = this_hostextinfo->y_2d; + new_hostextinfo->have_2d_coords = this_hostextinfo->have_2d_coords; + new_hostextinfo->x_3d = this_hostextinfo->x_3d; + new_hostextinfo->y_3d = this_hostextinfo->y_3d; + new_hostextinfo->z_3d = this_hostextinfo->z_3d; + new_hostextinfo->have_3d_coords = this_hostextinfo->have_3d_coords; + + /* add new object to head of list */ + new_hostextinfo->next = xodtemplate_hostextinfo_list; + xodtemplate_hostextinfo_list = new_hostextinfo; + + return OK; + } + + + +/* duplicates a serviceextinfo object definition */ +int xodtemplate_duplicate_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo, char *host_name) { + xodtemplate_serviceextinfo *new_serviceextinfo = NULL; + int error = FALSE; + + /* allocate zero'd out object for a new serviceextinfo object */ + new_serviceextinfo = (xodtemplate_serviceextinfo *)calloc(1, sizeof(xodtemplate_serviceextinfo)); + if(new_serviceextinfo == NULL) + return ERROR; + + /* standard items */ + new_serviceextinfo->has_been_resolved = this_serviceextinfo->has_been_resolved; + new_serviceextinfo->register_object = this_serviceextinfo->register_object; + new_serviceextinfo->_config_file = this_serviceextinfo->_config_file; + new_serviceextinfo->_start_line = this_serviceextinfo->_start_line; + + /* string defaults */ + new_serviceextinfo->have_host_name = this_serviceextinfo->have_host_name; + new_serviceextinfo->have_service_description = this_serviceextinfo->have_service_description; + new_serviceextinfo->have_hostgroup_name = this_serviceextinfo->have_hostgroup_name; + new_serviceextinfo->have_notes = this_serviceextinfo->have_notes; + new_serviceextinfo->have_notes_url = this_serviceextinfo->have_notes_url; + new_serviceextinfo->have_action_url = this_serviceextinfo->have_action_url; + new_serviceextinfo->have_icon_image = this_serviceextinfo->have_icon_image; + new_serviceextinfo->have_icon_image_alt = this_serviceextinfo->have_icon_image_alt; + + /* duplicate strings (host_name member is passed in) */ + if(host_name != NULL && (new_serviceextinfo->host_name = (char *)strdup(host_name)) == NULL) + error = TRUE; + if(this_serviceextinfo->template != NULL && (new_serviceextinfo->template = (char *)strdup(this_serviceextinfo->template)) == NULL) + error = TRUE; + if(this_serviceextinfo->name != NULL && (new_serviceextinfo->name = (char *)strdup(this_serviceextinfo->name)) == NULL) + error = TRUE; + if(this_serviceextinfo->service_description != NULL && (new_serviceextinfo->service_description = (char *)strdup(this_serviceextinfo->service_description)) == NULL) + error = TRUE; + if(this_serviceextinfo->notes != NULL && (new_serviceextinfo->notes = (char *)strdup(this_serviceextinfo->notes)) == NULL) + error = TRUE; + if(this_serviceextinfo->notes_url != NULL && (new_serviceextinfo->notes_url = (char *)strdup(this_serviceextinfo->notes_url)) == NULL) + error = TRUE; + if(this_serviceextinfo->action_url != NULL && (new_serviceextinfo->action_url = (char *)strdup(this_serviceextinfo->action_url)) == NULL) + error = TRUE; + if(this_serviceextinfo->icon_image != NULL && (new_serviceextinfo->icon_image = (char *)strdup(this_serviceextinfo->icon_image)) == NULL) + error = TRUE; + if(this_serviceextinfo->icon_image_alt != NULL && (new_serviceextinfo->icon_image_alt = (char *)strdup(this_serviceextinfo->icon_image_alt)) == NULL) + error = TRUE; + + if(error == TRUE) { + my_free(new_serviceextinfo->host_name); + my_free(new_serviceextinfo->template); + my_free(new_serviceextinfo->name); + my_free(new_serviceextinfo->service_description); + my_free(new_serviceextinfo->notes); + my_free(new_serviceextinfo->notes_url); + my_free(new_serviceextinfo->action_url); + my_free(new_serviceextinfo->icon_image); + my_free(new_serviceextinfo->icon_image_alt); + my_free(new_serviceextinfo); + return ERROR; + } + + /* add new object to head of list */ + new_serviceextinfo->next = xodtemplate_serviceextinfo_list; + xodtemplate_serviceextinfo_list = new_serviceextinfo; + + return OK; + } + +#endif + + +/******************************************************************/ +/***************** OBJECT RESOLUTION FUNCTIONS ********************/ +/******************************************************************/ + +#ifdef NSCORE + +/* inherit object properties */ +/* some missing defaults (notification options, etc.) are also applied here */ +int xodtemplate_inherit_object_properties(void) { + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + + + /* fill in missing defaults for hosts... */ + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* if notification options are missing, assume all */ + if(temp_host->have_notification_options == FALSE) { + temp_host->notify_on_down = TRUE; + temp_host->notify_on_unreachable = TRUE; + temp_host->notify_on_recovery = TRUE; + temp_host->notify_on_flapping = TRUE; + temp_host->notify_on_downtime = TRUE; + temp_host->have_notification_options = TRUE; + } + } + + /* services inherit some properties from their associated host... */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* find the host */ + if((temp_host = xodtemplate_find_real_host(temp_service->host_name)) == NULL) + continue; + + /* services inherit contact groups from host if not already specified */ + if(temp_service->have_contact_groups == FALSE && temp_host->have_contact_groups == TRUE && temp_host->contact_groups != NULL) { + temp_service->contact_groups = (char *)strdup(temp_host->contact_groups); + temp_service->have_contact_groups = TRUE; + } + + /* services inherit contacts from host if not already specified */ + if(temp_service->have_contacts == FALSE && temp_host->have_contacts == TRUE && temp_host->contacts != NULL) { + temp_service->contacts = (char *)strdup(temp_host->contacts); + temp_service->have_contacts = TRUE; + } + + /* services inherit notification interval from host if not already specified */ + if(temp_service->have_notification_interval == FALSE && temp_host->have_notification_interval == TRUE) { + temp_service->notification_interval = temp_host->notification_interval; + temp_service->have_notification_interval = TRUE; + } + + /* services inherit notification period from host if not already specified */ + if(temp_service->have_notification_period == FALSE && temp_host->have_notification_period == TRUE && temp_host->notification_period != NULL) { + temp_service->notification_period = (char *)strdup(temp_host->notification_period); + temp_service->have_notification_period = TRUE; + } + + /* if notification options are missing, assume all */ + if(temp_service->have_notification_options == FALSE) { + temp_service->notify_on_unknown = TRUE; + temp_service->notify_on_warning = TRUE; + temp_service->notify_on_critical = TRUE; + temp_service->notify_on_recovery = TRUE; + temp_service->notify_on_flapping = TRUE; + temp_service->notify_on_downtime = TRUE; + temp_service->have_notification_options = TRUE; + } + } + + /* service escalations inherit some properties from their associated service... */ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + + /* find the service */ + if((temp_service = xodtemplate_find_real_service(temp_serviceescalation->host_name, temp_serviceescalation->service_description)) == NULL) + continue; + + /* service escalations inherit contact groups from service if not already specified */ + if(temp_serviceescalation->have_contact_groups == FALSE && temp_service->have_contact_groups == TRUE && temp_service->contact_groups != NULL) { + temp_serviceescalation->contact_groups = (char *)strdup(temp_service->contact_groups); + temp_serviceescalation->have_contact_groups = TRUE; + } + + /* SPECIAL RULE 10/04/07 - additive inheritance from service's contactgroup(s) */ + if(temp_serviceescalation->contact_groups != NULL && temp_serviceescalation->contact_groups[0] == '+') + xodtemplate_get_inherited_string(&temp_service->have_contact_groups, &temp_service->contact_groups, &temp_serviceescalation->have_contact_groups, &temp_serviceescalation->contact_groups); + + /* service escalations inherit contacts from service if not already specified */ + if(temp_serviceescalation->have_contacts == FALSE && temp_service->have_contacts == TRUE && temp_service->contacts != NULL) { + temp_serviceescalation->contacts = (char *)strdup(temp_service->contacts); + temp_serviceescalation->have_contacts = TRUE; + } + + /* SPECIAL RULE 10/04/07 - additive inheritance from service's contact(s) */ + if(temp_serviceescalation->contacts != NULL && temp_serviceescalation->contacts[0] == '+') + xodtemplate_get_inherited_string(&temp_service->have_contacts, &temp_service->contacts, &temp_serviceescalation->have_contacts, &temp_serviceescalation->contacts); + + /* service escalations inherit notification interval from service if not already defined */ + if(temp_serviceescalation->have_notification_interval == FALSE && temp_service->have_notification_interval == TRUE) { + temp_serviceescalation->notification_interval = temp_service->notification_interval; + temp_serviceescalation->have_notification_interval = TRUE; + } + + /* service escalations inherit escalation period from service if not already defined */ + if(temp_serviceescalation->have_escalation_period == FALSE && temp_service->have_notification_period == TRUE && temp_service->notification_period != NULL) { + temp_serviceescalation->escalation_period = (char *)strdup(temp_service->notification_period); + temp_serviceescalation->have_escalation_period = TRUE; + } + + /* if escalation options are missing, assume all */ + if(temp_serviceescalation->have_escalation_options == FALSE) { + temp_serviceescalation->escalate_on_unknown = TRUE; + temp_serviceescalation->escalate_on_warning = TRUE; + temp_serviceescalation->escalate_on_critical = TRUE; + temp_serviceescalation->escalate_on_recovery = TRUE; + temp_serviceescalation->have_escalation_options = TRUE; + } + + /* 03/05/08 clear additive string chars - not done in xodtemplate_clean_additive_strings() anymore */ + xodtemplate_clean_additive_string(&temp_serviceescalation->contact_groups); + xodtemplate_clean_additive_string(&temp_serviceescalation->contacts); + } + + /* host escalations inherit some properties from their associated host... */ + for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) { + + /* find the host */ + if((temp_host = xodtemplate_find_real_host(temp_hostescalation->host_name)) == NULL) + continue; + + /* host escalations inherit contact groups from service if not already specified */ + if(temp_hostescalation->have_contact_groups == FALSE && temp_host->have_contact_groups == TRUE && temp_host->contact_groups != NULL) { + temp_hostescalation->contact_groups = (char *)strdup(temp_host->contact_groups); + temp_hostescalation->have_contact_groups = TRUE; + } + + /* SPECIAL RULE 10/04/07 - additive inheritance from host's contactgroup(s) */ + if(temp_hostescalation->contact_groups != NULL && temp_hostescalation->contact_groups[0] == '+') + xodtemplate_get_inherited_string(&temp_host->have_contact_groups, &temp_host->contact_groups, &temp_hostescalation->have_contact_groups, &temp_hostescalation->contact_groups); + + /* host escalations inherit contacts from service if not already specified */ + if(temp_hostescalation->have_contacts == FALSE && temp_host->have_contacts == TRUE && temp_host->contacts != NULL) { + temp_hostescalation->contacts = (char *)strdup(temp_host->contacts); + temp_hostescalation->have_contacts = TRUE; + } + + /* SPECIAL RULE 10/04/07 - additive inheritance from host's contact(s) */ + if(temp_hostescalation->contacts != NULL && temp_hostescalation->contacts[0] == '+') + xodtemplate_get_inherited_string(&temp_host->have_contacts, &temp_host->contacts, &temp_hostescalation->have_contacts, &temp_hostescalation->contacts); + + /* host escalations inherit notification interval from host if not already defined */ + if(temp_hostescalation->have_notification_interval == FALSE && temp_host->have_notification_interval == TRUE) { + temp_hostescalation->notification_interval = temp_host->notification_interval; + temp_hostescalation->have_notification_interval = TRUE; + } + + /* host escalations inherit escalation period from host if not already defined */ + if(temp_hostescalation->have_escalation_period == FALSE && temp_host->have_notification_period == TRUE && temp_host->notification_period != NULL) { + temp_hostescalation->escalation_period = (char *)strdup(temp_host->notification_period); + temp_hostescalation->have_escalation_period = TRUE; + } + + /* if escalation options are missing, assume all */ + if(temp_hostescalation->have_escalation_options == FALSE) { + temp_hostescalation->escalate_on_down = TRUE; + temp_hostescalation->escalate_on_unreachable = TRUE; + temp_hostescalation->escalate_on_recovery = TRUE; + temp_hostescalation->have_escalation_options = TRUE; + } + + /* 03/05/08 clear additive string chars - not done in xodtemplate_clean_additive_strings() anymore */ + xodtemplate_clean_additive_string(&temp_hostescalation->contact_groups); + xodtemplate_clean_additive_string(&temp_hostescalation->contacts); + } + + return OK; + } + +#endif + + +/******************************************************************/ +/***************** OBJECT RESOLUTION FUNCTIONS ********************/ +/******************************************************************/ + +#ifdef NSCORE + +/* resolves object definitions */ +int xodtemplate_resolve_objects(void) { + xodtemplate_timeperiod *temp_timeperiod = NULL; + xodtemplate_command *temp_command = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_contact *temp_contact = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + xodtemplate_hostextinfo *temp_hostextinfo = NULL; + xodtemplate_serviceextinfo *temp_serviceextinfo = NULL; + + /* resolve all timeperiod objects */ + for(temp_timeperiod = xodtemplate_timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) { + if(xodtemplate_resolve_timeperiod(temp_timeperiod) == ERROR) + return ERROR; + } + + /* resolve all command objects */ + for(temp_command = xodtemplate_command_list; temp_command != NULL; temp_command = temp_command->next) { + if(xodtemplate_resolve_command(temp_command) == ERROR) + return ERROR; + } + + /* resolve all contactgroup objects */ + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + if(xodtemplate_resolve_contactgroup(temp_contactgroup) == ERROR) + return ERROR; + } + + /* resolve all hostgroup objects */ + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + if(xodtemplate_resolve_hostgroup(temp_hostgroup) == ERROR) + return ERROR; + } + + /* resolve all servicegroup objects */ + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + if(xodtemplate_resolve_servicegroup(temp_servicegroup) == ERROR) + return ERROR; + } + + /* resolve all servicedependency objects */ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + if(xodtemplate_resolve_servicedependency(temp_servicedependency) == ERROR) + return ERROR; + } + + /* resolve all serviceescalation objects */ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + if(xodtemplate_resolve_serviceescalation(temp_serviceescalation) == ERROR) + return ERROR; + } + + /* resolve all contact objects */ + for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + if(xodtemplate_resolve_contact(temp_contact) == ERROR) + return ERROR; + } + + /* resolve all host objects */ + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) { + if(xodtemplate_resolve_host(temp_host) == ERROR) + return ERROR; + } + + /* resolve all service objects */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + if(xodtemplate_resolve_service(temp_service) == ERROR) + return ERROR; + } + + /* resolve all hostdependency objects */ + for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) { + if(xodtemplate_resolve_hostdependency(temp_hostdependency) == ERROR) + return ERROR; + } + + /* resolve all hostescalation objects */ + for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) { + if(xodtemplate_resolve_hostescalation(temp_hostescalation) == ERROR) + return ERROR; + } + + /* resolve all hostextinfo objects */ + for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) { + if(xodtemplate_resolve_hostextinfo(temp_hostextinfo) == ERROR) + return ERROR; + } + + /* resolve all serviceextinfo objects */ + for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) { + if(xodtemplate_resolve_serviceextinfo(temp_serviceextinfo) == ERROR) + return ERROR; + } + + return OK; + } + + + +/* resolves a timeperiod object */ +int xodtemplate_resolve_timeperiod(xodtemplate_timeperiod *this_timeperiod) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_daterange *template_daterange = NULL; + xodtemplate_daterange *this_daterange = NULL; + xodtemplate_daterange *new_daterange = NULL; + xodtemplate_timeperiod *template_timeperiod = NULL; + int x; + + /* return if this timeperiod has already been resolved */ + if(this_timeperiod->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_timeperiod->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_timeperiod->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_timeperiod->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_timeperiod = xodtemplate_find_timeperiod(temp_ptr); + if(template_timeperiod == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in timeperiod definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template timeperiod... */ + xodtemplate_resolve_timeperiod(template_timeperiod); + + /* apply missing properties from template timeperiod... */ + if(this_timeperiod->timeperiod_name == NULL && template_timeperiod->timeperiod_name != NULL) + this_timeperiod->timeperiod_name = (char *)strdup(template_timeperiod->timeperiod_name); + if(this_timeperiod->alias == NULL && template_timeperiod->alias != NULL) + this_timeperiod->alias = (char *)strdup(template_timeperiod->alias); + if(this_timeperiod->exclusions == NULL && template_timeperiod->exclusions != NULL) + this_timeperiod->exclusions = (char *)strdup(template_timeperiod->exclusions); + for(x = 0; x < 7; x++) { + if(this_timeperiod->timeranges[x] == NULL && template_timeperiod->timeranges[x] != NULL) { + this_timeperiod->timeranges[x] = (char *)strdup(template_timeperiod->timeranges[x]); + } + } + /* daterange exceptions require more work to apply missing ranges... */ + for(x = 0; x < DATERANGE_TYPES; x++) { + for(template_daterange = template_timeperiod->exceptions[x]; template_daterange != NULL; template_daterange = template_daterange->next) { + + /* see if this same daterange already exists in the timeperiod */ + for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = this_daterange->next) { + if((this_daterange->type == template_daterange->type) && (this_daterange->syear == template_daterange->syear) && (this_daterange->smon == template_daterange->smon) && (this_daterange->smday == template_daterange->smday) && (this_daterange->swday == template_daterange->swday) && (this_daterange->swday_offset == template_daterange->swday_offset) && (this_daterange->eyear == template_daterange->eyear) && (this_daterange->emon == template_daterange->emon) && (this_daterange->emday == template_daterange->emday) && (this_daterange->ewday == template_daterange->ewday) && (this_daterange->ewday_offset == template_daterange->ewday_offset) && (this_daterange->skip_interval == template_daterange->skip_interval)) + break; + } + + /* this daterange already exists in the timeperiod, so don't inherit it */ + if(this_daterange != NULL) + continue; + + /* inherit the daterange from the template */ + if((new_daterange = (xodtemplate_daterange *)malloc(sizeof(xodtemplate_daterange))) == NULL) + continue; + new_daterange->type = template_daterange->type; + new_daterange->syear = template_daterange->syear; + new_daterange->smon = template_daterange->smon; + new_daterange->smday = template_daterange->smday; + new_daterange->swday = template_daterange->swday; + new_daterange->swday_offset = template_daterange->swday_offset; + new_daterange->eyear = template_daterange->eyear; + new_daterange->emon = template_daterange->emon; + new_daterange->emday = template_daterange->emday; + new_daterange->ewday = template_daterange->ewday; + new_daterange->ewday_offset = template_daterange->ewday_offset; + new_daterange->skip_interval = template_daterange->skip_interval; + new_daterange->timeranges = NULL; + if(template_daterange->timeranges != NULL) + new_daterange->timeranges = (char *)strdup(template_daterange->timeranges); + + /* add new daterange to head of list (should it be added to the end instead?) */ + new_daterange->next = this_timeperiod->exceptions[x]; + this_timeperiod->exceptions[x] = new_daterange; + } + } + } + + my_free(template_names); + + return OK; + } + + + + +/* resolves a command object */ +int xodtemplate_resolve_command(xodtemplate_command *this_command) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_command *template_command = NULL; + + /* return if this command has already been resolved */ + if(this_command->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_command->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_command->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_command->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_command = xodtemplate_find_command(temp_ptr); + if(template_command == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in command definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_command->_config_file), this_command->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template command... */ + xodtemplate_resolve_command(template_command); + + /* apply missing properties from template command... */ + if(this_command->command_name == NULL && template_command->command_name != NULL) + this_command->command_name = (char *)strdup(template_command->command_name); + if(this_command->command_line == NULL && template_command->command_line != NULL) + this_command->command_line = (char *)strdup(template_command->command_line); + } + + my_free(template_names); + + return OK; + } + + + + +/* resolves a contactgroup object */ +int xodtemplate_resolve_contactgroup(xodtemplate_contactgroup *this_contactgroup) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_contactgroup *template_contactgroup = NULL; + + /* return if this contactgroup has already been resolved */ + if(this_contactgroup->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_contactgroup->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_contactgroup->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_contactgroup->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_contactgroup = xodtemplate_find_contactgroup(temp_ptr); + if(template_contactgroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in contactgroup definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template contactgroup... */ + xodtemplate_resolve_contactgroup(template_contactgroup); + + /* apply missing properties from template contactgroup... */ + if(this_contactgroup->contactgroup_name == NULL && template_contactgroup->contactgroup_name != NULL) + this_contactgroup->contactgroup_name = (char *)strdup(template_contactgroup->contactgroup_name); + if(this_contactgroup->alias == NULL && template_contactgroup->alias != NULL) + this_contactgroup->alias = (char *)strdup(template_contactgroup->alias); + + xodtemplate_get_inherited_string(&template_contactgroup->have_members, &template_contactgroup->members, &this_contactgroup->have_members, &this_contactgroup->members); + xodtemplate_get_inherited_string(&template_contactgroup->have_contactgroup_members, &template_contactgroup->contactgroup_members, &this_contactgroup->have_contactgroup_members, &this_contactgroup->contactgroup_members); + + } + + my_free(template_names); + + return OK; + } + + + + +/* resolves a hostgroup object */ +int xodtemplate_resolve_hostgroup(xodtemplate_hostgroup *this_hostgroup) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_hostgroup *template_hostgroup = NULL; + + /* return if this hostgroup has already been resolved */ + if(this_hostgroup->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_hostgroup->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_hostgroup->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_hostgroup->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_hostgroup = xodtemplate_find_hostgroup(temp_ptr); + if(template_hostgroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in hostgroup definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template hostgroup... */ + xodtemplate_resolve_hostgroup(template_hostgroup); + + /* apply missing properties from template hostgroup... */ + if(this_hostgroup->hostgroup_name == NULL && template_hostgroup->hostgroup_name != NULL) + this_hostgroup->hostgroup_name = (char *)strdup(template_hostgroup->hostgroup_name); + if(this_hostgroup->alias == NULL && template_hostgroup->alias != NULL) + this_hostgroup->alias = (char *)strdup(template_hostgroup->alias); + + xodtemplate_get_inherited_string(&template_hostgroup->have_members, &template_hostgroup->members, &this_hostgroup->have_members, &this_hostgroup->members); + xodtemplate_get_inherited_string(&template_hostgroup->have_hostgroup_members, &template_hostgroup->hostgroup_members, &this_hostgroup->have_hostgroup_members, &this_hostgroup->hostgroup_members); + + if(this_hostgroup->have_notes == FALSE && template_hostgroup->have_notes == TRUE) { + if(this_hostgroup->notes == NULL && template_hostgroup->notes != NULL) + this_hostgroup->notes = (char *)strdup(template_hostgroup->notes); + this_hostgroup->have_notes = TRUE; + } + if(this_hostgroup->have_notes_url == FALSE && template_hostgroup->have_notes_url == TRUE) { + if(this_hostgroup->notes_url == NULL && template_hostgroup->notes_url != NULL) + this_hostgroup->notes_url = (char *)strdup(template_hostgroup->notes_url); + this_hostgroup->have_notes_url = TRUE; + } + if(this_hostgroup->have_action_url == FALSE && template_hostgroup->have_action_url == TRUE) { + if(this_hostgroup->action_url == NULL && template_hostgroup->action_url != NULL) + this_hostgroup->action_url = (char *)strdup(template_hostgroup->action_url); + this_hostgroup->have_action_url = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + + + +/* resolves a servicegroup object */ +int xodtemplate_resolve_servicegroup(xodtemplate_servicegroup *this_servicegroup) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_servicegroup *template_servicegroup = NULL; + + /* return if this servicegroup has already been resolved */ + if(this_servicegroup->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_servicegroup->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_servicegroup->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_servicegroup->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_servicegroup = xodtemplate_find_servicegroup(temp_ptr); + if(template_servicegroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in servicegroup definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template servicegroup... */ + xodtemplate_resolve_servicegroup(template_servicegroup); + + /* apply missing properties from template servicegroup... */ + if(this_servicegroup->servicegroup_name == NULL && template_servicegroup->servicegroup_name != NULL) + this_servicegroup->servicegroup_name = (char *)strdup(template_servicegroup->servicegroup_name); + if(this_servicegroup->alias == NULL && template_servicegroup->alias != NULL) + this_servicegroup->alias = (char *)strdup(template_servicegroup->alias); + + xodtemplate_get_inherited_string(&template_servicegroup->have_members, &template_servicegroup->members, &this_servicegroup->have_members, &this_servicegroup->members); + xodtemplate_get_inherited_string(&template_servicegroup->have_servicegroup_members, &template_servicegroup->servicegroup_members, &this_servicegroup->have_servicegroup_members, &this_servicegroup->servicegroup_members); + + if(this_servicegroup->have_notes == FALSE && template_servicegroup->have_notes == TRUE) { + if(this_servicegroup->notes == NULL && template_servicegroup->notes != NULL) + this_servicegroup->notes = (char *)strdup(template_servicegroup->notes); + this_servicegroup->have_notes = TRUE; + } + if(this_servicegroup->have_notes_url == FALSE && template_servicegroup->have_notes_url == TRUE) { + if(this_servicegroup->notes_url == NULL && template_servicegroup->notes_url != NULL) + this_servicegroup->notes_url = (char *)strdup(template_servicegroup->notes_url); + this_servicegroup->have_notes_url = TRUE; + } + if(this_servicegroup->have_action_url == FALSE && template_servicegroup->have_action_url == TRUE) { + if(this_servicegroup->action_url == NULL && template_servicegroup->action_url != NULL) + this_servicegroup->action_url = (char *)strdup(template_servicegroup->action_url); + this_servicegroup->have_action_url = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + +/* resolves a servicedependency object */ +int xodtemplate_resolve_servicedependency(xodtemplate_servicedependency *this_servicedependency) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_servicedependency *template_servicedependency = NULL; + + /* return if this servicedependency has already been resolved */ + if(this_servicedependency->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_servicedependency->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_servicedependency->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_servicedependency->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_servicedependency = xodtemplate_find_servicedependency(temp_ptr); + if(template_servicedependency == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in service dependency definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template servicedependency... */ + xodtemplate_resolve_servicedependency(template_servicedependency); + + /* apply missing properties from template servicedependency... */ + xodtemplate_get_inherited_string(&template_servicedependency->have_servicegroup_name, &template_servicedependency->servicegroup_name, &this_servicedependency->have_servicegroup_name, &this_servicedependency->servicegroup_name); + xodtemplate_get_inherited_string(&template_servicedependency->have_hostgroup_name, &template_servicedependency->hostgroup_name, &this_servicedependency->have_hostgroup_name, &this_servicedependency->hostgroup_name); + xodtemplate_get_inherited_string(&template_servicedependency->have_host_name, &template_servicedependency->host_name, &this_servicedependency->have_host_name, &this_servicedependency->host_name); + xodtemplate_get_inherited_string(&template_servicedependency->have_service_description, &template_servicedependency->service_description, &this_servicedependency->have_service_description, &this_servicedependency->service_description); + xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_servicegroup_name, &template_servicedependency->dependent_servicegroup_name, &this_servicedependency->have_dependent_servicegroup_name, &this_servicedependency->dependent_servicegroup_name); + xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_hostgroup_name, &template_servicedependency->dependent_hostgroup_name, &this_servicedependency->have_dependent_hostgroup_name, &this_servicedependency->dependent_hostgroup_name); + xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_host_name, &template_servicedependency->dependent_host_name, &this_servicedependency->have_dependent_host_name, &this_servicedependency->dependent_host_name); + xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_service_description, &template_servicedependency->dependent_service_description, &this_servicedependency->have_dependent_service_description, &this_servicedependency->dependent_service_description); + + if(this_servicedependency->have_dependency_period == FALSE && template_servicedependency->have_dependency_period == TRUE) { + if(this_servicedependency->dependency_period == NULL && template_servicedependency->dependency_period != NULL) + this_servicedependency->dependency_period = (char *)strdup(template_servicedependency->dependency_period); + this_servicedependency->have_dependency_period = TRUE; + } + if(this_servicedependency->have_inherits_parent == FALSE && template_servicedependency->have_inherits_parent == TRUE) { + this_servicedependency->inherits_parent = template_servicedependency->inherits_parent; + this_servicedependency->have_inherits_parent = TRUE; + } + if(this_servicedependency->have_execution_dependency_options == FALSE && template_servicedependency->have_execution_dependency_options == TRUE) { + this_servicedependency->fail_execute_on_ok = template_servicedependency->fail_execute_on_ok; + this_servicedependency->fail_execute_on_unknown = template_servicedependency->fail_execute_on_unknown; + this_servicedependency->fail_execute_on_warning = template_servicedependency->fail_execute_on_warning; + this_servicedependency->fail_execute_on_critical = template_servicedependency->fail_execute_on_critical; + this_servicedependency->fail_execute_on_pending = template_servicedependency->fail_execute_on_pending; + this_servicedependency->have_execution_dependency_options = TRUE; + } + if(this_servicedependency->have_notification_dependency_options == FALSE && template_servicedependency->have_notification_dependency_options == TRUE) { + this_servicedependency->fail_notify_on_ok = template_servicedependency->fail_notify_on_ok; + this_servicedependency->fail_notify_on_unknown = template_servicedependency->fail_notify_on_unknown; + this_servicedependency->fail_notify_on_warning = template_servicedependency->fail_notify_on_warning; + this_servicedependency->fail_notify_on_critical = template_servicedependency->fail_notify_on_critical; + this_servicedependency->fail_notify_on_pending = template_servicedependency->fail_notify_on_pending; + this_servicedependency->have_notification_dependency_options = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + +/* resolves a serviceescalation object */ +int xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_serviceescalation *template_serviceescalation = NULL; + + /* return if this serviceescalation has already been resolved */ + if(this_serviceescalation->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_serviceescalation->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_serviceescalation->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_serviceescalation->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_serviceescalation = xodtemplate_find_serviceescalation(temp_ptr); + if(template_serviceescalation == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in service escalation definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template serviceescalation... */ + xodtemplate_resolve_serviceescalation(template_serviceescalation); + + /* apply missing properties from template serviceescalation... */ + xodtemplate_get_inherited_string(&template_serviceescalation->have_servicegroup_name, &template_serviceescalation->servicegroup_name, &this_serviceescalation->have_servicegroup_name, &this_serviceescalation->servicegroup_name); + xodtemplate_get_inherited_string(&template_serviceescalation->have_hostgroup_name, &template_serviceescalation->hostgroup_name, &this_serviceescalation->have_hostgroup_name, &this_serviceescalation->hostgroup_name); + xodtemplate_get_inherited_string(&template_serviceescalation->have_host_name, &template_serviceescalation->host_name, &this_serviceescalation->have_host_name, &this_serviceescalation->host_name); + xodtemplate_get_inherited_string(&template_serviceescalation->have_service_description, &template_serviceescalation->service_description, &this_serviceescalation->have_service_description, &this_serviceescalation->service_description); + xodtemplate_get_inherited_string(&template_serviceescalation->have_contact_groups, &template_serviceescalation->contact_groups, &this_serviceescalation->have_contact_groups, &this_serviceescalation->contact_groups); + xodtemplate_get_inherited_string(&template_serviceescalation->have_contacts, &template_serviceescalation->contacts, &this_serviceescalation->have_contacts, &this_serviceescalation->contacts); + + if(this_serviceescalation->have_escalation_period == FALSE && template_serviceescalation->have_escalation_period == TRUE) { + if(this_serviceescalation->escalation_period == NULL && template_serviceescalation->escalation_period != NULL) + this_serviceescalation->escalation_period = (char *)strdup(template_serviceescalation->escalation_period); + this_serviceescalation->have_escalation_period = TRUE; + } + if(this_serviceescalation->have_first_notification == FALSE && template_serviceescalation->have_first_notification == TRUE) { + this_serviceescalation->first_notification = template_serviceescalation->first_notification; + this_serviceescalation->have_first_notification = TRUE; + } + if(this_serviceescalation->have_last_notification == FALSE && template_serviceescalation->have_last_notification == TRUE) { + this_serviceescalation->last_notification = template_serviceescalation->last_notification; + this_serviceescalation->have_last_notification = TRUE; + } + if(this_serviceescalation->have_notification_interval == FALSE && template_serviceescalation->have_notification_interval == TRUE) { + this_serviceescalation->notification_interval = template_serviceescalation->notification_interval; + this_serviceescalation->have_notification_interval = TRUE; + } + if(this_serviceescalation->have_escalation_options == FALSE && template_serviceescalation->have_escalation_options == TRUE) { + this_serviceescalation->escalate_on_warning = template_serviceescalation->escalate_on_warning; + this_serviceescalation->escalate_on_unknown = template_serviceescalation->escalate_on_unknown; + this_serviceescalation->escalate_on_critical = template_serviceescalation->escalate_on_critical; + this_serviceescalation->escalate_on_recovery = template_serviceescalation->escalate_on_recovery; + this_serviceescalation->have_escalation_options = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + + +/* resolves a contact object */ +int xodtemplate_resolve_contact(xodtemplate_contact *this_contact) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_contact *template_contact = NULL; + xodtemplate_customvariablesmember *this_customvariablesmember = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + int x; + + /* return if this contact has already been resolved */ + if(this_contact->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_contact->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_contact->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_contact->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_contact = xodtemplate_find_contact(temp_ptr); + if(template_contact == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in contact definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template contact... */ + xodtemplate_resolve_contact(template_contact); + + /* apply missing properties from template contact... */ + if(this_contact->contact_name == NULL && template_contact->contact_name != NULL) + this_contact->contact_name = (char *)strdup(template_contact->contact_name); + if(this_contact->alias == NULL && template_contact->alias != NULL) + this_contact->alias = (char *)strdup(template_contact->alias); + + if(this_contact->have_email == FALSE && template_contact->have_email == TRUE) { + if(this_contact->email == NULL && template_contact->email != NULL) + this_contact->email = (char *)strdup(template_contact->email); + this_contact->have_email = TRUE; + } + if(this_contact->have_pager == FALSE && template_contact->have_pager == TRUE) { + if(this_contact->pager == NULL && template_contact->pager != NULL) + this_contact->pager = (char *)strdup(template_contact->pager); + this_contact->have_pager = TRUE; + } + for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++) { + if(this_contact->have_address[x] == FALSE && template_contact->have_address[x] == TRUE) { + if(this_contact->address[x] == NULL && template_contact->address[x] != NULL) + this_contact->address[x] = (char *)strdup(template_contact->address[x]); + this_contact->have_address[x] = TRUE; + } + } + + xodtemplate_get_inherited_string(&template_contact->have_contact_groups, &template_contact->contact_groups, &this_contact->have_contact_groups, &this_contact->contact_groups); + xodtemplate_get_inherited_string(&template_contact->have_host_notification_commands, &template_contact->host_notification_commands, &this_contact->have_host_notification_commands, &this_contact->host_notification_commands); + xodtemplate_get_inherited_string(&template_contact->have_service_notification_commands, &template_contact->service_notification_commands, &this_contact->have_service_notification_commands, &this_contact->service_notification_commands); + + if(this_contact->have_host_notification_period == FALSE && template_contact->have_host_notification_period == TRUE) { + if(this_contact->host_notification_period == NULL && template_contact->host_notification_period != NULL) + this_contact->host_notification_period = (char *)strdup(template_contact->host_notification_period); + this_contact->have_host_notification_period = TRUE; + } + if(this_contact->have_service_notification_period == FALSE && template_contact->have_service_notification_period == TRUE) { + if(this_contact->service_notification_period == NULL && template_contact->service_notification_period != NULL) + this_contact->service_notification_period = (char *)strdup(template_contact->service_notification_period); + this_contact->have_service_notification_period = TRUE; + } + if(this_contact->have_host_notification_options == FALSE && template_contact->have_host_notification_options == TRUE) { + this_contact->notify_on_host_down = template_contact->notify_on_host_down; + this_contact->notify_on_host_unreachable = template_contact->notify_on_host_unreachable; + this_contact->notify_on_host_recovery = template_contact->notify_on_host_recovery; + this_contact->notify_on_host_flapping = template_contact->notify_on_host_flapping; + this_contact->notify_on_host_downtime = template_contact->notify_on_host_downtime; + this_contact->have_host_notification_options = TRUE; + } + if(this_contact->have_service_notification_options == FALSE && template_contact->have_service_notification_options == TRUE) { + this_contact->notify_on_service_unknown = template_contact->notify_on_service_unknown; + this_contact->notify_on_service_warning = template_contact->notify_on_service_warning; + this_contact->notify_on_service_critical = template_contact->notify_on_service_critical; + this_contact->notify_on_service_recovery = template_contact->notify_on_service_recovery; + this_contact->notify_on_service_flapping = template_contact->notify_on_service_flapping; + this_contact->notify_on_service_downtime = template_contact->notify_on_service_downtime; + this_contact->have_service_notification_options = TRUE; + } + if(this_contact->have_host_notifications_enabled == FALSE && template_contact->have_host_notifications_enabled == TRUE) { + this_contact->host_notifications_enabled = template_contact->host_notifications_enabled; + this_contact->have_host_notifications_enabled = TRUE; + } + if(this_contact->have_service_notifications_enabled == FALSE && template_contact->have_service_notifications_enabled == TRUE) { + this_contact->service_notifications_enabled = template_contact->service_notifications_enabled; + this_contact->have_service_notifications_enabled = TRUE; + } + if(this_contact->have_can_submit_commands == FALSE && template_contact->have_can_submit_commands == TRUE) { + this_contact->can_submit_commands = template_contact->can_submit_commands; + this_contact->have_can_submit_commands = TRUE; + } + if(this_contact->have_retain_status_information == FALSE && template_contact->have_retain_status_information == TRUE) { + this_contact->retain_status_information = template_contact->retain_status_information; + this_contact->have_retain_status_information = TRUE; + } + if(this_contact->have_retain_nonstatus_information == FALSE && template_contact->have_retain_nonstatus_information == TRUE) { + this_contact->retain_nonstatus_information = template_contact->retain_nonstatus_information; + this_contact->have_retain_nonstatus_information = TRUE; + } + + /* apply missing custom variables from template contact... */ + for(temp_customvariablesmember = template_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + + /* see if this host has a variable by the same name */ + for(this_customvariablesmember = this_contact->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) { + if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name)) + break; + } + + /* we didn't find the same variable name, so add a new custom variable */ + if(this_customvariablesmember == NULL) + xodtemplate_add_custom_variable_to_contact(this_contact, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value); + } + } + + my_free(template_names); + + return OK; + } + + + +/* resolves a host object */ +int xodtemplate_resolve_host(xodtemplate_host *this_host) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_host *template_host = NULL; + xodtemplate_customvariablesmember *this_customvariablesmember = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + + /* return if this host has already been resolved */ + if(this_host->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_host->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_host->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_host->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_host = xodtemplate_find_host(temp_ptr); + if(template_host == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in host definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template host... */ + xodtemplate_resolve_host(template_host); + + /* apply missing properties from template host... */ + if(this_host->host_name == NULL && template_host->host_name != NULL) + this_host->host_name = (char *)strdup(template_host->host_name); + if(this_host->have_display_name == FALSE && template_host->have_display_name == TRUE) { + if(this_host->display_name == NULL && template_host->display_name != NULL) + this_host->display_name = (char *)strdup(template_host->display_name); + this_host->have_display_name = TRUE; + } + if(this_host->alias == NULL && template_host->alias != NULL) + this_host->alias = (char *)strdup(template_host->alias); + if(this_host->address == NULL && template_host->address != NULL) + this_host->address = (char *)strdup(template_host->address); + + xodtemplate_get_inherited_string(&template_host->have_parents, &template_host->parents, &this_host->have_parents, &this_host->parents); + xodtemplate_get_inherited_string(&template_host->have_host_groups, &template_host->host_groups, &this_host->have_host_groups, &this_host->host_groups); + xodtemplate_get_inherited_string(&template_host->have_contact_groups, &template_host->contact_groups, &this_host->have_contact_groups, &this_host->contact_groups); + xodtemplate_get_inherited_string(&template_host->have_contacts, &template_host->contacts, &this_host->have_contacts, &this_host->contacts); + + if(this_host->have_check_command == FALSE && template_host->have_check_command == TRUE) { + if(this_host->check_command == NULL && template_host->check_command != NULL) + this_host->check_command = (char *)strdup(template_host->check_command); + this_host->have_check_command = TRUE; + } + if(this_host->have_check_period == FALSE && template_host->have_check_period == TRUE) { + if(this_host->check_period == NULL && template_host->check_period != NULL) + this_host->check_period = (char *)strdup(template_host->check_period); + this_host->have_check_period = TRUE; + } + if(this_host->have_event_handler == FALSE && template_host->have_event_handler == TRUE) { + if(this_host->event_handler == NULL && template_host->event_handler != NULL) + this_host->event_handler = (char *)strdup(template_host->event_handler); + this_host->have_event_handler = TRUE; + } + if(this_host->have_notification_period == FALSE && template_host->have_notification_period == TRUE) { + if(this_host->notification_period == NULL && template_host->notification_period != NULL) + this_host->notification_period = (char *)strdup(template_host->notification_period); + this_host->have_notification_period = TRUE; + } + if(this_host->have_failure_prediction_options == FALSE && template_host->have_failure_prediction_options == TRUE) { + if(this_host->failure_prediction_options == NULL && template_host->failure_prediction_options != NULL) + this_host->failure_prediction_options = (char *)strdup(template_host->failure_prediction_options); + this_host->have_failure_prediction_options = TRUE; + } + if(this_host->have_notes == FALSE && template_host->have_notes == TRUE) { + if(this_host->notes == NULL && template_host->notes != NULL) + this_host->notes = (char *)strdup(template_host->notes); + this_host->have_notes = TRUE; + } + if(this_host->have_notes_url == FALSE && template_host->have_notes_url == TRUE) { + if(this_host->notes_url == NULL && template_host->notes_url != NULL) + this_host->notes_url = (char *)strdup(template_host->notes_url); + this_host->have_notes_url = TRUE; + } + if(this_host->have_action_url == FALSE && template_host->have_action_url == TRUE) { + if(this_host->action_url == NULL && template_host->action_url != NULL) + this_host->action_url = (char *)strdup(template_host->action_url); + this_host->have_action_url = TRUE; + } + if(this_host->have_icon_image == FALSE && template_host->have_icon_image == TRUE) { + if(this_host->icon_image == NULL && template_host->icon_image != NULL) + this_host->icon_image = (char *)strdup(template_host->icon_image); + this_host->have_icon_image = TRUE; + } + if(this_host->have_icon_image_alt == FALSE && template_host->have_icon_image_alt == TRUE) { + if(this_host->icon_image_alt == NULL && template_host->icon_image_alt != NULL) + this_host->icon_image_alt = (char *)strdup(template_host->icon_image_alt); + this_host->have_icon_image_alt = TRUE; + } + if(this_host->have_vrml_image == FALSE && template_host->have_vrml_image == TRUE) { + if(this_host->vrml_image == NULL && template_host->vrml_image != NULL) + this_host->vrml_image = (char *)strdup(template_host->vrml_image); + this_host->have_vrml_image = TRUE; + } + if(this_host->have_statusmap_image == FALSE && template_host->have_statusmap_image == TRUE) { + if(this_host->statusmap_image == NULL && template_host->statusmap_image != NULL) + this_host->statusmap_image = (char *)strdup(template_host->statusmap_image); + this_host->have_statusmap_image = TRUE; + } + if(this_host->have_initial_state == FALSE && template_host->have_initial_state == TRUE) { + this_host->initial_state = template_host->initial_state; + this_host->have_initial_state = TRUE; + } + if(this_host->have_check_interval == FALSE && template_host->have_check_interval == TRUE) { + this_host->check_interval = template_host->check_interval; + this_host->have_check_interval = TRUE; + } + if(this_host->have_retry_interval == FALSE && template_host->have_retry_interval == TRUE) { + this_host->retry_interval = template_host->retry_interval; + this_host->have_retry_interval = TRUE; + } + if(this_host->have_max_check_attempts == FALSE && template_host->have_max_check_attempts == TRUE) { + this_host->max_check_attempts = template_host->max_check_attempts; + this_host->have_max_check_attempts = TRUE; + } + if(this_host->have_active_checks_enabled == FALSE && template_host->have_active_checks_enabled == TRUE) { + this_host->active_checks_enabled = template_host->active_checks_enabled; + this_host->have_active_checks_enabled = TRUE; + } + if(this_host->have_passive_checks_enabled == FALSE && template_host->have_passive_checks_enabled == TRUE) { + this_host->passive_checks_enabled = template_host->passive_checks_enabled; + this_host->have_passive_checks_enabled = TRUE; + } + if(this_host->have_obsess_over_host == FALSE && template_host->have_obsess_over_host == TRUE) { + this_host->obsess_over_host = template_host->obsess_over_host; + this_host->have_obsess_over_host = TRUE; + } + if(this_host->have_event_handler_enabled == FALSE && template_host->have_event_handler_enabled == TRUE) { + this_host->event_handler_enabled = template_host->event_handler_enabled; + this_host->have_event_handler_enabled = TRUE; + } + if(this_host->have_check_freshness == FALSE && template_host->have_check_freshness == TRUE) { + this_host->check_freshness = template_host->check_freshness; + this_host->have_check_freshness = TRUE; + } + if(this_host->have_freshness_threshold == FALSE && template_host->have_freshness_threshold == TRUE) { + this_host->freshness_threshold = template_host->freshness_threshold; + this_host->have_freshness_threshold = TRUE; + } + if(this_host->have_low_flap_threshold == FALSE && template_host->have_low_flap_threshold == TRUE) { + this_host->low_flap_threshold = template_host->low_flap_threshold; + this_host->have_low_flap_threshold = TRUE; + } + if(this_host->have_high_flap_threshold == FALSE && template_host->have_high_flap_threshold == TRUE) { + this_host->high_flap_threshold = template_host->high_flap_threshold; + this_host->have_high_flap_threshold = TRUE; + } + if(this_host->have_flap_detection_enabled == FALSE && template_host->have_flap_detection_enabled == TRUE) { + this_host->flap_detection_enabled = template_host->flap_detection_enabled; + this_host->have_flap_detection_enabled = TRUE; + } + if(this_host->have_flap_detection_options == FALSE && template_host->have_flap_detection_options == TRUE) { + this_host->flap_detection_on_up = template_host->flap_detection_on_up; + this_host->flap_detection_on_down = template_host->flap_detection_on_down; + this_host->flap_detection_on_unreachable = template_host->flap_detection_on_unreachable; + this_host->have_flap_detection_options = TRUE; + } + if(this_host->have_notification_options == FALSE && template_host->have_notification_options == TRUE) { + this_host->notify_on_down = template_host->notify_on_down; + this_host->notify_on_unreachable = template_host->notify_on_unreachable; + this_host->notify_on_recovery = template_host->notify_on_recovery; + this_host->notify_on_flapping = template_host->notify_on_flapping; + this_host->notify_on_downtime = template_host->notify_on_downtime; + this_host->have_notification_options = TRUE; + } + if(this_host->have_notifications_enabled == FALSE && template_host->have_notifications_enabled == TRUE) { + this_host->notifications_enabled = template_host->notifications_enabled; + this_host->have_notifications_enabled = TRUE; + } + if(this_host->have_notification_interval == FALSE && template_host->have_notification_interval == TRUE) { + this_host->notification_interval = template_host->notification_interval; + this_host->have_notification_interval = TRUE; + } + if(this_host->have_first_notification_delay == FALSE && template_host->have_first_notification_delay == TRUE) { + this_host->first_notification_delay = template_host->first_notification_delay; + this_host->have_first_notification_delay = TRUE; + } + if(this_host->have_stalking_options == FALSE && template_host->have_stalking_options == TRUE) { + this_host->stalk_on_up = template_host->stalk_on_up; + this_host->stalk_on_down = template_host->stalk_on_down; + this_host->stalk_on_unreachable = template_host->stalk_on_unreachable; + this_host->have_stalking_options = TRUE; + } + if(this_host->have_process_perf_data == FALSE && template_host->have_process_perf_data == TRUE) { + this_host->process_perf_data = template_host->process_perf_data; + this_host->have_process_perf_data = TRUE; + } + if(this_host->have_failure_prediction_enabled == FALSE && template_host->have_failure_prediction_enabled == TRUE) { + this_host->failure_prediction_enabled = template_host->failure_prediction_enabled; + this_host->have_failure_prediction_enabled = TRUE; + } + if(this_host->have_2d_coords == FALSE && template_host->have_2d_coords == TRUE) { + this_host->x_2d = template_host->x_2d; + this_host->y_2d = template_host->y_2d; + this_host->have_2d_coords = TRUE; + } + if(this_host->have_3d_coords == FALSE && template_host->have_3d_coords == TRUE) { + this_host->x_3d = template_host->x_3d; + this_host->y_3d = template_host->y_3d; + this_host->z_3d = template_host->z_3d; + this_host->have_3d_coords = TRUE; + } + if(this_host->have_retain_status_information == FALSE && template_host->have_retain_status_information == TRUE) { + this_host->retain_status_information = template_host->retain_status_information; + this_host->have_retain_status_information = TRUE; + } + if(this_host->have_retain_nonstatus_information == FALSE && template_host->have_retain_nonstatus_information == TRUE) { + this_host->retain_nonstatus_information = template_host->retain_nonstatus_information; + this_host->have_retain_nonstatus_information = TRUE; + } + + /* apply missing custom variables from template host... */ + for(temp_customvariablesmember = template_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + + /* see if this host has a variable by the same name */ + for(this_customvariablesmember = this_host->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) { + if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name)) + break; + } + + /* we didn't find the same variable name, so add a new custom variable */ + if(this_customvariablesmember == NULL) + xodtemplate_add_custom_variable_to_host(this_host, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value); + } + } + + my_free(template_names); + + return OK; + } + + + +/* resolves a service object */ +int xodtemplate_resolve_service(xodtemplate_service *this_service) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_service *template_service = NULL; + xodtemplate_customvariablesmember *this_customvariablesmember = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + + /* return if this service has already been resolved */ + if(this_service->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_service->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_service->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_service->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_service = xodtemplate_find_service(temp_ptr); + if(template_service == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in service definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template service... */ + xodtemplate_resolve_service(template_service); + + /* apply missing properties from template service... */ + if(this_service->have_service_description == FALSE && template_service->have_service_description == TRUE) { + if(this_service->service_description == NULL && template_service->service_description != NULL) + this_service->service_description = (char *)strdup(template_service->service_description); + this_service->have_service_description = TRUE; + } + if(this_service->have_display_name == FALSE && template_service->have_display_name == TRUE) { + if(this_service->display_name == NULL && template_service->display_name != NULL) + this_service->display_name = (char *)strdup(template_service->display_name); + this_service->have_display_name = TRUE; + } + + xodtemplate_get_inherited_string(&template_service->have_host_name, &template_service->host_name, &this_service->have_host_name, &this_service->host_name); + xodtemplate_get_inherited_string(&template_service->have_hostgroup_name, &template_service->hostgroup_name, &this_service->have_hostgroup_name, &this_service->hostgroup_name); + xodtemplate_get_inherited_string(&template_service->have_service_groups, &template_service->service_groups, &this_service->have_service_groups, &this_service->service_groups); + xodtemplate_get_inherited_string(&template_service->have_contact_groups, &template_service->contact_groups, &this_service->have_contact_groups, &this_service->contact_groups); + xodtemplate_get_inherited_string(&template_service->have_contacts, &template_service->contacts, &this_service->have_contacts, &this_service->contacts); + + if(template_service->have_check_command == TRUE) { + if(template_service->have_important_check_command == TRUE) { + my_free(this_service->check_command); + this_service->have_check_command = FALSE; + } + if(this_service->have_check_command == FALSE) { + if(this_service->check_command == NULL && template_service->check_command != NULL) + this_service->check_command = (char *)strdup(template_service->check_command); + this_service->have_check_command = TRUE; + } + } + if(this_service->have_check_period == FALSE && template_service->have_check_period == TRUE) { + if(this_service->check_period == NULL && template_service->check_period != NULL) + this_service->check_period = (char *)strdup(template_service->check_period); + this_service->have_check_period = TRUE; + } + if(this_service->have_event_handler == FALSE && template_service->have_event_handler == TRUE) { + if(this_service->event_handler == NULL && template_service->event_handler != NULL) + this_service->event_handler = (char *)strdup(template_service->event_handler); + this_service->have_event_handler = TRUE; + } + if(this_service->have_notification_period == FALSE && template_service->have_notification_period == TRUE) { + if(this_service->notification_period == NULL && template_service->notification_period != NULL) + this_service->notification_period = (char *)strdup(template_service->notification_period); + this_service->have_notification_period = TRUE; + } + if(this_service->have_failure_prediction_options == FALSE && template_service->have_failure_prediction_options == TRUE) { + if(this_service->failure_prediction_options == NULL && template_service->failure_prediction_options != NULL) + this_service->failure_prediction_options = (char *)strdup(template_service->failure_prediction_options); + this_service->have_failure_prediction_options = TRUE; + } + if(this_service->have_notes == FALSE && template_service->have_notes == TRUE) { + if(this_service->notes == NULL && template_service->notes != NULL) + this_service->notes = (char *)strdup(template_service->notes); + this_service->have_notes = TRUE; + } + if(this_service->have_notes_url == FALSE && template_service->have_notes_url == TRUE) { + if(this_service->notes_url == NULL && template_service->notes_url != NULL) + this_service->notes_url = (char *)strdup(template_service->notes_url); + this_service->have_notes_url = TRUE; + } + if(this_service->have_action_url == FALSE && template_service->have_action_url == TRUE) { + if(this_service->action_url == NULL && template_service->action_url != NULL) + this_service->action_url = (char *)strdup(template_service->action_url); + this_service->have_action_url = TRUE; + } + if(this_service->have_icon_image == FALSE && template_service->have_icon_image == TRUE) { + if(this_service->icon_image == NULL && template_service->icon_image != NULL) + this_service->icon_image = (char *)strdup(template_service->icon_image); + this_service->have_icon_image = TRUE; + } + if(this_service->have_icon_image_alt == FALSE && template_service->have_icon_image_alt == TRUE) { + if(this_service->icon_image_alt == NULL && template_service->icon_image_alt != NULL) + this_service->icon_image_alt = (char *)strdup(template_service->icon_image_alt); + this_service->have_icon_image_alt = TRUE; + } + if(this_service->have_initial_state == FALSE && template_service->have_initial_state == TRUE) { + this_service->initial_state = template_service->initial_state; + this_service->have_initial_state = TRUE; + } + if(this_service->have_max_check_attempts == FALSE && template_service->have_max_check_attempts == TRUE) { + this_service->max_check_attempts = template_service->max_check_attempts; + this_service->have_max_check_attempts = TRUE; + } + if(this_service->have_check_interval == FALSE && template_service->have_check_interval == TRUE) { + this_service->check_interval = template_service->check_interval; + this_service->have_check_interval = TRUE; + } + if(this_service->have_retry_interval == FALSE && template_service->have_retry_interval == TRUE) { + this_service->retry_interval = template_service->retry_interval; + this_service->have_retry_interval = TRUE; + } + if(this_service->have_active_checks_enabled == FALSE && template_service->have_active_checks_enabled == TRUE) { + this_service->active_checks_enabled = template_service->active_checks_enabled; + this_service->have_active_checks_enabled = TRUE; + } + if(this_service->have_passive_checks_enabled == FALSE && template_service->have_passive_checks_enabled == TRUE) { + this_service->passive_checks_enabled = template_service->passive_checks_enabled; + this_service->have_passive_checks_enabled = TRUE; + } + if(this_service->have_parallelize_check == FALSE && template_service->have_parallelize_check == TRUE) { + this_service->parallelize_check = template_service->parallelize_check; + this_service->have_parallelize_check = TRUE; + } + if(this_service->have_is_volatile == FALSE && template_service->have_is_volatile == TRUE) { + this_service->is_volatile = template_service->is_volatile; + this_service->have_is_volatile = TRUE; + } + if(this_service->have_obsess_over_service == FALSE && template_service->have_obsess_over_service == TRUE) { + this_service->obsess_over_service = template_service->obsess_over_service; + this_service->have_obsess_over_service = TRUE; + } + if(this_service->have_event_handler_enabled == FALSE && template_service->have_event_handler_enabled == TRUE) { + this_service->event_handler_enabled = template_service->event_handler_enabled; + this_service->have_event_handler_enabled = TRUE; + } + if(this_service->have_check_freshness == FALSE && template_service->have_check_freshness == TRUE) { + this_service->check_freshness = template_service->check_freshness; + this_service->have_check_freshness = TRUE; + } + if(this_service->have_freshness_threshold == FALSE && template_service->have_freshness_threshold == TRUE) { + this_service->freshness_threshold = template_service->freshness_threshold; + this_service->have_freshness_threshold = TRUE; + } + if(this_service->have_low_flap_threshold == FALSE && template_service->have_low_flap_threshold == TRUE) { + this_service->low_flap_threshold = template_service->low_flap_threshold; + this_service->have_low_flap_threshold = TRUE; + } + if(this_service->have_high_flap_threshold == FALSE && template_service->have_high_flap_threshold == TRUE) { + this_service->high_flap_threshold = template_service->high_flap_threshold; + this_service->have_high_flap_threshold = TRUE; + } + if(this_service->have_flap_detection_enabled == FALSE && template_service->have_flap_detection_enabled == TRUE) { + this_service->flap_detection_enabled = template_service->flap_detection_enabled; + this_service->have_flap_detection_enabled = TRUE; + } + if(this_service->have_flap_detection_options == FALSE && template_service->have_flap_detection_options == TRUE) { + this_service->flap_detection_on_ok = template_service->flap_detection_on_ok; + this_service->flap_detection_on_unknown = template_service->flap_detection_on_unknown; + this_service->flap_detection_on_warning = template_service->flap_detection_on_warning; + this_service->flap_detection_on_critical = template_service->flap_detection_on_critical; + this_service->have_flap_detection_options = TRUE; + } + if(this_service->have_notification_options == FALSE && template_service->have_notification_options == TRUE) { + this_service->notify_on_unknown = template_service->notify_on_unknown; + this_service->notify_on_warning = template_service->notify_on_warning; + this_service->notify_on_critical = template_service->notify_on_critical; + this_service->notify_on_recovery = template_service->notify_on_recovery; + this_service->notify_on_flapping = template_service->notify_on_flapping; + this_service->notify_on_downtime = template_service->notify_on_downtime; + this_service->have_notification_options = TRUE; + } + if(this_service->have_notifications_enabled == FALSE && template_service->have_notifications_enabled == TRUE) { + this_service->notifications_enabled = template_service->notifications_enabled; + this_service->have_notifications_enabled = TRUE; + } + if(this_service->have_notification_interval == FALSE && template_service->have_notification_interval == TRUE) { + this_service->notification_interval = template_service->notification_interval; + this_service->have_notification_interval = TRUE; + } + if(this_service->have_first_notification_delay == FALSE && template_service->have_first_notification_delay == TRUE) { + this_service->first_notification_delay = template_service->first_notification_delay; + this_service->have_first_notification_delay = TRUE; + } + if(this_service->have_stalking_options == FALSE && template_service->have_stalking_options == TRUE) { + this_service->stalk_on_ok = template_service->stalk_on_ok; + this_service->stalk_on_unknown = template_service->stalk_on_unknown; + this_service->stalk_on_warning = template_service->stalk_on_warning; + this_service->stalk_on_critical = template_service->stalk_on_critical; + this_service->have_stalking_options = TRUE; + } + if(this_service->have_process_perf_data == FALSE && template_service->have_process_perf_data == TRUE) { + this_service->process_perf_data = template_service->process_perf_data; + this_service->have_process_perf_data = TRUE; + } + if(this_service->have_failure_prediction_enabled == FALSE && template_service->have_failure_prediction_enabled == TRUE) { + this_service->failure_prediction_enabled = template_service->failure_prediction_enabled; + this_service->have_failure_prediction_enabled = TRUE; + } + if(this_service->have_retain_status_information == FALSE && template_service->have_retain_status_information == TRUE) { + this_service->retain_status_information = template_service->retain_status_information; + this_service->have_retain_status_information = TRUE; + } + if(this_service->have_retain_nonstatus_information == FALSE && template_service->have_retain_nonstatus_information == TRUE) { + this_service->retain_nonstatus_information = template_service->retain_nonstatus_information; + this_service->have_retain_nonstatus_information = TRUE; + } + + /* apply missing custom variables from template service... */ + for(temp_customvariablesmember = template_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + + /* see if this host has a variable by the same name */ + for(this_customvariablesmember = this_service->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) { + if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name)) + break; + } + + /* we didn't find the same variable name, so add a new custom variable */ + if(this_customvariablesmember == NULL) + xodtemplate_add_custom_variable_to_service(this_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value); + } + } + + my_free(template_names); + + return OK; + } + + +/* resolves a hostdependency object */ +int xodtemplate_resolve_hostdependency(xodtemplate_hostdependency *this_hostdependency) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_hostdependency *template_hostdependency = NULL; + + /* return if this hostdependency has already been resolved */ + if(this_hostdependency->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_hostdependency->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_hostdependency->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_hostdependency->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_hostdependency = xodtemplate_find_hostdependency(temp_ptr); + if(template_hostdependency == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in host dependency definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostdependency->_config_file), this_hostdependency->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template hostdependency... */ + xodtemplate_resolve_hostdependency(template_hostdependency); + + /* apply missing properties from template hostdependency... */ + + xodtemplate_get_inherited_string(&template_hostdependency->have_host_name, &template_hostdependency->host_name, &this_hostdependency->have_host_name, &this_hostdependency->host_name); + xodtemplate_get_inherited_string(&template_hostdependency->have_dependent_host_name, &template_hostdependency->dependent_host_name, &this_hostdependency->have_dependent_host_name, &this_hostdependency->dependent_host_name); + xodtemplate_get_inherited_string(&template_hostdependency->have_hostgroup_name, &template_hostdependency->hostgroup_name, &this_hostdependency->have_hostgroup_name, &this_hostdependency->hostgroup_name); + xodtemplate_get_inherited_string(&template_hostdependency->have_dependent_hostgroup_name, &template_hostdependency->dependent_hostgroup_name, &this_hostdependency->have_dependent_hostgroup_name, &this_hostdependency->dependent_hostgroup_name); + + if(this_hostdependency->have_dependency_period == FALSE && template_hostdependency->have_dependency_period == TRUE) { + if(this_hostdependency->dependency_period == NULL && template_hostdependency->dependency_period != NULL) + this_hostdependency->dependency_period = (char *)strdup(template_hostdependency->dependency_period); + this_hostdependency->have_dependency_period = TRUE; + } + if(this_hostdependency->have_inherits_parent == FALSE && template_hostdependency->have_inherits_parent == TRUE) { + this_hostdependency->inherits_parent = template_hostdependency->inherits_parent; + this_hostdependency->have_inherits_parent = TRUE; + } + if(this_hostdependency->have_execution_dependency_options == FALSE && template_hostdependency->have_execution_dependency_options == TRUE) { + this_hostdependency->fail_execute_on_up = template_hostdependency->fail_execute_on_up; + this_hostdependency->fail_execute_on_down = template_hostdependency->fail_execute_on_down; + this_hostdependency->fail_execute_on_unreachable = template_hostdependency->fail_execute_on_unreachable; + this_hostdependency->fail_execute_on_pending = template_hostdependency->fail_execute_on_pending; + this_hostdependency->have_execution_dependency_options = TRUE; + } + if(this_hostdependency->have_notification_dependency_options == FALSE && template_hostdependency->have_notification_dependency_options == TRUE) { + this_hostdependency->fail_notify_on_up = template_hostdependency->fail_notify_on_up; + this_hostdependency->fail_notify_on_down = template_hostdependency->fail_notify_on_down; + this_hostdependency->fail_notify_on_unreachable = template_hostdependency->fail_notify_on_unreachable; + this_hostdependency->fail_notify_on_pending = template_hostdependency->fail_notify_on_pending; + this_hostdependency->have_notification_dependency_options = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + +/* resolves a hostescalation object */ +int xodtemplate_resolve_hostescalation(xodtemplate_hostescalation *this_hostescalation) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_hostescalation *template_hostescalation = NULL; + + /* return if this hostescalation has already been resolved */ + if(this_hostescalation->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_hostescalation->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_hostescalation->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_hostescalation->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_hostescalation = xodtemplate_find_hostescalation(temp_ptr); + if(template_hostescalation == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in host escalation definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template hostescalation... */ + xodtemplate_resolve_hostescalation(template_hostescalation); + + /* apply missing properties from template hostescalation... */ + xodtemplate_get_inherited_string(&template_hostescalation->have_host_name, &template_hostescalation->host_name, &this_hostescalation->have_host_name, &this_hostescalation->host_name); + xodtemplate_get_inherited_string(&template_hostescalation->have_hostgroup_name, &template_hostescalation->hostgroup_name, &this_hostescalation->have_hostgroup_name, &this_hostescalation->hostgroup_name); + xodtemplate_get_inherited_string(&template_hostescalation->have_contact_groups, &template_hostescalation->contact_groups, &this_hostescalation->have_contact_groups, &this_hostescalation->contact_groups); + xodtemplate_get_inherited_string(&template_hostescalation->have_contacts, &template_hostescalation->contacts, &this_hostescalation->have_contacts, &this_hostescalation->contacts); + + if(this_hostescalation->have_escalation_period == FALSE && template_hostescalation->have_escalation_period == TRUE) { + if(this_hostescalation->escalation_period == NULL && template_hostescalation->escalation_period != NULL) + this_hostescalation->escalation_period = (char *)strdup(template_hostescalation->escalation_period); + this_hostescalation->have_escalation_period = TRUE; + } + if(this_hostescalation->have_first_notification == FALSE && template_hostescalation->have_first_notification == TRUE) { + this_hostescalation->first_notification = template_hostescalation->first_notification; + this_hostescalation->have_first_notification = TRUE; + } + if(this_hostescalation->have_last_notification == FALSE && template_hostescalation->have_last_notification == TRUE) { + this_hostescalation->last_notification = template_hostescalation->last_notification; + this_hostescalation->have_last_notification = TRUE; + } + if(this_hostescalation->have_notification_interval == FALSE && template_hostescalation->have_notification_interval == TRUE) { + this_hostescalation->notification_interval = template_hostescalation->notification_interval; + this_hostescalation->have_notification_interval = TRUE; + } + if(this_hostescalation->have_escalation_options == FALSE && template_hostescalation->have_escalation_options == TRUE) { + this_hostescalation->escalate_on_down = template_hostescalation->escalate_on_down; + this_hostescalation->escalate_on_unreachable = template_hostescalation->escalate_on_unreachable; + this_hostescalation->escalate_on_recovery = template_hostescalation->escalate_on_recovery; + this_hostescalation->have_escalation_options = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + + +/* resolves a hostextinfo object */ +int xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_hostextinfo *template_hostextinfo = NULL; + + /* return if this object has already been resolved */ + if(this_hostextinfo->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_hostextinfo->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_hostextinfo->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_hostextinfo->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_hostextinfo = xodtemplate_find_hostextinfo(temp_ptr); + if(template_hostextinfo == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in extended host info definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostextinfo->_config_file), this_hostextinfo->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template hostextinfo... */ + xodtemplate_resolve_hostextinfo(template_hostextinfo); + + /* apply missing properties from template hostextinfo... */ + if(this_hostextinfo->have_host_name == FALSE && template_hostextinfo->have_host_name == TRUE) { + if(this_hostextinfo->host_name == NULL && template_hostextinfo->host_name != NULL) + this_hostextinfo->host_name = (char *)strdup(template_hostextinfo->host_name); + this_hostextinfo->have_host_name = TRUE; + } + if(this_hostextinfo->have_hostgroup_name == FALSE && template_hostextinfo->have_hostgroup_name == TRUE) { + if(this_hostextinfo->hostgroup_name == NULL && template_hostextinfo->hostgroup_name != NULL) + this_hostextinfo->hostgroup_name = (char *)strdup(template_hostextinfo->hostgroup_name); + this_hostextinfo->have_hostgroup_name = TRUE; + } + if(this_hostextinfo->have_notes == FALSE && template_hostextinfo->have_notes == TRUE) { + if(this_hostextinfo->notes == NULL && template_hostextinfo->notes != NULL) + this_hostextinfo->notes = (char *)strdup(template_hostextinfo->notes); + this_hostextinfo->have_notes = TRUE; + } + if(this_hostextinfo->have_notes_url == FALSE && template_hostextinfo->have_notes_url == TRUE) { + if(this_hostextinfo->notes_url == NULL && template_hostextinfo->notes_url != NULL) + this_hostextinfo->notes_url = (char *)strdup(template_hostextinfo->notes_url); + this_hostextinfo->have_notes_url = TRUE; + } + if(this_hostextinfo->have_action_url == FALSE && template_hostextinfo->have_action_url == TRUE) { + if(this_hostextinfo->action_url == NULL && template_hostextinfo->action_url != NULL) + this_hostextinfo->action_url = (char *)strdup(template_hostextinfo->action_url); + this_hostextinfo->have_action_url = TRUE; + } + if(this_hostextinfo->have_icon_image == FALSE && template_hostextinfo->have_icon_image == TRUE) { + if(this_hostextinfo->icon_image == NULL && template_hostextinfo->icon_image != NULL) + this_hostextinfo->icon_image = (char *)strdup(template_hostextinfo->icon_image); + this_hostextinfo->have_icon_image = TRUE; + } + if(this_hostextinfo->have_icon_image_alt == FALSE && template_hostextinfo->have_icon_image_alt == TRUE) { + if(this_hostextinfo->icon_image_alt == NULL && template_hostextinfo->icon_image_alt != NULL) + this_hostextinfo->icon_image_alt = (char *)strdup(template_hostextinfo->icon_image_alt); + this_hostextinfo->have_icon_image_alt = TRUE; + } + if(this_hostextinfo->have_vrml_image == FALSE && template_hostextinfo->have_vrml_image == TRUE) { + if(this_hostextinfo->vrml_image == NULL && template_hostextinfo->vrml_image != NULL) + this_hostextinfo->vrml_image = (char *)strdup(template_hostextinfo->vrml_image); + this_hostextinfo->have_vrml_image = TRUE; + } + if(this_hostextinfo->have_statusmap_image == FALSE && template_hostextinfo->have_statusmap_image == TRUE) { + if(this_hostextinfo->statusmap_image == NULL && template_hostextinfo->statusmap_image != NULL) + this_hostextinfo->statusmap_image = (char *)strdup(template_hostextinfo->statusmap_image); + this_hostextinfo->have_statusmap_image = TRUE; + } + if(this_hostextinfo->have_2d_coords == FALSE && template_hostextinfo->have_2d_coords == TRUE) { + this_hostextinfo->x_2d = template_hostextinfo->x_2d; + this_hostextinfo->y_2d = template_hostextinfo->y_2d; + this_hostextinfo->have_2d_coords = TRUE; + } + if(this_hostextinfo->have_3d_coords == FALSE && template_hostextinfo->have_3d_coords == TRUE) { + this_hostextinfo->x_3d = template_hostextinfo->x_3d; + this_hostextinfo->y_3d = template_hostextinfo->y_3d; + this_hostextinfo->z_3d = template_hostextinfo->z_3d; + this_hostextinfo->have_3d_coords = TRUE; + } + } + + my_free(template_names); + + return OK; + } + + + +/* resolves a serviceextinfo object */ +int xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo) { + char *temp_ptr = NULL; + char *template_names = NULL; + char *template_name_ptr = NULL; + xodtemplate_serviceextinfo *template_serviceextinfo = NULL; + + /* return if this object has already been resolved */ + if(this_serviceextinfo->has_been_resolved == TRUE) + return OK; + + /* set the resolved flag */ + this_serviceextinfo->has_been_resolved = TRUE; + + /* return if we have no template */ + if(this_serviceextinfo->template == NULL) + return OK; + + if((template_names = (char *)strdup(this_serviceextinfo->template)) == NULL) + return ERROR; + + /* apply all templates */ + template_name_ptr = template_names; + for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) { + + template_serviceextinfo = xodtemplate_find_serviceextinfo(temp_ptr); + if(template_serviceextinfo == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in extended service info definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_serviceextinfo->_config_file), this_serviceextinfo->_start_line); + my_free(template_names); + return ERROR; + } + + /* resolve the template serviceextinfo... */ + xodtemplate_resolve_serviceextinfo(template_serviceextinfo); + + /* apply missing properties from template serviceextinfo... */ + if(this_serviceextinfo->have_host_name == FALSE && template_serviceextinfo->have_host_name == TRUE) { + if(this_serviceextinfo->host_name == NULL && template_serviceextinfo->host_name != NULL) + this_serviceextinfo->host_name = (char *)strdup(template_serviceextinfo->host_name); + this_serviceextinfo->have_host_name = TRUE; + } + if(this_serviceextinfo->have_hostgroup_name == FALSE && template_serviceextinfo->have_hostgroup_name == TRUE) { + if(this_serviceextinfo->hostgroup_name == NULL && template_serviceextinfo->hostgroup_name != NULL) + this_serviceextinfo->hostgroup_name = (char *)strdup(template_serviceextinfo->hostgroup_name); + this_serviceextinfo->have_hostgroup_name = TRUE; + } + if(this_serviceextinfo->have_service_description == FALSE && template_serviceextinfo->have_service_description == TRUE) { + if(this_serviceextinfo->service_description == NULL && template_serviceextinfo->service_description != NULL) + this_serviceextinfo->service_description = (char *)strdup(template_serviceextinfo->service_description); + this_serviceextinfo->have_service_description = TRUE; + } + if(this_serviceextinfo->have_notes == FALSE && template_serviceextinfo->have_notes == TRUE) { + if(this_serviceextinfo->notes == NULL && template_serviceextinfo->notes != NULL) + this_serviceextinfo->notes = (char *)strdup(template_serviceextinfo->notes); + this_serviceextinfo->have_notes = TRUE; + } + if(this_serviceextinfo->have_notes_url == FALSE && template_serviceextinfo->have_notes_url == TRUE) { + if(this_serviceextinfo->notes_url == NULL && template_serviceextinfo->notes_url != NULL) + this_serviceextinfo->notes_url = (char *)strdup(template_serviceextinfo->notes_url); + this_serviceextinfo->have_notes_url = TRUE; + } + if(this_serviceextinfo->have_action_url == FALSE && template_serviceextinfo->have_action_url == TRUE) { + if(this_serviceextinfo->action_url == NULL && template_serviceextinfo->action_url != NULL) + this_serviceextinfo->action_url = (char *)strdup(template_serviceextinfo->action_url); + this_serviceextinfo->have_action_url = TRUE; + } + if(this_serviceextinfo->have_icon_image == FALSE && template_serviceextinfo->have_icon_image == TRUE) { + if(this_serviceextinfo->icon_image == NULL && template_serviceextinfo->icon_image != NULL) + this_serviceextinfo->icon_image = (char *)strdup(template_serviceextinfo->icon_image); + this_serviceextinfo->have_icon_image = TRUE; + } + if(this_serviceextinfo->have_icon_image_alt == FALSE && template_serviceextinfo->have_icon_image_alt == TRUE) { + if(this_serviceextinfo->icon_image_alt == NULL && template_serviceextinfo->icon_image_alt != NULL) + this_serviceextinfo->icon_image_alt = (char *)strdup(template_serviceextinfo->icon_image_alt); + this_serviceextinfo->have_icon_image_alt = TRUE; + } + } + + my_free(template_names); + + return OK; + } + +#endif + + + +/******************************************************************/ +/*************** OBJECT RECOMBOBULATION FUNCTIONS *****************/ +/******************************************************************/ + +#ifdef NSCORE + + +/* recombobulates contactgroup definitions */ +int xodtemplate_recombobulate_contactgroups(void) { + xodtemplate_contact *temp_contact = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_memberlist *temp_memberlist = NULL; + xodtemplate_memberlist *this_memberlist = NULL; + char *contactgroup_names = NULL; + char *temp_ptr = NULL; + char *new_members = NULL; + + /* This should happen before we expand contactgroup members, to avoid duplicate contact memberships 01/07/2006 EG */ + /* process all contacts that have contactgroup directives */ + for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + + /* skip contacts without contactgroup directives or contact names */ + if(temp_contact->contact_groups == NULL || temp_contact->contact_name == NULL) + continue; + + /* preprocess the contactgroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */ + if((contactgroup_names = xodtemplate_process_contactgroup_names(temp_contact->contact_groups, temp_contact->_config_file, temp_contact->_start_line)) == NULL) + return ERROR; + + /* process the list of contactgroups */ + for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + /* strip trailing spaces */ + strip(temp_ptr); + + /* find the contactgroup */ + temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr); + if(temp_contactgroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find contactgroup '%s' specified in contact '%s' definition (config file '%s', starting on line %d)\n", temp_ptr, temp_contact->contact_name, xodtemplate_config_file_name(temp_contact->_config_file), temp_contact->_start_line); + my_free(contactgroup_names); + return ERROR; + } + + /* add this contact to the contactgroup members directive */ + if(temp_contactgroup->members == NULL) + temp_contactgroup->members = (char *)strdup(temp_contact->contact_name); + else { + new_members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(temp_contact->contact_name) + 2); + if(new_members != NULL) { + temp_contactgroup->members = new_members; + strcat(temp_contactgroup->members, ","); + strcat(temp_contactgroup->members, temp_contact->contact_name); + } + } + } + + /* free memory */ + my_free(contactgroup_names); + } + + + /* expand subgroup membership recursively */ + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup; temp_contactgroup = temp_contactgroup->next) + xodtemplate_recombobulate_contactgroup_subgroups(temp_contactgroup, NULL); + + + /* expand members of all contactgroups - this could be done in xodtemplate_register_contactgroup(), but we can save the CGIs some work if we do it here */ + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup; temp_contactgroup = temp_contactgroup->next) { + + if(temp_contactgroup->members == NULL) + continue; + + /* get list of contacts in the contactgroup */ + temp_memberlist = xodtemplate_expand_contactgroups_and_contacts(temp_contactgroup->contactgroup_members, temp_contactgroup->members, temp_contactgroup->_config_file, temp_contactgroup->_start_line); + + /* add all members to the contact group */ + if(temp_memberlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand member contacts specified in contactgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line); + return ERROR; + } + my_free(temp_contactgroup->members); + for(this_memberlist = temp_memberlist; this_memberlist; this_memberlist = this_memberlist->next) { + + /* add this contact to the contactgroup members directive */ + if(temp_contactgroup->members == NULL) + temp_contactgroup->members = (char *)strdup(this_memberlist->name1); + else { + new_members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(this_memberlist->name1) + 2); + if(new_members != NULL) { + temp_contactgroup->members = new_members; + strcat(temp_contactgroup->members, ","); + strcat(temp_contactgroup->members, this_memberlist->name1); + } + } + } + xodtemplate_free_memberlist(&temp_memberlist); + } + + return OK; + } + + + +int xodtemplate_recombobulate_contactgroup_subgroups(xodtemplate_contactgroup *temp_contactgroup, char **members) { + xodtemplate_contactgroup *sub_group = NULL; + char *orig_cgmembers = NULL; + char *cgmembers = NULL; + char *newmembers = NULL; + char *buf = NULL; + char *ptr = NULL; + + if(temp_contactgroup == NULL) + return ERROR; + + /* resolve subgroup memberships first */ + if(temp_contactgroup->contactgroup_members != NULL) { + + /* save members, null pointer so we don't recurse into infinite hell */ + orig_cgmembers = temp_contactgroup->contactgroup_members; + temp_contactgroup->contactgroup_members = NULL; + + /* make new working copy of members */ + cgmembers = (char *)strdup(orig_cgmembers); + + ptr = cgmembers; + while((buf = ptr) != NULL) { + + /* get next member for next run*/ + ptr = strchr(ptr, ','); + if(ptr) { + ptr[0] = '\x0'; + ptr++; + } + + strip(buf); + + /* find subgroup and recurse */ + if((sub_group = xodtemplate_find_real_contactgroup(buf)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in contactgroup (config file '%s', starting on line %d)\n", buf, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line); + return ERROR; + } + xodtemplate_recombobulate_contactgroup_subgroups(sub_group, &newmembers); + + /* add new (sub) members */ + if(newmembers != NULL) { + if(temp_contactgroup->members == NULL) + temp_contactgroup->members = (char *)strdup(newmembers); + else if((temp_contactgroup->members = realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(newmembers) + 2))) { + strcat(temp_contactgroup->members, ","); + strcat(temp_contactgroup->members, newmembers); + } + } + } + + /* free memory */ + my_free(cgmembers); + + /* restore group members */ + temp_contactgroup->contactgroup_members = orig_cgmembers; + } + + /* return contact members */ + if(members != NULL) + *members = temp_contactgroup->members; + + return OK; + } + + + +/* NOTE: this was originally implemented in the late alpha cycle of + * 3.0 development, but was removed in 3.0b2, as flattening + * contactgroups into a list of contacts makes it impossible for + * NDOUtils to create a reverse mapping */ +/* recombobulates contacts in various object definitions */ +int xodtemplate_recombobulate_object_contacts(void) { + return OK; + } + + +/* recombobulates hostgroup definitions */ +int xodtemplate_recombobulate_hostgroups(void) { + xodtemplate_host *temp_host = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_memberlist *temp_memberlist = NULL; + xodtemplate_memberlist *this_memberlist = NULL; + char *hostgroup_names = NULL; + char *temp_ptr = NULL; + char *new_members = NULL; + +#ifdef DEBUG + printf("** PRE-EXPANSION 1\n"); + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) { + printf("HOSTGROUP [%s]\n", temp_hostgroup->hostgroup_name); + printf("H MEMBERS: %s\n", temp_hostgroup->members); + printf("G MEMBERS: %s\n", temp_hostgroup->hostgroup_members); + printf("\n"); + } +#endif + + /* This should happen before we expand hostgroup members, to avoid duplicate host memberships 01/07/2006 EG */ + /* process all hosts that have hostgroup directives */ + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) { + + /* skip hosts without hostgroup directives or host names */ + if(temp_host->host_groups == NULL || temp_host->host_name == NULL) + continue; + + /* skip hosts that shouldn't be registered */ + if(temp_host->register_object == FALSE) + continue; + + /* preprocess the hostgroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */ + /* 10/18/07 EG an empty return value means an error occured */ + if((hostgroup_names = xodtemplate_process_hostgroup_names(temp_host->host_groups, temp_host->_config_file, temp_host->_start_line)) == NULL) + return ERROR; + + /* process the list of hostgroups */ + for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + /* strip trailing spaces */ + strip(temp_ptr); + + /* find the hostgroup */ + temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr); + if(temp_hostgroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find hostgroup '%s' specified in host '%s' definition (config file '%s', starting on line %d)\n", temp_ptr, temp_host->host_name, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line); + my_free(hostgroup_names); + return ERROR; + } + + /* add this list to the hostgroup members directive */ + if(temp_hostgroup->members == NULL) + temp_hostgroup->members = (char *)strdup(temp_host->host_name); + else { + new_members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(temp_host->host_name) + 2); + if(new_members != NULL) { + temp_hostgroup->members = new_members; + strcat(temp_hostgroup->members, ","); + strcat(temp_hostgroup->members, temp_host->host_name); + } + } + } + + /* free memory */ + my_free(hostgroup_names); + } + +#ifdef DEBUG + printf("** POST-EXPANSION 1\n"); + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) { + printf("HOSTGROUP [%s]\n", temp_hostgroup->hostgroup_name); + printf("H MEMBERS: %s\n", temp_hostgroup->members); + printf("G MEMBERS: %s\n", temp_hostgroup->hostgroup_members); + printf("\n"); + } +#endif + + /* expand subgroup membership recursively */ + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) + xodtemplate_recombobulate_hostgroup_subgroups(temp_hostgroup, NULL); + + /* expand members of all hostgroups - this could be done in xodtemplate_register_hostgroup(), but we can save the CGIs some work if we do it here */ + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) { + + if(temp_hostgroup->members == NULL && temp_hostgroup->hostgroup_members == NULL) + continue; + + /* skip hostgroups that shouldn't be registered */ + if(temp_hostgroup->register_object == FALSE) + continue; + + /* get list of hosts in the hostgroup */ + temp_memberlist = xodtemplate_expand_hostgroups_and_hosts(NULL, temp_hostgroup->members, temp_hostgroup->_config_file, temp_hostgroup->_start_line); + + /* add all members to the host group */ + if(temp_memberlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand members specified in hostgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line); + return ERROR; + } + my_free(temp_hostgroup->members); + for(this_memberlist = temp_memberlist; this_memberlist; this_memberlist = this_memberlist->next) { + + /* add this host to the hostgroup members directive */ + if(temp_hostgroup->members == NULL) + temp_hostgroup->members = (char *)strdup(this_memberlist->name1); + else { + new_members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(this_memberlist->name1) + 2); + if(new_members != NULL) { + temp_hostgroup->members = new_members; + strcat(temp_hostgroup->members, ","); + strcat(temp_hostgroup->members, this_memberlist->name1); + } + } + } + xodtemplate_free_memberlist(&temp_memberlist); + } + +#ifdef DEBUG + printf("** POST-EXPANSION 2\n"); + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) { + printf("HOSTGROUP [%s]\n", temp_hostgroup->hostgroup_name); + printf("H MEMBERS: %s\n", temp_hostgroup->members); + printf("G MEMBERS: %s\n", temp_hostgroup->hostgroup_members); + printf("\n"); + } +#endif + + return OK; + } + + + + +int xodtemplate_recombobulate_hostgroup_subgroups(xodtemplate_hostgroup *temp_hostgroup, char **members) { + xodtemplate_hostgroup *sub_group = NULL; + char *orig_hgmembers = NULL; + char *hgmembers = NULL; + char *newmembers = NULL; + char *buf = NULL; + char *ptr = NULL; + + if(temp_hostgroup == NULL) + return ERROR; + + /* resolve subgroup memberships first */ + if(temp_hostgroup->hostgroup_members != NULL) { + + /* save members, null pointer so we don't recurse into infinite hell */ + orig_hgmembers = temp_hostgroup->hostgroup_members; + temp_hostgroup->hostgroup_members = NULL; + + /* make new working copy of members */ + hgmembers = (char *)strdup(orig_hgmembers); + + ptr = hgmembers; + while((buf = ptr) != NULL) { + + /* get next member for next run*/ + ptr = strchr(ptr, ','); + if(ptr) { + ptr[0] = '\x0'; + ptr++; + } + + strip(buf); + + /* find subgroup and recurse */ + if((sub_group = xodtemplate_find_real_hostgroup(buf)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in hostgroup (config file '%s', starting on line %d)\n", buf, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line); + return ERROR; + } + xodtemplate_recombobulate_hostgroup_subgroups(sub_group, &newmembers); + + /* add new (sub) members */ + if(newmembers != NULL) { + if(temp_hostgroup->members == NULL) + temp_hostgroup->members = (char *)strdup(newmembers); + else if((temp_hostgroup->members = realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(newmembers) + 2))) { + strcat(temp_hostgroup->members, ","); + strcat(temp_hostgroup->members, newmembers); + } + } + } + + /* free memory */ + my_free(hgmembers); + + /* restore group members */ + temp_hostgroup->hostgroup_members = orig_hgmembers; + } + + /* return host members */ + if(members != NULL) + *members = temp_hostgroup->members; + + return OK; + } + + + +/* recombobulates servicegroup definitions */ +/***** THIS NEEDS TO BE CALLED AFTER OBJECTS (SERVICES) ARE RESOLVED AND DUPLICATED *****/ +int xodtemplate_recombobulate_servicegroups(void) { + xodtemplate_service *temp_service = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_memberlist *temp_memberlist = NULL; + xodtemplate_memberlist *this_memberlist = NULL; + char *servicegroup_names = NULL; + char *member_names = NULL; + char *host_name = NULL; + char *service_description = NULL; + char *temp_ptr = NULL; + char *temp_ptr2 = NULL; + char *new_members = NULL; + + /* This should happen before we expand servicegroup members, to avoid duplicate service memberships 01/07/2006 EG */ + /* process all services that have servicegroup directives */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + /* skip services without servicegroup directives or service names */ + if(temp_service->service_groups == NULL || temp_service->host_name == NULL || temp_service->service_description == NULL) + continue; + + /* skip services that shouldn't be registered */ + if(temp_service->register_object == FALSE) + continue; + + /* preprocess the servicegroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */ + /* 10/19/07 EG an empry return value means an error occured */ + if((servicegroup_names = xodtemplate_process_servicegroup_names(temp_service->service_groups, temp_service->_config_file, temp_service->_start_line)) == NULL) + return ERROR; + + /* process the list of servicegroups */ + for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + /* strip trailing spaces */ + strip(temp_ptr); + + /* find the servicegroup */ + temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr); + if(temp_servicegroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find servicegroup '%s' specified in service '%s' on host '%s' definition (config file '%s', starting on line %d)\n", temp_ptr, temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line); + my_free(servicegroup_names); + return ERROR; + } + + /* add this list to the servicegroup members directive */ + if(temp_servicegroup->members == NULL) { + temp_servicegroup->members = (char *)malloc(strlen(temp_service->host_name) + strlen(temp_service->service_description) + 2); + if(temp_servicegroup->members != NULL) { + strcpy(temp_servicegroup->members, temp_service->host_name); + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, temp_service->service_description); + } + } + else { + new_members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(temp_service->host_name) + strlen(temp_service->service_description) + 3); + if(new_members != NULL) { + temp_servicegroup->members = new_members; + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, temp_service->host_name); + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, temp_service->service_description); + } + } + } + + /* free servicegroup names */ + my_free(servicegroup_names); + } + + + /* expand subgroup membership recursively */ + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup; temp_servicegroup = temp_servicegroup->next) + xodtemplate_recombobulate_servicegroup_subgroups(temp_servicegroup, NULL); + + /* expand members of all servicegroups - this could be done in xodtemplate_register_servicegroup(), but we can save the CGIs some work if we do it here */ + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup; temp_servicegroup = temp_servicegroup->next) { + + if(temp_servicegroup->members == NULL) + continue; + + /* skip servicegroups that shouldn't be registered */ + if(temp_servicegroup->register_object == FALSE) + continue; + + member_names = temp_servicegroup->members; + temp_servicegroup->members = NULL; + + for(temp_ptr = member_names; temp_ptr; temp_ptr = strchr(temp_ptr + 1, ',')) { + + /* this is the host name */ + if(host_name == NULL) + host_name = (char *)strdup((temp_ptr[0] == ',') ? temp_ptr + 1 : temp_ptr); + + /* this is the service description */ + else { + service_description = (char *)strdup(temp_ptr + 1); + + /* strsep and strtok cannot be used, as they're used in expand_servicegroups...() */ + temp_ptr2 = strchr(host_name, ','); + if(temp_ptr2) + temp_ptr2[0] = '\x0'; + temp_ptr2 = strchr(service_description, ','); + if(temp_ptr2) + temp_ptr2[0] = '\x0'; + + /* strip trailing spaces */ + strip(host_name); + strip(service_description); + + /* get list of services in the servicegroup */ + temp_memberlist = xodtemplate_expand_servicegroups_and_services(NULL, host_name, service_description, temp_servicegroup->_config_file, temp_servicegroup->_start_line); + + /* add all members to the service group */ + if(temp_memberlist == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand member services specified in servicegroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line); + my_free(member_names); + my_free(host_name); + my_free(service_description); + return ERROR; + } + + for(this_memberlist = temp_memberlist; this_memberlist; this_memberlist = this_memberlist->next) { + + /* add this service to the servicegroup members directive */ + if(temp_servicegroup->members == NULL) { + temp_servicegroup->members = (char *)malloc(strlen(this_memberlist->name1) + strlen(this_memberlist->name2) + 2); + if(temp_servicegroup != NULL) { + strcpy(temp_servicegroup->members, this_memberlist->name1); + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, this_memberlist->name2); + } + } + else { + new_members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(this_memberlist->name1) + strlen(this_memberlist->name2) + 3); + if(new_members != NULL) { + temp_servicegroup->members = new_members; + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, this_memberlist->name1); + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, this_memberlist->name2); + } + } + } + xodtemplate_free_memberlist(&temp_memberlist); + + my_free(host_name); + my_free(service_description); + } + } + + my_free(member_names); + + /* error if there were an odd number of items specified (unmatched host/service pair) */ + if(host_name != NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup members must be specified in , pairs (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line); + my_free(host_name); + return ERROR; + } + } + + return OK; + } + + + + +int xodtemplate_recombobulate_servicegroup_subgroups(xodtemplate_servicegroup *temp_servicegroup, char **members) { + xodtemplate_servicegroup *sub_group = NULL; + char *orig_sgmembers = NULL; + char *sgmembers = NULL; + char *newmembers = NULL; + char *buf = NULL; + char *ptr = NULL; + + if(temp_servicegroup == NULL) + return ERROR; + + /* resolve subgroup memberships first */ + if(temp_servicegroup->servicegroup_members != NULL) { + + /* save members, null pointer so we don't recurse into infinite hell */ + orig_sgmembers = temp_servicegroup->servicegroup_members; + temp_servicegroup->servicegroup_members = NULL; + + /* make new working copy of members */ + sgmembers = (char *)strdup(orig_sgmembers); + + ptr = sgmembers; + while((buf = ptr) != NULL) { + + /* get next member for next run*/ + ptr = strchr(ptr, ','); + if(ptr) { + ptr[0] = '\x0'; + ptr++; + } + + strip(buf); + + /* find subgroup and recurse */ + if((sub_group = xodtemplate_find_real_servicegroup(buf)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in servicegroup (config file '%s', starting on line %d)\n", buf, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line); + return ERROR; + } + xodtemplate_recombobulate_servicegroup_subgroups(sub_group, &newmembers); + + /* add new (sub) members */ + if(newmembers != NULL) { + if(temp_servicegroup->members == NULL) + temp_servicegroup->members = (char *)strdup(newmembers); + else if((temp_servicegroup->members = realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(newmembers) + 2))) { + strcat(temp_servicegroup->members, ","); + strcat(temp_servicegroup->members, newmembers); + } + } + } + + /* free memory */ + my_free(sgmembers); + + /* restore group members */ + temp_servicegroup->servicegroup_members = orig_sgmembers; + } + + /* return service members */ + if(members != NULL) + *members = temp_servicegroup->members; + + return OK; + } + +#endif + + + +/******************************************************************/ +/******************* OBJECT SEARCH FUNCTIONS **********************/ +/******************************************************************/ + +#ifdef NSCORE + +/* finds a specific timeperiod object */ +xodtemplate_timeperiod *xodtemplate_find_timeperiod(char *name) { + xodtemplate_timeperiod temp_timeperiod; + + if(name == NULL) + return NULL; + + temp_timeperiod.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_TIMEPERIOD_SKIPLIST], &temp_timeperiod, NULL); + } + + +/* finds a specific command object */ +xodtemplate_command *xodtemplate_find_command(char *name) { + xodtemplate_command temp_command; + + if(name == NULL) + return NULL; + + temp_command.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_COMMAND_SKIPLIST], &temp_command, NULL); + } + + +/* finds a specific contactgroup object */ +xodtemplate_contactgroup *xodtemplate_find_contactgroup(char *name) { + xodtemplate_contactgroup temp_contactgroup; + + if(name == NULL) + return NULL; + + temp_contactgroup.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL); + } + + +/* finds a specific contactgroup object by its REAL name, not its TEMPLATE name */ +xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *name) { + xodtemplate_contactgroup temp_contactgroup; + + if(name == NULL) + return NULL; + + temp_contactgroup.contactgroup_name = name; + + return skiplist_find_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL); + } + + +/* finds a specific hostgroup object */ +xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *name) { + xodtemplate_hostgroup temp_hostgroup; + + if(name == NULL) + return NULL; + + temp_hostgroup.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL); + } + + +/* finds a specific hostgroup object by its REAL name, not its TEMPLATE name */ +xodtemplate_hostgroup *xodtemplate_find_real_hostgroup(char *name) { + xodtemplate_hostgroup temp_hostgroup; + + if(name == NULL) + return NULL; + + temp_hostgroup.hostgroup_name = name; + + return skiplist_find_first(xobject_skiplists[X_HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL); + } + + +/* finds a specific servicegroup object */ +xodtemplate_servicegroup *xodtemplate_find_servicegroup(char *name) { + xodtemplate_servicegroup temp_servicegroup; + + if(name == NULL) + return NULL; + + temp_servicegroup.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL); + } + + +/* finds a specific servicegroup object by its REAL name, not its TEMPLATE name */ +xodtemplate_servicegroup *xodtemplate_find_real_servicegroup(char *name) { + xodtemplate_servicegroup temp_servicegroup; + + if(name == NULL) + return NULL; + + temp_servicegroup.servicegroup_name = name; + + return skiplist_find_first(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL); + } + + +/* finds a specific servicedependency object */ +xodtemplate_servicedependency *xodtemplate_find_servicedependency(char *name) { + xodtemplate_servicedependency temp_servicedependency; + + if(name == NULL) + return NULL; + + temp_servicedependency.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], &temp_servicedependency, NULL); + } + + +/* finds a specific serviceescalation object */ +xodtemplate_serviceescalation *xodtemplate_find_serviceescalation(char *name) { + xodtemplate_serviceescalation temp_serviceescalation; + + if(name == NULL) + return NULL; + + temp_serviceescalation.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, NULL); + } + + +/* finds a specific contact object */ +xodtemplate_contact *xodtemplate_find_contact(char *name) { + xodtemplate_contact temp_contact; + + if(name == NULL) + return NULL; + + temp_contact.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_CONTACT_SKIPLIST], &temp_contact, NULL); + } + + +/* finds a specific contact object by its REAL name, not its TEMPLATE name */ +xodtemplate_contact *xodtemplate_find_real_contact(char *name) { + xodtemplate_contact temp_contact; + + if(name == NULL) + return NULL; + + temp_contact.contact_name = name; + + return skiplist_find_first(xobject_skiplists[X_CONTACT_SKIPLIST], &temp_contact, NULL); + } + + +/* finds a specific host object */ +xodtemplate_host *xodtemplate_find_host(char *name) { + xodtemplate_host temp_host; + + if(name == NULL) + return NULL; + + temp_host.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_HOST_SKIPLIST], &temp_host, NULL); + } + + +/* finds a specific host object by its REAL name, not its TEMPLATE name */ +xodtemplate_host *xodtemplate_find_real_host(char *name) { + xodtemplate_host temp_host; + + if(name == NULL) + return NULL; + + temp_host.host_name = name; + + return skiplist_find_first(xobject_skiplists[X_HOST_SKIPLIST], &temp_host, NULL); + } + + +/* finds a specific hostdependency object */ +xodtemplate_hostdependency *xodtemplate_find_hostdependency(char *name) { + xodtemplate_hostdependency temp_hostdependency; + + if(name == NULL) + return NULL; + + temp_hostdependency.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_HOSTDEPENDENCY_SKIPLIST], &temp_hostdependency, NULL); + } + + +/* finds a specific hostescalation object */ +xodtemplate_hostescalation *xodtemplate_find_hostescalation(char *name) { + xodtemplate_hostescalation temp_hostescalation; + + if(name == NULL) + return NULL; + + temp_hostescalation.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_HOSTESCALATION_SKIPLIST], &temp_hostescalation, NULL); + } + + +/* finds a specific hostextinfo object */ +xodtemplate_hostextinfo *xodtemplate_find_hostextinfo(char *name) { + xodtemplate_hostextinfo temp_hostextinfo; + + if(name == NULL) + return NULL; + + temp_hostextinfo.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_HOSTEXTINFO_SKIPLIST], &temp_hostextinfo, NULL); + } + + +/* finds a specific serviceextinfo object */ +xodtemplate_serviceextinfo *xodtemplate_find_serviceextinfo(char *name) { + xodtemplate_serviceextinfo temp_serviceextinfo; + + if(name == NULL) + return NULL; + + temp_serviceextinfo.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_SERVICEEXTINFO_SKIPLIST], &temp_serviceextinfo, NULL); + } + + +/* finds a specific service object */ +xodtemplate_service *xodtemplate_find_service(char *name) { + xodtemplate_service temp_service; + + if(name == NULL) + return NULL; + + temp_service.name = name; + + return skiplist_find_first(xobject_template_skiplists[X_SERVICE_SKIPLIST], &temp_service, NULL); + } + + +/* finds a specific service object by its REAL name, not its TEMPLATE name */ +xodtemplate_service *xodtemplate_find_real_service(char *host_name, char *service_description) { + xodtemplate_service temp_service; + + if(host_name == NULL || service_description == NULL) + return NULL; + + temp_service.host_name = host_name; + temp_service.service_description = service_description; + + return skiplist_find_first(xobject_skiplists[X_SERVICE_SKIPLIST], &temp_service, NULL); + } + +#endif + + + +/******************************************************************/ +/**************** OBJECT REGISTRATION FUNCTIONS *******************/ +/******************************************************************/ + +/* registers object definitions */ +int xodtemplate_register_objects(void) { + int result = OK; + xodtemplate_timeperiod *temp_timeperiod = NULL; + xodtemplate_command *temp_command = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_contact *temp_contact = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + void *ptr = NULL; + + /* register timeperiods */ + /*for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){*/ + ptr = NULL; + for(temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_first(xobject_skiplists[X_TIMEPERIOD_SKIPLIST], &ptr); temp_timeperiod != NULL; temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_timeperiod(temp_timeperiod)) == ERROR) + return ERROR; + } + + /* register commands */ + /*for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){*/ + ptr = NULL; + for(temp_command = (xodtemplate_command *)skiplist_get_first(xobject_skiplists[X_COMMAND_SKIPLIST], &ptr); temp_command != NULL; temp_command = (xodtemplate_command *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_command(temp_command)) == ERROR) + return ERROR; + } + + /* register contactgroups */ + /*for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){*/ + ptr = NULL; + for(temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], &ptr); temp_contactgroup != NULL; temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_contactgroup(temp_contactgroup)) == ERROR) + return ERROR; + } + + /* register hostgroups */ + /*for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){*/ + ptr = NULL; + for(temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_first(xobject_skiplists[X_HOSTGROUP_SKIPLIST], &ptr); temp_hostgroup != NULL; temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_hostgroup(temp_hostgroup)) == ERROR) + return ERROR; + } + + /* register servicegroups */ + /*for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){*/ + ptr = NULL; + for(temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_first(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], &ptr); temp_servicegroup != NULL; temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_servicegroup(temp_servicegroup)) == ERROR) + return ERROR; + } + + /* register contacts */ + /*for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){*/ + ptr = NULL; + for(temp_contact = (xodtemplate_contact *)skiplist_get_first(xobject_skiplists[X_CONTACT_SKIPLIST], &ptr); temp_contact != NULL; temp_contact = (xodtemplate_contact *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_contact(temp_contact)) == ERROR) + return ERROR; + } + + /* register hosts */ + /*for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){*/ + ptr = NULL; + for(temp_host = (xodtemplate_host *)skiplist_get_first(xobject_skiplists[X_HOST_SKIPLIST], &ptr); temp_host != NULL; temp_host = (xodtemplate_host *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_host(temp_host)) == ERROR) + return ERROR; + } + + /* register services */ + /*for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){*/ + ptr = NULL; + for(temp_service = (xodtemplate_service *)skiplist_get_first(xobject_skiplists[X_SERVICE_SKIPLIST], &ptr); temp_service != NULL; temp_service = (xodtemplate_service *)skiplist_get_next(&ptr)) { + + if((result = xodtemplate_register_service(temp_service)) == ERROR) + return ERROR; + } + + /* register service dependencies */ + /*for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){*/ + ptr = NULL; + for(temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_first(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], &ptr); temp_servicedependency != NULL; temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_servicedependency(temp_servicedependency)) == ERROR) + return ERROR; + } + + /* register service escalations */ + /*for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){*/ + ptr = NULL; + for(temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_first(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], &ptr); temp_serviceescalation != NULL; temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_serviceescalation(temp_serviceescalation)) == ERROR) + return ERROR; + } + + /* register host dependencies */ + /*for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){*/ + ptr = NULL; + for(temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_first(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], &ptr); temp_hostdependency != NULL; temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_hostdependency(temp_hostdependency)) == ERROR) + return ERROR; + } + + /* register host escalations */ + /*for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){*/ + ptr = NULL; + for(temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_first(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], &ptr); temp_hostescalation != NULL; temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_next(&ptr)) { + if((result = xodtemplate_register_hostescalation(temp_hostescalation)) == ERROR) + return ERROR; + } + + return OK; + } + + + +/* registers a timeperiod definition */ +int xodtemplate_register_timeperiod(xodtemplate_timeperiod *this_timeperiod) { + xodtemplate_daterange *temp_daterange = NULL; + timeperiod *new_timeperiod = NULL; + daterange *new_daterange = NULL; + timerange *new_timerange = NULL; + timeperiodexclusion *new_timeperiodexclusion = NULL; + int day = 0; + int range = 0; + int x = 0; + char *day_range_ptr = NULL; + char *day_range_start_buffer = NULL; + char *temp_ptr = NULL; + unsigned long range_start_time = 0L; + unsigned long range_end_time = 0L; + + + /* bail out if we shouldn't register this object */ + if(this_timeperiod->register_object == FALSE) + return OK; + + /* add the timeperiod */ + new_timeperiod = add_timeperiod(this_timeperiod->timeperiod_name, this_timeperiod->alias); + + /* return with an error if we couldn't add the timeperiod */ + if(new_timeperiod == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register timeperiod (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + + /* add all exceptions to timeperiod */ + for(x = 0; x < DATERANGE_TYPES; x++) { + for(temp_daterange = this_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) { + + /* skip null entries */ + if(temp_daterange->timeranges == NULL || !strcmp(temp_daterange->timeranges, XODTEMPLATE_NULL)) + continue; + + /* add new exception to timeperiod */ + new_daterange = add_exception_to_timeperiod(new_timeperiod, temp_daterange->type, temp_daterange->syear, temp_daterange->smon, temp_daterange->smday, temp_daterange->swday, temp_daterange->swday_offset, temp_daterange->eyear, temp_daterange->emon, temp_daterange->emday, temp_daterange->ewday, temp_daterange->ewday_offset, temp_daterange->skip_interval); + if(new_daterange == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add date exception to timeperiod (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + + /* add timeranges to exception */ + day_range_ptr = temp_daterange->timeranges; + range = 0; + for(day_range_start_buffer = my_strsep(&day_range_ptr, ", "); day_range_start_buffer != NULL; day_range_start_buffer = my_strsep(&day_range_ptr, ", ")) { + + range++; + + /* get time ranges */ + if(xodtemplate_get_time_ranges(day_range_start_buffer, &range_start_time, &range_end_time) == ERROR) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not parse timerange #%d of timeperiod (config file '%s', starting on line %d)\n", range, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + + /* add the new time range to the date range */ + new_timerange = add_timerange_to_daterange(new_daterange, range_start_time, range_end_time); + if(new_timerange == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add timerange #%d to timeperiod (config file '%s', starting on line %d)\n", range, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + } + } + } + + /* add all necessary timeranges to timeperiod */ + for(day = 0; day < 7; day++) { + + /* skip null entries */ + if(this_timeperiod->timeranges[day] == NULL || !strcmp(this_timeperiod->timeranges[day], XODTEMPLATE_NULL)) + continue; + + day_range_ptr = this_timeperiod->timeranges[day]; + range = 0; + for(day_range_start_buffer = my_strsep(&day_range_ptr, ", "); day_range_start_buffer != NULL; day_range_start_buffer = my_strsep(&day_range_ptr, ", ")) { + + range++; + + /* get time ranges */ + if(xodtemplate_get_time_ranges(day_range_start_buffer, &range_start_time, &range_end_time) == ERROR) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not parse timerange #%d for day %d of timeperiod (config file '%s', starting on line %d)\n", range, day, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + + /* add the new time range to the time period */ + new_timerange = add_timerange_to_timeperiod(new_timeperiod, day, range_start_time, range_end_time); + if(new_timerange == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add timerange #%d for day %d to timeperiod (config file '%s', starting on line %d)\n", range, day, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + } + + } + + /* add timeperiod exclusions */ + if(this_timeperiod->exclusions) { + for(temp_ptr = strtok(this_timeperiod->exclusions, ","); temp_ptr != NULL; temp_ptr = strtok(NULL, ",")) { + strip(temp_ptr); + new_timeperiodexclusion = add_exclusion_to_timeperiod(new_timeperiod, temp_ptr); + if(new_timeperiodexclusion == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add excluded timeperiod '%s' to timeperiod (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line); + return ERROR; + } + } + } + + return OK; + } + + + +/* parses timerange string into start and end minutes */ +int xodtemplate_get_time_ranges(char *buf, unsigned long *range_start, unsigned long *range_end) { + char *range_ptr = NULL; + char *range_buffer = NULL; + char *time_ptr = NULL; + char *time_buffer = NULL; + int hours = 0; + int minutes = 0; + + if(buf == NULL || range_start == NULL || range_end == NULL) + return ERROR; + + range_ptr = buf; + range_buffer = my_strsep(&range_ptr, "-"); + if(range_buffer == NULL) + return ERROR; + + time_ptr = range_buffer; + time_buffer = my_strsep(&time_ptr, ":"); + if(time_buffer == NULL) + return ERROR; + hours = atoi(time_buffer); + + time_buffer = my_strsep(&time_ptr, ":"); + if(time_buffer == NULL) + return ERROR; + minutes = atoi(time_buffer); + + /* calculate the range start time in seconds */ + *range_start = (unsigned long)((minutes * 60) + (hours * 60 * 60)); + + range_buffer = my_strsep(&range_ptr, "-"); + if(range_buffer == NULL) + return ERROR; + + time_ptr = range_buffer; + time_buffer = my_strsep(&time_ptr, ":"); + if(time_buffer == NULL) + return ERROR; + hours = atoi(time_buffer); + + time_buffer = my_strsep(&time_ptr, ":"); + if(time_buffer == NULL) + return ERROR; + minutes = atoi(time_buffer); + + /* calculate the range end time in seconds */ + *range_end = (unsigned long)((minutes * 60) + (hours * 3600)); + + return OK; + } + + + +/* registers a command definition */ +int xodtemplate_register_command(xodtemplate_command *this_command) { + command *new_command = NULL; + + /* bail out if we shouldn't register this object */ + if(this_command->register_object == FALSE) + return OK; + + /* add the command */ + new_command = add_command(this_command->command_name, this_command->command_line); + + /* return with an error if we couldn't add the command */ + if(new_command == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register command (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_command->_config_file), this_command->_start_line); + return ERROR; + } + + return OK; + } + + + +/* registers a contactgroup definition */ +int xodtemplate_register_contactgroup(xodtemplate_contactgroup *this_contactgroup) { + contactgroup *new_contactgroup = NULL; + contactsmember *new_contactsmember = NULL; + char *contact_name = NULL; + + /* bail out if we shouldn't register this object */ + if(this_contactgroup->register_object == FALSE) + return OK; + + /* add the contact group */ + new_contactgroup = add_contactgroup(this_contactgroup->contactgroup_name, this_contactgroup->alias); + + /* return with an error if we couldn't add the contactgroup */ + if(new_contactgroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register contactgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line); + return ERROR; + } + + /* Need to check for NULL because strtok could use a NULL value to check the previous string's token value */ + if(this_contactgroup->members != NULL) { + for(contact_name = strtok(this_contactgroup->members, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) { + strip(contact_name); + new_contactsmember = add_contact_to_contactgroup(new_contactgroup, contact_name); + if(new_contactsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to contactgroup (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line); + return ERROR; + } + } + } + + return OK; + } + + + +/* registers a hostgroup definition */ +int xodtemplate_register_hostgroup(xodtemplate_hostgroup *this_hostgroup) { + hostgroup *new_hostgroup = NULL; + hostsmember *new_hostsmember = NULL; + char *host_name = NULL; + + /* bail out if we shouldn't register this object */ + if(this_hostgroup->register_object == FALSE) + return OK; + + /* add the host group */ + new_hostgroup = add_hostgroup(this_hostgroup->hostgroup_name, this_hostgroup->alias, this_hostgroup->notes, this_hostgroup->notes_url, this_hostgroup->action_url); + + /* return with an error if we couldn't add the hostgroup */ + if(new_hostgroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register hostgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line); + return ERROR; + } + + if(this_hostgroup->members != NULL) { + for(host_name = strtok(this_hostgroup->members, ","); host_name != NULL; host_name = strtok(NULL, ",")) { + strip(host_name); + new_hostsmember = add_host_to_hostgroup(new_hostgroup, host_name); + if(new_hostsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host '%s' to hostgroup (config file '%s', starting on line %d)\n", host_name, xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line); + return ERROR; + } + } + } + + return OK; + } + + + +/* registers a servicegroup definition */ +int xodtemplate_register_servicegroup(xodtemplate_servicegroup *this_servicegroup) { + servicegroup *new_servicegroup = NULL; + servicesmember *new_servicesmember = NULL; + char *host_name = NULL; + char *svc_description = NULL; + + /* bail out if we shouldn't register this object */ + if(this_servicegroup->register_object == FALSE) + return OK; + + /* add the service group */ + new_servicegroup = add_servicegroup(this_servicegroup->servicegroup_name, this_servicegroup->alias, this_servicegroup->notes, this_servicegroup->notes_url, this_servicegroup->action_url); + + /* return with an error if we couldn't add the servicegroup */ + if(new_servicegroup == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register servicegroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line); + return ERROR; + } + + if(this_servicegroup->members != NULL) { + for(host_name = strtok(this_servicegroup->members, ","); host_name != NULL; host_name = strtok(NULL, ",")) { + strip(host_name); + svc_description = strtok(NULL, ","); + if(svc_description == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Missing service name in servicegroup definition (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line); + return ERROR; + } + strip(svc_description); + + new_servicesmember = add_service_to_servicegroup(new_servicegroup, host_name, svc_description); + if(new_servicesmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service '%s' on host '%s' to servicegroup (config file '%s', starting on line %d)\n", svc_description, host_name, xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line); + return ERROR; + } + } + } + + return OK; + } + + + +/* registers a servicedependency definition */ +int xodtemplate_register_servicedependency(xodtemplate_servicedependency *this_servicedependency) { + servicedependency *new_servicedependency = NULL; + + /* bail out if we shouldn't register this object */ + if(this_servicedependency->register_object == FALSE) + return OK; + + /* throw a warning on servicedeps that have no options */ + if(this_servicedependency->have_notification_dependency_options == FALSE && this_servicedependency->have_execution_dependency_options == FALSE) { + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Ignoring lame service dependency (config file '%s', line %d)\n", xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line); + return OK; + } + + /* add the servicedependency */ + if(this_servicedependency->have_execution_dependency_options == TRUE) { + + new_servicedependency = add_service_dependency(this_servicedependency->dependent_host_name, this_servicedependency->dependent_service_description, this_servicedependency->host_name, this_servicedependency->service_description, EXECUTION_DEPENDENCY, this_servicedependency->inherits_parent, this_servicedependency->fail_execute_on_ok, this_servicedependency->fail_execute_on_warning, this_servicedependency->fail_execute_on_unknown, this_servicedependency->fail_execute_on_critical, this_servicedependency->fail_execute_on_pending, this_servicedependency->dependency_period); + + /* return with an error if we couldn't add the servicedependency */ + if(new_servicedependency == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service execution dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line); + return ERROR; + } + } + if(this_servicedependency->have_notification_dependency_options == TRUE) { + + new_servicedependency = add_service_dependency(this_servicedependency->dependent_host_name, this_servicedependency->dependent_service_description, this_servicedependency->host_name, this_servicedependency->service_description, NOTIFICATION_DEPENDENCY, this_servicedependency->inherits_parent, this_servicedependency->fail_notify_on_ok, this_servicedependency->fail_notify_on_warning, this_servicedependency->fail_notify_on_unknown, this_servicedependency->fail_notify_on_critical, this_servicedependency->fail_notify_on_pending, this_servicedependency->dependency_period); + + /* return with an error if we couldn't add the servicedependency */ + if(new_servicedependency == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service notification dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line); + return ERROR; + } + } + + return OK; + } + + + +/* registers a serviceescalation definition */ +int xodtemplate_register_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation) { + serviceescalation *new_serviceescalation = NULL; + contactsmember *new_contactsmember = NULL; + contactgroupsmember *new_contactgroupsmember = NULL; + char *contact_name = NULL; + char *contact_group = NULL; + + /* bail out if we shouldn't register this object */ + if(this_serviceescalation->register_object == FALSE) + return OK; + + /* default options if none specified */ + if(this_serviceescalation->have_escalation_options == FALSE) { + this_serviceescalation->escalate_on_warning = TRUE; + this_serviceescalation->escalate_on_unknown = TRUE; + this_serviceescalation->escalate_on_critical = TRUE; + this_serviceescalation->escalate_on_recovery = TRUE; + } + + /* add the serviceescalation */ + new_serviceescalation = add_serviceescalation(this_serviceescalation->host_name, this_serviceescalation->service_description, this_serviceescalation->first_notification, this_serviceescalation->last_notification, this_serviceescalation->notification_interval, this_serviceescalation->escalation_period, this_serviceescalation->escalate_on_warning, this_serviceescalation->escalate_on_unknown, this_serviceescalation->escalate_on_critical, this_serviceescalation->escalate_on_recovery); + + /* return with an error if we couldn't add the serviceescalation */ + if(new_serviceescalation == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line); + return ERROR; + } + + /* add the contact groups */ + if(this_serviceescalation->contact_groups != NULL) { + + for(contact_group = strtok(this_serviceescalation->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ", ")) { + + strip(contact_group); + new_contactgroupsmember = add_contactgroup_to_serviceescalation(new_serviceescalation, contact_group); + if(new_contactgroupsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to service escalation (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line); + return ERROR; + } + } + } + + /* add the contacts */ + if(this_serviceescalation->contacts != NULL) { + + for(contact_name = strtok(this_serviceescalation->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ", ")) { + + strip(contact_name); + new_contactsmember = add_contact_to_serviceescalation(new_serviceescalation, contact_name); + if(new_contactsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to service escalation (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line); + return ERROR; + } + } + } + + return OK; + } + + + +/* registers a contact definition */ +int xodtemplate_register_contact(xodtemplate_contact *this_contact) { + contact *new_contact = NULL; + char *command_name = NULL; + commandsmember *new_commandsmember = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + + /* bail out if we shouldn't register this object */ + if(this_contact->register_object == FALSE) + return OK; + + /* add the contact */ + new_contact = add_contact(this_contact->contact_name, this_contact->alias, this_contact->email, this_contact->pager, this_contact->address, this_contact->service_notification_period, this_contact->host_notification_period, this_contact->notify_on_service_recovery, this_contact->notify_on_service_critical, this_contact->notify_on_service_warning, this_contact->notify_on_service_unknown, this_contact->notify_on_service_flapping, this_contact->notify_on_service_downtime, this_contact->notify_on_host_recovery, this_contact->notify_on_host_down, this_contact->notify_on_host_unreachable, this_contact->notify_on_host_flapping, this_contact->notify_on_host_downtime, this_contact->host_notifications_enabled, this_contact->service_notifications_enabled, this_contact->can_submit_commands, this_contact->retain_status_information, this_contact->retain_nonstatus_information); + + /* return with an error if we couldn't add the contact */ + if(new_contact == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register contact (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line); + return ERROR; + } + + /* add all the host notification commands */ + if(this_contact->host_notification_commands != NULL) { + + for(command_name = strtok(this_contact->host_notification_commands, ", "); command_name != NULL; command_name = strtok(NULL, ", ")) { + new_commandsmember = add_host_notification_command_to_contact(new_contact, command_name); + if(new_commandsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host notification command '%s' to contact (config file '%s', starting on line %d)\n", command_name, xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line); + return ERROR; + } + } + } + + /* add all the service notification commands */ + if(this_contact->service_notification_commands != NULL) { + + for(command_name = strtok(this_contact->service_notification_commands, ", "); command_name != NULL; command_name = strtok(NULL, ", ")) { + new_commandsmember = add_service_notification_command_to_contact(new_contact, command_name); + if(new_commandsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service notification command '%s' to contact (config file '%s', starting on line %d)\n", command_name, xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line); + return ERROR; + } + } + } + + /* add all custom variables */ + for(temp_customvariablesmember = this_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if((add_custom_variable_to_contact(new_contact, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not custom variable to contact (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line); + return ERROR; + } + } + + return OK; + } + + + +/* registers a host definition */ +int xodtemplate_register_host(xodtemplate_host *this_host) { + host *new_host = NULL; + char *parent_host = NULL; + hostsmember *new_hostsmember = NULL; + contactsmember *new_contactsmember = NULL; + contactgroupsmember *new_contactgroupsmember = NULL; + char *contact_name = NULL; + char *contact_group = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + + /* bail out if we shouldn't register this object */ + if(this_host->register_object == FALSE) + return OK; + + /* if host has no alias or address, use host name - added 3/11/05 */ + if(this_host->alias == NULL && this_host->host_name != NULL) + this_host->alias = (char *)strdup(this_host->host_name); + if(this_host->address == NULL && this_host->host_name != NULL) + this_host->address = (char *)strdup(this_host->host_name); + + /* add the host definition */ + new_host = add_host(this_host->host_name, this_host->display_name, this_host->alias, (this_host->address == NULL) ? this_host->host_name : this_host->address, this_host->check_period, this_host->initial_state, this_host->check_interval, this_host->retry_interval, this_host->max_check_attempts, this_host->notify_on_recovery, this_host->notify_on_down, this_host->notify_on_unreachable, this_host->notify_on_flapping, this_host->notify_on_downtime, this_host->notification_interval, this_host->first_notification_delay, this_host->notification_period, this_host->notifications_enabled, this_host->check_command, this_host->active_checks_enabled, this_host->passive_checks_enabled, this_host->event_handler, this_host->event_handler_enabled, this_host->flap_detection_enabled, this_host->low_flap_threshold, this_host->high_flap_threshold, this_host->flap_detection_on_up, this_host->flap_detection_on_down, this_host->flap_detection_on_unreachable, this_host->stalk_on_up, this_host->stalk_on_down, this_host->stalk_on_unreachable, this_host->process_perf_data, this_host->failure_prediction_enabled, this_host->failure_prediction_options, this_host->check_freshness, this_host->freshness_threshold, this_host->notes, this_host->notes_url, this_host->action_url, this_host->icon_image, this_host->icon_image_alt, this_host->vrml_image, this_host->statusmap_image, this_host->x_2d, this_host->y_2d, this_host->have_2d_coords, this_host->x_3d, this_host->y_3d, this_host->z_3d, this_host->have_3d_coords, TRUE, this_host->retain_status_information, this_host->retain_nonstatus_information, this_host->obsess_over_host); + + + /* return with an error if we couldn't add the host */ + if(new_host == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line); + return ERROR; + } + + /* add the parent hosts */ + if(this_host->parents != NULL) { + + for(parent_host = strtok(this_host->parents, ","); parent_host != NULL; parent_host = strtok(NULL, ",")) { + strip(parent_host); + new_hostsmember = add_parent_host_to_host(new_host, parent_host); + if(new_hostsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add parent host '%s' to host (config file '%s', starting on line %d)\n", parent_host, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line); + return ERROR; + } + } + } + + /* add all contact groups to the host */ + if(this_host->contact_groups != NULL) { + + for(contact_group = strtok(this_host->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) { + + strip(contact_group); + new_contactgroupsmember = add_contactgroup_to_host(new_host, contact_group); + if(new_contactgroupsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to host (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line); + return ERROR; + } + } + } + + /* add all contacts to the host */ + if(this_host->contacts != NULL) { + + for(contact_name = strtok(this_host->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) { + + strip(contact_name); + new_contactsmember = add_contact_to_host(new_host, contact_name); + if(new_contactsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to host (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line); + return ERROR; + } + } + } + + /* add all custom variables */ + for(temp_customvariablesmember = this_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if((add_custom_variable_to_host(new_host, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not custom variable to host (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line); + return ERROR; + } + } + + return OK; + } + + + +/* registers a service definition */ +int xodtemplate_register_service(xodtemplate_service *this_service) { + service *new_service = NULL; + contactsmember *new_contactsmember = NULL; + contactgroupsmember *new_contactgroupsmember = NULL; + char *contact_name = NULL; + char *contact_group = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + + /* bail out if we shouldn't register this object */ + if(this_service->register_object == FALSE) + return OK; + + /* add the service */ + new_service = add_service(this_service->host_name, this_service->service_description, this_service->display_name, this_service->check_period, this_service->initial_state, this_service->max_check_attempts, this_service->parallelize_check, this_service->passive_checks_enabled, this_service->check_interval, this_service->retry_interval, this_service->notification_interval, this_service->first_notification_delay, this_service->notification_period, this_service->notify_on_recovery, this_service->notify_on_unknown, this_service->notify_on_warning, this_service->notify_on_critical, this_service->notify_on_flapping, this_service->notify_on_downtime, this_service->notifications_enabled, this_service->is_volatile, this_service->event_handler, this_service->event_handler_enabled, this_service->check_command, this_service->active_checks_enabled, this_service->flap_detection_enabled, this_service->low_flap_threshold, this_service->high_flap_threshold, this_service->flap_detection_on_ok, this_service->flap_detection_on_warning, this_service->flap_detection_on_unknown, this_service->flap_detection_on_critical, this_service->stalk_on_ok, this_service->stalk_on_warning, this_service->stalk_on_unknown, this_service->stalk_on_critical, this_service->process_perf_data, this_service->failure_prediction_enabled, this_service->failure_prediction_options, this_service->check_freshness, this_service->freshness_threshold, this_service->notes, this_service->notes_url, this_service->action_url, this_service->icon_image, this_service->icon_image_alt, this_service->retain_status_information, this_service->retain_nonstatus_information, this_service->obsess_over_service); + + /* return with an error if we couldn't add the service */ + if(new_service == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line); + return ERROR; + } + + /* add all contact groups to the service */ + if(this_service->contact_groups != NULL) { + + for(contact_group = strtok(this_service->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) { + + strip(contact_group); + new_contactgroupsmember = add_contactgroup_to_service(new_service, contact_group); + if(new_contactgroupsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to service (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line); + return ERROR; + } + } + } + + /* add all the contacts to the service */ + if(this_service->contacts != NULL) { + + for(contact_name = strtok(this_service->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) { + + /* add this contact to the service definition */ + strip(contact_name); + new_contactsmember = add_contact_to_service(new_service, contact_name); + + /* stop adding contacts if we ran into an error */ + if(new_contactsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to service (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line); + return ERROR; + } + } + } + + /* add all custom variables */ + for(temp_customvariablesmember = this_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if((add_custom_variable_to_service(new_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not custom variable to service (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line); + return ERROR; + } + } + + return OK; + } + + + +/* registers a hostdependency definition */ +int xodtemplate_register_hostdependency(xodtemplate_hostdependency *this_hostdependency) { + hostdependency *new_hostdependency = NULL; + + /* bail out if we shouldn't register this object */ + if(this_hostdependency->register_object == FALSE) + return OK; + + /* add the host execution dependency */ + if(this_hostdependency->have_execution_dependency_options == TRUE) { + + new_hostdependency = add_host_dependency(this_hostdependency->dependent_host_name, this_hostdependency->host_name, EXECUTION_DEPENDENCY, this_hostdependency->inherits_parent, this_hostdependency->fail_execute_on_up, this_hostdependency->fail_execute_on_down, this_hostdependency->fail_execute_on_unreachable, this_hostdependency->fail_execute_on_pending, this_hostdependency->dependency_period); + + /* return with an error if we couldn't add the hostdependency */ + if(new_hostdependency == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host execution dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostdependency->_config_file), this_hostdependency->_start_line); + return ERROR; + } + } + + /* add the host notification dependency */ + if(this_hostdependency->have_notification_dependency_options == TRUE) { + + new_hostdependency = add_host_dependency(this_hostdependency->dependent_host_name, this_hostdependency->host_name, NOTIFICATION_DEPENDENCY, this_hostdependency->inherits_parent, this_hostdependency->fail_notify_on_up, this_hostdependency->fail_notify_on_down, this_hostdependency->fail_notify_on_unreachable, this_hostdependency->fail_notify_on_pending, this_hostdependency->dependency_period); + + /* return with an error if we couldn't add the hostdependency */ + if(new_hostdependency == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host notification dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostdependency->_config_file), this_hostdependency->_start_line); + return ERROR; + } + } + + return OK; + } + + + +/* registers a hostescalation definition */ +int xodtemplate_register_hostescalation(xodtemplate_hostescalation *this_hostescalation) { + hostescalation *new_hostescalation = NULL; + contactsmember *new_contactsmember = NULL; + contactgroupsmember *new_contactgroupsmember = NULL; + char *contact_name = NULL; + char *contact_group = NULL; + + /* bail out if we shouldn't register this object */ + if(this_hostescalation->register_object == FALSE) + return OK; + + /* default options if none specified */ + if(this_hostescalation->have_escalation_options == FALSE) { + this_hostescalation->escalate_on_down = TRUE; + this_hostescalation->escalate_on_unreachable = TRUE; + this_hostescalation->escalate_on_recovery = TRUE; + } + + /* add the hostescalation */ + new_hostescalation = add_hostescalation(this_hostescalation->host_name, this_hostescalation->first_notification, this_hostescalation->last_notification, this_hostescalation->notification_interval, this_hostescalation->escalation_period, this_hostescalation->escalate_on_down, this_hostescalation->escalate_on_unreachable, this_hostescalation->escalate_on_recovery); + + /* return with an error if we couldn't add the hostescalation */ + if(new_hostescalation == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line); + return ERROR; + } + + /* add all contact groups */ + if(this_hostescalation->contact_groups != NULL) { + + for(contact_group = strtok(this_hostescalation->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) { + + strip(contact_group); + new_contactgroupsmember = add_contactgroup_to_hostescalation(new_hostescalation, contact_group); + if(new_contactgroupsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to host escalation (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line); + return ERROR; + } + } + } + + /* add the contacts */ + if(this_hostescalation->contacts != NULL) { + + for(contact_name = strtok(this_hostescalation->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ", ")) { + + strip(contact_name); + new_contactsmember = add_contact_to_hostescalation(new_hostescalation, contact_name); + if(new_contactsmember == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to host escalation (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line); + return ERROR; + } + } + } + + return OK; + } + + + + +/******************************************************************/ +/********************** SORTING FUNCTIONS *************************/ +/******************************************************************/ + +#ifdef NSCORE + +/* sorts all objects by name */ +int xodtemplate_sort_objects(void) { + + /* NOTE: with skiplists, we no longer need to sort things manually... */ + return OK; + + /* sort timeperiods */ + if(xodtemplate_sort_timeperiods() == ERROR) + return ERROR; + + /* sort commands */ + if(xodtemplate_sort_commands() == ERROR) + return ERROR; + + /* sort contactgroups */ + if(xodtemplate_sort_contactgroups() == ERROR) + return ERROR; + + /* sort hostgroups */ + if(xodtemplate_sort_hostgroups() == ERROR) + return ERROR; + + /* sort servicegroups */ + if(xodtemplate_sort_servicegroups() == ERROR) + return ERROR; + + /* sort contacts */ + if(xodtemplate_sort_contacts() == ERROR) + return ERROR; + + /* sort hosts */ + if(xodtemplate_sort_hosts() == ERROR) + return ERROR; + + /* sort services */ + if(xodtemplate_sort_services() == ERROR) + return ERROR; + + /* sort service dependencies */ + if(xodtemplate_sort_servicedependencies() == ERROR) + return ERROR; + + /* sort service escalations */ + if(xodtemplate_sort_serviceescalations() == ERROR) + return ERROR; + + /* sort host dependencies */ + if(xodtemplate_sort_hostdependencies() == ERROR) + return ERROR; + + /* sort hostescalations */ + if(xodtemplate_sort_hostescalations() == ERROR) + return ERROR; + + /* sort host extended info */ + /* NOT NEEDED */ + + /* sort service extended info */ + /* NOT NEEDED */ + + return OK; + } + + +/* used to compare two strings (object names) */ +int xodtemplate_compare_strings1(char *string1, char *string2) { + + if(string1 == NULL && string2 == NULL) + return 0; + else if(string1 == NULL) + return -1; + else if(string2 == NULL) + return 1; + else + return strcmp(string1, string2); + } + + +/* used to compare two sets of strings (dually-named objects, i.e. services) */ +int xodtemplate_compare_strings2(char *string1a, char *string1b, char *string2a, char *string2b) { + int result; + + if((result = xodtemplate_compare_strings1(string1a, string2a)) == 0) + result = xodtemplate_compare_strings1(string1b, string2b); + + return result; + } + + +/* sort timeperiods by name */ +int xodtemplate_sort_timeperiods() { + xodtemplate_timeperiod *new_timeperiod_list = NULL; + xodtemplate_timeperiod *temp_timeperiod = NULL; + xodtemplate_timeperiod *last_timeperiod = NULL; + xodtemplate_timeperiod *temp_timeperiod_orig = NULL; + xodtemplate_timeperiod *next_timeperiod_orig = NULL; + + /* sort all existing timeperiods */ + for(temp_timeperiod_orig = xodtemplate_timeperiod_list; temp_timeperiod_orig != NULL; temp_timeperiod_orig = next_timeperiod_orig) { + + next_timeperiod_orig = temp_timeperiod_orig->next; + + /* add timeperiod to new list, sorted by timeperiod name */ + last_timeperiod = new_timeperiod_list; + for(temp_timeperiod = new_timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) { + + if(xodtemplate_compare_strings1(temp_timeperiod_orig->timeperiod_name, temp_timeperiod->timeperiod_name) <= 0) + break; + else + last_timeperiod = temp_timeperiod; + } + + /* first item added to new sorted list */ + if(new_timeperiod_list == NULL) { + temp_timeperiod_orig->next = NULL; + new_timeperiod_list = temp_timeperiod_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_timeperiod == new_timeperiod_list) { + temp_timeperiod_orig->next = new_timeperiod_list; + new_timeperiod_list = temp_timeperiod_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_timeperiod_orig->next = temp_timeperiod; + last_timeperiod->next = temp_timeperiod_orig; + } + } + + /* list is now sorted */ + xodtemplate_timeperiod_list = new_timeperiod_list; + + return OK; + } + + +/* sort commands by name */ +int xodtemplate_sort_commands() { + xodtemplate_command *new_command_list = NULL; + xodtemplate_command *temp_command = NULL; + xodtemplate_command *last_command = NULL; + xodtemplate_command *temp_command_orig = NULL; + xodtemplate_command *next_command_orig = NULL; + + /* sort all existing commands */ + for(temp_command_orig = xodtemplate_command_list; temp_command_orig != NULL; temp_command_orig = next_command_orig) { + + next_command_orig = temp_command_orig->next; + + /* add command to new list, sorted by command name */ + last_command = new_command_list; + for(temp_command = new_command_list; temp_command != NULL; temp_command = temp_command->next) { + + if(xodtemplate_compare_strings1(temp_command_orig->command_name, temp_command->command_name) <= 0) + break; + else + last_command = temp_command; + } + + /* first item added to new sorted list */ + if(new_command_list == NULL) { + temp_command_orig->next = NULL; + new_command_list = temp_command_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_command == new_command_list) { + temp_command_orig->next = new_command_list; + new_command_list = temp_command_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_command_orig->next = temp_command; + last_command->next = temp_command_orig; + } + } + + /* list is now sorted */ + xodtemplate_command_list = new_command_list; + + return OK; + } + + +/* sort contactgroups by name */ +int xodtemplate_sort_contactgroups() { + xodtemplate_contactgroup *new_contactgroup_list = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_contactgroup *last_contactgroup = NULL; + xodtemplate_contactgroup *temp_contactgroup_orig = NULL; + xodtemplate_contactgroup *next_contactgroup_orig = NULL; + + /* sort all existing contactgroups */ + for(temp_contactgroup_orig = xodtemplate_contactgroup_list; temp_contactgroup_orig != NULL; temp_contactgroup_orig = next_contactgroup_orig) { + + next_contactgroup_orig = temp_contactgroup_orig->next; + + /* add contactgroup to new list, sorted by contactgroup name */ + last_contactgroup = new_contactgroup_list; + for(temp_contactgroup = new_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + + if(xodtemplate_compare_strings1(temp_contactgroup_orig->contactgroup_name, temp_contactgroup->contactgroup_name) <= 0) + break; + else + last_contactgroup = temp_contactgroup; + } + + /* first item added to new sorted list */ + if(new_contactgroup_list == NULL) { + temp_contactgroup_orig->next = NULL; + new_contactgroup_list = temp_contactgroup_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_contactgroup == new_contactgroup_list) { + temp_contactgroup_orig->next = new_contactgroup_list; + new_contactgroup_list = temp_contactgroup_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_contactgroup_orig->next = temp_contactgroup; + last_contactgroup->next = temp_contactgroup_orig; + } + } + + /* list is now sorted */ + xodtemplate_contactgroup_list = new_contactgroup_list; + + return OK; + } + + +/* sort hostgroups by name */ +int xodtemplate_sort_hostgroups() { + xodtemplate_hostgroup *new_hostgroup_list = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_hostgroup *last_hostgroup = NULL; + xodtemplate_hostgroup *temp_hostgroup_orig = NULL; + xodtemplate_hostgroup *next_hostgroup_orig = NULL; + + /* sort all existing hostgroups */ + for(temp_hostgroup_orig = xodtemplate_hostgroup_list; temp_hostgroup_orig != NULL; temp_hostgroup_orig = next_hostgroup_orig) { + + next_hostgroup_orig = temp_hostgroup_orig->next; + + /* add hostgroup to new list, sorted by hostgroup name */ + last_hostgroup = new_hostgroup_list; + for(temp_hostgroup = new_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + if(xodtemplate_compare_strings1(temp_hostgroup_orig->hostgroup_name, temp_hostgroup->hostgroup_name) <= 0) + break; + else + last_hostgroup = temp_hostgroup; + } + + /* first item added to new sorted list */ + if(new_hostgroup_list == NULL) { + temp_hostgroup_orig->next = NULL; + new_hostgroup_list = temp_hostgroup_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_hostgroup == new_hostgroup_list) { + temp_hostgroup_orig->next = new_hostgroup_list; + new_hostgroup_list = temp_hostgroup_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_hostgroup_orig->next = temp_hostgroup; + last_hostgroup->next = temp_hostgroup_orig; + } + } + + /* list is now sorted */ + xodtemplate_hostgroup_list = new_hostgroup_list; + + return OK; + } + + +/* sort servicegroups by name */ +int xodtemplate_sort_servicegroups() { + xodtemplate_servicegroup *new_servicegroup_list = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_servicegroup *last_servicegroup = NULL; + xodtemplate_servicegroup *temp_servicegroup_orig = NULL; + xodtemplate_servicegroup *next_servicegroup_orig = NULL; + + /* sort all existing servicegroups */ + for(temp_servicegroup_orig = xodtemplate_servicegroup_list; temp_servicegroup_orig != NULL; temp_servicegroup_orig = next_servicegroup_orig) { + + next_servicegroup_orig = temp_servicegroup_orig->next; + + /* add servicegroup to new list, sorted by servicegroup name */ + last_servicegroup = new_servicegroup_list; + for(temp_servicegroup = new_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + if(xodtemplate_compare_strings1(temp_servicegroup_orig->servicegroup_name, temp_servicegroup->servicegroup_name) <= 0) + break; + else + last_servicegroup = temp_servicegroup; + } + + /* first item added to new sorted list */ + if(new_servicegroup_list == NULL) { + temp_servicegroup_orig->next = NULL; + new_servicegroup_list = temp_servicegroup_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_servicegroup == new_servicegroup_list) { + temp_servicegroup_orig->next = new_servicegroup_list; + new_servicegroup_list = temp_servicegroup_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_servicegroup_orig->next = temp_servicegroup; + last_servicegroup->next = temp_servicegroup_orig; + } + } + + /* list is now sorted */ + xodtemplate_servicegroup_list = new_servicegroup_list; + + return OK; + } + + +/* sort contacts by name */ +int xodtemplate_sort_contacts() { + xodtemplate_contact *new_contact_list = NULL; + xodtemplate_contact *temp_contact = NULL; + xodtemplate_contact *last_contact = NULL; + xodtemplate_contact *temp_contact_orig = NULL; + xodtemplate_contact *next_contact_orig = NULL; + + /* sort all existing contacts */ + for(temp_contact_orig = xodtemplate_contact_list; temp_contact_orig != NULL; temp_contact_orig = next_contact_orig) { + + next_contact_orig = temp_contact_orig->next; + + /* add contact to new list, sorted by contact name */ + last_contact = new_contact_list; + for(temp_contact = new_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + + if(xodtemplate_compare_strings1(temp_contact_orig->contact_name, temp_contact->contact_name) <= 0) + break; + else + last_contact = temp_contact; + } + + /* first item added to new sorted list */ + if(new_contact_list == NULL) { + temp_contact_orig->next = NULL; + new_contact_list = temp_contact_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_contact == new_contact_list) { + temp_contact_orig->next = new_contact_list; + new_contact_list = temp_contact_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_contact_orig->next = temp_contact; + last_contact->next = temp_contact_orig; + } + } + + /* list is now sorted */ + xodtemplate_contact_list = new_contact_list; + + return OK; + } + + +int xodtemplate_compare_host(void *arg1, void *arg2) { + xodtemplate_host *h1 = NULL; + xodtemplate_host *h2 = NULL; + int x = 0; + + h1 = (xodtemplate_host *)arg1; + h2 = (xodtemplate_host *)arg2; + + if(h1 == NULL && h2 == NULL) + return 0; + if(h1 == NULL) + return 1; + if(h2 == NULL) + return -1; + + x = strcmp((h1->host_name == NULL) ? "" : h1->host_name, (h2->host_name == NULL) ? "" : h2->host_name); + + return x; + } + + + +/* sort hosts by name */ +int xodtemplate_sort_hosts() { +#ifdef NEWSTUFF + xodtemplate_host *temp_host = NULL; + + /* initialize a new skip list */ + if((xodtemplate_host_skiplist = skiplist_new(15, 0.5, FALSE, xodtemplate_compare_host)) == NULL) + return ERROR; + + /* add all hosts to skip list */ + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) + skiplist_insert(xodtemplate_host_skiplist, temp_host); + /*printf("SKIPLIST ITEMS: %lu\n",xodtemplate_host_skiplist->items);*/ + + /* now move items from skiplist to linked list... */ + /* TODO */ +#endif + + xodtemplate_host *new_host_list = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_host *last_host = NULL; + xodtemplate_host *temp_host_orig = NULL; + xodtemplate_host *next_host_orig = NULL; + + /* sort all existing hosts */ + for(temp_host_orig = xodtemplate_host_list; temp_host_orig != NULL; temp_host_orig = next_host_orig) { + + next_host_orig = temp_host_orig->next; + + /* add host to new list, sorted by host name */ + last_host = new_host_list; + for(temp_host = new_host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(xodtemplate_compare_strings1(temp_host_orig->host_name, temp_host->host_name) <= 0) + break; + else + last_host = temp_host; + } + + /* first item added to new sorted list */ + if(new_host_list == NULL) { + temp_host_orig->next = NULL; + new_host_list = temp_host_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_host == new_host_list) { + temp_host_orig->next = new_host_list; + new_host_list = temp_host_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_host_orig->next = temp_host; + last_host->next = temp_host_orig; + } + } + + /* list is now sorted */ + xodtemplate_host_list = new_host_list; + + return OK; + } + + +int xodtemplate_compare_service(void *arg1, void *arg2) { + xodtemplate_service *s1 = NULL; + xodtemplate_service *s2 = NULL; + int x = 0; + + s1 = (xodtemplate_service *)arg1; + s2 = (xodtemplate_service *)arg2; + + if(s1 == NULL && s2 == NULL) + return 0; + if(s1 == NULL) + return 1; + if(s2 == NULL) + return -1; + + x = strcmp((s1->host_name == NULL) ? "" : s1->host_name, (s2->host_name == NULL) ? "" : s2->host_name); + if(x == 0) + x = strcmp((s1->service_description == NULL) ? "" : s1->service_description, (s2->service_description == NULL) ? "" : s2->service_description); + + return x; + } + + +/* sort services by name */ +int xodtemplate_sort_services() { +#ifdef NEWSTUFF + xodtemplate_service *temp_service = NULL; + + /* initialize a new skip list */ + if((xodtemplate_service_skiplist = skiplist_new(15, 0.5, FALSE, xodtemplate_compare_service)) == NULL) + return ERROR; + + /* add all services to skip list */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) + skiplist_insert(xodtemplate_service_skiplist, temp_service); + /*printf("SKIPLIST ITEMS: %lu\n",xodtemplate_service_skiplist->items);*/ + + /* now move items to linked list... */ + /* TODO */ +#endif + + xodtemplate_service *new_service_list = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_service *last_service = NULL; + xodtemplate_service *temp_service_orig = NULL; + xodtemplate_service *next_service_orig = NULL; + + /* sort all existing services */ + for(temp_service_orig = xodtemplate_service_list; temp_service_orig != NULL; temp_service_orig = next_service_orig) { + + next_service_orig = temp_service_orig->next; + + /* add service to new list, sorted by host name then service description */ + last_service = new_service_list; + for(temp_service = new_service_list; temp_service != NULL; temp_service = temp_service->next) { + + if(xodtemplate_compare_strings2(temp_service_orig->host_name, temp_service_orig->service_description, temp_service->host_name, temp_service->service_description) <= 0) + break; + else + last_service = temp_service; + } + + /* first item added to new sorted list */ + if(new_service_list == NULL) { + temp_service_orig->next = NULL; + new_service_list = temp_service_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_service == new_service_list) { + temp_service_orig->next = new_service_list; + new_service_list = temp_service_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_service_orig->next = temp_service; + last_service->next = temp_service_orig; + } + } + + /* list is now sorted */ + xodtemplate_service_list = new_service_list; + + return OK; + } + + +/* sort servicedependencies by name */ +int xodtemplate_sort_servicedependencies() { + xodtemplate_servicedependency *new_servicedependency_list = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_servicedependency *last_servicedependency = NULL; + xodtemplate_servicedependency *temp_servicedependency_orig = NULL; + xodtemplate_servicedependency *next_servicedependency_orig = NULL; + + /* sort all existing servicedependencies */ + for(temp_servicedependency_orig = xodtemplate_servicedependency_list; temp_servicedependency_orig != NULL; temp_servicedependency_orig = next_servicedependency_orig) { + + next_servicedependency_orig = temp_servicedependency_orig->next; + + /* add servicedependency to new list, sorted by host name then service description */ + last_servicedependency = new_servicedependency_list; + for(temp_servicedependency = new_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + + if(xodtemplate_compare_strings2(temp_servicedependency_orig->host_name, temp_servicedependency_orig->service_description, temp_servicedependency->host_name, temp_servicedependency->service_description) <= 0) + break; + else + last_servicedependency = temp_servicedependency; + } + + /* first item added to new sorted list */ + if(new_servicedependency_list == NULL) { + temp_servicedependency_orig->next = NULL; + new_servicedependency_list = temp_servicedependency_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_servicedependency == new_servicedependency_list) { + temp_servicedependency_orig->next = new_servicedependency_list; + new_servicedependency_list = temp_servicedependency_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_servicedependency_orig->next = temp_servicedependency; + last_servicedependency->next = temp_servicedependency_orig; + } + } + + /* list is now sorted */ + xodtemplate_servicedependency_list = new_servicedependency_list; + + return OK; + } + + +/* sort serviceescalations by name */ +int xodtemplate_sort_serviceescalations() { + xodtemplate_serviceescalation *new_serviceescalation_list = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_serviceescalation *last_serviceescalation = NULL; + xodtemplate_serviceescalation *temp_serviceescalation_orig = NULL; + xodtemplate_serviceescalation *next_serviceescalation_orig = NULL; + + /* sort all existing serviceescalations */ + for(temp_serviceescalation_orig = xodtemplate_serviceescalation_list; temp_serviceescalation_orig != NULL; temp_serviceescalation_orig = next_serviceescalation_orig) { + + next_serviceescalation_orig = temp_serviceescalation_orig->next; + + /* add serviceescalation to new list, sorted by host name then service description */ + last_serviceescalation = new_serviceescalation_list; + for(temp_serviceescalation = new_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + + if(xodtemplate_compare_strings2(temp_serviceescalation_orig->host_name, temp_serviceescalation_orig->service_description, temp_serviceescalation->host_name, temp_serviceescalation->service_description) <= 0) + break; + else + last_serviceescalation = temp_serviceescalation; + } + + /* first item added to new sorted list */ + if(new_serviceescalation_list == NULL) { + temp_serviceescalation_orig->next = NULL; + new_serviceescalation_list = temp_serviceescalation_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_serviceescalation == new_serviceescalation_list) { + temp_serviceescalation_orig->next = new_serviceescalation_list; + new_serviceescalation_list = temp_serviceescalation_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_serviceescalation_orig->next = temp_serviceescalation; + last_serviceescalation->next = temp_serviceescalation_orig; + } + } + + /* list is now sorted */ + xodtemplate_serviceescalation_list = new_serviceescalation_list; + + return OK; + } + + +/* sort hostescalations by name */ +int xodtemplate_sort_hostescalations() { + xodtemplate_hostescalation *new_hostescalation_list = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + xodtemplate_hostescalation *last_hostescalation = NULL; + xodtemplate_hostescalation *temp_hostescalation_orig = NULL; + xodtemplate_hostescalation *next_hostescalation_orig = NULL; + + /* sort all existing hostescalations */ + for(temp_hostescalation_orig = xodtemplate_hostescalation_list; temp_hostescalation_orig != NULL; temp_hostescalation_orig = next_hostescalation_orig) { + + next_hostescalation_orig = temp_hostescalation_orig->next; + + /* add hostescalation to new list, sorted by host name then hostescalation description */ + last_hostescalation = new_hostescalation_list; + for(temp_hostescalation = new_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) { + + if(xodtemplate_compare_strings1(temp_hostescalation_orig->host_name, temp_hostescalation->host_name) <= 0) + break; + else + last_hostescalation = temp_hostescalation; + } + + /* first item added to new sorted list */ + if(new_hostescalation_list == NULL) { + temp_hostescalation_orig->next = NULL; + new_hostescalation_list = temp_hostescalation_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_hostescalation == new_hostescalation_list) { + temp_hostescalation_orig->next = new_hostescalation_list; + new_hostescalation_list = temp_hostescalation_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_hostescalation_orig->next = temp_hostescalation; + last_hostescalation->next = temp_hostescalation_orig; + } + } + + /* list is now sorted */ + xodtemplate_hostescalation_list = new_hostescalation_list; + + return OK; + } + + +/* sort hostdependencies by name */ +int xodtemplate_sort_hostdependencies() { + xodtemplate_hostdependency *new_hostdependency_list = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_hostdependency *last_hostdependency = NULL; + xodtemplate_hostdependency *temp_hostdependency_orig = NULL; + xodtemplate_hostdependency *next_hostdependency_orig = NULL; + + /* sort all existing hostdependencys */ + for(temp_hostdependency_orig = xodtemplate_hostdependency_list; temp_hostdependency_orig != NULL; temp_hostdependency_orig = next_hostdependency_orig) { + + next_hostdependency_orig = temp_hostdependency_orig->next; + + /* add hostdependency to new list, sorted by host name then hostdependency description */ + last_hostdependency = new_hostdependency_list; + for(temp_hostdependency = new_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) { + + if(xodtemplate_compare_strings1(temp_hostdependency_orig->host_name, temp_hostdependency->host_name) <= 0) + break; + else + last_hostdependency = temp_hostdependency; + } + + /* first item added to new sorted list */ + if(new_hostdependency_list == NULL) { + temp_hostdependency_orig->next = NULL; + new_hostdependency_list = temp_hostdependency_orig; + } + + /* item goes at head of new sorted list */ + else if(temp_hostdependency == new_hostdependency_list) { + temp_hostdependency_orig->next = new_hostdependency_list; + new_hostdependency_list = temp_hostdependency_orig; + } + + /* item goes in middle or at end of new sorted list */ + else { + temp_hostdependency_orig->next = temp_hostdependency; + last_hostdependency->next = temp_hostdependency_orig; + } + } + + /* list is now sorted */ + xodtemplate_hostdependency_list = new_hostdependency_list; + + return OK; + } + +#endif + + + + +/******************************************************************/ +/*********************** MERGE FUNCTIONS **************************/ +/******************************************************************/ + +#ifdef NSCORE + +/* merge extinfo definitions */ +int xodtemplate_merge_extinfo_ojects(void) { + xodtemplate_hostextinfo *temp_hostextinfo = NULL; + xodtemplate_serviceextinfo *temp_serviceextinfo = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + + /* merge service extinfo definitions */ + for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) { + + /* make sure we have everything */ + if(temp_serviceextinfo->host_name == NULL || temp_serviceextinfo->service_description == NULL) + continue; + + /* find the service */ + if((temp_service = xodtemplate_find_real_service(temp_serviceextinfo->host_name, temp_serviceextinfo->service_description)) == NULL) + continue; + + /* merge the definitions */ + xodtemplate_merge_service_extinfo_object(temp_service, temp_serviceextinfo); + } + + /* merge host extinfo definitions */ + for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) { + + /* make sure we have everything */ + if(temp_hostextinfo->host_name == NULL) + continue; + + /* find the host */ + if((temp_host = xodtemplate_find_real_host(temp_hostextinfo->host_name)) == NULL) + continue; + + /* merge the definitions */ + xodtemplate_merge_host_extinfo_object(temp_host, temp_hostextinfo); + } + + return OK; + } + + +/* merges a service extinfo definition */ +int xodtemplate_merge_service_extinfo_object(xodtemplate_service *this_service, xodtemplate_serviceextinfo *this_serviceextinfo) { + + if(this_service == NULL || this_serviceextinfo == NULL) + return ERROR; + + if(this_service->notes == NULL && this_serviceextinfo->notes != NULL) + this_service->notes = strdup(this_serviceextinfo->notes); + if(this_service->notes_url == NULL && this_serviceextinfo->notes_url != NULL) + this_service->notes_url = strdup(this_serviceextinfo->notes_url); + if(this_service->action_url == NULL && this_serviceextinfo->action_url != NULL) + this_service->action_url = strdup(this_serviceextinfo->action_url); + if(this_service->icon_image == NULL && this_serviceextinfo->icon_image != NULL) + this_service->icon_image = strdup(this_serviceextinfo->icon_image); + if(this_service->icon_image_alt == NULL && this_serviceextinfo->icon_image_alt != NULL) + this_service->icon_image_alt = strdup(this_serviceextinfo->icon_image_alt); + + return OK; + } + + +/* merges a host extinfo definition */ +int xodtemplate_merge_host_extinfo_object(xodtemplate_host *this_host, xodtemplate_hostextinfo *this_hostextinfo) { + + if(this_host == NULL || this_hostextinfo == NULL) + return ERROR; + + if(this_host->notes == NULL && this_hostextinfo->notes != NULL) + this_host->notes = strdup(this_hostextinfo->notes); + if(this_host->notes_url == NULL && this_hostextinfo->notes_url != NULL) + this_host->notes_url = strdup(this_hostextinfo->notes_url); + if(this_host->action_url == NULL && this_hostextinfo->action_url != NULL) + this_host->action_url = strdup(this_hostextinfo->action_url); + if(this_host->icon_image == NULL && this_hostextinfo->icon_image != NULL) + this_host->icon_image = strdup(this_hostextinfo->icon_image); + if(this_host->icon_image_alt == NULL && this_hostextinfo->icon_image_alt != NULL) + this_host->icon_image_alt = strdup(this_hostextinfo->icon_image_alt); + if(this_host->vrml_image == NULL && this_hostextinfo->vrml_image != NULL) + this_host->vrml_image = strdup(this_hostextinfo->vrml_image); + if(this_host->statusmap_image == NULL && this_hostextinfo->statusmap_image != NULL) + this_host->statusmap_image = strdup(this_hostextinfo->statusmap_image); + + if(this_host->have_2d_coords == FALSE && this_hostextinfo->have_2d_coords == TRUE) { + this_host->x_2d = this_hostextinfo->x_2d; + this_host->y_2d = this_hostextinfo->y_2d; + this_host->have_2d_coords = TRUE; + } + if(this_host->have_3d_coords == FALSE && this_hostextinfo->have_3d_coords == TRUE) { + this_host->x_3d = this_hostextinfo->x_3d; + this_host->y_3d = this_hostextinfo->y_3d; + this_host->z_3d = this_hostextinfo->z_3d; + this_host->have_3d_coords = TRUE; + } + + return OK; + } + +#endif + + + +/******************************************************************/ +/*********************** CACHE FUNCTIONS **************************/ +/******************************************************************/ + +#ifdef NSCORE + +/* writes cached object definitions for use by web interface */ +int xodtemplate_cache_objects(char *cache_file) { + FILE *fp = NULL; + register int x = 0; + char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}; + char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}; + xodtemplate_timeperiod *temp_timeperiod = NULL; + xodtemplate_daterange *temp_daterange = NULL; + xodtemplate_command *temp_command = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_contact *temp_contact = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + xodtemplate_customvariablesmember *temp_customvariablesmember = NULL; + time_t current_time = 0L; + void *ptr = NULL; + + + time(¤t_time); + + /* open the cache file for writing */ + fp = fopen(cache_file, "w"); + if(fp == NULL) { + logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Could not open object cache file '%s' for writing!\n", cache_file); + return ERROR; + } + + /* write header to cache file */ + fprintf(fp, "########################################\n"); + fprintf(fp, "# NAGIOS OBJECT CACHE FILE\n"); + fprintf(fp, "#\n"); + fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n"); + fprintf(fp, "# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); + fprintf(fp, "#\n"); + fprintf(fp, "# Created: %s", ctime(¤t_time)); + fprintf(fp, "########################################\n\n"); + + + /* cache timeperiods */ + /*for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){*/ + ptr = NULL; + for(temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_first(xobject_skiplists[X_TIMEPERIOD_SKIPLIST], &ptr); temp_timeperiod != NULL; temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_next(&ptr)) { + + if(temp_timeperiod->register_object == FALSE) + continue; + fprintf(fp, "define timeperiod {\n"); + if(temp_timeperiod->timeperiod_name) + fprintf(fp, "\ttimeperiod_name\t%s\n", temp_timeperiod->timeperiod_name); + if(temp_timeperiod->alias) + fprintf(fp, "\talias\t%s\n", temp_timeperiod->alias); + for(x = 0; x < DATERANGE_TYPES; x++) { + for(temp_daterange = temp_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) { + + /* skip null entries */ + if(temp_daterange->timeranges == NULL || !strcmp(temp_daterange->timeranges, XODTEMPLATE_NULL)) + continue; + + switch(temp_daterange->type) { + case DATERANGE_CALENDAR_DATE: + fprintf(fp, "\t%d-%02d-%02d", temp_daterange->syear, temp_daterange->smon + 1, temp_daterange->smday); + if((temp_daterange->smday != temp_daterange->emday) || (temp_daterange->smon != temp_daterange->emon) || (temp_daterange->syear != temp_daterange->eyear)) + fprintf(fp, " - %d-%02d-%02d", temp_daterange->eyear, temp_daterange->emon + 1, temp_daterange->emday); + if(temp_daterange->skip_interval > 1) + fprintf(fp, " / %d", temp_daterange->skip_interval); + break; + case DATERANGE_MONTH_DATE: + fprintf(fp, "\t%s %d", months[temp_daterange->smon], temp_daterange->smday); + if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->smday != temp_daterange->emday)) { + fprintf(fp, " - %s %d", months[temp_daterange->emon], temp_daterange->emday); + if(temp_daterange->skip_interval > 1) + fprintf(fp, " / %d", temp_daterange->skip_interval); + } + break; + case DATERANGE_MONTH_DAY: + fprintf(fp, "\tday %d", temp_daterange->smday); + if(temp_daterange->smday != temp_daterange->emday) { + fprintf(fp, " - %d", temp_daterange->emday); + if(temp_daterange->skip_interval > 1) + fprintf(fp, " / %d", temp_daterange->skip_interval); + } + break; + case DATERANGE_MONTH_WEEK_DAY: + fprintf(fp, "\t%s %d %s", days[temp_daterange->swday], temp_daterange->swday_offset, months[temp_daterange->smon]); + if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) { + fprintf(fp, " - %s %d %s", days[temp_daterange->ewday], temp_daterange->ewday_offset, months[temp_daterange->emon]); + if(temp_daterange->skip_interval > 1) + fprintf(fp, " / %d", temp_daterange->skip_interval); + } + break; + case DATERANGE_WEEK_DAY: + fprintf(fp, "\t%s %d", days[temp_daterange->swday], temp_daterange->swday_offset); + if((temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) { + fprintf(fp, " - %s %d", days[temp_daterange->ewday], temp_daterange->ewday_offset); + if(temp_daterange->skip_interval > 1) + fprintf(fp, " / %d", temp_daterange->skip_interval); + } + break; + default: + break; + } + + fprintf(fp, "\t%s\n", temp_daterange->timeranges); + } + } + for(x = 0; x < 7; x++) { + /* skip null entries */ + if(temp_timeperiod->timeranges[x] == NULL || !strcmp(temp_timeperiod->timeranges[x], XODTEMPLATE_NULL)) + continue; + + fprintf(fp, "\t%s\t%s\n", days[x], temp_timeperiod->timeranges[x]); + } + if(temp_timeperiod->exclusions) + fprintf(fp, "\texclude\t%s\n", temp_timeperiod->exclusions); + fprintf(fp, "\t}\n\n"); + } + + /* cache commands */ + /*for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){*/ + ptr = NULL; + for(temp_command = (xodtemplate_command *)skiplist_get_first(xobject_skiplists[X_COMMAND_SKIPLIST], &ptr); temp_command != NULL; temp_command = (xodtemplate_command *)skiplist_get_next(&ptr)) { + if(temp_command->register_object == FALSE) + continue; + fprintf(fp, "define command {\n"); + if(temp_command->command_name) + fprintf(fp, "\tcommand_name\t%s\n", temp_command->command_name); + if(temp_command->command_line) + fprintf(fp, "\tcommand_line\t%s\n", temp_command->command_line); + fprintf(fp, "\t}\n\n"); + } + + /* cache contactgroups */ + /*for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){*/ + ptr = NULL; + for(temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], &ptr); temp_contactgroup != NULL; temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_next(&ptr)) { + if(temp_contactgroup->register_object == FALSE) + continue; + fprintf(fp, "define contactgroup {\n"); + if(temp_contactgroup->contactgroup_name) + fprintf(fp, "\tcontactgroup_name\t%s\n", temp_contactgroup->contactgroup_name); + if(temp_contactgroup->alias) + fprintf(fp, "\talias\t%s\n", temp_contactgroup->alias); + if(temp_contactgroup->members) + fprintf(fp, "\tmembers\t%s\n", temp_contactgroup->members); + fprintf(fp, "\t}\n\n"); + } + + /* cache hostgroups */ + /*for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){*/ + ptr = NULL; + for(temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_first(xobject_skiplists[X_HOSTGROUP_SKIPLIST], &ptr); temp_hostgroup != NULL; temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_next(&ptr)) { + if(temp_hostgroup->register_object == FALSE) + continue; + fprintf(fp, "define hostgroup {\n"); + if(temp_hostgroup->hostgroup_name) + fprintf(fp, "\thostgroup_name\t%s\n", temp_hostgroup->hostgroup_name); + if(temp_hostgroup->alias) + fprintf(fp, "\talias\t%s\n", temp_hostgroup->alias); + if(temp_hostgroup->members) + fprintf(fp, "\tmembers\t%s\n", temp_hostgroup->members); + if(temp_hostgroup->notes) + fprintf(fp, "\tnotes\t%s\n", temp_hostgroup->notes); + if(temp_hostgroup->notes_url) + fprintf(fp, "\tnotes_url\t%s\n", temp_hostgroup->notes_url); + if(temp_hostgroup->action_url) + fprintf(fp, "\taction_url\t%s\n", temp_hostgroup->action_url); + fprintf(fp, "\t}\n\n"); + } + + /* cache servicegroups */ + /*for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){*/ + ptr = NULL; + for(temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_first(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], &ptr); temp_servicegroup != NULL; temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_next(&ptr)) { + if(temp_servicegroup->register_object == FALSE) + continue; + fprintf(fp, "define servicegroup {\n"); + if(temp_servicegroup->servicegroup_name) + fprintf(fp, "\tservicegroup_name\t%s\n", temp_servicegroup->servicegroup_name); + if(temp_servicegroup->alias) + fprintf(fp, "\talias\t%s\n", temp_servicegroup->alias); + if(temp_servicegroup->members) + fprintf(fp, "\tmembers\t%s\n", temp_servicegroup->members); + if(temp_servicegroup->notes) + fprintf(fp, "\tnotes\t%s\n", temp_servicegroup->notes); + if(temp_servicegroup->notes_url) + fprintf(fp, "\tnotes_url\t%s\n", temp_servicegroup->notes_url); + if(temp_servicegroup->action_url) + fprintf(fp, "\taction_url\t%s\n", temp_servicegroup->action_url); + fprintf(fp, "\t}\n\n"); + } + + /* cache contacts */ + /*for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){*/ + ptr = NULL; + for(temp_contact = (xodtemplate_contact *)skiplist_get_first(xobject_skiplists[X_CONTACT_SKIPLIST], &ptr); temp_contact != NULL; temp_contact = (xodtemplate_contact *)skiplist_get_next(&ptr)) { + if(temp_contact->register_object == FALSE) + continue; + fprintf(fp, "define contact {\n"); + if(temp_contact->contact_name) + fprintf(fp, "\tcontact_name\t%s\n", temp_contact->contact_name); + if(temp_contact->alias) + fprintf(fp, "\talias\t%s\n", temp_contact->alias); + if(temp_contact->service_notification_period) + fprintf(fp, "\tservice_notification_period\t%s\n", temp_contact->service_notification_period); + if(temp_contact->host_notification_period) + fprintf(fp, "\thost_notification_period\t%s\n", temp_contact->host_notification_period); + fprintf(fp, "\tservice_notification_options\t"); + x = 0; + if(temp_contact->notify_on_service_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_service_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_service_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_service_recovery == TRUE) + fprintf(fp, "%sr", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_service_flapping == TRUE) + fprintf(fp, "%sf", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_service_downtime == TRUE) + fprintf(fp, "%ss", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\thost_notification_options\t"); + x = 0; + if(temp_contact->notify_on_host_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_host_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_host_recovery == TRUE) + fprintf(fp, "%sr", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_host_flapping == TRUE) + fprintf(fp, "%sf", (x++ > 0) ? "," : ""); + if(temp_contact->notify_on_host_downtime == TRUE) + fprintf(fp, "%ss", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + if(temp_contact->service_notification_commands) + fprintf(fp, "\tservice_notification_commands\t%s\n", temp_contact->service_notification_commands); + if(temp_contact->host_notification_commands) + fprintf(fp, "\thost_notification_commands\t%s\n", temp_contact->host_notification_commands); + if(temp_contact->email) + fprintf(fp, "\temail\t%s\n", temp_contact->email); + if(temp_contact->pager) + fprintf(fp, "\tpager\t%s\n", temp_contact->pager); + for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++) { + if(temp_contact->address[x]) + fprintf(fp, "\taddress%d\t%s\n", x + 1, temp_contact->address[x]); + } + fprintf(fp, "\thost_notifications_enabled\t%d\n", temp_contact->host_notifications_enabled); + fprintf(fp, "\tservice_notifications_enabled\t%d\n", temp_contact->service_notifications_enabled); + fprintf(fp, "\tcan_submit_commands\t%d\n", temp_contact->can_submit_commands); + fprintf(fp, "\tretain_status_information\t%d\n", temp_contact->retain_status_information); + fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_contact->retain_nonstatus_information); + + /* custom variables */ + for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "\t_%s\t%s\n", temp_customvariablesmember->variable_name, (temp_customvariablesmember->variable_value == NULL) ? XODTEMPLATE_NULL : temp_customvariablesmember->variable_value); + } + + + fprintf(fp, "\t}\n\n"); + } + + /* cache hosts */ + /*for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){*/ + ptr = NULL; + for(temp_host = (xodtemplate_host *)skiplist_get_first(xobject_skiplists[X_HOST_SKIPLIST], &ptr); temp_host != NULL; temp_host = (xodtemplate_host *)skiplist_get_next(&ptr)) { + if(temp_host->register_object == FALSE) + continue; + fprintf(fp, "define host {\n"); + if(temp_host->host_name) + fprintf(fp, "\thost_name\t%s\n", temp_host->host_name); + if(temp_host->display_name) + fprintf(fp, "\tdisplay_name\t%s\n", temp_host->display_name); + if(temp_host->alias) + fprintf(fp, "\talias\t%s\n", temp_host->alias); + if(temp_host->address) + fprintf(fp, "\taddress\t%s\n", temp_host->address); + if(temp_host->parents) + fprintf(fp, "\tparents\t%s\n", temp_host->parents); + if(temp_host->check_period) + fprintf(fp, "\tcheck_period\t%s\n", temp_host->check_period); + if(temp_host->check_command) + fprintf(fp, "\tcheck_command\t%s\n", temp_host->check_command); + if(temp_host->event_handler) + fprintf(fp, "\tevent_handler\t%s\n", temp_host->event_handler); + if(temp_host->contacts) + fprintf(fp, "\tcontacts\t%s\n", temp_host->contacts); + if(temp_host->contact_groups) + fprintf(fp, "\tcontact_groups\t%s\n", temp_host->contact_groups); + if(temp_host->notification_period) + fprintf(fp, "\tnotification_period\t%s\n", temp_host->notification_period); + if(temp_host->failure_prediction_options) + fprintf(fp, "\tfailure_prediction_options\t%s\n", temp_host->failure_prediction_options); + fprintf(fp, "\tinitial_state\t"); + if(temp_host->initial_state == HOST_DOWN) + fprintf(fp, "d\n"); + else if(temp_host->initial_state == HOST_UNREACHABLE) + fprintf(fp, "u\n"); + else + fprintf(fp, "o\n"); + fprintf(fp, "\tcheck_interval\t%f\n", temp_host->check_interval); + fprintf(fp, "\tretry_interval\t%f\n", temp_host->retry_interval); + fprintf(fp, "\tmax_check_attempts\t%d\n", temp_host->max_check_attempts); + fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_host->active_checks_enabled); + fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_host->passive_checks_enabled); + fprintf(fp, "\tobsess_over_host\t%d\n", temp_host->obsess_over_host); + fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_host->event_handler_enabled); + fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_host->low_flap_threshold); + fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_host->high_flap_threshold); + fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_host->flap_detection_enabled); + fprintf(fp, "\tflap_detection_options\t"); + x = 0; + if(temp_host->flap_detection_on_up == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_host->flap_detection_on_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_host->flap_detection_on_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\tfreshness_threshold\t%d\n", temp_host->freshness_threshold); + fprintf(fp, "\tcheck_freshness\t%d\n", temp_host->check_freshness); + fprintf(fp, "\tnotification_options\t"); + x = 0; + if(temp_host->notify_on_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_host->notify_on_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_host->notify_on_recovery == TRUE) + fprintf(fp, "%sr", (x++ > 0) ? "," : ""); + if(temp_host->notify_on_flapping == TRUE) + fprintf(fp, "%sf", (x++ > 0) ? "," : ""); + if(temp_host->notify_on_downtime == TRUE) + fprintf(fp, "%ss", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\tnotifications_enabled\t%d\n", temp_host->notifications_enabled); + fprintf(fp, "\tnotification_interval\t%f\n", temp_host->notification_interval); + fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_host->first_notification_delay); + fprintf(fp, "\tstalking_options\t"); + x = 0; + if(temp_host->stalk_on_up == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_host->stalk_on_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_host->stalk_on_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\tprocess_perf_data\t%d\n", temp_host->process_perf_data); + fprintf(fp, "\tfailure_prediction_enabled\t%d\n", temp_host->failure_prediction_enabled); + if(temp_host->icon_image) + fprintf(fp, "\ticon_image\t%s\n", temp_host->icon_image); + if(temp_host->icon_image_alt) + fprintf(fp, "\ticon_image_alt\t%s\n", temp_host->icon_image_alt); + if(temp_host->vrml_image) + fprintf(fp, "\tvrml_image\t%s\n", temp_host->vrml_image); + if(temp_host->statusmap_image) + fprintf(fp, "\tstatusmap_image\t%s\n", temp_host->statusmap_image); + if(temp_host->have_2d_coords == TRUE) + fprintf(fp, "\t2d_coords\t%d,%d\n", temp_host->x_2d, temp_host->y_2d); + if(temp_host->have_3d_coords == TRUE) + fprintf(fp, "\t3d_coords\t%f,%f,%f\n", temp_host->x_3d, temp_host->y_3d, temp_host->z_3d); + if(temp_host->notes) + fprintf(fp, "\tnotes\t%s\n", temp_host->notes); + if(temp_host->notes_url) + fprintf(fp, "\tnotes_url\t%s\n", temp_host->notes_url); + if(temp_host->action_url) + fprintf(fp, "\taction_url\t%s\n", temp_host->action_url); + fprintf(fp, "\tretain_status_information\t%d\n", temp_host->retain_status_information); + fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_host->retain_nonstatus_information); + + /* custom variables */ + for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "\t_%s\t%s\n", temp_customvariablesmember->variable_name, (temp_customvariablesmember->variable_value == NULL) ? XODTEMPLATE_NULL : temp_customvariablesmember->variable_value); + } + + + fprintf(fp, "\t}\n\n"); + } + + /* cache services */ + /*for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){*/ + ptr = NULL; + for(temp_service = (xodtemplate_service *)skiplist_get_first(xobject_skiplists[X_SERVICE_SKIPLIST], &ptr); temp_service != NULL; temp_service = (xodtemplate_service *)skiplist_get_next(&ptr)) { + if(temp_service->register_object == FALSE) + continue; + fprintf(fp, "define service {\n"); + if(temp_service->host_name) + fprintf(fp, "\thost_name\t%s\n", temp_service->host_name); + if(temp_service->service_description) + fprintf(fp, "\tservice_description\t%s\n", temp_service->service_description); + if(temp_service->display_name) + fprintf(fp, "\tdisplay_name\t%s\n", temp_service->display_name); + if(temp_service->check_period) + fprintf(fp, "\tcheck_period\t%s\n", temp_service->check_period); + if(temp_service->check_command) + fprintf(fp, "\tcheck_command\t%s\n", temp_service->check_command); + if(temp_service->event_handler) + fprintf(fp, "\tevent_handler\t%s\n", temp_service->event_handler); + if(temp_service->contacts) + fprintf(fp, "\tcontacts\t%s\n", temp_service->contacts); + if(temp_service->contact_groups) + fprintf(fp, "\tcontact_groups\t%s\n", temp_service->contact_groups); + if(temp_service->notification_period) + fprintf(fp, "\tnotification_period\t%s\n", temp_service->notification_period); + if(temp_service->failure_prediction_options) + fprintf(fp, "\tfailure_prediction_options\t%s\n", temp_service->failure_prediction_options); + fprintf(fp, "\tinitial_state\t"); + if(temp_service->initial_state == STATE_WARNING) + fprintf(fp, "w\n"); + else if(temp_service->initial_state == STATE_UNKNOWN) + fprintf(fp, "u\n"); + else if(temp_service->initial_state == STATE_CRITICAL) + fprintf(fp, "c\n"); + else + fprintf(fp, "o\n"); + fprintf(fp, "\tcheck_interval\t%f\n", temp_service->check_interval); + fprintf(fp, "\tretry_interval\t%f\n", temp_service->retry_interval); + fprintf(fp, "\tmax_check_attempts\t%d\n", temp_service->max_check_attempts); + fprintf(fp, "\tis_volatile\t%d\n", temp_service->is_volatile); + fprintf(fp, "\tparallelize_check\t%d\n", temp_service->parallelize_check); + fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_service->active_checks_enabled); + fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_service->passive_checks_enabled); + fprintf(fp, "\tobsess_over_service\t%d\n", temp_service->obsess_over_service); + fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_service->event_handler_enabled); + fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_service->low_flap_threshold); + fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_service->high_flap_threshold); + fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_service->flap_detection_enabled); + fprintf(fp, "\tflap_detection_options\t"); + x = 0; + if(temp_service->flap_detection_on_ok == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_service->flap_detection_on_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_service->flap_detection_on_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_service->flap_detection_on_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\tfreshness_threshold\t%d\n", temp_service->freshness_threshold); + fprintf(fp, "\tcheck_freshness\t%d\n", temp_service->check_freshness); + fprintf(fp, "\tnotification_options\t"); + x = 0; + if(temp_service->notify_on_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_service->notify_on_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_service->notify_on_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(temp_service->notify_on_recovery == TRUE) + fprintf(fp, "%sr", (x++ > 0) ? "," : ""); + if(temp_service->notify_on_flapping == TRUE) + fprintf(fp, "%sf", (x++ > 0) ? "," : ""); + if(temp_service->notify_on_downtime == TRUE) + fprintf(fp, "%ss", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\tnotifications_enabled\t%d\n", temp_service->notifications_enabled); + fprintf(fp, "\tnotification_interval\t%f\n", temp_service->notification_interval); + fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_service->first_notification_delay); + fprintf(fp, "\tstalking_options\t"); + x = 0; + if(temp_service->stalk_on_ok == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_service->stalk_on_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_service->stalk_on_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_service->stalk_on_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + fprintf(fp, "\tprocess_perf_data\t%d\n", temp_service->process_perf_data); + fprintf(fp, "\tfailure_prediction_enabled\t%d\n", temp_service->failure_prediction_enabled); + if(temp_service->icon_image) + fprintf(fp, "\ticon_image\t%s\n", temp_service->icon_image); + if(temp_service->icon_image_alt) + fprintf(fp, "\ticon_image_alt\t%s\n", temp_service->icon_image_alt); + if(temp_service->notes) + fprintf(fp, "\tnotes\t%s\n", temp_service->notes); + if(temp_service->notes_url) + fprintf(fp, "\tnotes_url\t%s\n", temp_service->notes_url); + if(temp_service->action_url) + fprintf(fp, "\taction_url\t%s\n", temp_service->action_url); + fprintf(fp, "\tretain_status_information\t%d\n", temp_service->retain_status_information); + fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_service->retain_nonstatus_information); + + /* custom variables */ + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "\t_%s\t%s\n", temp_customvariablesmember->variable_name, (temp_customvariablesmember->variable_value == NULL) ? XODTEMPLATE_NULL : temp_customvariablesmember->variable_value); + } + + fprintf(fp, "\t}\n\n"); + } + + /* cache service dependencies */ + /*for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){*/ + ptr = NULL; + for(temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_first(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], &ptr); temp_servicedependency != NULL; temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_next(&ptr)) { + if(temp_servicedependency->register_object == FALSE) + continue; + fprintf(fp, "define servicedependency {\n"); + if(temp_servicedependency->host_name) + fprintf(fp, "\thost_name\t%s\n", temp_servicedependency->host_name); + if(temp_servicedependency->service_description) + fprintf(fp, "\tservice_description\t%s\n", temp_servicedependency->service_description); + if(temp_servicedependency->dependent_host_name) + fprintf(fp, "\tdependent_host_name\t%s\n", temp_servicedependency->dependent_host_name); + if(temp_servicedependency->dependent_service_description) + fprintf(fp, "\tdependent_service_description\t%s\n", temp_servicedependency->dependent_service_description); + if(temp_servicedependency->dependency_period) + fprintf(fp, "\tdependency_period\t%s\n", temp_servicedependency->dependency_period); + fprintf(fp, "\tinherits_parent\t%d\n", temp_servicedependency->inherits_parent); + if(temp_servicedependency->have_notification_dependency_options == TRUE) { + fprintf(fp, "\tnotification_failure_options\t"); + x = 0; + if(temp_servicedependency->fail_notify_on_ok == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_notify_on_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_notify_on_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_notify_on_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_notify_on_pending == TRUE) + fprintf(fp, "%sp", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + } + if(temp_servicedependency->have_execution_dependency_options == TRUE) { + fprintf(fp, "\texecution_failure_options\t"); + x = 0; + if(temp_servicedependency->fail_execute_on_ok == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_execute_on_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_execute_on_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_execute_on_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(temp_servicedependency->fail_execute_on_pending == TRUE) + fprintf(fp, "%sp", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + } + fprintf(fp, "\t}\n\n"); + } + + /* cache service escalations */ + /*for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){*/ + ptr = NULL; + for(temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_first(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], &ptr); temp_serviceescalation != NULL; temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_next(&ptr)) { + if(temp_serviceescalation->register_object == FALSE) + continue; + fprintf(fp, "define serviceescalation {\n"); + if(temp_serviceescalation->host_name) + fprintf(fp, "\thost_name\t%s\n", temp_serviceescalation->host_name); + if(temp_serviceescalation->service_description) + fprintf(fp, "\tservice_description\t%s\n", temp_serviceescalation->service_description); + fprintf(fp, "\tfirst_notification\t%d\n", temp_serviceescalation->first_notification); + fprintf(fp, "\tlast_notification\t%d\n", temp_serviceescalation->last_notification); + fprintf(fp, "\tnotification_interval\t%f\n", temp_serviceescalation->notification_interval); + if(temp_serviceescalation->escalation_period) + fprintf(fp, "\tescalation_period\t%s\n", temp_serviceescalation->escalation_period); + if(temp_serviceescalation->have_escalation_options == TRUE) { + fprintf(fp, "\tescalation_options\t"); + x = 0; + if(temp_serviceescalation->escalate_on_warning == TRUE) + fprintf(fp, "%sw", (x++ > 0) ? "," : ""); + if(temp_serviceescalation->escalate_on_unknown == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_serviceescalation->escalate_on_critical == TRUE) + fprintf(fp, "%sc", (x++ > 0) ? "," : ""); + if(temp_serviceescalation->escalate_on_recovery == TRUE) + fprintf(fp, "%sr", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + } + if(temp_serviceescalation->contacts) + fprintf(fp, "\tcontacts\t%s\n", temp_serviceescalation->contacts); + if(temp_serviceescalation->contact_groups) + fprintf(fp, "\tcontact_groups\t%s\n", temp_serviceescalation->contact_groups); + fprintf(fp, "\t}\n\n"); + } + + /* cache host dependencies */ + /*for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){*/ + ptr = NULL; + for(temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_first(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], &ptr); temp_hostdependency != NULL; temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_next(&ptr)) { + if(temp_hostdependency->register_object == FALSE) + continue; + fprintf(fp, "define hostdependency {\n"); + if(temp_hostdependency->host_name) + fprintf(fp, "\thost_name\t%s\n", temp_hostdependency->host_name); + if(temp_hostdependency->dependent_host_name) + fprintf(fp, "\tdependent_host_name\t%s\n", temp_hostdependency->dependent_host_name); + if(temp_hostdependency->dependency_period) + fprintf(fp, "\tdependency_period\t%s\n", temp_hostdependency->dependency_period); + fprintf(fp, "\tinherits_parent\t%d\n", temp_hostdependency->inherits_parent); + if(temp_hostdependency->have_notification_dependency_options == TRUE) { + fprintf(fp, "\tnotification_failure_options\t"); + x = 0; + if(temp_hostdependency->fail_notify_on_up == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_hostdependency->fail_notify_on_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_hostdependency->fail_notify_on_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_hostdependency->fail_notify_on_pending == TRUE) + fprintf(fp, "%sp", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + } + if(temp_hostdependency->have_execution_dependency_options == TRUE) { + fprintf(fp, "\texecution_failure_options\t"); + x = 0; + if(temp_hostdependency->fail_execute_on_up == TRUE) + fprintf(fp, "%so", (x++ > 0) ? "," : ""); + if(temp_hostdependency->fail_execute_on_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_hostdependency->fail_execute_on_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_hostdependency->fail_execute_on_pending == TRUE) + fprintf(fp, "%sp", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + } + fprintf(fp, "\t}\n\n"); + } + + /* cache host escalations */ + /*for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){*/ + ptr = NULL; + for(temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_first(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], &ptr); temp_hostescalation != NULL; temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_next(&ptr)) { + if(temp_hostescalation->register_object == FALSE) + continue; + fprintf(fp, "define hostescalation {\n"); + if(temp_hostescalation->host_name) + fprintf(fp, "\thost_name\t%s\n", temp_hostescalation->host_name); + fprintf(fp, "\tfirst_notification\t%d\n", temp_hostescalation->first_notification); + fprintf(fp, "\tlast_notification\t%d\n", temp_hostescalation->last_notification); + fprintf(fp, "\tnotification_interval\t%f\n", temp_hostescalation->notification_interval); + if(temp_hostescalation->escalation_period) + fprintf(fp, "\tescalation_period\t%s\n", temp_hostescalation->escalation_period); + if(temp_hostescalation->have_escalation_options == TRUE) { + fprintf(fp, "\tescalation_options\t"); + x = 0; + if(temp_hostescalation->escalate_on_down == TRUE) + fprintf(fp, "%sd", (x++ > 0) ? "," : ""); + if(temp_hostescalation->escalate_on_unreachable == TRUE) + fprintf(fp, "%su", (x++ > 0) ? "," : ""); + if(temp_hostescalation->escalate_on_recovery == TRUE) + fprintf(fp, "%sr", (x++ > 0) ? "," : ""); + if(x == 0) + fprintf(fp, "n"); + fprintf(fp, "\n"); + } + if(temp_hostescalation->contacts) + fprintf(fp, "\tcontacts\t%s\n", temp_hostescalation->contacts); + if(temp_hostescalation->contact_groups) + fprintf(fp, "\tcontact_groups\t%s\n", temp_hostescalation->contact_groups); + fprintf(fp, "\t}\n\n"); + } + + fclose(fp); + + return OK; + } + +#endif + +/******************************************************************/ +/******************** SKIPLIST FUNCTIONS **************************/ +/******************************************************************/ + +int xodtemplate_init_xobject_skiplists(void) { + int x = 0; + + for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) { + xobject_template_skiplists[x] = NULL; + xobject_skiplists[x] = NULL; + } + + xobject_template_skiplists[X_HOST_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_host_template); + xobject_template_skiplists[X_SERVICE_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_service_template); + xobject_template_skiplists[X_COMMAND_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_command_template); + xobject_template_skiplists[X_TIMEPERIOD_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_timeperiod_template); + xobject_template_skiplists[X_CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contact_template); + xobject_template_skiplists[X_CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contactgroup_template); + xobject_template_skiplists[X_HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostgroup_template); + xobject_template_skiplists[X_SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicegroup_template); + xobject_template_skiplists[X_HOSTDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostdependency_template); + xobject_template_skiplists[X_SERVICEDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicedependency_template); + xobject_template_skiplists[X_HOSTESCALATION_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostescalation_template); + xobject_template_skiplists[X_SERVICEESCALATION_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_serviceescalation_template); + xobject_template_skiplists[X_HOSTEXTINFO_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostextinfo_template); + xobject_template_skiplists[X_SERVICEEXTINFO_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_serviceextinfo_template); + + xobject_skiplists[X_HOST_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_host); + xobject_skiplists[X_SERVICE_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_service); + xobject_skiplists[X_COMMAND_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_command); + xobject_skiplists[X_TIMEPERIOD_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_timeperiod); + xobject_skiplists[X_CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contact); + xobject_skiplists[X_CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contactgroup); + xobject_skiplists[X_HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostgroup); + xobject_skiplists[X_SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicegroup); + /* allow dups in the following lists... */ + xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_hostdependency); + xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_servicedependency); + xobject_skiplists[X_HOSTESCALATION_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_hostescalation); + xobject_skiplists[X_SERVICEESCALATION_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_serviceescalation); + /* host and service extinfo entries don't need to be added to a list... */ + + return OK; + } + + + +int xodtemplate_free_xobject_skiplists(void) { + int x = 0; + + for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) { + skiplist_free(&xobject_template_skiplists[x]); + skiplist_free(&xobject_skiplists[x]); + } + + return OK; + } + + +int xodtemplate_skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b) { + int result = 0; + + /* 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; + } + + + +int xodtemplate_skiplist_compare_host_template(void *a, void *b) { + xodtemplate_host *oa = NULL; + xodtemplate_host *ob = NULL; + + oa = (xodtemplate_host *)a; + ob = (xodtemplate_host *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_host(void *a, void *b) { + xodtemplate_host *oa = NULL; + xodtemplate_host *ob = NULL; + + oa = (xodtemplate_host *)a; + ob = (xodtemplate_host *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL); + } + + + +int xodtemplate_skiplist_compare_service_template(void *a, void *b) { + xodtemplate_service *oa = NULL; + xodtemplate_service *ob = NULL; + + oa = (xodtemplate_service *)a; + ob = (xodtemplate_service *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_service(void *a, void *b) { + xodtemplate_service *oa = NULL; + xodtemplate_service *ob = NULL; + + oa = (xodtemplate_service *)a; + ob = (xodtemplate_service *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, oa->service_description, ob->host_name, ob->service_description); + } + + + +int xodtemplate_skiplist_compare_timeperiod_template(void *a, void *b) { + xodtemplate_timeperiod *oa = NULL; + xodtemplate_timeperiod *ob = NULL; + + oa = (xodtemplate_timeperiod *)a; + ob = (xodtemplate_timeperiod *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_timeperiod(void *a, void *b) { + xodtemplate_timeperiod *oa = NULL; + xodtemplate_timeperiod *ob = NULL; + + oa = (xodtemplate_timeperiod *)a; + ob = (xodtemplate_timeperiod *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->timeperiod_name, NULL, ob->timeperiod_name, NULL); + } + + + +int xodtemplate_skiplist_compare_command_template(void *a, void *b) { + xodtemplate_command *oa = NULL; + xodtemplate_command *ob = NULL; + + oa = (xodtemplate_command *)a; + ob = (xodtemplate_command *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_command(void *a, void *b) { + xodtemplate_command *oa = NULL; + xodtemplate_command *ob = NULL; + + oa = (xodtemplate_command *)a; + ob = (xodtemplate_command *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->command_name, NULL, ob->command_name, NULL); + } + + + +int xodtemplate_skiplist_compare_contact_template(void *a, void *b) { + xodtemplate_contact *oa = NULL; + xodtemplate_contact *ob = NULL; + + oa = (xodtemplate_contact *)a; + ob = (xodtemplate_contact *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_contact(void *a, void *b) { + xodtemplate_contact *oa = NULL; + xodtemplate_contact *ob = NULL; + + oa = (xodtemplate_contact *)a; + ob = (xodtemplate_contact *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->contact_name, NULL, ob->contact_name, NULL); + } + + + +int xodtemplate_skiplist_compare_contactgroup_template(void *a, void *b) { + xodtemplate_contactgroup *oa = NULL; + xodtemplate_contactgroup *ob = NULL; + + oa = (xodtemplate_contactgroup *)a; + ob = (xodtemplate_contactgroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_contactgroup(void *a, void *b) { + xodtemplate_contactgroup *oa = NULL; + xodtemplate_contactgroup *ob = NULL; + + oa = (xodtemplate_contactgroup *)a; + ob = (xodtemplate_contactgroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->contactgroup_name, NULL, ob->contactgroup_name, NULL); + } + + + +int xodtemplate_skiplist_compare_hostgroup_template(void *a, void *b) { + xodtemplate_hostgroup *oa = NULL; + xodtemplate_hostgroup *ob = NULL; + + oa = (xodtemplate_hostgroup *)a; + ob = (xodtemplate_hostgroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_hostgroup(void *a, void *b) { + xodtemplate_hostgroup *oa = NULL; + xodtemplate_hostgroup *ob = NULL; + + oa = (xodtemplate_hostgroup *)a; + ob = (xodtemplate_hostgroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->hostgroup_name, NULL, ob->hostgroup_name, NULL); + } + + + +int xodtemplate_skiplist_compare_servicegroup_template(void *a, void *b) { + xodtemplate_servicegroup *oa = NULL; + xodtemplate_servicegroup *ob = NULL; + + oa = (xodtemplate_servicegroup *)a; + ob = (xodtemplate_servicegroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_servicegroup(void *a, void *b) { + xodtemplate_servicegroup *oa = NULL; + xodtemplate_servicegroup *ob = NULL; + + oa = (xodtemplate_servicegroup *)a; + ob = (xodtemplate_servicegroup *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->servicegroup_name, NULL, ob->servicegroup_name, NULL); + } + + + +int xodtemplate_skiplist_compare_hostdependency_template(void *a, void *b) { + xodtemplate_hostdependency *oa = NULL; + xodtemplate_hostdependency *ob = NULL; + + oa = (xodtemplate_hostdependency *)a; + ob = (xodtemplate_hostdependency *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_hostdependency(void *a, void *b) { + xodtemplate_hostdependency *oa = NULL; + xodtemplate_hostdependency *ob = NULL; + + oa = (xodtemplate_hostdependency *)a; + ob = (xodtemplate_hostdependency *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->dependent_host_name, NULL, ob->dependent_host_name, NULL); + } + + + +int xodtemplate_skiplist_compare_servicedependency_template(void *a, void *b) { + xodtemplate_servicedependency *oa = NULL; + xodtemplate_servicedependency *ob = NULL; + + oa = (xodtemplate_servicedependency *)a; + ob = (xodtemplate_servicedependency *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_servicedependency(void *a, void *b) { + xodtemplate_servicedependency *oa = NULL; + xodtemplate_servicedependency *ob = NULL; + + oa = (xodtemplate_servicedependency *)a; + ob = (xodtemplate_servicedependency *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->dependent_host_name, oa->dependent_service_description, ob->dependent_host_name, ob->dependent_service_description); + } + + + +int xodtemplate_skiplist_compare_hostescalation_template(void *a, void *b) { + xodtemplate_hostescalation *oa = NULL; + xodtemplate_hostescalation *ob = NULL; + + oa = (xodtemplate_hostescalation *)a; + ob = (xodtemplate_hostescalation *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_hostescalation(void *a, void *b) { + xodtemplate_hostescalation *oa = NULL; + xodtemplate_hostescalation *ob = NULL; + + oa = (xodtemplate_hostescalation *)a; + ob = (xodtemplate_hostescalation *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL); + } + + + +int xodtemplate_skiplist_compare_serviceescalation_template(void *a, void *b) { + xodtemplate_serviceescalation *oa = NULL; + xodtemplate_serviceescalation *ob = NULL; + + oa = (xodtemplate_serviceescalation *)a; + ob = (xodtemplate_serviceescalation *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_serviceescalation(void *a, void *b) { + xodtemplate_serviceescalation *oa = NULL; + xodtemplate_serviceescalation *ob = NULL; + + oa = (xodtemplate_serviceescalation *)a; + ob = (xodtemplate_serviceescalation *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->host_name, oa->service_description, ob->host_name, ob->service_description); + } + + + +int xodtemplate_skiplist_compare_hostextinfo_template(void *a, void *b) { + xodtemplate_hostextinfo *oa = NULL; + xodtemplate_hostextinfo *ob = NULL; + + oa = (xodtemplate_hostextinfo *)a; + ob = (xodtemplate_hostextinfo *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + +int xodtemplate_skiplist_compare_serviceextinfo_template(void *a, void *b) { + xodtemplate_serviceextinfo *oa = NULL; + xodtemplate_serviceextinfo *ob = NULL; + + oa = (xodtemplate_serviceextinfo *)a; + ob = (xodtemplate_serviceextinfo *)b; + + if(oa == NULL && ob == NULL) + return 0; + if(oa == NULL) + return 1; + if(ob == NULL) + return -1; + + return skiplist_compare_text(oa->name, NULL, ob->name, NULL); + } + + + + +/******************************************************************/ +/********************** CLEANUP FUNCTIONS *************************/ +/******************************************************************/ + +/* frees memory */ +int xodtemplate_free_memory(void) { + xodtemplate_timeperiod *this_timeperiod = NULL; + xodtemplate_timeperiod *next_timeperiod = NULL; + xodtemplate_daterange *this_daterange = NULL; + xodtemplate_daterange *next_daterange = NULL; + xodtemplate_command *this_command = NULL; + xodtemplate_command *next_command = NULL; + xodtemplate_contactgroup *this_contactgroup = NULL; + xodtemplate_contactgroup *next_contactgroup = NULL; + xodtemplate_hostgroup *this_hostgroup = NULL; + xodtemplate_hostgroup *next_hostgroup = NULL; + xodtemplate_servicegroup *this_servicegroup = NULL; + xodtemplate_servicegroup *next_servicegroup = NULL; + xodtemplate_servicedependency *this_servicedependency = NULL; + xodtemplate_servicedependency *next_servicedependency = NULL; + xodtemplate_serviceescalation *this_serviceescalation = NULL; + xodtemplate_serviceescalation *next_serviceescalation = NULL; + xodtemplate_contact *this_contact = NULL; + xodtemplate_contact *next_contact = NULL; + xodtemplate_host *this_host = NULL; + xodtemplate_host *next_host = NULL; + xodtemplate_service *this_service = NULL; + xodtemplate_service *next_service = NULL; + xodtemplate_hostdependency *this_hostdependency = NULL; + xodtemplate_hostdependency *next_hostdependency = NULL; + xodtemplate_hostescalation *this_hostescalation = NULL; + xodtemplate_hostescalation *next_hostescalation = NULL; + xodtemplate_hostextinfo *this_hostextinfo = NULL; + xodtemplate_hostextinfo *next_hostextinfo = NULL; + xodtemplate_serviceextinfo *this_serviceextinfo = NULL; + xodtemplate_serviceextinfo *next_serviceextinfo = NULL; + xodtemplate_customvariablesmember *this_customvariablesmember = NULL; + xodtemplate_customvariablesmember *next_customvariablesmember = NULL; + register int x = 0; + + + /* free memory allocated to timeperiod list */ + for(this_timeperiod = xodtemplate_timeperiod_list; this_timeperiod != NULL; this_timeperiod = next_timeperiod) { + next_timeperiod = this_timeperiod->next; + my_free(this_timeperiod->template); + my_free(this_timeperiod->name); + my_free(this_timeperiod->timeperiod_name); + my_free(this_timeperiod->alias); + for(x = 0; x < 7; x++) + my_free(this_timeperiod->timeranges[x]); + for(x = 0; x < DATERANGE_TYPES; x++) { + for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = next_daterange) { + next_daterange = this_daterange->next; + my_free(this_daterange->timeranges); + my_free(this_daterange); + } + } + my_free(this_timeperiod->exclusions); + my_free(this_timeperiod); + } + xodtemplate_timeperiod_list = NULL; + xodtemplate_timeperiod_list_tail = NULL; + + /* free memory allocated to command list */ + for(this_command = xodtemplate_command_list; this_command != NULL; this_command = next_command) { + next_command = this_command->next; + my_free(this_command->template); + my_free(this_command->name); + my_free(this_command->command_name); + my_free(this_command->command_line); + my_free(this_command); + } + xodtemplate_command_list = NULL; + xodtemplate_command_list_tail = NULL; + + /* free memory allocated to contactgroup list */ + for(this_contactgroup = xodtemplate_contactgroup_list; this_contactgroup != NULL; this_contactgroup = next_contactgroup) { + next_contactgroup = this_contactgroup->next; + my_free(this_contactgroup->template); + my_free(this_contactgroup->name); + my_free(this_contactgroup->contactgroup_name); + my_free(this_contactgroup->alias); + my_free(this_contactgroup->members); + my_free(this_contactgroup->contactgroup_members); + my_free(this_contactgroup); + } + xodtemplate_contactgroup_list = NULL; + xodtemplate_contactgroup_list_tail = NULL; + + /* free memory allocated to hostgroup list */ + for(this_hostgroup = xodtemplate_hostgroup_list; this_hostgroup != NULL; this_hostgroup = next_hostgroup) { + next_hostgroup = this_hostgroup->next; + my_free(this_hostgroup->template); + my_free(this_hostgroup->name); + my_free(this_hostgroup->hostgroup_name); + my_free(this_hostgroup->alias); + my_free(this_hostgroup->members); + my_free(this_hostgroup->hostgroup_members); + my_free(this_hostgroup->notes); + my_free(this_hostgroup->notes_url); + my_free(this_hostgroup->action_url); + my_free(this_hostgroup); + } + xodtemplate_hostgroup_list = NULL; + xodtemplate_hostgroup_list_tail = NULL; + + /* free memory allocated to servicegroup list */ + for(this_servicegroup = xodtemplate_servicegroup_list; this_servicegroup != NULL; this_servicegroup = next_servicegroup) { + next_servicegroup = this_servicegroup->next; + my_free(this_servicegroup->template); + my_free(this_servicegroup->name); + my_free(this_servicegroup->servicegroup_name); + my_free(this_servicegroup->alias); + my_free(this_servicegroup->members); + my_free(this_servicegroup->servicegroup_members); + my_free(this_servicegroup->notes); + my_free(this_servicegroup->notes_url); + my_free(this_servicegroup->action_url); + my_free(this_servicegroup); + } + xodtemplate_servicegroup_list = NULL; + xodtemplate_servicegroup_list_tail = NULL; + + /* free memory allocated to servicedependency list */ + for(this_servicedependency = xodtemplate_servicedependency_list; this_servicedependency != NULL; this_servicedependency = next_servicedependency) { + next_servicedependency = this_servicedependency->next; + my_free(this_servicedependency->template); + my_free(this_servicedependency->name); + my_free(this_servicedependency->servicegroup_name); + my_free(this_servicedependency->hostgroup_name); + my_free(this_servicedependency->host_name); + my_free(this_servicedependency->service_description); + my_free(this_servicedependency->dependent_servicegroup_name); + my_free(this_servicedependency->dependent_hostgroup_name); + my_free(this_servicedependency->dependent_host_name); + my_free(this_servicedependency->dependent_service_description); + my_free(this_servicedependency->dependency_period); + my_free(this_servicedependency); + } + xodtemplate_servicedependency_list = NULL; + xodtemplate_servicedependency_list_tail = NULL; + + /* free memory allocated to serviceescalation list */ + for(this_serviceescalation = xodtemplate_serviceescalation_list; this_serviceescalation != NULL; this_serviceescalation = next_serviceescalation) { + next_serviceescalation = this_serviceescalation->next; + my_free(this_serviceescalation->template); + my_free(this_serviceescalation->name); + my_free(this_serviceescalation->servicegroup_name); + my_free(this_serviceescalation->hostgroup_name); + my_free(this_serviceescalation->host_name); + my_free(this_serviceescalation->service_description); + my_free(this_serviceescalation->escalation_period); + my_free(this_serviceescalation->contact_groups); + my_free(this_serviceescalation->contacts); + my_free(this_serviceescalation); + } + xodtemplate_serviceescalation_list = NULL; + xodtemplate_serviceescalation_list_tail = NULL; + + /* free memory allocated to contact list */ + for(this_contact = xodtemplate_contact_list; this_contact != NULL; this_contact = next_contact) { + + /* free custom variables */ + this_customvariablesmember = this_contact->custom_variables; + while(this_customvariablesmember != NULL) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + this_customvariablesmember = next_customvariablesmember; + } + + next_contact = this_contact->next; + my_free(this_contact->template); + my_free(this_contact->name); + my_free(this_contact->contact_name); + my_free(this_contact->alias); + my_free(this_contact->contact_groups); + my_free(this_contact->email); + my_free(this_contact->pager); + for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++) + my_free(this_contact->address[x]); + my_free(this_contact->service_notification_period); + my_free(this_contact->service_notification_commands); + my_free(this_contact->host_notification_period); + my_free(this_contact->host_notification_commands); + my_free(this_contact); + } + xodtemplate_contact_list = NULL; + xodtemplate_contact_list_tail = NULL; + + /* free memory allocated to host list */ + for(this_host = xodtemplate_host_list; this_host != NULL; this_host = next_host) { + + /* free custom variables */ + this_customvariablesmember = this_host->custom_variables; + while(this_customvariablesmember != NULL) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + this_customvariablesmember = next_customvariablesmember; + } + + next_host = this_host->next; + my_free(this_host->template); + my_free(this_host->name); + my_free(this_host->host_name); + my_free(this_host->alias); + my_free(this_host->display_name); + my_free(this_host->address); + my_free(this_host->parents); + my_free(this_host->host_groups); + my_free(this_host->check_command); + my_free(this_host->check_period); + my_free(this_host->event_handler); + my_free(this_host->contact_groups); + my_free(this_host->contacts); + my_free(this_host->notification_period); + my_free(this_host->failure_prediction_options); + my_free(this_host->notes); + my_free(this_host->notes_url); + my_free(this_host->action_url); + my_free(this_host->icon_image); + my_free(this_host->icon_image_alt); + my_free(this_host->vrml_image); + my_free(this_host->statusmap_image); + my_free(this_host); + } + xodtemplate_host_list = NULL; + xodtemplate_host_list_tail = NULL; + + /* free memory allocated to service list */ + for(this_service = xodtemplate_service_list; this_service != NULL; this_service = next_service) { + + /* free custom variables */ + this_customvariablesmember = this_service->custom_variables; + while(this_customvariablesmember != NULL) { + next_customvariablesmember = this_customvariablesmember->next; + my_free(this_customvariablesmember->variable_name); + my_free(this_customvariablesmember->variable_value); + my_free(this_customvariablesmember); + this_customvariablesmember = next_customvariablesmember; + } + + next_service = this_service->next; + my_free(this_service->template); + my_free(this_service->name); + my_free(this_service->display_name); + my_free(this_service->hostgroup_name); + my_free(this_service->host_name); + my_free(this_service->service_description); + my_free(this_service->service_groups); + my_free(this_service->check_command); + my_free(this_service->check_period); + my_free(this_service->event_handler); + my_free(this_service->notification_period); + my_free(this_service->contact_groups); + my_free(this_service->contacts); + my_free(this_service->failure_prediction_options); + my_free(this_service->notes); + my_free(this_service->notes_url); + my_free(this_service->action_url); + my_free(this_service->icon_image); + my_free(this_service->icon_image_alt); + my_free(this_service); + } + xodtemplate_service_list = NULL; + xodtemplate_service_list_tail = NULL; + + /* free memory allocated to hostdependency list */ + for(this_hostdependency = xodtemplate_hostdependency_list; this_hostdependency != NULL; this_hostdependency = next_hostdependency) { + next_hostdependency = this_hostdependency->next; + my_free(this_hostdependency->template); + my_free(this_hostdependency->name); + my_free(this_hostdependency->hostgroup_name); + my_free(this_hostdependency->dependent_hostgroup_name); + my_free(this_hostdependency->host_name); + my_free(this_hostdependency->dependent_host_name); + my_free(this_hostdependency->dependency_period); + my_free(this_hostdependency); + } + xodtemplate_hostdependency_list = NULL; + xodtemplate_hostdependency_list_tail = NULL; + + /* free memory allocated to hostescalation list */ + for(this_hostescalation = xodtemplate_hostescalation_list; this_hostescalation != NULL; this_hostescalation = next_hostescalation) { + next_hostescalation = this_hostescalation->next; + my_free(this_hostescalation->template); + my_free(this_hostescalation->name); + my_free(this_hostescalation->hostgroup_name); + my_free(this_hostescalation->host_name); + my_free(this_hostescalation->escalation_period); + my_free(this_hostescalation->contact_groups); + my_free(this_hostescalation->contacts); + my_free(this_hostescalation); + } + xodtemplate_hostescalation_list = NULL; + xodtemplate_hostescalation_list_tail = NULL; + + /* free memory allocated to hostextinfo list */ + for(this_hostextinfo = xodtemplate_hostextinfo_list; this_hostextinfo != NULL; this_hostextinfo = next_hostextinfo) { + next_hostextinfo = this_hostextinfo->next; + my_free(this_hostextinfo->template); + my_free(this_hostextinfo->name); + my_free(this_hostextinfo->host_name); + my_free(this_hostextinfo->hostgroup_name); + my_free(this_hostextinfo->notes); + my_free(this_hostextinfo->notes_url); + my_free(this_hostextinfo->action_url); + my_free(this_hostextinfo->icon_image); + my_free(this_hostextinfo->icon_image_alt); + my_free(this_hostextinfo->vrml_image); + my_free(this_hostextinfo->statusmap_image); + my_free(this_hostextinfo); + } + xodtemplate_hostextinfo_list = NULL; + xodtemplate_hostextinfo_list_tail = NULL; + + /* free memory allocated to serviceextinfo list */ + for(this_serviceextinfo = xodtemplate_serviceextinfo_list; this_serviceextinfo != NULL; this_serviceextinfo = next_serviceextinfo) { + next_serviceextinfo = this_serviceextinfo->next; + my_free(this_serviceextinfo->template); + my_free(this_serviceextinfo->name); + my_free(this_serviceextinfo->host_name); + my_free(this_serviceextinfo->hostgroup_name); + my_free(this_serviceextinfo->service_description); + my_free(this_serviceextinfo->notes); + my_free(this_serviceextinfo->notes_url); + my_free(this_serviceextinfo->action_url); + my_free(this_serviceextinfo->icon_image); + my_free(this_serviceextinfo->icon_image_alt); + my_free(this_serviceextinfo); + } + xodtemplate_serviceextinfo_list = NULL; + xodtemplate_serviceextinfo_list_tail = NULL; + + /* free memory for the config file names */ + for(x = 0; x < xodtemplate_current_config_file; x++) + my_free(xodtemplate_config_files[x]); + my_free(xodtemplate_config_files); + xodtemplate_current_config_file = 0; + + /* free skiplists */ + xodtemplate_free_xobject_skiplists(); + + return OK; + } + + + + +#ifdef NSCORE +/* adds a member to a list */ +int xodtemplate_add_member_to_memberlist(xodtemplate_memberlist **list, char *name1, char *name2) { + xodtemplate_memberlist *temp_item = NULL; + xodtemplate_memberlist *new_item = NULL; + int error = FALSE; + + if(list == NULL) + return ERROR; + if(name1 == NULL) + return ERROR; + + /* skip this member if its already in the list */ + for(temp_item = *list; temp_item; temp_item = temp_item->next) { + if(!strcmp(temp_item->name1, name1)) { + if(temp_item->name2 == NULL) { + if(name2 == NULL) + break; + } + else if(name2 != NULL && !strcmp(temp_item->name2, name2)) + break; + } + } + if(temp_item) + return OK; + + /* allocate zero'd out memory for a new list item */ + if((new_item = (xodtemplate_memberlist *)calloc(1, sizeof(xodtemplate_memberlist))) == NULL) + return ERROR; + + /* save the member name(s) */ + if(name1) { + if((new_item->name1 = (char *)strdup(name1)) == NULL) + error = TRUE; + } + if(name2) { + if((new_item->name2 = (char *)strdup(name2)) == NULL) + error = TRUE; + } + + if(error == TRUE) { + my_free(new_item->name1); + my_free(new_item->name2); + my_free(new_item); + return ERROR; + } + + /* add new item to head of list */ + new_item->next = *list; + *list = new_item; + + return OK; + } + + +/* frees memory allocated to a temporary member list */ +int xodtemplate_free_memberlist(xodtemplate_memberlist **temp_list) { + xodtemplate_memberlist *this_memberlist = NULL; + xodtemplate_memberlist *next_memberlist = NULL; + + /* free memory allocated to member name list */ + for(this_memberlist = *temp_list; this_memberlist != NULL; this_memberlist = next_memberlist) { + next_memberlist = this_memberlist->next; + my_free(this_memberlist->name1); + my_free(this_memberlist->name2); + my_free(this_memberlist); + } + + *temp_list = NULL; + + return OK; + } + + +/* remove an entry from the member list */ +void xodtemplate_remove_memberlist_item(xodtemplate_memberlist *item, xodtemplate_memberlist **list) { + xodtemplate_memberlist *temp_item = NULL; + + if(item == NULL || list == NULL) + return; + + if(*list == NULL) + return; + + if(*list == item) + *list = item->next; + + else { + + for(temp_item = *list; temp_item != NULL; temp_item = temp_item->next) { + if(temp_item->next == item) { + temp_item->next = item->next; + break; + } + } + } + + my_free(item->name1); + my_free(item->name2); + my_free(item); + + return; + } +#endif + + +/******************************************************************/ +/********************** UTILITY FUNCTIONS *************************/ +/******************************************************************/ + +#ifdef NSCORE + +/* expands a comma-delimited list of contactgroups and/or contacts to member contact names */ +xodtemplate_memberlist *xodtemplate_expand_contactgroups_and_contacts(char *contactgroups, char *contacts, int _config_file, int _start_line) { + xodtemplate_memberlist *temp_list = NULL; + xodtemplate_memberlist *reject_list = NULL; + xodtemplate_memberlist *list_ptr = NULL; + xodtemplate_memberlist *reject_ptr = NULL; + int result = OK; + + /* process list of contactgroups... */ + if(contactgroups != NULL) { + + /* expand contactgroups */ + result = xodtemplate_expand_contactgroups(&temp_list, &reject_list, contactgroups, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + } + + /* process contact names */ + if(contacts != NULL) { + + /* expand contacts */ + result = xodtemplate_expand_contacts(&temp_list, &reject_list, contacts, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + } + + /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ + /* NOTE: rejects from this list also affect contacts generated from processing contactgroup names (see above) */ + for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) { + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + if(!strcmp(reject_ptr->name1, list_ptr->name1)) { + xodtemplate_remove_memberlist_item(list_ptr, &temp_list); + break; + } + } + } + xodtemplate_free_memberlist(&reject_list); + reject_list = NULL; + + return temp_list; + } + + + +/* expands contactgroups */ +int xodtemplate_expand_contactgroups(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contactgroups, int _config_file, int _start_line) { + char *contactgroup_names = NULL; + char *temp_ptr = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || contactgroups == NULL) + return ERROR; + + /* allocate memory for contactgroup name list */ + if((contactgroup_names = (char *)strdup(contactgroups)) == NULL) + return ERROR; + + for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + else + use_regexp = FALSE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(contactgroup_names); + return ERROR; + } + + /* test match against all contactgroup names */ + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + + if(temp_contactgroup->contactgroup_name == NULL) + continue; + + /* skip this contactgroup if it did not match the expression */ + if(regexec(&preg, temp_contactgroup->contactgroup_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add contactgroups that shouldn't be registered */ + if(temp_contactgroup->register_object == FALSE) + continue; + + /* add contactgroup members to list */ + xodtemplate_add_contactgroup_members_to_memberlist(list, temp_contactgroup, _config_file, _start_line); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all contactgroups */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + + /* dont' add contactgroups that shouldn't be registered */ + if(temp_contactgroup->register_object == FALSE) + continue; + + /* add contactgroup to list */ + xodtemplate_add_contactgroup_members_to_memberlist(list, temp_contactgroup, _config_file, _start_line); + } + } + + /* else this is just a single contactgroup... */ + else { + + /* this contactgroup should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the contactgroup */ + temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr); + if(temp_contactgroup != NULL) { + + found_match = TRUE; + + /* add contactgroup members to proper list */ + xodtemplate_add_contactgroup_members_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_contactgroup, _config_file, _start_line); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any contactgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(contactgroup_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + + +/* expands contacts */ +int xodtemplate_expand_contacts(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contacts, int _config_file, int _start_line) { + char *contact_names = NULL; + char *temp_ptr = NULL; + xodtemplate_contact *temp_contact = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || contacts == NULL) + return ERROR; + + if((contact_names = (char *)strdup(contacts)) == NULL) + return ERROR; + + /* expand each contact name */ + for(temp_ptr = strtok(contact_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(contact_names); + return ERROR; + } + + /* test match against all contacts */ + for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + + if(temp_contact->contact_name == NULL) + continue; + + /* skip this contact if it did not match the expression */ + if(regexec(&preg, temp_contact->contact_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add contacts that shouldn't be registered */ + if(temp_contact->register_object == FALSE) + continue; + + /* add contact to list */ + xodtemplate_add_member_to_memberlist(list, temp_contact->contact_name, NULL); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all contacts */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + + if(temp_contact->contact_name == NULL) + continue; + + /* dont' add contacts that shouldn't be registered */ + if(temp_contact->register_object == FALSE) + continue; + + /* add contact to list */ + xodtemplate_add_member_to_memberlist(list, temp_contact->contact_name, NULL); + } + } + + /* else this is just a single contact... */ + else { + + /* this contact should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the contact */ + temp_contact = xodtemplate_find_real_contact(temp_ptr); + if(temp_contact != NULL) { + + found_match = TRUE; + + /* add contact to list */ + xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_ptr, NULL); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any contact matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(contact_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + + +/* adds members of a contactgroups to the list of expanded (accepted) or rejected contacts */ +int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_contactgroup *temp_contactgroup, int _config_file, int _start_line) { + char *group_members = NULL; + char *member_name = NULL; + char *member_ptr = NULL; + + if(list == NULL || temp_contactgroup == NULL) + return ERROR; + + /* if we have no members, just return. Empty contactgroups are ok */ + if(temp_contactgroup->members == NULL) { + return OK; + } + + /* save a copy of the members */ + if((group_members = (char *)strdup(temp_contactgroup->members)) == NULL) + return ERROR; + + /* process all contacts that belong to the contactgroup */ + /* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_contactgroups(), so we don't need to do it here */ + member_ptr = group_members; + for(member_name = my_strsep(&member_ptr, ","); member_name != NULL; member_name = my_strsep(&member_ptr, ",")) { + + /* strip trailing spaces from member name */ + strip(member_name); + + /* add contact to the list */ + xodtemplate_add_member_to_memberlist(list, member_name, NULL); + } + + my_free(group_members); + + return OK; + } + + + +/* expands a comma-delimited list of hostgroups and/or hosts to member host names */ +xodtemplate_memberlist *xodtemplate_expand_hostgroups_and_hosts(char *hostgroups, char *hosts, int _config_file, int _start_line) { + xodtemplate_memberlist *temp_list = NULL; + xodtemplate_memberlist *reject_list = NULL; + xodtemplate_memberlist *list_ptr = NULL; + xodtemplate_memberlist *reject_ptr = NULL; + int result = OK; + + /* process list of hostgroups... */ + if(hostgroups != NULL) { + + /* expand host */ + result = xodtemplate_expand_hostgroups(&temp_list, &reject_list, hostgroups, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + } + + /* process host names */ + if(hosts != NULL) { + + /* expand hosts */ + result = xodtemplate_expand_hosts(&temp_list, &reject_list, hosts, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + } + +#ifdef TESTING + printf("->PRIOR TO CLEANUP\n"); + printf(" REJECT LIST:\n"); + for(list_ptr = reject_list; list_ptr != NULL; list_ptr = list_ptr->next) { + printf(" '%s'\n", list_ptr->name1); + } + printf(" ACCEPT LIST:\n"); + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + printf(" '%s'\n", list_ptr->name1); + } +#endif + + /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ + /* NOTE: rejects from this list also affect hosts generated from processing hostgroup names (see above) */ + for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) { + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + if(!strcmp(reject_ptr->name1, list_ptr->name1)) { + xodtemplate_remove_memberlist_item(list_ptr, &temp_list); + break; + } + } + } + xodtemplate_free_memberlist(&reject_list); + reject_list = NULL; + + return temp_list; + } + + + +/* expands hostgroups */ +int xodtemplate_expand_hostgroups(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hostgroups, int _config_file, int _start_line) { + char *hostgroup_names = NULL; + char *temp_ptr = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || hostgroups == NULL) + return ERROR; + + /* allocate memory for hostgroup name list */ + if((hostgroup_names = (char *)strdup(hostgroups)) == NULL) + return ERROR; + + for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + else + use_regexp = FALSE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(hostgroup_names); + return ERROR; + } + + /* test match against all hostgroup names */ + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + if(temp_hostgroup->hostgroup_name == NULL) + continue; + + /* skip this hostgroup if it did not match the expression */ + if(regexec(&preg, temp_hostgroup->hostgroup_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add hostgroups that shouldn't be registered */ + if(temp_hostgroup->register_object == FALSE) + continue; + + /* add hostgroup members to list */ + xodtemplate_add_hostgroup_members_to_memberlist(list, temp_hostgroup, _config_file, _start_line); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all hostgroups */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + /* dont' add hostgroups that shouldn't be registered */ + if(temp_hostgroup->register_object == FALSE) + continue; + + /* add hostgroup to list */ + xodtemplate_add_hostgroup_members_to_memberlist(list, temp_hostgroup, _config_file, _start_line); + } + } + + /* else this is just a single hostgroup... */ + else { + + /* this hostgroup should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the hostgroup */ + temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr); + if(temp_hostgroup != NULL) { + + found_match = TRUE; + + /* add hostgroup members to proper list */ + xodtemplate_add_hostgroup_members_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_hostgroup, _config_file, _start_line); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any hostgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(hostgroup_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + + +/* expands hosts */ +int xodtemplate_expand_hosts(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hosts, int _config_file, int _start_line) { + char *host_names = NULL; + char *temp_ptr = NULL; + xodtemplate_host *temp_host = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || hosts == NULL) + return ERROR; + + if((host_names = (char *)strdup(hosts)) == NULL) + return ERROR; + + /* expand each host name */ + for(temp_ptr = strtok(host_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(host_names); + return ERROR; + } + + /* test match against all hosts */ + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(temp_host->host_name == NULL) + continue; + + /* skip this host if it did not match the expression */ + if(regexec(&preg, temp_host->host_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add hosts that shouldn't be registered */ + if(temp_host->register_object == FALSE) + continue; + + /* add host to list */ + xodtemplate_add_member_to_memberlist(list, temp_host->host_name, NULL); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all hosts */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) { + + if(temp_host->host_name == NULL) + continue; + + /* dont' add hosts that shouldn't be registered */ + if(temp_host->register_object == FALSE) + continue; + + /* add host to list */ + xodtemplate_add_member_to_memberlist(list, temp_host->host_name, NULL); + } + } + + /* else this is just a single host... */ + else { + + /* this host should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the host */ + temp_host = xodtemplate_find_real_host(temp_ptr); + if(temp_host != NULL) { + + found_match = TRUE; + + /* add host to list */ + xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_ptr, NULL); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any host matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(host_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + +/* adds members of a hostgroups to the list of expanded (accepted) or rejected hosts */ +int xodtemplate_add_hostgroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_hostgroup *temp_hostgroup, int _config_file, int _start_line) { + char *group_members = NULL; + char *member_name = NULL; + char *member_ptr = NULL; + + if(list == NULL || temp_hostgroup == NULL) + return ERROR; + + /* if we have no members, just return. Empty hostgroups are ok */ + if(temp_hostgroup->members == NULL) { + return OK; + } + + /* save a copy of the members */ + if((group_members = (char *)strdup(temp_hostgroup->members)) == NULL) + return ERROR; + + /* process all hosts that belong to the hostgroup */ + /* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_hostgroups(), so we don't need to do it here */ + member_ptr = group_members; + for(member_name = my_strsep(&member_ptr, ","); member_name != NULL; member_name = my_strsep(&member_ptr, ",")) { + + /* strip trailing spaces from member name */ + strip(member_name); + + /* add host to the list */ + xodtemplate_add_member_to_memberlist(list, member_name, NULL); + } + + my_free(group_members); + + return OK; + } + + + +/* expands a comma-delimited list of servicegroups and/or service descriptions */ +xodtemplate_memberlist *xodtemplate_expand_servicegroups_and_services(char *servicegroups, char *host_name, char *services, int _config_file, int _start_line) { + xodtemplate_memberlist *temp_list = NULL; + xodtemplate_memberlist *reject_list = NULL; + xodtemplate_memberlist *list_ptr = NULL; + xodtemplate_memberlist *reject_ptr = NULL; + int result = OK; + + /* process list of servicegroups... */ + if(servicegroups != NULL) { + + /* expand servicegroups */ + result = xodtemplate_expand_servicegroups(&temp_list, &reject_list, servicegroups, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + } + + /* process service names */ + if(host_name != NULL && services != NULL) { + + /* expand services */ + result = xodtemplate_expand_services(&temp_list, &reject_list, host_name, services, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + } + + /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ + /* NOTE: rejects from this list also affect hosts generated from processing hostgroup names (see above) */ + for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) { + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + if(!strcmp(reject_ptr->name1, list_ptr->name1) && !strcmp(reject_ptr->name2, list_ptr->name2)) { + xodtemplate_remove_memberlist_item(list_ptr, &temp_list); + break; + } + } + } + xodtemplate_free_memberlist(&reject_list); + reject_list = NULL; + + return temp_list; + } + + +/* expands servicegroups */ +int xodtemplate_expand_servicegroups(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *servicegroups, int _config_file, int _start_line) { + xodtemplate_servicegroup *temp_servicegroup = NULL; + regex_t preg; + char *servicegroup_names = NULL; + char *temp_ptr = NULL; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL) + return ERROR; + if(servicegroups == NULL) + return OK; + + /* allocate memory for servicegroup name list */ + if((servicegroup_names = (char *)strdup(servicegroups)) == NULL) + return ERROR; + + /* expand each servicegroup */ + for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + else + use_regexp = FALSE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(servicegroup_names); + return ERROR; + } + + /* test match against all servicegroup names */ + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + if(temp_servicegroup->servicegroup_name == NULL) + continue; + + /* skip this servicegroup if it did not match the expression */ + if(regexec(&preg, temp_servicegroup->servicegroup_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add servicegroups that shouldn't be registered */ + if(temp_servicegroup->register_object == FALSE) + continue; + + /* add servicegroup members to list */ + xodtemplate_add_servicegroup_members_to_memberlist(list, temp_servicegroup, _config_file, _start_line); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all servicegroups */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + /* dont' add servicegroups that shouldn't be registered */ + if(temp_servicegroup->register_object == FALSE) + continue; + + /* add servicegroup to list */ + xodtemplate_add_servicegroup_members_to_memberlist(list, temp_servicegroup, _config_file, _start_line); + } + } + + /* else this is just a single servicegroup... */ + else { + + /* this servicegroup should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the servicegroup */ + if((temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr)) != NULL) { + + found_match = TRUE; + + /* add servicegroup members to list */ + xodtemplate_add_servicegroup_members_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_servicegroup, _config_file, _start_line); + } + } + } + + /* we didn't find a matching servicegroup */ + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any servicegroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(servicegroup_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + +/* expands services (host name is not expanded) */ +int xodtemplate_expand_services(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *host_name, char *services, int _config_file, int _start_line) { + char *service_names = NULL; + char *temp_ptr = NULL; + xodtemplate_service *temp_service = NULL; + regex_t preg; + regex_t preg2; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp_host = FALSE; + int use_regexp_service = FALSE; + + if(list == NULL) + return ERROR; + if(host_name == NULL || services == NULL) + return OK; + + /* should we use regular expression matching for the host name? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(host_name, "*") || strstr(host_name, "?") || strstr(host_name, "+") || strstr(host_name, "\\."))) + use_regexp_host = TRUE; + + /* compile regular expression for host name */ + if(use_regexp_host == TRUE) { + if(regcomp(&preg2, host_name, REG_EXTENDED)) + return ERROR; + } + + if((service_names = (char *)strdup(services)) == NULL) { + if(use_regexp_host == TRUE) + regfree(&preg2); + return ERROR; + } + + /* expand each service description */ + for(temp_ptr = strtok(service_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching for the service description? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp_service = TRUE; + else + use_regexp_service = FALSE; + + /* compile regular expression for service description */ + if(use_regexp_service == TRUE) { + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + if(use_regexp_host == TRUE) + regfree(&preg2); + my_free(service_names); + return ERROR; + } + } + + /* use regular expression matching */ + if(use_regexp_host == TRUE || use_regexp_service == TRUE) { + + /* test match against all services */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + if(temp_service->host_name == NULL || temp_service->service_description == NULL) + continue; + + /* skip this service if it doesn't match the host name expression */ + if(use_regexp_host == TRUE) { + if(regexec(&preg2, temp_service->host_name, 0, NULL, 0)) + continue; + } + else { + if(strcmp(temp_service->host_name, host_name)) + continue; + } + + /* skip this service if it doesn't match the service description expression */ + if(use_regexp_service == TRUE) { + if(regexec(&preg, temp_service->service_description, 0, NULL, 0)) + continue; + } + else { + if(strcmp(temp_service->service_description, temp_ptr)) + continue; + } + + found_match = TRUE; + + /* dont' add services that shouldn't be registered */ + if(temp_service->register_object == FALSE) + continue; + + /* add service to the list */ + xodtemplate_add_member_to_memberlist(list, host_name, temp_service->service_description); + } + + /* free memory allocated to compiled regexp */ + if(use_regexp_service == TRUE) + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all services on the host */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + + if(temp_service->host_name == NULL || temp_service->service_description == NULL) + continue; + + if(strcmp(temp_service->host_name, host_name)) + continue; + + /* dont' add services that shouldn't be registered */ + if(temp_service->register_object == FALSE) + continue; + + /* add service to the list */ + xodtemplate_add_member_to_memberlist(list, host_name, temp_service->service_description); + } + } + + /* else this is just a single service... */ + else { + + /* this service should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the service */ + if((temp_service = xodtemplate_find_real_service(host_name, temp_ptr)) != NULL) { + + found_match = TRUE; + + /* add service to the list */ + xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, host_name, temp_service->service_description); + } + } + } + + /* we didn't find a match */ + if(found_match == FALSE && reject_item == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find a service matching host name '%s' and description '%s' (config file '%s', starting on line %d)\n", host_name, temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + if(use_regexp_host == TRUE) + regfree(&preg2); + my_free(service_names); + + if(found_match == FALSE && reject_item == FALSE) + return ERROR; + + return OK; + } + + +/* adds members of a servicegroups to the list of expanded services */ +int xodtemplate_add_servicegroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_servicegroup *temp_servicegroup, int _config_file, int _start_line) { + char *group_members = NULL; + char *member_name = NULL; + char *host_name = NULL; + char *member_ptr = NULL; + + if(list == NULL || temp_servicegroup == NULL) + return ERROR; + + /* if we have no members, just return. Empty servicegroups are ok */ + if(temp_servicegroup->members == NULL) { + return OK; + } + + /* save a copy of the members */ + if((group_members = (char *)strdup(temp_servicegroup->members)) == NULL) + return ERROR; + + /* process all services that belong to the servicegroup */ + /* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_servicegroups(), so we don't need to do it here */ + member_ptr = group_members; + for(member_name = my_strsep(&member_ptr, ","); member_name != NULL; member_name = my_strsep(&member_ptr, ",")) { + + /* strip trailing spaces from member name */ + strip(member_name); + + /* host name */ + if(host_name == NULL) { + if((host_name = (char *)strdup(member_name)) == NULL) { + my_free(group_members); + return ERROR; + } + } + + /* service description */ + else { + + /* add service to the list */ + xodtemplate_add_member_to_memberlist(list, host_name, member_name); + + my_free(host_name); + } + } + + my_free(group_members); + + return OK; + } + + + + +/* returns a comma-delimited list of hostgroup names */ +char * xodtemplate_process_hostgroup_names(char *hostgroups, int _config_file, int _start_line) { + xodtemplate_memberlist *temp_list = NULL; + xodtemplate_memberlist *reject_list = NULL; + xodtemplate_memberlist *list_ptr = NULL; + xodtemplate_memberlist *reject_ptr = NULL; + xodtemplate_memberlist *this_list = NULL; + char *buf = NULL; + int result = OK; + + /* process list of hostgroups... */ + if(hostgroups != NULL) { + + /* split group names into two lists */ + result = xodtemplate_get_hostgroup_names(&temp_list, &reject_list, hostgroups, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + + /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ + for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) { + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + if(!strcmp(reject_ptr->name1, list_ptr->name1)) { + xodtemplate_remove_memberlist_item(list_ptr, &temp_list); + break; + } + } + } + + xodtemplate_free_memberlist(&reject_list); + reject_list = NULL; + } + + /* generate the list of group members */ + for(this_list = temp_list; this_list != NULL; this_list = this_list->next) { + if(buf == NULL) { + buf = (char *)malloc(strlen(this_list->name1) + 1); + strcpy(buf, this_list->name1); + } + else { + buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2); + strcat(buf, ","); + strcat(buf, this_list->name1); + } + } + + xodtemplate_free_memberlist(&temp_list); + + return buf; + } + + + +/* return a list of hostgroup names */ +int xodtemplate_get_hostgroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hostgroups, int _config_file, int _start_line) { + char *hostgroup_names = NULL; + char *temp_ptr = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || hostgroups == NULL) + return ERROR; + + /* allocate memory for hostgroup name list */ + if((hostgroup_names = (char *)strdup(hostgroups)) == NULL) + return ERROR; + + for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + else + use_regexp = FALSE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(hostgroup_names); + return ERROR; + } + + /* test match against all hostgroup names */ + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + if(temp_hostgroup->hostgroup_name == NULL) + continue; + + /* skip this hostgroup if it did not match the expression */ + if(regexec(&preg, temp_hostgroup->hostgroup_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add hostgroups that shouldn't be registered */ + if(temp_hostgroup->register_object == FALSE) + continue; + + /* add hostgroup to list */ + xodtemplate_add_member_to_memberlist(list, temp_hostgroup->hostgroup_name, NULL); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all hostgroups */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + + /* dont' add hostgroups that shouldn't be registered */ + if(temp_hostgroup->register_object == FALSE) + continue; + + /* add hostgroup to list */ + xodtemplate_add_member_to_memberlist(list, temp_hostgroup->hostgroup_name, NULL); + } + } + + /* else this is just a single hostgroup... */ + else { + + /* this hostgroup should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the hostgroup */ + temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr); + if(temp_hostgroup != NULL) { + + found_match = TRUE; + + /* add hostgroup members to proper list */ + xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_hostgroup->hostgroup_name, NULL); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any hostgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(hostgroup_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + + +/* returns a comma-delimited list of contactgroup names */ +char * xodtemplate_process_contactgroup_names(char *contactgroups, int _config_file, int _start_line) { + xodtemplate_memberlist *temp_list = NULL; + xodtemplate_memberlist *reject_list = NULL; + xodtemplate_memberlist *list_ptr = NULL; + xodtemplate_memberlist *reject_ptr = NULL; + xodtemplate_memberlist *this_list = NULL; + char *buf = NULL; + int result = OK; + + /* process list of contactgroups... */ + if(contactgroups != NULL) { + + /* split group names into two lists */ + result = xodtemplate_get_contactgroup_names(&temp_list, &reject_list, contactgroups, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + + /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ + for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) { + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + if(!strcmp(reject_ptr->name1, list_ptr->name1)) { + xodtemplate_remove_memberlist_item(list_ptr, &temp_list); + break; + } + } + } + + xodtemplate_free_memberlist(&reject_list); + reject_list = NULL; + } + + /* generate the list of group members */ + for(this_list = temp_list; this_list != NULL; this_list = this_list->next) { + if(buf == NULL) { + buf = (char *)malloc(strlen(this_list->name1) + 1); + strcpy(buf, this_list->name1); + } + else { + buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2); + strcat(buf, ","); + strcat(buf, this_list->name1); + } + } + + xodtemplate_free_memberlist(&temp_list); + + return buf; + } + + + +/* return a list of contactgroup names */ +int xodtemplate_get_contactgroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contactgroups, int _config_file, int _start_line) { + char *contactgroup_names = NULL; + char *temp_ptr = NULL; + xodtemplate_contactgroup *temp_contactgroup = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || contactgroups == NULL) + return ERROR; + + /* allocate memory for contactgroup name list */ + if((contactgroup_names = (char *)strdup(contactgroups)) == NULL) + return ERROR; + + for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + else + use_regexp = FALSE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(contactgroup_names); + return ERROR; + } + + /* test match against all contactgroup names */ + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + + if(temp_contactgroup->contactgroup_name == NULL) + continue; + + /* skip this contactgroup if it did not match the expression */ + if(regexec(&preg, temp_contactgroup->contactgroup_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add contactgroups that shouldn't be registered */ + if(temp_contactgroup->register_object == FALSE) + continue; + + /* add contactgroup to list */ + xodtemplate_add_member_to_memberlist(list, temp_contactgroup->contactgroup_name, NULL); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all contactgroups */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + + /* dont' add contactgroups that shouldn't be registered */ + if(temp_contactgroup->register_object == FALSE) + continue; + + /* add contactgroup to list */ + xodtemplate_add_member_to_memberlist(list, temp_contactgroup->contactgroup_name, NULL); + } + } + + /* else this is just a single contactgroup... */ + else { + + /* this contactgroup should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the contactgroup */ + temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr); + if(temp_contactgroup != NULL) { + + found_match = TRUE; + + /* add contactgroup members to proper list */ + xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_contactgroup->contactgroup_name, NULL); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any contactgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(contactgroup_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + + + +/* returns a comma-delimited list of servicegroup names */ +char * xodtemplate_process_servicegroup_names(char *servicegroups, int _config_file, int _start_line) { + xodtemplate_memberlist *temp_list = NULL; + xodtemplate_memberlist *reject_list = NULL; + xodtemplate_memberlist *list_ptr = NULL; + xodtemplate_memberlist *reject_ptr = NULL; + xodtemplate_memberlist *this_list = NULL; + char *buf = NULL; + int result = OK; + + /* process list of servicegroups... */ + if(servicegroups != NULL) { + + /* split group names into two lists */ + result = xodtemplate_get_servicegroup_names(&temp_list, &reject_list, servicegroups, _config_file, _start_line); + if(result != OK) { + xodtemplate_free_memberlist(&temp_list); + xodtemplate_free_memberlist(&reject_list); + return NULL; + } + + /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ + for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) { + for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) { + if(!strcmp(reject_ptr->name1, list_ptr->name1)) { + xodtemplate_remove_memberlist_item(list_ptr, &temp_list); + break; + } + } + } + + xodtemplate_free_memberlist(&reject_list); + reject_list = NULL; + } + + /* generate the list of group members */ + for(this_list = temp_list; this_list != NULL; this_list = this_list->next) { + if(buf == NULL) { + buf = (char *)malloc(strlen(this_list->name1) + 1); + strcpy(buf, this_list->name1); + } + else { + buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2); + strcat(buf, ","); + strcat(buf, this_list->name1); + } + } + + xodtemplate_free_memberlist(&temp_list); + + return buf; + } + + + +/* return a list of servicegroup names */ +int xodtemplate_get_servicegroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *servicegroups, int _config_file, int _start_line) { + char *servicegroup_names = NULL; + char *temp_ptr = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + regex_t preg; + int found_match = TRUE; + int reject_item = FALSE; + int use_regexp = FALSE; + + if(list == NULL || servicegroups == NULL) + return ERROR; + + /* allocate memory for servicegroup name list */ + if((servicegroup_names = (char *)strdup(servicegroups)) == NULL) + return ERROR; + + for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) { + + found_match = FALSE; + reject_item = FALSE; + + /* strip trailing spaces */ + strip(temp_ptr); + + /* should we use regular expression matching? */ + if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\."))) + use_regexp = TRUE; + else + use_regexp = FALSE; + + /* use regular expression matching */ + if(use_regexp == TRUE) { + + /* compile regular expression */ + if(regcomp(&preg, temp_ptr, REG_EXTENDED)) { + my_free(servicegroup_names); + return ERROR; + } + + /* test match against all servicegroup names */ + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + if(temp_servicegroup->servicegroup_name == NULL) + continue; + + /* skip this servicegroup if it did not match the expression */ + if(regexec(&preg, temp_servicegroup->servicegroup_name, 0, NULL, 0)) + continue; + + found_match = TRUE; + + /* dont' add servicegroups that shouldn't be registered */ + if(temp_servicegroup->register_object == FALSE) + continue; + + /* add servicegroup to list */ + xodtemplate_add_member_to_memberlist(list, temp_servicegroup->servicegroup_name, NULL); + } + + /* free memory allocated to compiled regexp */ + regfree(&preg); + } + + /* use standard matching... */ + else { + + /* return a list of all servicegroups */ + if(!strcmp(temp_ptr, "*")) { + + found_match = TRUE; + + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + + /* dont' add servicegroups that shouldn't be registered */ + if(temp_servicegroup->register_object == FALSE) + continue; + + /* add servicegroup to list */ + xodtemplate_add_member_to_memberlist(list, temp_servicegroup->servicegroup_name, NULL); + } + } + + /* else this is just a single servicegroup... */ + else { + + /* this servicegroup should be excluded (rejected) */ + if(temp_ptr[0] == '!') { + reject_item = TRUE; + temp_ptr++; + } + + /* find the servicegroup */ + temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr); + if(temp_servicegroup != NULL) { + + found_match = TRUE; + + /* add servicegroup members to proper list */ + xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_servicegroup->servicegroup_name, NULL); + } + } + } + + if(found_match == FALSE) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any servicegroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line); + break; + } + } + + /* free memory */ + my_free(servicegroup_names); + + if(found_match == FALSE) + return ERROR; + + return OK; + } + +#ifdef NSCORE + +/******************************************************************/ +/****************** ADDITIVE INHERITANCE STUFF ********************/ +/******************************************************************/ + +/* determines the value of an inherited string */ +int xodtemplate_get_inherited_string(int *have_template_value, char **template_value, int *have_this_value, char **this_value) { + char *buf = NULL; + + /* template has a value we should use */ + if(*have_template_value == TRUE) { + + /* template has a non-NULL value */ + if(*template_value != NULL) { + + /* we have no value... */ + if(*this_value == NULL) { + + /* use the template value only if we need a value - otherwise stay NULL */ + if(*have_this_value == FALSE) { + /* NOTE: leave leading + sign if present, as it needed during object resolution and will get stripped later */ + *this_value = (char *)strdup(*template_value); + } + } + + /* we already have a value... */ + else { + /* our value should be added to the template value */ + if(*this_value[0] == '+') { + if((buf = (char *)malloc(strlen(*template_value) + strlen(*this_value) + 1))) { + strcpy(buf, *template_value); + strcat(buf, ","); + strcat(buf, *this_value + 1); + my_free(*this_value); + *this_value = buf; + } + } + + /* otherwise our value overrides/replaces the template value */ + } + } + + /* template has a NULL value.... */ + + *have_this_value = TRUE; + } + + return OK; + } + + +/* removes leading + sign from various directives */ +int xodtemplate_clean_additive_string(char **str) { + char *buf = NULL; + + /* remove the additive symbol if present */ + if(*str != NULL && *str[0] == '+') { + buf = (char *)strdup(*str + 1); + my_free(*str); + *str = buf; + } + + return OK; + } + + +/* cleans strings which may contain additive inheritance directives */ +/* NOTE: this must be done after objects are resolved */ +int xodtemplate_clean_additive_strings(void) { + xodtemplate_contactgroup *temp_contactgroup = NULL; + xodtemplate_hostgroup *temp_hostgroup = NULL; + xodtemplate_servicegroup *temp_servicegroup = NULL; + xodtemplate_servicedependency *temp_servicedependency = NULL; + xodtemplate_serviceescalation *temp_serviceescalation = NULL; + xodtemplate_contact *temp_contact = NULL; + xodtemplate_host *temp_host = NULL; + xodtemplate_service *temp_service = NULL; + xodtemplate_hostdependency *temp_hostdependency = NULL; + xodtemplate_hostescalation *temp_hostescalation = NULL; + + /* resolve all contactgroup objects */ + for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) { + xodtemplate_clean_additive_string(&temp_contactgroup->members); + xodtemplate_clean_additive_string(&temp_contactgroup->contactgroup_members); + } + + /* resolve all hostgroup objects */ + for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { + xodtemplate_clean_additive_string(&temp_hostgroup->members); + xodtemplate_clean_additive_string(&temp_hostgroup->hostgroup_members); + } + + /* resolve all servicegroup objects */ + for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { + xodtemplate_clean_additive_string(&temp_servicegroup->members); + xodtemplate_clean_additive_string(&temp_servicegroup->servicegroup_members); + } + + /* resolve all servicedependency objects */ + for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) { + xodtemplate_clean_additive_string(&temp_servicedependency->servicegroup_name); + xodtemplate_clean_additive_string(&temp_servicedependency->hostgroup_name); + xodtemplate_clean_additive_string(&temp_servicedependency->host_name); + xodtemplate_clean_additive_string(&temp_servicedependency->service_description); + xodtemplate_clean_additive_string(&temp_servicedependency->dependent_servicegroup_name); + xodtemplate_clean_additive_string(&temp_servicedependency->dependent_hostgroup_name); + xodtemplate_clean_additive_string(&temp_servicedependency->dependent_host_name); + xodtemplate_clean_additive_string(&temp_servicedependency->dependent_service_description); + } + + /* resolve all serviceescalation objects */ + for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) { + /* 03/05/08 some vars are now handled in xodtemplate_inherit_object_properties() */ + /* + xodtemplate_clean_additive_string(&temp_serviceescalation->contact_groups); + xodtemplate_clean_additive_string(&temp_serviceescalation->contacts); + */ + xodtemplate_clean_additive_string(&temp_serviceescalation->servicegroup_name); + xodtemplate_clean_additive_string(&temp_serviceescalation->hostgroup_name); + xodtemplate_clean_additive_string(&temp_serviceescalation->host_name); + xodtemplate_clean_additive_string(&temp_serviceescalation->service_description); + } + + /* resolve all contact objects */ + for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + xodtemplate_clean_additive_string(&temp_contact->contact_groups); + xodtemplate_clean_additive_string(&temp_contact->host_notification_commands); + xodtemplate_clean_additive_string(&temp_contact->service_notification_commands); + } + + /* clean all host objects */ + for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) { + xodtemplate_clean_additive_string(&temp_host->contact_groups); + xodtemplate_clean_additive_string(&temp_host->contacts); + xodtemplate_clean_additive_string(&temp_host->parents); + xodtemplate_clean_additive_string(&temp_host->host_groups); + } + + /* clean all service objects */ + for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) { + xodtemplate_clean_additive_string(&temp_service->contact_groups); + xodtemplate_clean_additive_string(&temp_service->contacts); + xodtemplate_clean_additive_string(&temp_service->host_name); + xodtemplate_clean_additive_string(&temp_service->hostgroup_name); + xodtemplate_clean_additive_string(&temp_service->service_groups); + } + + /* resolve all hostdependency objects */ + for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) { + xodtemplate_clean_additive_string(&temp_hostdependency->host_name); + xodtemplate_clean_additive_string(&temp_hostdependency->dependent_host_name); + xodtemplate_clean_additive_string(&temp_hostdependency->hostgroup_name); + xodtemplate_clean_additive_string(&temp_hostdependency->dependent_hostgroup_name); + } + + /* resolve all hostescalation objects */ + for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) { + /* 03/05/08 some vars are now handled in xodtemplate_inherit_object_properties() */ + /* + xodtemplate_clean_additive_string(&temp_hostescalation->contact_groups); + xodtemplate_clean_additive_string(&temp_hostescalation->contacts); + */ + xodtemplate_clean_additive_string(&temp_hostescalation->host_name); + xodtemplate_clean_additive_string(&temp_hostescalation->hostgroup_name); + } + + return OK; + } +#endif + +#endif + + diff --git a/xdata/xodtemplate.h b/xdata/xodtemplate.h new file mode 100644 index 0000000..2bea581 --- /dev/null +++ b/xdata/xodtemplate.h @@ -0,0 +1,972 @@ +/***************************************************************************** + * + * XODTEMPLATE.H - Template-based object configuration data header file + * + * Copyright (c) 2001-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-17-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _XODTEMPLATE_H +#define _XODTEMPLATE_H + + + +/*********** GENERAL DEFINITIONS ************/ + +#define XODTEMPLATE_NULL "null" + +#define MAX_XODTEMPLATE_INPUT_BUFFER 1024 + +#define MAX_XODTEMPLATE_CONTACT_ADDRESSES 6 + +#define XODTEMPLATE_NONE 0 +#define XODTEMPLATE_TIMEPERIOD 1 +#define XODTEMPLATE_COMMAND 2 +#define XODTEMPLATE_CONTACT 3 +#define XODTEMPLATE_CONTACTGROUP 4 +#define XODTEMPLATE_HOST 5 +#define XODTEMPLATE_HOSTGROUP 6 +#define XODTEMPLATE_SERVICE 7 +#define XODTEMPLATE_SERVICEDEPENDENCY 8 +#define XODTEMPLATE_HOSTGROUPESCALATION 9 /* no longer implemented */ +#define XODTEMPLATE_SERVICEESCALATION 10 +#define XODTEMPLATE_HOSTESCALATION 11 +#define XODTEMPLATE_HOSTDEPENDENCY 12 +#define XODTEMPLATE_HOSTEXTINFO 13 +#define XODTEMPLATE_SERVICEEXTINFO 14 +#define XODTEMPLATE_SERVICEGROUP 15 + + + +/***************** SKIP LISTS ****************/ + +#define NUM_XOBJECT_SKIPLISTS 15 + +#define X_HOST_SKIPLIST 1 +#define X_SERVICE_SKIPLIST 2 +#define X_COMMAND_SKIPLIST 3 +#define X_TIMEPERIOD_SKIPLIST 4 +#define X_CONTACT_SKIPLIST 5 +#define X_CONTACTGROUP_SKIPLIST 6 +#define X_HOSTGROUP_SKIPLIST 7 +#define X_SERVICEGROUP_SKIPLIST 8 +#define X_HOSTDEPENDENCY_SKIPLIST 9 +#define X_SERVICEDEPENDENCY_SKIPLIST 10 +#define X_HOSTESCALATION_SKIPLIST 11 +#define X_SERVICEESCALATION_SKIPLIST 12 +#define X_HOSTEXTINFO_SKIPLIST 13 +#define X_SERVICEEXTINFO_SKIPLIST 14 + + +/********** STRUCTURE DEFINITIONS **********/ + +/* CUSTOMVARIABLESMEMBER structure */ +typedef struct xodtemplate_customvariablesmember_struct { + char *variable_name; + char *variable_value; + struct xodtemplate_customvariablesmember_struct *next; + } xodtemplate_customvariablesmember; + + +/* DATERANGE structure */ +typedef struct xodtemplate_daterange_struct { + int type; + int syear; /* start year */ + int smon; /* start month */ + int smday; /* start day of month (may 3rd, last day in feb) */ + int swday; /* start day of week (thursday) */ + int swday_offset; /* start weekday offset (3rd thursday, last monday in jan) */ + int eyear; + int emon; + int emday; + int ewday; + int ewday_offset; + int skip_interval; + char *timeranges; + struct xodtemplate_daterange_struct *next; + } xodtemplate_daterange; + + +/* TIMEPERIOD TEMPLATE STRUCTURE */ +typedef struct xodtemplate_timeperiod_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *timeperiod_name; + char *alias; + char *timeranges[7]; + xodtemplate_daterange *exceptions[DATERANGE_TYPES]; + char *exclusions; + + int has_been_resolved; + int register_object; + struct xodtemplate_timeperiod_struct *next; + } xodtemplate_timeperiod; + + +/* COMMAND TEMPLATE STRUCTURE */ +typedef struct xodtemplate_command_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *command_name; + char *command_line; + + int has_been_resolved; + int register_object; + struct xodtemplate_command_struct *next; +} xodtemplate_command; + + +/* CONTACT TEMPLATE STRUCTURE */ +typedef struct xodtemplate_contact_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *contact_name; + char *alias; + char *contact_groups; + char *email; + char *pager; + char *address[MAX_XODTEMPLATE_CONTACT_ADDRESSES]; + char *host_notification_period; + char *host_notification_commands; + int notify_on_host_down; + int notify_on_host_unreachable; + int notify_on_host_recovery; + int notify_on_host_flapping; + int notify_on_host_downtime; + char *service_notification_period; + char *service_notification_commands; + int notify_on_service_unknown; + int notify_on_service_warning; + int notify_on_service_critical; + int notify_on_service_recovery; + int notify_on_service_flapping; + int notify_on_service_downtime; + int host_notifications_enabled; + int service_notifications_enabled; + int can_submit_commands; + int retain_status_information; + int retain_nonstatus_information; + xodtemplate_customvariablesmember *custom_variables; + + int have_contact_groups; + int have_email; + int have_pager; + int have_address[MAX_XODTEMPLATE_CONTACT_ADDRESSES]; + int have_host_notification_period; + int have_host_notification_commands; + int have_service_notification_period; + int have_service_notification_commands; + + int have_host_notification_options; + int have_service_notification_options; + int have_host_notifications_enabled; + int have_service_notifications_enabled; + int have_can_submit_commands; + int have_retain_status_information; + int have_retain_nonstatus_information; + + int has_been_resolved; + int register_object; + struct xodtemplate_contact_struct *next; +} xodtemplate_contact; + + +/* CONTACTGROUP TEMPLATE STRUCTURE */ +typedef struct xodtemplate_contactgroup_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *contactgroup_name; + char *alias; + char *members; + char *contactgroup_members; + + int have_members; + int have_contactgroup_members; + + int has_been_resolved; + int register_object; + struct xodtemplate_contactgroup_struct *next; +} xodtemplate_contactgroup; + + +/* HOST TEMPLATE STRUCTURE */ +typedef struct xodtemplate_host_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *display_name; + char *alias; + char *address; + char *parents; + char *host_groups; + char *check_command; + char *check_period; + int initial_state; + double check_interval; + double retry_interval; + int max_check_attempts; + int active_checks_enabled; + int passive_checks_enabled; + int obsess_over_host; + char *event_handler; + int event_handler_enabled; + int check_freshness; + int freshness_threshold; + float low_flap_threshold; + float high_flap_threshold; + int flap_detection_enabled; + int flap_detection_on_up; + int flap_detection_on_down; + int flap_detection_on_unreachable; + char *contact_groups; + char *contacts; + int notify_on_down; + int notify_on_unreachable; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + int notifications_enabled; + char *notification_period; + double notification_interval; + double first_notification_delay; + int stalk_on_up; + int stalk_on_down; + int stalk_on_unreachable; + int process_perf_data; + int failure_prediction_enabled; + char *failure_prediction_options; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + char *vrml_image; + char *statusmap_image; + int x_2d; + int y_2d; + double x_3d; + double y_3d; + double z_3d; + int retain_status_information; + int retain_nonstatus_information; + xodtemplate_customvariablesmember *custom_variables; + + int have_display_name; + int have_parents; + int have_host_groups; + int have_check_command; + int have_check_period; + int have_event_handler; + int have_contact_groups; + int have_contacts; + int have_notification_period; + int have_failure_prediction_options; + int have_notes; + int have_notes_url; + int have_action_url; + int have_icon_image; + int have_icon_image_alt; + int have_vrml_image; + int have_statusmap_image; + + int have_initial_state; + int have_check_interval; + int have_retry_interval; + int have_max_check_attempts; + int have_active_checks_enabled; + int have_passive_checks_enabled; + int have_obsess_over_host; + int have_event_handler_enabled; + int have_check_freshness; + int have_freshness_threshold; + int have_low_flap_threshold; + int have_high_flap_threshold; + int have_flap_detection_enabled; + int have_flap_detection_options; + int have_notification_options; + int have_notifications_enabled; + int have_notification_interval; + int have_first_notification_delay; + int have_stalking_options; + int have_process_perf_data; + int have_failure_prediction_enabled; + int have_2d_coords; + int have_3d_coords; + int have_retain_status_information; + int have_retain_nonstatus_information; + + int has_been_resolved; + int register_object; + struct xodtemplate_host_struct *next; +} xodtemplate_host; + + +/* HOSTGROUP TEMPLATE STRUCTURE */ +typedef struct xodtemplate_hostgroup_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *hostgroup_name; + char *alias; + char *members; + char *hostgroup_members; + char *notes; + char *notes_url; + char *action_url; + + int have_members; + int have_hostgroup_members; + int have_notes; + int have_notes_url; + int have_action_url; + + int has_been_resolved; + int register_object; + struct xodtemplate_hostgroup_struct *next; +} xodtemplate_hostgroup; + + +/* SERVICE TEMPLATE STRUCTURE */ +typedef struct xodtemplate_service_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *service_description; + char *display_name; + char *hostgroup_name; + char *service_groups; + char *check_command; + int initial_state; + int max_check_attempts; + double check_interval; + double retry_interval; + char *check_period; + int active_checks_enabled; + int passive_checks_enabled; + int parallelize_check; + int is_volatile; + int obsess_over_service; + char *event_handler; + int event_handler_enabled; + int check_freshness; + int freshness_threshold; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_enabled; + int flap_detection_on_ok; + int flap_detection_on_warning; + int flap_detection_on_unknown; + int flap_detection_on_critical; + int notify_on_unknown; + int notify_on_warning; + int notify_on_critical; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + int notifications_enabled; + char *notification_period; + double notification_interval; + double first_notification_delay; + char *contact_groups; + char *contacts; + int stalk_on_ok; + int stalk_on_unknown; + int stalk_on_warning; + int stalk_on_critical; + int process_perf_data; + int failure_prediction_enabled; + char *failure_prediction_options; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + int retain_status_information; + int retain_nonstatus_information; + xodtemplate_customvariablesmember *custom_variables; + + int have_host_name; + int have_service_description; + int have_display_name; + int have_hostgroup_name; + int have_service_groups; + int have_check_command; + int have_important_check_command; + int have_check_period; + int have_event_handler; + int have_notification_period; + int have_contact_groups; + int have_contacts; + int have_failure_prediction_options; + int have_notes; + int have_notes_url; + int have_action_url; + int have_icon_image; + int have_icon_image_alt; + + int have_initial_state; + int have_max_check_attempts; + int have_check_interval; + int have_retry_interval; + int have_active_checks_enabled; + int have_passive_checks_enabled; + int have_parallelize_check; + int have_is_volatile; + int have_obsess_over_service; + int have_event_handler_enabled; + int have_check_freshness; + int have_freshness_threshold; + int have_low_flap_threshold; + int have_high_flap_threshold; + int have_flap_detection_enabled; + int have_flap_detection_options; + int have_notification_options; + int have_notifications_enabled; + int have_notification_dependencies; + int have_notification_interval; + int have_first_notification_delay; + int have_stalking_options; + int have_process_perf_data; + int have_failure_prediction_enabled; + int have_retain_status_information; + int have_retain_nonstatus_information; + + int has_been_resolved; + int register_object; + struct xodtemplate_service_struct *next; +} xodtemplate_service; + + +/* SERVICEGROUP TEMPLATE STRUCTURE */ +typedef struct xodtemplate_servicegroup_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *servicegroup_name; + char *alias; + char *members; + char *servicegroup_members; + char *notes; + char *notes_url; + char *action_url; + + int have_members; + int have_servicegroup_members; + int have_notes; + int have_notes_url; + int have_action_url; + + int has_been_resolved; + int register_object; + struct xodtemplate_servicegroup_struct *next; +} xodtemplate_servicegroup; + + +/* SERVICEDEPENDENCY TEMPLATE STRUCTURE */ +typedef struct xodtemplate_servicedependency_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *service_description; + char *dependent_host_name; + char *dependent_service_description; + char *servicegroup_name; + char *hostgroup_name; + char *dependent_servicegroup_name; + char *dependent_hostgroup_name; + char *dependency_period; + int inherits_parent; + int fail_notify_on_ok; + int fail_notify_on_unknown; + int fail_notify_on_warning; + int fail_notify_on_critical; + int fail_notify_on_pending; + int fail_execute_on_ok; + int fail_execute_on_unknown; + int fail_execute_on_warning; + int fail_execute_on_critical; + int fail_execute_on_pending; + + int have_host_name; + int have_service_description; + int have_dependent_host_name; + int have_dependent_service_description; + int have_servicegroup_name; + int have_hostgroup_name; + int have_dependent_servicegroup_name; + int have_dependent_hostgroup_name; + int have_dependency_period; + + int have_inherits_parent; + int have_notification_dependency_options; + int have_execution_dependency_options; + + int has_been_resolved; + int register_object; + struct xodtemplate_servicedependency_struct *next; +} xodtemplate_servicedependency; + + +/* SERVICEESCALATION TEMPLATE STRUCTURE */ +typedef struct xodtemplate_serviceescalation_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *service_description; + char *servicegroup_name; + char *hostgroup_name; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_warning; + int escalate_on_unknown; + int escalate_on_critical; + int escalate_on_recovery; + char *contact_groups; + char *contacts; + + int have_host_name; + int have_service_description; + int have_servicegroup_name; + int have_hostgroup_name; + int have_escalation_period; + int have_contact_groups; + int have_contacts; + + int have_first_notification; + int have_last_notification; + int have_notification_interval; + int have_escalation_options; + + int has_been_resolved; + int register_object; + struct xodtemplate_serviceescalation_struct *next; +} xodtemplate_serviceescalation; + + +/* HOSTDEPENDENCY TEMPLATE STRUCTURE */ +typedef struct xodtemplate_hostdependency_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *dependent_host_name; + char *hostgroup_name; + char *dependent_hostgroup_name; + char *dependency_period; + int inherits_parent; + int fail_notify_on_up; + int fail_notify_on_down; + int fail_notify_on_unreachable; + int fail_notify_on_pending; + int fail_execute_on_up; + int fail_execute_on_down; + int fail_execute_on_unreachable; + int fail_execute_on_pending; + + int have_host_name; + int have_dependent_host_name; + int have_hostgroup_name; + int have_dependent_hostgroup_name; + int have_dependency_period; + + int have_inherits_parent; + int have_notification_dependency_options; + int have_execution_dependency_options; + + int has_been_resolved; + int register_object; + struct xodtemplate_hostdependency_struct *next; +} xodtemplate_hostdependency; + + +/* HOSTESCALATION TEMPLATE STRUCTURE */ +typedef struct xodtemplate_hostescalation_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *hostgroup_name; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_down; + int escalate_on_unreachable; + int escalate_on_recovery; + char *contact_groups; + char *contacts; + + int have_host_name; + int have_hostgroup_name; + int have_escalation_period; + int have_contact_groups; + int have_contacts; + + int have_first_notification; + int have_last_notification; + int have_notification_interval; + int have_escalation_options; + + int has_been_resolved; + int register_object; + struct xodtemplate_hostescalation_struct *next; +} xodtemplate_hostescalation; + + +/* HOSTEXTINFO TEMPLATE STRUCTURE */ +typedef struct xodtemplate_hostextinfo_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *hostgroup_name; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + char *vrml_image; + char *statusmap_image; + int x_2d; + int y_2d; + double x_3d; + double y_3d; + double z_3d; + + int have_host_name; + int have_hostgroup_name; + int have_notes; + int have_notes_url; + int have_action_url; + int have_icon_image; + int have_icon_image_alt; + int have_vrml_image; + int have_statusmap_image; + + int have_2d_coords; + int have_3d_coords; + + int has_been_resolved; + int register_object; + struct xodtemplate_hostextinfo_struct *next; +} xodtemplate_hostextinfo; + + +/* SERVICEEXTINFO TEMPLATE STRUCTURE */ +typedef struct xodtemplate_serviceextinfo_struct { + char *template; + char *name; + int _config_file; + int _start_line; + + char *host_name; + char *hostgroup_name; + char *service_description; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + + int have_host_name; + int have_hostgroup_name; + int have_service_description; + int have_notes; + int have_notes_url; + int have_action_url; + int have_icon_image; + int have_icon_image_alt; + + int has_been_resolved; + int register_object; + struct xodtemplate_serviceextinfo_struct *next; +} xodtemplate_serviceextinfo; + + +/* CONTACT LIST STRUCTURE */ +typedef struct xodtemplate_contactlist_struct { + char *contact_name; + struct xodtemplate_contactlist_struct *next; +} xodtemplate_contactlist; + + +/* HOST LIST STRUCTURE */ +typedef struct xodtemplate_hostlist_struct { + char *host_name; + struct xodtemplate_hostlist_struct *next; +} xodtemplate_hostlist; + + +/* SERVICE LIST STRUCTURE */ +typedef struct xodtemplate_servicelist_struct { + char *host_name; + char *service_description; + struct xodtemplate_servicelist_struct *next; +} xodtemplate_servicelist; + + +/* MEMBER LIST STRUCTURE */ +typedef struct xodtemplate_memberlist_struct { + char *name1; + char *name2; + struct xodtemplate_memberlist_struct *next; +} xodtemplate_memberlist; + + +/***** CHAINED HASH DATA STRUCTURES ******/ + +typedef struct xodtemplate_service_cursor_struct { + int xodtemplate_service_iterator; + xodtemplate_service *current_xodtemplate_service; +} xodtemplate_service_cursor; + + + +/********* FUNCTION DEFINITIONS **********/ + +int xodtemplate_read_config_data(char *, int, int, int); /* top-level routine processes all config files */ +int xodtemplate_grab_config_info(char *); /* grabs variables from main config file */ +int xodtemplate_process_config_file(char *, int); /* process data in a specific config file */ +int xodtemplate_process_config_dir(char *, int); /* process all files in a specific config directory */ + +#ifdef NSCORE +xodtemplate_memberlist *xodtemplate_expand_contactgroups_and_contacts(char *, char *, int, int); +int xodtemplate_expand_contactgroups(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); +int xodtemplate_expand_contacts(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); +int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **, xodtemplate_contactgroup *, int, int); + +xodtemplate_memberlist *xodtemplate_expand_hostgroups_and_hosts(char *, char *, int, int); +int xodtemplate_expand_hostgroups(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); +int xodtemplate_expand_hosts(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); +int xodtemplate_add_hostgroup_members_to_memberlist(xodtemplate_memberlist **, xodtemplate_hostgroup *, int, int); + +xodtemplate_memberlist *xodtemplate_expand_servicegroups_and_services(char *, char *, char *, int, int); +int xodtemplate_expand_servicegroups(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); +int xodtemplate_expand_services(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, char *, int, int); +int xodtemplate_add_servicegroup_members_to_memberlist(xodtemplate_memberlist **, xodtemplate_servicegroup *, int, int); + +char *xodtemplate_process_contactgroup_names(char *, int, int); +int xodtemplate_get_contactgroup_names(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); + +char *xodtemplate_process_hostgroup_names(char *, int, int); +int xodtemplate_get_hostgroup_names(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); + +char *xodtemplate_process_servicegroup_names(char *, int, int); +int xodtemplate_get_servicegroup_names(xodtemplate_memberlist **, xodtemplate_memberlist **, char *, int, int); + +int xodtemplate_add_member_to_memberlist(xodtemplate_memberlist **, char *, char *); +int xodtemplate_free_memberlist(xodtemplate_memberlist **); +void xodtemplate_remove_memberlist_item(xodtemplate_memberlist *, xodtemplate_memberlist **); +#endif + + +int xodtemplate_begin_object_definition(char *, int, int, int); +int xodtemplate_add_object_property(char *, int); +int xodtemplate_end_object_definition(int); + +int xodtemplate_parse_timeperiod_directive(xodtemplate_timeperiod *, char *, char *); +xodtemplate_daterange *xodtemplate_add_exception_to_timeperiod(xodtemplate_timeperiod *, int, int, int, int, int, int, int, int, int, int, int, int, char *); +int xodtemplate_get_month_from_string(char *, int *); +int xodtemplate_get_weekday_from_string(char *, int *); + +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_host(xodtemplate_host *, char *, char *); +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_service(xodtemplate_service *, char *, char *); +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_contact(xodtemplate_contact *, char *, char *); +xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_object(xodtemplate_customvariablesmember **, char *, char *); + + +int xodtemplate_register_objects(void); +int xodtemplate_free_memory(void); + +#ifdef NSCORE +int xodtemplate_duplicate_objects(void); +int xodtemplate_duplicate_services(void); + +int xodtemplate_inherit_object_properties(void); + +int xodtemplate_resolve_objects(void); + +int xodtemplate_sort_objects(void); +int xodtemplate_compare_strings1(char *, char *); +int xodtemplate_compare_strings2(char *, char *, char *, char *); + +int xodtemplate_cache_objects(char *); + +int xodtemplate_duplicate_service(xodtemplate_service *, char *); +int xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation *, char *); +int xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation *, char *, char *); +int xodtemplate_duplicate_hostdependency(xodtemplate_hostdependency *, char *, char *); +int xodtemplate_duplicate_servicedependency(xodtemplate_servicedependency *, char *, char *, char *, char *, char *, char *, char *, char *); +int xodtemplate_duplicate_hostextinfo(xodtemplate_hostextinfo *, char *); +int xodtemplate_duplicate_serviceextinfo(xodtemplate_serviceextinfo *, char *); + +int xodtemplate_recombobulate_contactgroups(void); +int xodtemplate_recombobulate_contactgroup_subgroups(xodtemplate_contactgroup *, char **); +int xodtemplate_recombobulate_object_contacts(void); +int xodtemplate_recombobulate_hostgroups(void); +int xodtemplate_recombobulate_hostgroup_subgroups(xodtemplate_hostgroup *, char **); +int xodtemplate_recombobulate_servicegroups(void); +int xodtemplate_recombobulate_servicegroup_subgroups(xodtemplate_servicegroup *, char **); + +int xodtemplate_resolve_timeperiod(xodtemplate_timeperiod *); +int xodtemplate_resolve_command(xodtemplate_command *); +int xodtemplate_resolve_contactgroup(xodtemplate_contactgroup *); +int xodtemplate_resolve_hostgroup(xodtemplate_hostgroup *); +int xodtemplate_resolve_servicegroup(xodtemplate_servicegroup *); +int xodtemplate_resolve_servicedependency(xodtemplate_servicedependency *); +int xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation *); +int xodtemplate_resolve_contact(xodtemplate_contact *); +int xodtemplate_resolve_host(xodtemplate_host *); +int xodtemplate_resolve_service(xodtemplate_service *); +int xodtemplate_resolve_hostdependency(xodtemplate_hostdependency *); +int xodtemplate_resolve_hostescalation(xodtemplate_hostescalation *); +int xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo *); +int xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo *); + +int xodtemplate_sort_timeperiods(void); +int xodtemplate_sort_commands(void); +int xodtemplate_sort_contactgroups(void); +int xodtemplate_sort_hostgroups(void); +int xodtemplate_sort_servicegroups(void); +int xodtemplate_sort_contacts(void); +int xodtemplate_sort_hosts(void); +int xodtemplate_sort_services(void); +int xodtemplate_sort_servicedependencies(void); +int xodtemplate_sort_serviceescalations(void); +int xodtemplate_sort_hostdependencies(void); +int xodtemplate_sort_hostescalations(void); + +int xodtemplate_merge_extinfo_ojects(void); +int xodtemplate_merge_host_extinfo_object(xodtemplate_host *, xodtemplate_hostextinfo *); +int xodtemplate_merge_service_extinfo_object(xodtemplate_service *, xodtemplate_serviceextinfo *); + +xodtemplate_timeperiod *xodtemplate_find_timeperiod(char *); +xodtemplate_command *xodtemplate_find_command(char *); +xodtemplate_contactgroup *xodtemplate_find_contactgroup(char *); +xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *); +xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *); +xodtemplate_hostgroup *xodtemplate_find_real_hostgroup(char *); +xodtemplate_servicegroup *xodtemplate_find_servicegroup(char *); +xodtemplate_servicegroup *xodtemplate_find_real_servicegroup(char *); +xodtemplate_servicedependency *xodtemplate_find_servicedependency(char *); +xodtemplate_serviceescalation *xodtemplate_find_serviceescalation(char *); +xodtemplate_contact *xodtemplate_find_contact(char *); +xodtemplate_contact *xodtemplate_find_real_contact(char *); +xodtemplate_host *xodtemplate_find_host(char *); +xodtemplate_host *xodtemplate_find_real_host(char *); +xodtemplate_service *xodtemplate_find_service(char *); +xodtemplate_service *xodtemplate_find_real_service(char *, char *); +xodtemplate_hostdependency *xodtemplate_find_hostdependency(char *); +xodtemplate_hostescalation *xodtemplate_find_hostescalation(char *); +xodtemplate_hostextinfo *xodtemplate_find_hostextinfo(char *); +xodtemplate_serviceextinfo *xodtemplate_find_serviceextinfo(char *); + +int xodtemplate_get_inherited_string(int *, char **, int *, char **); +int xodtemplate_clean_additive_string(char **); +int xodtemplate_clean_additive_strings(void); +#endif + +int xodtemplate_register_timeperiod(xodtemplate_timeperiod *); +int xodtemplate_get_time_ranges(char *, unsigned long *, unsigned long *); +int xodtemplate_register_command(xodtemplate_command *); +int xodtemplate_register_contactgroup(xodtemplate_contactgroup *); +int xodtemplate_register_hostgroup(xodtemplate_hostgroup *); +int xodtemplate_register_servicegroup(xodtemplate_servicegroup *); +int xodtemplate_register_servicedependency(xodtemplate_servicedependency *); +int xodtemplate_register_serviceescalation(xodtemplate_serviceescalation *); +int xodtemplate_register_contact(xodtemplate_contact *); +int xodtemplate_register_host(xodtemplate_host *); +int xodtemplate_register_service(xodtemplate_service *); +int xodtemplate_register_hostdependency(xodtemplate_hostdependency *); +int xodtemplate_register_hostescalation(xodtemplate_hostescalation *); + + +int xodtemplate_init_xobject_skiplists(void); +int xodtemplate_free_xobject_skiplists(void); + +int xodtemplate_skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b); +int xodtemplate_skiplist_compare_host_template(void *a, void *b); +int xodtemplate_skiplist_compare_service_template(void *a, void *b); +int xodtemplate_skiplist_compare_command_template(void *a, void *b); +int xodtemplate_skiplist_compare_timeperiod_template(void *a, void *b); +int xodtemplate_skiplist_compare_contact_template(void *a, void *b); +int xodtemplate_skiplist_compare_contactgroup_template(void *a, void *b); +int xodtemplate_skiplist_compare_hostgroup_template(void *a, void *b); +int xodtemplate_skiplist_compare_servicegroup_template(void *a, void *b); +int xodtemplate_skiplist_compare_hostdependency_template(void *a, void *b); +int xodtemplate_skiplist_compare_servicedependency_template(void *a, void *b); +int xodtemplate_skiplist_compare_hostescalation_template(void *a, void *b); +int xodtemplate_skiplist_compare_serviceescalation_template(void *a, void *b); +int xodtemplate_skiplist_compare_hostextinfo_template(void *a, void *b); +int xodtemplate_skiplist_compare_serviceextinfo_template(void *a, void *b); + +int xodtemplate_skiplist_compare_host(void *a, void *b); +int xodtemplate_skiplist_compare_service(void *a, void *b); +int xodtemplate_skiplist_compare_contact(void *a, void *b); +int xodtemplate_skiplist_compare_contactgroup(void *a, void *b); +int xodtemplate_skiplist_compare_hostgroup(void *a, void *b); +int xodtemplate_skiplist_compare_servicegroup(void *a, void *b); +int xodtemplate_skiplist_compare_command(void *a, void *b); +int xodtemplate_skiplist_compare_timeperiod(void *a, void *b); +int xodtemplate_skiplist_compare_hostdependency(void *a, void *b); +int xodtemplate_skiplist_compare_servicedependency(void *a, void *b); +int xodtemplate_skiplist_compare_hostescalation(void *a, void *b); +int xodtemplate_skiplist_compare_serviceescalation(void *a, void *b); + + +#endif + + diff --git a/xdata/xpddefault.c b/xdata/xpddefault.c new file mode 100644 index 0000000..0da846a --- /dev/null +++ b/xdata/xpddefault.c @@ -0,0 +1,903 @@ +/***************************************************************************** + * + * XPDDEFAULT.C - Default performance data routines + * + * Copyright (c) 2000-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. + * + *****************************************************************************/ + + +/*********** COMMON HEADER FILES ***********/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/macros.h" +#include "../include/nagios.h" + + +/**** DATA INPUT-SPECIFIC HEADER FILES ****/ + +#include "xpddefault.h" + + +int xpddefault_perfdata_timeout; + +char *xpddefault_host_perfdata_command = NULL; +char *xpddefault_service_perfdata_command = NULL; +command *xpddefault_host_perfdata_command_ptr = NULL; +command *xpddefault_service_perfdata_command_ptr = NULL; + +char *xpddefault_host_perfdata_file_template = NULL; +char *xpddefault_service_perfdata_file_template = NULL; + +char *xpddefault_host_perfdata_file = NULL; +char *xpddefault_service_perfdata_file = NULL; + +int xpddefault_host_perfdata_file_append = TRUE; +int xpddefault_service_perfdata_file_append = TRUE; +int xpddefault_host_perfdata_file_pipe = FALSE; +int xpddefault_service_perfdata_file_pipe = FALSE; + +unsigned long xpddefault_host_perfdata_file_processing_interval = 0L; +unsigned long xpddefault_service_perfdata_file_processing_interval = 0L; + +char *xpddefault_host_perfdata_file_processing_command = NULL; +char *xpddefault_service_perfdata_file_processing_command = NULL; +command *xpddefault_host_perfdata_file_processing_command_ptr = NULL; +command *xpddefault_service_perfdata_file_processing_command_ptr = NULL; + +int xpddefault_host_perfdata_process_empty_results = DEFAULT_HOST_PERFDATA_PROCESS_EMPTY_RESULTS; +int xpddefault_service_perfdata_process_empty_results = DEFAULT_SERVICE_PERFDATA_PROCESS_EMPTY_RESULTS; + +FILE *xpddefault_host_perfdata_fp = NULL; +FILE *xpddefault_service_perfdata_fp = NULL; +int xpddefault_host_perfdata_fd = -1; +int xpddefault_service_perfdata_fd = -1; + + +static pthread_mutex_t xpddefault_host_perfdata_fp_lock; +static pthread_mutex_t xpddefault_service_perfdata_fp_lock; + +/******************************************************************/ +/***************** COMMON CONFIG INITIALIZATION ******************/ +/******************************************************************/ + +/* grabs configuration information from main config file */ +int xpddefault_grab_config_info(char *config_file) { + char *input = NULL; + mmapfile *thefile = NULL; + + /* open the config file for reading */ + if((thefile = mmap_fopen(config_file)) == NULL) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not open main config file '%s' for reading performance variables!\n", config_file); + return ERROR; + } + + /* read in all lines from the config file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == '\x0') + continue; + + strip(input); + + xpddefault_grab_config_directives(input); + } + + /* free memory and close the file */ + my_free(input); + mmap_fclose(thefile); + + return OK; + } + + +/* processes a single directive */ +int xpddefault_grab_config_directives(char *input) { + char *temp_ptr = NULL; + char *varname = NULL; + char *varvalue = NULL; + + /* get the variable name */ + if((temp_ptr = my_strtok(input, "=")) == NULL) + return ERROR; + if((varname = (char *)strdup(temp_ptr)) == NULL) + return ERROR; + + /* get the variable value */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + my_free(varname); + return ERROR; + } + if((varvalue = (char *)strdup(temp_ptr)) == NULL) { + my_free(varname); + return ERROR; + } + + if(!strcmp(varname, "perfdata_timeout")) { + strip(varvalue); + xpddefault_perfdata_timeout = atoi(varvalue); + } + + else if(!strcmp(varname, "host_perfdata_command")) + xpddefault_host_perfdata_command = (char *)strdup(varvalue); + + else if(!strcmp(varname, "service_perfdata_command")) + xpddefault_service_perfdata_command = (char *)strdup(varvalue); + + else if(!strcmp(varname, "host_perfdata_file_template")) + xpddefault_host_perfdata_file_template = (char *)strdup(varvalue); + + else if(!strcmp(varname, "service_perfdata_file_template")) + xpddefault_service_perfdata_file_template = (char *)strdup(varvalue); + + else if(!strcmp(varname, "host_perfdata_file")) + xpddefault_host_perfdata_file = (char *)strdup(varvalue); + + else if(!strcmp(varname, "service_perfdata_file")) + xpddefault_service_perfdata_file = (char *)strdup(varvalue); + + else if(!strcmp(varname, "host_perfdata_file_mode")) { + if(strstr(varvalue, "p") != NULL) + xpddefault_host_perfdata_file_pipe = TRUE; + else if(strstr(varvalue, "w") != NULL) + xpddefault_host_perfdata_file_append = FALSE; + else + xpddefault_host_perfdata_file_append = TRUE; + } + + else if(!strcmp(varname, "service_perfdata_file_mode")) { + if(strstr(varvalue, "p") != NULL) + xpddefault_service_perfdata_file_pipe = TRUE; + else if(strstr(varvalue, "w") != NULL) + xpddefault_service_perfdata_file_append = FALSE; + else + xpddefault_service_perfdata_file_append = TRUE; + } + + else if(!strcmp(varname, "host_perfdata_file_processing_interval")) + xpddefault_host_perfdata_file_processing_interval = strtoul(varvalue, NULL, 0); + + else if(!strcmp(varname, "service_perfdata_file_processing_interval")) + xpddefault_service_perfdata_file_processing_interval = strtoul(varvalue, NULL, 0); + + else if(!strcmp(varname, "host_perfdata_file_processing_command")) + xpddefault_host_perfdata_file_processing_command = (char *)strdup(varvalue); + + else if(!strcmp(varname, "service_perfdata_file_processing_command")) + xpddefault_service_perfdata_file_processing_command = (char *)strdup(varvalue); + else if(!strcmp(varname, "host_perfdata_process_empty_results")) + xpddefault_host_perfdata_process_empty_results = (atoi(varvalue) > 0) ? TRUE : FALSE; + else if(!strcmp(varname, "service_perfdata_process_empty_results")) + xpddefault_service_perfdata_process_empty_results = (atoi(varvalue) > 0) ? TRUE : FALSE; + + /* free memory */ + my_free(varname); + my_free(varvalue); + + return OK; + } + + + +/******************************************************************/ +/************** INITIALIZATION & CLEANUP FUNCTIONS ****************/ +/******************************************************************/ + +/* initializes performance data */ +int xpddefault_initialize_performance_data(char *config_file) { + char *buffer = NULL; + char *temp_buffer = NULL; + char *temp_command_name = NULL; + command *temp_command = NULL; + time_t current_time; + nagios_macros *mac; + + mac = get_global_macros(); + time(¤t_time); + + /* reset vars */ + xpddefault_host_perfdata_command_ptr = NULL; + xpddefault_service_perfdata_command_ptr = NULL; + xpddefault_host_perfdata_file_processing_command_ptr = NULL; + xpddefault_service_perfdata_file_processing_command_ptr = NULL; + + /* grab config info from main config file */ + xpddefault_grab_config_info(config_file); + + /* make sure we have some templates defined */ + if(xpddefault_host_perfdata_file_template == NULL) + xpddefault_host_perfdata_file_template = (char *)strdup(DEFAULT_HOST_PERFDATA_FILE_TEMPLATE); + if(xpddefault_service_perfdata_file_template == NULL) + xpddefault_service_perfdata_file_template = (char *)strdup(DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE); + + /* process special chars in templates */ + xpddefault_preprocess_file_templates(xpddefault_host_perfdata_file_template); + xpddefault_preprocess_file_templates(xpddefault_service_perfdata_file_template); + + /* open the performance data files */ + xpddefault_open_host_perfdata_file(); + xpddefault_open_service_perfdata_file(); + + /* verify that performance data commands are valid */ + if(xpddefault_host_perfdata_command != NULL) { + + temp_buffer = (char *)strdup(xpddefault_host_perfdata_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(temp_buffer, "!"); + + if((temp_command = find_command(temp_command_name)) == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance command '%s' was not found - host performance data will not be processed!\n", temp_command_name); + + my_free(xpddefault_host_perfdata_command); + } + + my_free(temp_buffer); + + /* save the command pointer for later */ + xpddefault_host_perfdata_command_ptr = temp_command; + } + if(xpddefault_service_perfdata_command != NULL) { + + temp_buffer = (char *)strdup(xpddefault_service_perfdata_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(temp_buffer, "!"); + + if((temp_command = find_command(temp_command_name)) == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service performance command '%s' was not found - service performance data will not be processed!\n", temp_command_name); + + my_free(xpddefault_service_perfdata_command); + } + + /* free memory */ + my_free(temp_buffer); + + /* save the command pointer for later */ + xpddefault_service_perfdata_command_ptr = temp_command; + } + if(xpddefault_host_perfdata_file_processing_command != NULL) { + + temp_buffer = (char *)strdup(xpddefault_host_perfdata_file_processing_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(temp_buffer, "!"); + + if((temp_command = find_command(temp_command_name)) == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance file processing command '%s' was not found - host performance data file will not be processed!\n", temp_command_name); + + my_free(xpddefault_host_perfdata_file_processing_command); + } + + /* free memory */ + my_free(temp_buffer); + + /* save the command pointer for later */ + xpddefault_host_perfdata_file_processing_command_ptr = temp_command; + } + if(xpddefault_service_perfdata_file_processing_command != NULL) { + + temp_buffer = (char *)strdup(xpddefault_service_perfdata_file_processing_command); + + /* get the command name, leave any arguments behind */ + temp_command_name = my_strtok(temp_buffer, "!"); + + if((temp_command = find_command(temp_command_name)) == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service performance file processing command '%s' was not found - service performance data file will not be processed!\n", temp_command_name); + + my_free(xpddefault_service_perfdata_file_processing_command); + } + + /* save the command pointer for later */ + xpddefault_service_perfdata_file_processing_command_ptr = temp_command; + } + + /* periodically process the host perfdata file */ + if(xpddefault_host_perfdata_file_processing_interval > 0 && xpddefault_host_perfdata_file_processing_command != NULL) + schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + xpddefault_host_perfdata_file_processing_interval, TRUE, xpddefault_host_perfdata_file_processing_interval, NULL, TRUE, (void *)xpddefault_process_host_perfdata_file, NULL, 0); + + /* periodically process the service perfdata file */ + if(xpddefault_service_perfdata_file_processing_interval > 0 && xpddefault_service_perfdata_file_processing_command != NULL) + schedule_new_event(EVENT_USER_FUNCTION, TRUE, current_time + xpddefault_service_perfdata_file_processing_interval, TRUE, xpddefault_service_perfdata_file_processing_interval, NULL, TRUE, (void *)xpddefault_process_service_perfdata_file, NULL, 0); + + /* save the host perf data file macro */ + my_free(mac->x[MACRO_HOSTPERFDATAFILE]); + if(xpddefault_host_perfdata_file != NULL) { + if((mac->x[MACRO_HOSTPERFDATAFILE] = (char *)strdup(xpddefault_host_perfdata_file))) + strip(mac->x[MACRO_HOSTPERFDATAFILE]); + } + + /* save the service perf data file macro */ + my_free(mac->x[MACRO_SERVICEPERFDATAFILE]); + if(xpddefault_service_perfdata_file != NULL) { + if((mac->x[MACRO_SERVICEPERFDATAFILE] = (char *)strdup(xpddefault_service_perfdata_file))) + strip(mac->x[MACRO_SERVICEPERFDATAFILE]); + } + + /* free memory */ + my_free(temp_buffer); + my_free(buffer); + + return OK; + } + + + +/* cleans up performance data */ +int xpddefault_cleanup_performance_data(char *config_file) { + + /* free memory */ + my_free(xpddefault_host_perfdata_command); + my_free(xpddefault_service_perfdata_command); + my_free(xpddefault_host_perfdata_file_template); + my_free(xpddefault_service_perfdata_file_template); + my_free(xpddefault_host_perfdata_file); + my_free(xpddefault_service_perfdata_file); + my_free(xpddefault_host_perfdata_file_processing_command); + my_free(xpddefault_service_perfdata_file_processing_command); + + /* close the files */ + xpddefault_close_host_perfdata_file(); + xpddefault_close_service_perfdata_file(); + + return OK; + } + + + +/******************************************************************/ +/****************** PERFORMANCE DATA FUNCTIONS ********************/ +/******************************************************************/ + + +/* updates service performance data */ +int xpddefault_update_service_performance_data(service *svc) { + nagios_macros mac; + host *hst; + + /* + * bail early if we've got nothing to do so we don't spend a lot + * of time calculating macros that never get used + * on distributed setups, empty perfdata results are required, so + * only drop out if demanded via configs. + */ + if(xpddefault_service_perfdata_process_empty_results == FALSE) { + if(!svc || !svc->perf_data || !*svc->perf_data) { + return OK; + } + if((!xpddefault_service_perfdata_fp || !xpddefault_service_perfdata_file_template) && !xpddefault_service_perfdata_command) { + return OK; + } + + } + /* + * we know we've got some work to do, so grab the necessary + * macros and get busy + */ + memset(&mac, 0, sizeof(mac)); + hst = find_host(svc->host_name); + grab_host_macros_r(&mac, hst); + grab_service_macros_r(&mac, svc); + + /* run the performance data command */ + xpddefault_run_service_performance_data_command(&mac, svc); + + /* get rid of used memory we won't need anymore */ + clear_argv_macros_r(&mac); + + /* update the performance data file */ + xpddefault_update_service_performance_data_file(&mac, svc); + + /* now free() it all */ + clear_volatile_macros_r(&mac); + + return OK; + } + + +/* updates host performance data */ +int xpddefault_update_host_performance_data(host *hst) { + nagios_macros mac; + + + /* + * bail early if we've got nothing to do so we don't spend a lot + * of time calculating macros that never get used + * on distributed setups, empty perfdata results are required, so + * only drop out if demanded via configs. + */ + if(xpddefault_host_perfdata_process_empty_results == FALSE) { + if(!hst || !hst->perf_data || !*hst->perf_data) { + return OK; + } + if((!xpddefault_host_perfdata_fp || !xpddefault_host_perfdata_file_template) && !xpddefault_host_perfdata_command) { + return OK; + } + } + + /* set up macros and get to work */ + memset(&mac, 0, sizeof(mac)); + grab_host_macros_r(&mac, hst); + + /* run the performance data command */ + xpddefault_run_host_performance_data_command(&mac, hst); + + /* no more commands to run, so we won't need this any more */ + clear_argv_macros_r(&mac); + + /* update the performance data file */ + xpddefault_update_host_performance_data_file(&mac, hst); + + /* free() all */ + clear_volatile_macros_r(&mac); + + return OK; + } + + + + +/******************************************************************/ +/************** PERFORMANCE DATA COMMAND FUNCTIONS ****************/ +/******************************************************************/ + + +/* runs the service performance data command */ +int xpddefault_run_service_performance_data_command(nagios_macros *mac, service *svc) { + char *raw_command_line = NULL; + char *processed_command_line = NULL; + int early_timeout = FALSE; + double exectime; + int result = OK; + int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_service_performance_data_command()\n"); + + if(svc == NULL) + return ERROR; + + /* we don't have a command */ + if(xpddefault_service_perfdata_command == NULL) + return OK; + + /* get the raw command line */ + get_raw_command_line_r(mac, xpddefault_service_perfdata_command_ptr, xpddefault_service_perfdata_command, &raw_command_line, macro_options); + if(raw_command_line == NULL) + return ERROR; + + log_debug_info(DEBUGL_PERFDATA, 2, "Raw service performance data command line: %s\n", raw_command_line); + + /* process any macros in the raw command line */ + process_macros_r(mac, raw_command_line, &processed_command_line, macro_options); + my_free(raw_command_line); + if(processed_command_line == NULL) + return ERROR; + + log_debug_info(DEBUGL_PERFDATA, 2, "Processed service performance data command line: %s\n", processed_command_line); + + /* run the command */ + my_system_r(mac, processed_command_line, xpddefault_perfdata_timeout, &early_timeout, &exectime, NULL, 0); + + /* check to see if the command timed out */ + if(early_timeout == TRUE) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service performance data command '%s' for service '%s' on host '%s' timed out after %d seconds\n", processed_command_line, svc->description, svc->host_name, xpddefault_perfdata_timeout); + + /* free memory */ + my_free(processed_command_line); + + return result; + } + + +/* runs the host performance data command */ +int xpddefault_run_host_performance_data_command(nagios_macros *mac, host *hst) { + char *raw_command_line = NULL; + char *processed_command_line = NULL; + int early_timeout = FALSE; + double exectime; + int result = OK; + int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "run_host_performance_data_command()\n"); + + if(hst == NULL) + return ERROR; + + /* we don't have a command */ + if(xpddefault_host_perfdata_command == NULL) + return OK; + + /* get the raw command line */ + get_raw_command_line_r(mac, xpddefault_host_perfdata_command_ptr, xpddefault_host_perfdata_command, &raw_command_line, macro_options); + if(raw_command_line == NULL) + return ERROR; + + log_debug_info(DEBUGL_PERFDATA, 2, "Raw host performance data command line: %s\n", raw_command_line); + + /* process any macros in the raw command line */ + process_macros_r(mac, raw_command_line, &processed_command_line, macro_options); + my_free(raw_command_line); + if(!processed_command_line) + return ERROR; + + log_debug_info(DEBUGL_PERFDATA, 2, "Processed host performance data command line: %s\n", processed_command_line); + + /* run the command */ + my_system_r(mac, processed_command_line, xpddefault_perfdata_timeout, &early_timeout, &exectime, NULL, 0); + if(processed_command_line == NULL) + return ERROR; + + /* check to see if the command timed out */ + if(early_timeout == TRUE) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance data command '%s' for host '%s' timed out after %d seconds\n", processed_command_line, hst->name, xpddefault_perfdata_timeout); + + /* free memory */ + my_free(processed_command_line); + + return result; + } + + + +/******************************************************************/ +/**************** FILE PERFORMANCE DATA FUNCTIONS *****************/ +/******************************************************************/ + +/* open the host performance data file for writing */ +int xpddefault_open_host_perfdata_file(void) { + + if(xpddefault_host_perfdata_file != NULL) { + + if(xpddefault_host_perfdata_file_pipe == TRUE) { + /* must open read-write to avoid failure if the other end isn't ready yet */ + xpddefault_host_perfdata_fd = open(xpddefault_host_perfdata_file, O_NONBLOCK | O_RDWR); + xpddefault_host_perfdata_fp = fdopen(xpddefault_host_perfdata_fd, "w"); + } + else + xpddefault_host_perfdata_fp = fopen(xpddefault_host_perfdata_file, (xpddefault_host_perfdata_file_append == TRUE) ? "a" : "w"); + + if(xpddefault_host_perfdata_fp == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: File '%s' could not be opened - host performance data will not be written to file!\n", xpddefault_host_perfdata_file); + + return ERROR; + } + } + + return OK; + } + + +/* open the service performance data file for writing */ +int xpddefault_open_service_perfdata_file(void) { + + if(xpddefault_service_perfdata_file != NULL) { + if(xpddefault_service_perfdata_file_pipe == TRUE) { + /* must open read-write to avoid failure if the other end isn't ready yet */ + xpddefault_service_perfdata_fd = open(xpddefault_service_perfdata_file, O_NONBLOCK | O_RDWR); + xpddefault_service_perfdata_fp = fdopen(xpddefault_service_perfdata_fd, "w"); + } + else + xpddefault_service_perfdata_fp = fopen(xpddefault_service_perfdata_file, (xpddefault_service_perfdata_file_append == TRUE) ? "a" : "w"); + + if(xpddefault_service_perfdata_fp == NULL) { + + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: File '%s' could not be opened - service performance data will not be written to file!\n", xpddefault_service_perfdata_file); + + return ERROR; + } + } + + return OK; + } + + +/* close the host performance data file */ +int xpddefault_close_host_perfdata_file(void) { + + if(xpddefault_host_perfdata_fp != NULL) + fclose(xpddefault_host_perfdata_fp); + if(xpddefault_host_perfdata_fd >= 0) { + close(xpddefault_host_perfdata_fd); + xpddefault_host_perfdata_fd = -1; + } + + return OK; + } + + +/* close the service performance data file */ +int xpddefault_close_service_perfdata_file(void) { + + if(xpddefault_service_perfdata_fp != NULL) + fclose(xpddefault_service_perfdata_fp); + if(xpddefault_service_perfdata_fd >= 0) { + close(xpddefault_service_perfdata_fd); + xpddefault_service_perfdata_fd = -1; + } + + return OK; + } + + +/* processes delimiter characters in templates */ +int xpddefault_preprocess_file_templates(char *template) { + char *tempbuf; + int x = 0; + int y = 0; + + if(template == NULL) + return OK; + + /* allocate temporary buffer */ + tempbuf = (char *)malloc(strlen(template) + 1); + if(tempbuf == NULL) + return ERROR; + strcpy(tempbuf, ""); + + for(x = 0, y = 0; x < strlen(template); x++, y++) { + if(template[x] == '\\') { + if(template[x + 1] == 't') { + tempbuf[y] = '\t'; + x++; + } + else if(template[x + 1] == 'r') { + tempbuf[y] = '\r'; + x++; + } + else if(template[x + 1] == 'n') { + tempbuf[y] = '\n'; + x++; + } + else + tempbuf[y] = template[x]; + } + else + tempbuf[y] = template[x]; + } + tempbuf[y] = '\x0'; + + strcpy(template, tempbuf); + my_free(tempbuf); + + return OK; + } + + +/* updates service performance data file */ +int xpddefault_update_service_performance_data_file(nagios_macros *mac, service *svc) { + char *raw_output = NULL; + char *processed_output = NULL; + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "update_service_performance_data_file()\n"); + + if(svc == NULL) + return ERROR; + + /* we don't have a file to write to*/ + if(xpddefault_service_perfdata_fp == NULL || xpddefault_service_perfdata_file_template == NULL) + return OK; + + /* get the raw line to write */ + raw_output = (char *)strdup(xpddefault_service_perfdata_file_template); + + log_debug_info(DEBUGL_PERFDATA, 2, "Raw service performance data file output: %s\n", raw_output); + + /* process any macros in the raw output line */ + process_macros_r(mac, raw_output, &processed_output, 0); + if(processed_output == NULL) + return ERROR; + + log_debug_info(DEBUGL_PERFDATA, 2, "Processed service performance data file output: %s\n", processed_output); + + /* lock, write to and unlock host performance data file */ + pthread_mutex_lock(&xpddefault_service_perfdata_fp_lock); + fputs(processed_output, xpddefault_service_perfdata_fp); + fputc('\n', xpddefault_service_perfdata_fp); + fflush(xpddefault_service_perfdata_fp); + pthread_mutex_unlock(&xpddefault_service_perfdata_fp_lock); + + /* free memory */ + my_free(raw_output); + my_free(processed_output); + + return result; + } + + +/* updates host performance data file */ +int xpddefault_update_host_performance_data_file(nagios_macros *mac, host *hst) { + char *raw_output = NULL; + char *processed_output = NULL; + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "update_host_performance_data_file()\n"); + + if(hst == NULL) + return ERROR; + + /* we don't have a host perfdata file */ + if(xpddefault_host_perfdata_fp == NULL || xpddefault_host_perfdata_file_template == NULL) + return OK; + + /* get the raw output */ + raw_output = (char *)strdup(xpddefault_host_perfdata_file_template); + + log_debug_info(DEBUGL_PERFDATA, 2, "Raw host performance file output: %s\n", raw_output); + + /* process any macros in the raw output */ + process_macros_r(mac, raw_output, &processed_output, 0); + if(processed_output == NULL) + return ERROR; + + log_debug_info(DEBUGL_PERFDATA, 2, "Processed host performance data file output: %s\n", processed_output); + + /* lock, write to and unlock host performance data file */ + pthread_mutex_lock(&xpddefault_host_perfdata_fp_lock); + fputs(processed_output, xpddefault_host_perfdata_fp); + fputc('\n', xpddefault_host_perfdata_fp); + fflush(xpddefault_host_perfdata_fp); + pthread_mutex_unlock(&xpddefault_host_perfdata_fp_lock); + + /* free memory */ + my_free(raw_output); + my_free(processed_output); + + return result; + } + + +/* periodically process the host perf data file */ +int xpddefault_process_host_perfdata_file(void) { + char *raw_command_line = NULL; + char *processed_command_line = NULL; + int early_timeout = FALSE; + double exectime = 0.0; + int result = OK; + int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; + nagios_macros mac; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_host_perfdata_file()\n"); + + /* we don't have a command */ + if(xpddefault_host_perfdata_file_processing_command == NULL) + return OK; + + /* init macros */ + memset(&mac, 0, sizeof(mac)); + + /* get the raw command line */ + get_raw_command_line_r(&mac, xpddefault_host_perfdata_file_processing_command_ptr, xpddefault_host_perfdata_file_processing_command, &raw_command_line, macro_options); + if(raw_command_line == NULL) { + clear_volatile_macros_r(&mac); + return ERROR; + } + + log_debug_info(DEBUGL_PERFDATA, 2, "Raw host performance data file processing command line: %s\n", raw_command_line); + + /* process any macros in the raw command line */ + process_macros_r(&mac, raw_command_line, &processed_command_line, macro_options); + my_free(raw_command_line); + if(processed_command_line == NULL) { + clear_volatile_macros_r(&mac); + return ERROR; + } + + log_debug_info(DEBUGL_PERFDATA, 2, "Processed host performance data file processing command line: %s\n", processed_command_line); + + /* lock and close the performance data file */ + pthread_mutex_lock(&xpddefault_host_perfdata_fp_lock); + xpddefault_close_host_perfdata_file(); + + /* run the command */ + my_system_r(&mac, processed_command_line, xpddefault_perfdata_timeout, &early_timeout, &exectime, NULL, 0); + clear_volatile_macros_r(&mac); + + /* re-open and unlock the performance data file */ + xpddefault_open_host_perfdata_file(); + pthread_mutex_unlock(&xpddefault_host_perfdata_fp_lock); + + /* check to see if the command timed out */ + if(early_timeout == TRUE) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance data file processing command '%s' timed out after %d seconds\n", processed_command_line, xpddefault_perfdata_timeout); + + + /* free memory */ + my_free(processed_command_line); + + return result; + } + + +/* periodically process the service perf data file */ +int xpddefault_process_service_perfdata_file(void) { + char *raw_command_line = NULL; + char *processed_command_line = NULL; + int early_timeout = FALSE; + double exectime = 0.0; + int result = OK; + int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; + nagios_macros mac; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "process_service_perfdata_file()\n"); + + /* we don't have a command */ + if(xpddefault_service_perfdata_file_processing_command == NULL) + return OK; + + /* init macros */ + memset(&mac, 0, sizeof(mac)); + + /* get the raw command line */ + get_raw_command_line_r(&mac, xpddefault_service_perfdata_file_processing_command_ptr, xpddefault_service_perfdata_file_processing_command, &raw_command_line, macro_options); + if(raw_command_line == NULL) { + clear_volatile_macros_r(&mac); + return ERROR; + } + + log_debug_info(DEBUGL_PERFDATA, 2, "Raw service performance data file processing command line: %s\n", raw_command_line); + + /* process any macros in the raw command line */ + process_macros_r(&mac, raw_command_line, &processed_command_line, macro_options); + my_free(raw_command_line); + if(processed_command_line == NULL) { + clear_volatile_macros_r(&mac); + return ERROR; + } + + log_debug_info(DEBUGL_PERFDATA, 2, "Processed service performance data file processing command line: %s\n", processed_command_line); + + /* lock and close the performance data file */ + pthread_mutex_lock(&xpddefault_service_perfdata_fp_lock); + xpddefault_close_service_perfdata_file(); + + /* run the command */ + my_system_r(&mac, processed_command_line, xpddefault_perfdata_timeout, &early_timeout, &exectime, NULL, 0); + + /* re-open and unlock the performance data file */ + xpddefault_open_service_perfdata_file(); + pthread_mutex_unlock(&xpddefault_service_perfdata_fp_lock); + + clear_volatile_macros_r(&mac); + + /* check to see if the command timed out */ + if(early_timeout == TRUE) + logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service performance data file processing command '%s' timed out after %d seconds\n", processed_command_line, xpddefault_perfdata_timeout); + + /* free memory */ + my_free(processed_command_line); + + return result; + } + diff --git a/xdata/xpddefault.h b/xdata/xpddefault.h new file mode 100644 index 0000000..881ce62 --- /dev/null +++ b/xdata/xpddefault.h @@ -0,0 +1,62 @@ +/***************************************************************************** + * + * XPDDEFAULT.H - Include file for default performance data routines + * + * Copyright (c) 2001-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-28-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _XPDDEFAULT_H +#define _XPDDEFAULT_H + +#include "../include/objects.h" + + +#define DEFAULT_HOST_PERFDATA_FILE_TEMPLATE "[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$" +#define DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE "[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$" + +#define DEFAULT_HOST_PERFDATA_PROCESS_EMPTY_RESULTS 1 +#define DEFAULT_SERVICE_PERFDATA_PROCESS_EMPTY_RESULTS 1 + + +int xpddefault_initialize_performance_data(char *); +int xpddefault_cleanup_performance_data(char *); +int xpddefault_grab_config_info(char *); +int xpddefault_grab_config_directives(char *); + +int xpddefault_update_service_performance_data(service *); +int xpddefault_update_host_performance_data(host *); + +int xpddefault_run_service_performance_data_command(nagios_macros *mac, service *); +int xpddefault_run_host_performance_data_command(nagios_macros *mac, host *); + +int xpddefault_update_service_performance_data_file(nagios_macros *mac, service *); +int xpddefault_update_host_performance_data_file(nagios_macros *mac, host *); + +int xpddefault_preprocess_file_templates(char *); + +int xpddefault_open_host_perfdata_file(void); +int xpddefault_open_service_perfdata_file(void); +int xpddefault_close_host_perfdata_file(void); +int xpddefault_close_service_perfdata_file(void); + +int xpddefault_process_host_perfdata_file(void); +int xpddefault_process_service_perfdata_file(void); + +#endif diff --git a/xdata/xrddefault.c b/xdata/xrddefault.c new file mode 100644 index 0000000..a3823b3 --- /dev/null +++ b/xdata/xrddefault.c @@ -0,0 +1,1893 @@ +/***************************************************************************** + * + * XRDDEFAULT.C - Default external state retention routines for Nagios + * + * Copyright (c) 2009 Nagios Core Development Team and Community Contributors + * Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 08-06-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. + * + *****************************************************************************/ + + +/*********** COMMON HEADER FILES ***********/ + +#include "../include/config.h" +#include "../include/common.h" +#include "../include/objects.h" +#include "../include/statusdata.h" +#include "../include/macros.h" +#include "../include/nagios.h" +#include "../include/sretention.h" +#include "../include/comments.h" +#include "../include/downtime.h" + + +/**** STATE INFORMATION SPECIFIC HEADER FILES ****/ + +#include "xrddefault.h" + +extern host *host_list; +extern service *service_list; +extern contact *contact_list; +extern comment *comment_list; +extern scheduled_downtime *scheduled_downtime_list; + +extern char *global_host_event_handler; +extern char *global_service_event_handler; + +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int enable_flap_detection; +extern int enable_failure_prediction; +extern int process_performance_data; +extern int check_service_freshness; +extern int check_host_freshness; + +extern int test_scheduling; + +extern int use_large_installation_tweaks; + +extern int use_retained_program_state; +extern int use_retained_scheduling_info; +extern int retention_scheduling_horizon; + +extern time_t last_program_stop; +extern time_t last_update_check; +extern unsigned long update_uid; +extern char *last_program_version; +extern int update_available; +extern char *last_program_version; +extern char *new_program_version; + +extern unsigned long next_comment_id; +extern unsigned long next_downtime_id; +extern unsigned long next_event_id; +extern unsigned long next_problem_id; +extern unsigned long next_notification_id; + +extern unsigned long modified_host_process_attributes; +extern unsigned long modified_service_process_attributes; + +extern unsigned long retained_host_attribute_mask; +extern unsigned long retained_service_attribute_mask; +extern unsigned long retained_contact_host_attribute_mask; +extern unsigned long retained_contact_service_attribute_mask; +extern unsigned long retained_process_host_attribute_mask; +extern unsigned long retained_process_service_attribute_mask; + + +char *xrddefault_retention_file = NULL; +char *xrddefault_temp_file = NULL; + + + + +/******************************************************************/ +/********************* CONFIG INITIALIZATION *********************/ +/******************************************************************/ + +int xrddefault_grab_config_info(char *main_config_file) { + char *input = NULL; + mmapfile *thefile = NULL; + nagios_macros *mac; + + mac = get_global_macros(); + + + /* open the main config file for reading */ + if((thefile = mmap_fopen(main_config_file)) == NULL) { + + log_debug_info(DEBUGL_RETENTIONDATA, 2, "Error: Cannot open main configuration file '%s' for reading!\n", main_config_file); + + my_free(xrddefault_retention_file); + my_free(xrddefault_temp_file); + + return ERROR; + } + + /* read in all lines from the main config file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + strip(input); + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == '\x0') + continue; + + xrddefault_grab_config_directives(input); + } + + /* free memory and close the file */ + my_free(input); + mmap_fclose(thefile); + + /* initialize locations if necessary */ + if(xrddefault_retention_file == NULL) + xrddefault_retention_file = (char *)strdup(DEFAULT_RETENTION_FILE); + if(xrddefault_temp_file == NULL) + xrddefault_temp_file = (char *)strdup(DEFAULT_TEMP_FILE); + + /* make sure we have everything */ + if(xrddefault_retention_file == NULL) + return ERROR; + if(xrddefault_temp_file == NULL) + return ERROR; + + /* save the retention file macro */ + my_free(mac->x[MACRO_RETENTIONDATAFILE]); + if((mac->x[MACRO_RETENTIONDATAFILE] = (char *)strdup(xrddefault_retention_file))) + strip(mac->x[MACRO_RETENTIONDATAFILE]); + + return OK; + } + + + +/* process a single config directive */ +int xrddefault_grab_config_directives(char *input) { + char *temp_ptr = NULL; + char *varname = NULL; + char *varvalue = NULL; + + /* get the variable name */ + if((temp_ptr = my_strtok(input, "=")) == NULL) + return ERROR; + if((varname = (char *)strdup(temp_ptr)) == NULL) + return ERROR; + + /* get the variable value */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + my_free(varname); + return ERROR; + } + if((varvalue = (char *)strdup(temp_ptr)) == NULL) { + my_free(varname); + return ERROR; + } + + /* retention file definition */ + if(!strcmp(varname, "xrddefault_retention_file") || !strcmp(varname, "state_retention_file")) + xrddefault_retention_file = (char *)strdup(varvalue); + + /* temp file definition */ + else if(!strcmp(varname, "temp_file")) + xrddefault_temp_file = (char *)strdup(varvalue); + + /* free memory */ + my_free(varname); + my_free(varvalue); + + return OK; + } + + + + +/******************************************************************/ +/********************* INIT/CLEANUP FUNCTIONS *********************/ +/******************************************************************/ + + +/* initialize retention data */ +int xrddefault_initialize_retention_data(char *config_file) { + int result; + + /* grab configuration data */ + result = xrddefault_grab_config_info(config_file); + if(result == ERROR) + return ERROR; + + return OK; + } + + +/* cleanup retention data before terminating */ +int xrddefault_cleanup_retention_data(char *config_file) { + + /* free memory */ + my_free(xrddefault_retention_file); + my_free(xrddefault_temp_file); + + return OK; + } + + +/******************************************************************/ +/**************** DEFAULT STATE OUTPUT FUNCTION *******************/ +/******************************************************************/ + +int xrddefault_save_state_information(void) { + char *temp_file = NULL; + customvariablesmember *temp_customvariablesmember = NULL; + time_t current_time = 0L; + int result = OK; + FILE *fp = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + contact *temp_contact = NULL; + comment *temp_comment = NULL; + scheduled_downtime *temp_downtime = NULL; + int x = 0; + int fd = 0; + unsigned long host_attribute_mask = 0L; + unsigned long service_attribute_mask = 0L; + unsigned long contact_attribute_mask = 0L; + unsigned long contact_host_attribute_mask = 0L; + unsigned long contact_service_attribute_mask = 0L; + unsigned long process_host_attribute_mask = 0L; + unsigned long process_service_attribute_mask = 0L; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "xrddefault_save_state_information()\n"); + + /* make sure we have everything */ + if(xrddefault_retention_file == NULL || xrddefault_temp_file == NULL) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: We don't have the required file names to store retention data!\n"); + return ERROR; + } + + /* open a safe temp file for output */ + asprintf(&temp_file, "%sXXXXXX", xrddefault_temp_file); + if(temp_file == NULL) + return ERROR; + if((fd = mkstemp(temp_file)) == -1) + return ERROR; + + log_debug_info(DEBUGL_RETENTIONDATA, 2, "Writing retention data to temp file '%s'\n", temp_file); + + fp = (FILE *)fdopen(fd, "w"); + if(fp == NULL) { + + close(fd); + unlink(temp_file); + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open temp state retention file '%s' for writing!\n", temp_file); + + my_free(temp_file); + + return ERROR; + } + + /* what attributes should be masked out? */ + /* NOTE: host/service/contact-specific values may be added in the future, but for now we only have global masks */ + process_host_attribute_mask = retained_process_host_attribute_mask; + process_service_attribute_mask = retained_process_host_attribute_mask; + host_attribute_mask = retained_host_attribute_mask; + service_attribute_mask = retained_host_attribute_mask; + contact_host_attribute_mask = retained_contact_host_attribute_mask; + contact_service_attribute_mask = retained_contact_service_attribute_mask; + + /* write version info to status file */ + fprintf(fp, "########################################\n"); + fprintf(fp, "# NAGIOS STATE RETENTION FILE\n"); + fprintf(fp, "#\n"); + fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n"); + fprintf(fp, "# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); + fprintf(fp, "########################################\n"); + + time(¤t_time); + + /* write file info */ + fprintf(fp, "info {\n"); + fprintf(fp, "created=%lu\n", current_time); + fprintf(fp, "version=%s\n", PROGRAM_VERSION); + fprintf(fp, "last_update_check=%lu\n", last_update_check); + fprintf(fp, "update_available=%d\n", update_available); + fprintf(fp, "update_uid=%lu\n", update_uid); + fprintf(fp, "last_version=%s\n", (last_program_version == NULL) ? "" : last_program_version); + fprintf(fp, "new_version=%s\n", (new_program_version == NULL) ? "" : new_program_version); + fprintf(fp, "}\n"); + + /* save program state information */ + fprintf(fp, "program {\n"); + fprintf(fp, "modified_host_attributes=%lu\n", (modified_host_process_attributes & ~process_host_attribute_mask)); + fprintf(fp, "modified_service_attributes=%lu\n", (modified_service_process_attributes & ~process_service_attribute_mask)); + fprintf(fp, "enable_notifications=%d\n", enable_notifications); + fprintf(fp, "active_service_checks_enabled=%d\n", execute_service_checks); + fprintf(fp, "passive_service_checks_enabled=%d\n", accept_passive_service_checks); + fprintf(fp, "active_host_checks_enabled=%d\n", execute_host_checks); + fprintf(fp, "passive_host_checks_enabled=%d\n", accept_passive_host_checks); + fprintf(fp, "enable_event_handlers=%d\n", enable_event_handlers); + fprintf(fp, "obsess_over_services=%d\n", obsess_over_services); + fprintf(fp, "obsess_over_hosts=%d\n", obsess_over_hosts); + fprintf(fp, "check_service_freshness=%d\n", check_service_freshness); + fprintf(fp, "check_host_freshness=%d\n", check_host_freshness); + fprintf(fp, "enable_flap_detection=%d\n", enable_flap_detection); + fprintf(fp, "enable_failure_prediction=%d\n", enable_failure_prediction); + fprintf(fp, "process_performance_data=%d\n", process_performance_data); + fprintf(fp, "global_host_event_handler=%s\n", (global_host_event_handler == NULL) ? "" : global_host_event_handler); + fprintf(fp, "global_service_event_handler=%s\n", (global_service_event_handler == NULL) ? "" : global_service_event_handler); + fprintf(fp, "next_comment_id=%lu\n", next_comment_id); + fprintf(fp, "next_downtime_id=%lu\n", next_downtime_id); + fprintf(fp, "next_event_id=%lu\n", next_event_id); + fprintf(fp, "next_problem_id=%lu\n", next_problem_id); + fprintf(fp, "next_notification_id=%lu\n", next_notification_id); + fprintf(fp, "}\n"); + + /* save host state information */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + fprintf(fp, "host {\n"); + fprintf(fp, "host_name=%s\n", temp_host->name); + fprintf(fp, "modified_attributes=%lu\n", (temp_host->modified_attributes & ~host_attribute_mask)); + fprintf(fp, "check_command=%s\n", (temp_host->host_check_command == NULL) ? "" : temp_host->host_check_command); + fprintf(fp, "check_period=%s\n", (temp_host->check_period == NULL) ? "" : temp_host->check_period); + fprintf(fp, "notification_period=%s\n", (temp_host->notification_period == NULL) ? "" : temp_host->notification_period); + fprintf(fp, "event_handler=%s\n", (temp_host->event_handler == NULL) ? "" : temp_host->event_handler); + fprintf(fp, "has_been_checked=%d\n", temp_host->has_been_checked); + fprintf(fp, "check_execution_time=%.3f\n", temp_host->execution_time); + fprintf(fp, "check_latency=%.3f\n", temp_host->latency); + fprintf(fp, "check_type=%d\n", temp_host->check_type); + fprintf(fp, "current_state=%d\n", temp_host->current_state); + fprintf(fp, "last_state=%d\n", temp_host->last_state); + fprintf(fp, "last_hard_state=%d\n", temp_host->last_hard_state); + fprintf(fp, "last_event_id=%lu\n", temp_host->last_event_id); + fprintf(fp, "current_event_id=%lu\n", temp_host->current_event_id); + fprintf(fp, "current_problem_id=%lu\n", temp_host->current_problem_id); + fprintf(fp, "last_problem_id=%lu\n", temp_host->last_problem_id); + fprintf(fp, "plugin_output=%s\n", (temp_host->plugin_output == NULL) ? "" : temp_host->plugin_output); + fprintf(fp, "long_plugin_output=%s\n", (temp_host->long_plugin_output == NULL) ? "" : temp_host->long_plugin_output); + fprintf(fp, "performance_data=%s\n", (temp_host->perf_data == NULL) ? "" : temp_host->perf_data); + fprintf(fp, "last_check=%lu\n", temp_host->last_check); + fprintf(fp, "next_check=%lu\n", temp_host->next_check); + fprintf(fp, "check_options=%d\n", temp_host->check_options); + fprintf(fp, "current_attempt=%d\n", temp_host->current_attempt); + fprintf(fp, "max_attempts=%d\n", temp_host->max_attempts); + fprintf(fp, "normal_check_interval=%f\n", temp_host->check_interval); + fprintf(fp, "retry_check_interval=%f\n", temp_host->check_interval); + fprintf(fp, "state_type=%d\n", temp_host->state_type); + fprintf(fp, "last_state_change=%lu\n", temp_host->last_state_change); + fprintf(fp, "last_hard_state_change=%lu\n", temp_host->last_hard_state_change); + fprintf(fp, "last_time_up=%lu\n", temp_host->last_time_up); + fprintf(fp, "last_time_down=%lu\n", temp_host->last_time_down); + fprintf(fp, "last_time_unreachable=%lu\n", temp_host->last_time_unreachable); + fprintf(fp, "notified_on_down=%d\n", temp_host->notified_on_down); + fprintf(fp, "notified_on_unreachable=%d\n", temp_host->notified_on_unreachable); + fprintf(fp, "last_notification=%lu\n", temp_host->last_host_notification); + fprintf(fp, "current_notification_number=%d\n", temp_host->current_notification_number); + fprintf(fp, "current_notification_id=%lu\n", temp_host->current_notification_id); + fprintf(fp, "notifications_enabled=%d\n", temp_host->notifications_enabled); + fprintf(fp, "problem_has_been_acknowledged=%d\n", temp_host->problem_has_been_acknowledged); + fprintf(fp, "acknowledgement_type=%d\n", temp_host->acknowledgement_type); + fprintf(fp, "active_checks_enabled=%d\n", temp_host->checks_enabled); + fprintf(fp, "passive_checks_enabled=%d\n", temp_host->accept_passive_host_checks); + fprintf(fp, "event_handler_enabled=%d\n", temp_host->event_handler_enabled); + fprintf(fp, "flap_detection_enabled=%d\n", temp_host->flap_detection_enabled); + fprintf(fp, "failure_prediction_enabled=%d\n", temp_host->failure_prediction_enabled); + fprintf(fp, "process_performance_data=%d\n", temp_host->process_performance_data); + fprintf(fp, "obsess_over_host=%d\n", temp_host->obsess_over_host); + fprintf(fp, "is_flapping=%d\n", temp_host->is_flapping); + fprintf(fp, "percent_state_change=%.2f\n", temp_host->percent_state_change); + fprintf(fp, "check_flapping_recovery_notification=%d\n", temp_host->check_flapping_recovery_notification); + + fprintf(fp, "state_history="); + for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) + fprintf(fp, "%s%d", (x > 0) ? "," : "", temp_host->state_history[(x + temp_host->state_history_index) % MAX_STATE_HISTORY_ENTRIES]); + fprintf(fp, "\n"); + + /* custom variables */ + for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); + } + + fprintf(fp, "}\n"); + } + + /* save service state information */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + fprintf(fp, "service {\n"); + fprintf(fp, "host_name=%s\n", temp_service->host_name); + fprintf(fp, "service_description=%s\n", temp_service->description); + fprintf(fp, "modified_attributes=%lu\n", (temp_service->modified_attributes & ~service_attribute_mask)); + fprintf(fp, "check_command=%s\n", (temp_service->service_check_command == NULL) ? "" : temp_service->service_check_command); + fprintf(fp, "check_period=%s\n", (temp_service->check_period == NULL) ? "" : temp_service->check_period); + fprintf(fp, "notification_period=%s\n", (temp_service->notification_period == NULL) ? "" : temp_service->notification_period); + fprintf(fp, "event_handler=%s\n", (temp_service->event_handler == NULL) ? "" : temp_service->event_handler); + fprintf(fp, "has_been_checked=%d\n", temp_service->has_been_checked); + fprintf(fp, "check_execution_time=%.3f\n", temp_service->execution_time); + fprintf(fp, "check_latency=%.3f\n", temp_service->latency); + fprintf(fp, "check_type=%d\n", temp_service->check_type); + fprintf(fp, "current_state=%d\n", temp_service->current_state); + fprintf(fp, "last_state=%d\n", temp_service->last_state); + fprintf(fp, "last_hard_state=%d\n", temp_service->last_hard_state); + fprintf(fp, "last_event_id=%lu\n", temp_service->last_event_id); + fprintf(fp, "current_event_id=%lu\n", temp_service->current_event_id); + fprintf(fp, "current_problem_id=%lu\n", temp_service->current_problem_id); + fprintf(fp, "last_problem_id=%lu\n", temp_service->last_problem_id); + fprintf(fp, "current_attempt=%d\n", temp_service->current_attempt); + fprintf(fp, "max_attempts=%d\n", temp_service->max_attempts); + fprintf(fp, "normal_check_interval=%f\n", temp_service->check_interval); + fprintf(fp, "retry_check_interval=%f\n", temp_service->retry_interval); + fprintf(fp, "state_type=%d\n", temp_service->state_type); + fprintf(fp, "last_state_change=%lu\n", temp_service->last_state_change); + fprintf(fp, "last_hard_state_change=%lu\n", temp_service->last_hard_state_change); + fprintf(fp, "last_time_ok=%lu\n", temp_service->last_time_ok); + fprintf(fp, "last_time_warning=%lu\n", temp_service->last_time_warning); + fprintf(fp, "last_time_unknown=%lu\n", temp_service->last_time_unknown); + fprintf(fp, "last_time_critical=%lu\n", temp_service->last_time_critical); + fprintf(fp, "plugin_output=%s\n", (temp_service->plugin_output == NULL) ? "" : temp_service->plugin_output); + fprintf(fp, "long_plugin_output=%s\n", (temp_service->long_plugin_output == NULL) ? "" : temp_service->long_plugin_output); + fprintf(fp, "performance_data=%s\n", (temp_service->perf_data == NULL) ? "" : temp_service->perf_data); + fprintf(fp, "last_check=%lu\n", temp_service->last_check); + fprintf(fp, "next_check=%lu\n", temp_service->next_check); + fprintf(fp, "check_options=%d\n", temp_service->check_options); + fprintf(fp, "notified_on_unknown=%d\n", temp_service->notified_on_unknown); + fprintf(fp, "notified_on_warning=%d\n", temp_service->notified_on_warning); + fprintf(fp, "notified_on_critical=%d\n", temp_service->notified_on_critical); + fprintf(fp, "current_notification_number=%d\n", temp_service->current_notification_number); + fprintf(fp, "current_notification_id=%lu\n", temp_service->current_notification_id); + fprintf(fp, "last_notification=%lu\n", temp_service->last_notification); + fprintf(fp, "notifications_enabled=%d\n", temp_service->notifications_enabled); + fprintf(fp, "active_checks_enabled=%d\n", temp_service->checks_enabled); + fprintf(fp, "passive_checks_enabled=%d\n", temp_service->accept_passive_service_checks); + fprintf(fp, "event_handler_enabled=%d\n", temp_service->event_handler_enabled); + fprintf(fp, "problem_has_been_acknowledged=%d\n", temp_service->problem_has_been_acknowledged); + fprintf(fp, "acknowledgement_type=%d\n", temp_service->acknowledgement_type); + fprintf(fp, "flap_detection_enabled=%d\n", temp_service->flap_detection_enabled); + fprintf(fp, "failure_prediction_enabled=%d\n", temp_service->failure_prediction_enabled); + fprintf(fp, "process_performance_data=%d\n", temp_service->process_performance_data); + fprintf(fp, "obsess_over_service=%d\n", temp_service->obsess_over_service); + fprintf(fp, "is_flapping=%d\n", temp_service->is_flapping); + fprintf(fp, "percent_state_change=%.2f\n", temp_service->percent_state_change); + fprintf(fp, "check_flapping_recovery_notification=%d\n", temp_service->check_flapping_recovery_notification); + + fprintf(fp, "state_history="); + for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) + fprintf(fp, "%s%d", (x > 0) ? "," : "", temp_service->state_history[(x + temp_service->state_history_index) % MAX_STATE_HISTORY_ENTRIES]); + fprintf(fp, "\n"); + + /* custom variables */ + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); + } + + fprintf(fp, "}\n"); + } + + /* save contact state information */ + for(temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + + fprintf(fp, "contact {\n"); + fprintf(fp, "contact_name=%s\n", temp_contact->name); + fprintf(fp, "modified_attributes=%lu\n", (temp_contact->modified_attributes & ~contact_attribute_mask)); + fprintf(fp, "modified_host_attributes=%lu\n", (temp_contact->modified_host_attributes & ~contact_host_attribute_mask)); + fprintf(fp, "modified_service_attributes=%lu\n", (temp_contact->modified_service_attributes & ~contact_service_attribute_mask)); + fprintf(fp, "host_notification_period=%s\n", (temp_contact->host_notification_period == NULL) ? "" : temp_contact->host_notification_period); + fprintf(fp, "service_notification_period=%s\n", (temp_contact->service_notification_period == NULL) ? "" : temp_contact->service_notification_period); + fprintf(fp, "last_host_notification=%lu\n", temp_contact->last_host_notification); + fprintf(fp, "last_service_notification=%lu\n", temp_contact->last_service_notification); + fprintf(fp, "host_notifications_enabled=%d\n", temp_contact->host_notifications_enabled); + fprintf(fp, "service_notifications_enabled=%d\n", temp_contact->service_notifications_enabled); + + /* custom variables */ + for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); + } + + fprintf(fp, "}\n"); + } + + /* save all comments */ + for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) { + + if(temp_comment->comment_type == HOST_COMMENT) + fprintf(fp, "hostcomment {\n"); + else + fprintf(fp, "servicecomment {\n"); + fprintf(fp, "host_name=%s\n", temp_comment->host_name); + if(temp_comment->comment_type == SERVICE_COMMENT) + fprintf(fp, "service_description=%s\n", temp_comment->service_description); + fprintf(fp, "entry_type=%d\n", temp_comment->entry_type); + fprintf(fp, "comment_id=%lu\n", temp_comment->comment_id); + fprintf(fp, "source=%d\n", temp_comment->source); + fprintf(fp, "persistent=%d\n", temp_comment->persistent); + fprintf(fp, "entry_time=%lu\n", temp_comment->entry_time); + fprintf(fp, "expires=%d\n", temp_comment->expires); + fprintf(fp, "expire_time=%lu\n", temp_comment->expire_time); + fprintf(fp, "author=%s\n", temp_comment->author); + fprintf(fp, "comment_data=%s\n", temp_comment->comment_data); + fprintf(fp, "}\n"); + } + + /* save all downtime */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + + if(temp_downtime->type == HOST_DOWNTIME) + fprintf(fp, "hostdowntime {\n"); + else + fprintf(fp, "servicedowntime {\n"); + fprintf(fp, "host_name=%s\n", temp_downtime->host_name); + if(temp_downtime->type == SERVICE_DOWNTIME) + fprintf(fp, "service_description=%s\n", temp_downtime->service_description); + fprintf(fp, "comment_id=%lu\n", temp_downtime->comment_id); + fprintf(fp, "downtime_id=%lu\n", temp_downtime->downtime_id); + fprintf(fp, "entry_time=%lu\n", temp_downtime->entry_time); + fprintf(fp, "start_time=%lu\n", temp_downtime->start_time); + fprintf(fp, "flex_downtime_start=%lu\n", temp_downtime->flex_downtime_start); + fprintf(fp, "end_time=%lu\n", temp_downtime->end_time); + fprintf(fp, "triggered_by=%lu\n", temp_downtime->triggered_by); + fprintf(fp, "fixed=%d\n", temp_downtime->fixed); + fprintf(fp, "duration=%lu\n", temp_downtime->duration); + fprintf(fp, "is_in_effect=%d\n", temp_downtime->is_in_effect); + fprintf(fp, "start_notification_sent=%d\n", temp_downtime->start_notification_sent); + fprintf(fp, "author=%s\n", temp_downtime->author); + fprintf(fp, "comment=%s\n", temp_downtime->comment); + fprintf(fp, "}\n"); + } + + fflush(fp); + result = fclose(fp); + fsync(fd); + + /* save/close was successful */ + if(result == 0) { + + result = OK; + + /* move the temp file to the retention file (overwrite the old retention file) */ + if(my_rename(temp_file, xrddefault_retention_file)) { + unlink(temp_file); + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to update retention file '%s': %s", xrddefault_retention_file, strerror(errno)); + result = ERROR; + } + } + + /* a problem occurred saving the file */ + else { + + result = ERROR; + + /* remove temp file and log an error */ + unlink(temp_file); + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to save retention file: %s", strerror(errno)); + } + + /* free memory */ + my_free(temp_file); + + return result; + } + + + + +/******************************************************************/ +/***************** DEFAULT STATE INPUT FUNCTION *******************/ +/******************************************************************/ + +int xrddefault_read_state_information(void) { + char *input = NULL; + char *inputbuf = NULL; + char *temp_ptr = NULL; + mmapfile *thefile; + char *host_name = NULL; + char *service_description = NULL; + char *contact_name = NULL; + char *author = NULL; + char *comment_data = NULL; + int data_type = XRDDEFAULT_NO_DATA; + int x = 0; + host *temp_host = NULL; + service *temp_service = NULL; + contact *temp_contact = NULL; + command *temp_command = NULL; + timeperiod *temp_timeperiod = NULL; + customvariablesmember *temp_customvariablesmember = NULL; + char *customvarname = NULL; + char *var = NULL; + char *val = NULL; + char *tempval = NULL; + char *ch = NULL; + unsigned long comment_id = 0; + int persistent = FALSE; + int expires = FALSE; + time_t expire_time = 0L; + int entry_type = USER_COMMENT; + int source = COMMENTSOURCE_INTERNAL; + time_t entry_time = 0L; + time_t creation_time; + time_t current_time; + int scheduling_info_is_ok = FALSE; + unsigned long downtime_id = 0; + time_t start_time = 0L; + time_t flex_downtime_start = (time_t)0; + time_t end_time = 0L; + int fixed = FALSE; + unsigned long triggered_by = 0; + unsigned long duration = 0L; + unsigned long host_attribute_mask = 0L; + unsigned long service_attribute_mask = 0L; + unsigned long contact_attribute_mask = 0L; + unsigned long contact_host_attribute_mask = 0L; + unsigned long contact_service_attribute_mask = 0L; + unsigned long process_host_attribute_mask = 0L; + unsigned long process_service_attribute_mask = 0L; + int remove_comment = FALSE; + int ack = FALSE; + int was_flapping = FALSE; + int allow_flapstart_notification = TRUE; + struct timeval tv[2]; + double runtime[2]; + int found_directive = FALSE; + int is_in_effect = FALSE; + int start_notification_sent = FALSE; + + + log_debug_info(DEBUGL_FUNCTIONS, 0, "xrddefault_read_state_information() start\n"); + + /* make sure we have what we need */ + if(xrddefault_retention_file == NULL) { + + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: We don't have a filename for retention data!\n"); + + return ERROR; + } + + if(test_scheduling == TRUE) + gettimeofday(&tv[0], NULL); + + /* open the retention file for reading */ + if((thefile = mmap_fopen(xrddefault_retention_file)) == NULL) + return ERROR; + + /* what attributes should be masked out? */ + /* NOTE: host/service/contact-specific values may be added in the future, but for now we only have global masks */ + process_host_attribute_mask = retained_process_host_attribute_mask; + process_service_attribute_mask = retained_process_host_attribute_mask; + host_attribute_mask = retained_host_attribute_mask; + service_attribute_mask = retained_host_attribute_mask; + contact_host_attribute_mask = retained_contact_host_attribute_mask; + contact_service_attribute_mask = retained_contact_service_attribute_mask; + + /* Big speedup when reading retention.dat in bulk */ + defer_downtime_sorting = 1; + defer_comment_sorting = 1; + + /* read all lines in the retention file */ + while(1) { + + /* free memory */ + my_free(inputbuf); + + /* read the next line */ + if((inputbuf = mmap_fgets(thefile)) == NULL) + break; + + input = inputbuf; + + /* far better than strip()ing */ + if(input[0] == '\t') + input++; + + strip(input); + + if(!strcmp(input, "service {")) + data_type = XRDDEFAULT_SERVICESTATUS_DATA; + else if(!strcmp(input, "host {")) + data_type = XRDDEFAULT_HOSTSTATUS_DATA; + else if(!strcmp(input, "contact {")) + data_type = XRDDEFAULT_CONTACTSTATUS_DATA; + else if(!strcmp(input, "hostcomment {")) + data_type = XRDDEFAULT_HOSTCOMMENT_DATA; + else if(!strcmp(input, "servicecomment {")) + data_type = XRDDEFAULT_SERVICECOMMENT_DATA; + else if(!strcmp(input, "hostdowntime {")) + data_type = XRDDEFAULT_HOSTDOWNTIME_DATA; + else if(!strcmp(input, "servicedowntime {")) + data_type = XRDDEFAULT_SERVICEDOWNTIME_DATA; + else if(!strcmp(input, "info {")) + data_type = XRDDEFAULT_INFO_DATA; + else if(!strcmp(input, "program {")) + data_type = XRDDEFAULT_PROGRAMSTATUS_DATA; + + else if(!strcmp(input, "}")) { + + switch(data_type) { + + case XRDDEFAULT_INFO_DATA: + break; + + case XRDDEFAULT_PROGRAMSTATUS_DATA: + + /* adjust modified attributes if necessary */ + if(use_retained_program_state == FALSE) { + modified_host_process_attributes = MODATTR_NONE; + modified_service_process_attributes = MODATTR_NONE; + } + break; + + case XRDDEFAULT_HOSTSTATUS_DATA: + + if(temp_host != NULL) { + + /* adjust modified attributes if necessary */ + if(temp_host->retain_nonstatus_information == FALSE) + temp_host->modified_attributes = MODATTR_NONE; + + /* adjust modified attributes if no custom variables have been changed */ + if(temp_host->modified_attributes & MODATTR_CUSTOM_VARIABLE) { + for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->has_been_modified == TRUE) + break; + + } + if(temp_customvariablesmember == NULL) + temp_host->modified_attributes -= MODATTR_CUSTOM_VARIABLE; + } + + /* calculate next possible notification time */ + if(temp_host->current_state != HOST_UP && temp_host->last_host_notification != (time_t)0) + temp_host->next_host_notification = get_next_host_notification_time(temp_host, temp_host->last_host_notification); + + /* ADDED 01/23/2009 adjust current check attempts if host in hard problem state (max attempts may have changed in config since restart) */ + if(temp_host->current_state != HOST_UP && temp_host->state_type == HARD_STATE) + temp_host->current_attempt = temp_host->max_attempts; + + + /* ADDED 02/20/08 assume same flapping state if large install tweaks enabled */ + if(use_large_installation_tweaks == TRUE) { + temp_host->is_flapping = was_flapping; + } + /* else use normal startup flap detection logic */ + else { + /* host was flapping before program started */ + /* 11/10/07 don't allow flapping notifications to go out */ + if(was_flapping == TRUE) + allow_flapstart_notification = FALSE; + else + /* flapstart notifications are okay */ + allow_flapstart_notification = TRUE; + + /* check for flapping */ + check_for_host_flapping(temp_host, FALSE, FALSE, allow_flapstart_notification); + + /* host was flapping before and isn't now, so clear recovery check variable if host isn't flapping now */ + if(was_flapping == TRUE && temp_host->is_flapping == FALSE) + temp_host->check_flapping_recovery_notification = FALSE; + } + + /* handle new vars added in 2.x */ + if(temp_host->last_hard_state_change == (time_t)0) + temp_host->last_hard_state_change = temp_host->last_state_change; + + /* update host status */ + update_host_status(temp_host, FALSE); + } + + /* reset vars */ + was_flapping = FALSE; + allow_flapstart_notification = TRUE; + + my_free(host_name); + host_name = NULL; + temp_host = NULL; + break; + + case XRDDEFAULT_SERVICESTATUS_DATA: + + if(temp_service != NULL) { + + /* adjust modified attributes if necessary */ + if(temp_service->retain_nonstatus_information == FALSE) + temp_service->modified_attributes = MODATTR_NONE; + + /* adjust modified attributes if no custom variables have been changed */ + if(temp_service->modified_attributes & MODATTR_CUSTOM_VARIABLE) { + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->has_been_modified == TRUE) + break; + + } + if(temp_customvariablesmember == NULL) + temp_service->modified_attributes -= MODATTR_CUSTOM_VARIABLE; + } + + /* calculate next possible notification time */ + if(temp_service->current_state != STATE_OK && temp_service->last_notification != (time_t)0) + temp_service->next_notification = get_next_service_notification_time(temp_service, temp_service->last_notification); + + /* fix old vars */ + if(temp_service->has_been_checked == FALSE && temp_service->state_type == SOFT_STATE) + temp_service->state_type = HARD_STATE; + + /* ADDED 01/23/2009 adjust current check attempt if service is in hard problem state (max attempts may have changed in config since restart) */ + if(temp_service->current_state != STATE_OK && temp_service->state_type == HARD_STATE) + temp_service->current_attempt = temp_service->max_attempts; + + + /* ADDED 02/20/08 assume same flapping state if large install tweaks enabled */ + if(use_large_installation_tweaks == TRUE) { + temp_service->is_flapping = was_flapping; + } + /* else use normal startup flap detection logic */ + else { + /* service was flapping before program started */ + /* 11/10/07 don't allow flapping notifications to go out */ + if(was_flapping == TRUE) + allow_flapstart_notification = FALSE; + else + /* flapstart notifications are okay */ + allow_flapstart_notification = TRUE; + + /* check for flapping */ + check_for_service_flapping(temp_service, FALSE, allow_flapstart_notification); + + /* service was flapping before and isn't now, so clear recovery check variable if service isn't flapping now */ + if(was_flapping == TRUE && temp_service->is_flapping == FALSE) + temp_service->check_flapping_recovery_notification = FALSE; + } + + /* handle new vars added in 2.x */ + if(temp_service->last_hard_state_change == (time_t)0) + temp_service->last_hard_state_change = temp_service->last_state_change; + + /* update service status */ + update_service_status(temp_service, FALSE); + } + + /* reset vars */ + was_flapping = FALSE; + allow_flapstart_notification = TRUE; + + my_free(host_name); + my_free(service_description); + temp_service = NULL; + break; + + case XRDDEFAULT_CONTACTSTATUS_DATA: + + if(temp_contact != NULL) { + + /* adjust modified attributes if necessary */ + if(temp_contact->retain_nonstatus_information == FALSE) + temp_contact->modified_attributes = MODATTR_NONE; + + /* adjust modified attributes if no custom variables have been changed */ + if(temp_contact->modified_attributes & MODATTR_CUSTOM_VARIABLE) { + for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->has_been_modified == TRUE) + break; + + } + if(temp_customvariablesmember == NULL) + temp_contact->modified_attributes -= MODATTR_CUSTOM_VARIABLE; + } + + /* update contact status */ + update_contact_status(temp_contact, FALSE); + } + + my_free(contact_name); + temp_contact = NULL; + break; + + case XRDDEFAULT_HOSTCOMMENT_DATA: + case XRDDEFAULT_SERVICECOMMENT_DATA: + + /* add the comment */ + add_comment((data_type == XRDDEFAULT_HOSTCOMMENT_DATA) ? HOST_COMMENT : SERVICE_COMMENT, entry_type, host_name, service_description, entry_time, author, comment_data, comment_id, persistent, expires, expire_time, source); + + /* delete the comment if necessary */ + /* it seems a bit backwards to add and then immediately delete the comment, but its necessary to track comment deletions in the event broker */ + remove_comment = FALSE; + /* host no longer exists */ + if((temp_host = find_host(host_name)) == NULL) + remove_comment = TRUE; + /* service no longer exists */ + else if(data_type == XRDDEFAULT_SERVICECOMMENT_DATA && (temp_service = find_service(host_name, service_description)) == NULL) + remove_comment = TRUE; + /* acknowledgement comments get deleted if they're not persistent and the original problem is no longer acknowledged */ + else if(entry_type == ACKNOWLEDGEMENT_COMMENT) { + ack = FALSE; + if(data_type == XRDDEFAULT_HOSTCOMMENT_DATA) + ack = temp_host->problem_has_been_acknowledged; + else + ack = temp_service->problem_has_been_acknowledged; + if(ack == FALSE && persistent == FALSE) + remove_comment = TRUE; + } + /* non-persistent comments don't last past restarts UNLESS they're acks (see above) */ + else if(persistent == FALSE) + remove_comment = TRUE; + + if(remove_comment == TRUE) + delete_comment((data_type == XRDDEFAULT_HOSTCOMMENT_DATA) ? HOST_COMMENT : SERVICE_COMMENT, comment_id); + + /* free temp memory */ + my_free(host_name); + my_free(service_description); + my_free(author); + my_free(comment_data); + + /* reset defaults */ + entry_type = USER_COMMENT; + comment_id = 0; + source = COMMENTSOURCE_INTERNAL; + persistent = FALSE; + entry_time = 0L; + expires = FALSE; + expire_time = 0L; + + break; + + case XRDDEFAULT_HOSTDOWNTIME_DATA: + case XRDDEFAULT_SERVICEDOWNTIME_DATA: + + /* add the downtime */ + if(data_type == XRDDEFAULT_HOSTDOWNTIME_DATA) + add_host_downtime(host_name, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + else + add_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + + /* must register the downtime with Nagios so it can schedule it, add comments, etc. */ + register_downtime((data_type == XRDDEFAULT_HOSTDOWNTIME_DATA) ? HOST_DOWNTIME : SERVICE_DOWNTIME, downtime_id); + + /* free temp memory */ + my_free(host_name); + my_free(service_description); + my_free(author); + my_free(comment_data); + + /* reset defaults */ + downtime_id = 0; + entry_time = 0L; + start_time = 0L; + flex_downtime_start = (time_t)0; + end_time = 0L; + fixed = FALSE; + triggered_by = 0; + duration = 0L; + + break; + + default: + break; + } + + data_type = XRDDEFAULT_NO_DATA; + } + + else if(data_type != XRDDEFAULT_NO_DATA) { + + /* slightly faster than strtok () */ + var = input; + if((val = strchr(input, '=')) == NULL) + continue; + val[0] = '\x0'; + val++; + + found_directive = TRUE; + + switch(data_type) { + + case XRDDEFAULT_INFO_DATA: + if(!strcmp(var, "created")) { + creation_time = strtoul(val, NULL, 10); + time(¤t_time); + if(current_time - creation_time < retention_scheduling_horizon) + scheduling_info_is_ok = TRUE; + else + scheduling_info_is_ok = FALSE; + last_program_stop = creation_time; + } + else if(!strcmp(var, "version")) { + /* initialize last version in case we're reading a pre-3.1.0 retention file */ + if(last_program_version == NULL) + last_program_version = (char *)strdup(val); + } + else if(!strcmp(var, "last_update_check")) + last_update_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "update_available")) + update_available = atoi(val); + else if(!strcmp(var, "update_uid")) + update_uid = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_version")) { + if(last_program_version) + my_free(last_program_version); + last_program_version = (char *)strdup(val); + } + else if(!strcmp(var, "new_version")) + new_program_version = (char *)strdup(val); + break; + + case XRDDEFAULT_PROGRAMSTATUS_DATA: + if(!strcmp(var, "modified_host_attributes")) { + + modified_host_process_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + modified_host_process_attributes &= ~process_host_attribute_mask; + } + else if(!strcmp(var, "modified_service_attributes")) { + + modified_service_process_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + modified_service_process_attributes &= ~process_service_attribute_mask; + } + if(use_retained_program_state == TRUE) { + if(!strcmp(var, "enable_notifications")) { + if(modified_host_process_attributes & MODATTR_NOTIFICATIONS_ENABLED) + enable_notifications = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "active_service_checks_enabled")) { + if(modified_service_process_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) + execute_service_checks = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "passive_service_checks_enabled")) { + if(modified_service_process_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) + accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "active_host_checks_enabled")) { + if(modified_host_process_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) + execute_host_checks = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "passive_host_checks_enabled")) { + if(modified_host_process_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) + accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "enable_event_handlers")) { + if(modified_host_process_attributes & MODATTR_EVENT_HANDLER_ENABLED) + enable_event_handlers = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "obsess_over_services")) { + if(modified_service_process_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) + obsess_over_services = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "obsess_over_hosts")) { + if(modified_host_process_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) + obsess_over_hosts = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "check_service_freshness")) { + if(modified_service_process_attributes & MODATTR_FRESHNESS_CHECKS_ENABLED) + check_service_freshness = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "check_host_freshness")) { + if(modified_host_process_attributes & MODATTR_FRESHNESS_CHECKS_ENABLED) + check_host_freshness = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "enable_flap_detection")) { + if(modified_host_process_attributes & MODATTR_FLAP_DETECTION_ENABLED) + enable_flap_detection = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "enable_failure_prediction")) { + if(modified_host_process_attributes & MODATTR_FAILURE_PREDICTION_ENABLED) + enable_failure_prediction = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "process_performance_data")) { + if(modified_host_process_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) + process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "global_host_event_handler")) { + if(modified_host_process_attributes & MODATTR_EVENT_HANDLER_COMMAND) { + + /* make sure the check command still exists... */ + tempval = (char *)strdup(val); + temp_ptr = my_strtok(tempval, "!"); + temp_command = find_command(temp_ptr); + temp_ptr = (char *)strdup(val); + my_free(tempval); + + if(temp_command != NULL && temp_ptr != NULL) { + my_free(global_host_event_handler); + global_host_event_handler = temp_ptr; + } + } + } + else if(!strcmp(var, "global_service_event_handler")) { + if(modified_service_process_attributes & MODATTR_EVENT_HANDLER_COMMAND) { + + /* make sure the check command still exists... */ + tempval = (char *)strdup(val); + temp_ptr = my_strtok(tempval, "!"); + temp_command = find_command(temp_ptr); + temp_ptr = (char *)strdup(val); + my_free(tempval); + + if(temp_command != NULL && temp_ptr != NULL) { + my_free(global_service_event_handler); + global_service_event_handler = temp_ptr; + } + } + } + else if(!strcmp(var, "next_comment_id")) + next_comment_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_downtime_id")) + next_downtime_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_event_id")) + next_event_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_problem_id")) + next_problem_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_notification_id")) + next_notification_id = strtoul(val, NULL, 10); + } + break; + + case XRDDEFAULT_HOSTSTATUS_DATA: + + if(temp_host == NULL) { + if(!strcmp(var, "host_name")) { + host_name = (char *)strdup(val); + temp_host = find_host(host_name); + } + } + else { + if(!strcmp(var, "modified_attributes")) { + + temp_host->modified_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + temp_host->modified_attributes &= ~host_attribute_mask; + + /* break out */ + break; + } + if(temp_host->retain_status_information == TRUE) { + if(!strcmp(var, "has_been_checked")) + temp_host->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "check_execution_time")) + temp_host->execution_time = strtod(val, NULL); + else if(!strcmp(var, "check_latency")) + temp_host->latency = strtod(val, NULL); + else if(!strcmp(var, "check_type")) + temp_host->check_type = atoi(val); + else if(!strcmp(var, "current_state")) + temp_host->current_state = atoi(val); + else if(!strcmp(var, "last_state")) + temp_host->last_state = atoi(val); + else if(!strcmp(var, "last_hard_state")) + temp_host->last_hard_state = atoi(val); + else if(!strcmp(var, "plugin_output")) { + my_free(temp_host->plugin_output); + temp_host->plugin_output = (char *)strdup(val); + } + else if(!strcmp(var, "long_plugin_output")) { + my_free(temp_host->long_plugin_output); + temp_host->long_plugin_output = (char *)strdup(val); + } + else if(!strcmp(var, "performance_data")) { + my_free(temp_host->perf_data); + temp_host->perf_data = (char *)strdup(val); + } + else if(!strcmp(var, "last_check")) + temp_host->last_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_check")) { + if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) + temp_host->next_check = strtoul(val, NULL, 10); + } + else if(!strcmp(var, "check_options")) { + if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) + temp_host->check_options = atoi(val); + } + else if(!strcmp(var, "current_attempt")) + temp_host->current_attempt = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "current_event_id")) + temp_host->current_event_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_event_id")) + temp_host->last_event_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "current_problem_id")) + temp_host->current_problem_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_problem_id")) + temp_host->last_problem_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "state_type")) + temp_host->state_type = atoi(val); + else if(!strcmp(var, "last_state_change")) + temp_host->last_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_hard_state_change")) + temp_host->last_hard_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_up")) + temp_host->last_time_up = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_down")) + temp_host->last_time_down = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_unreachable")) + temp_host->last_time_unreachable = strtoul(val, NULL, 10); + else if(!strcmp(var, "notified_on_down")) + temp_host->notified_on_down = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "notified_on_unreachable")) + temp_host->notified_on_unreachable = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "last_notification")) + temp_host->last_host_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "current_notification_number")) + temp_host->current_notification_number = atoi(val); + else if(!strcmp(var, "current_notification_id")) + temp_host->current_notification_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "is_flapping")) + was_flapping = atoi(val); + else if(!strcmp(var, "percent_state_change")) + temp_host->percent_state_change = strtod(val, NULL); + else if(!strcmp(var, "check_flapping_recovery_notification")) + temp_host->check_flapping_recovery_notification = atoi(val); + else if(!strcmp(var, "state_history")) { + temp_ptr = val; + for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) { + if((ch = my_strsep(&temp_ptr, ",")) != NULL) + temp_host->state_history[x] = atoi(ch); + else + break; + } + temp_host->state_history_index = 0; + } + else + found_directive = FALSE; + } + if(temp_host->retain_nonstatus_information == TRUE) { + /* null-op speeds up logic */ + if(found_directive == TRUE); + + else if(!strcmp(var, "problem_has_been_acknowledged")) + temp_host->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "acknowledgement_type")) + temp_host->acknowledgement_type = atoi(val); + else if(!strcmp(var, "notifications_enabled")) { + if(temp_host->modified_attributes & MODATTR_NOTIFICATIONS_ENABLED) + temp_host->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "active_checks_enabled")) { + if(temp_host->modified_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) + temp_host->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "passive_checks_enabled")) { + if(temp_host->modified_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) + temp_host->accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "event_handler_enabled")) { + if(temp_host->modified_attributes & MODATTR_EVENT_HANDLER_ENABLED) + temp_host->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "flap_detection_enabled")) { + if(temp_host->modified_attributes & MODATTR_FLAP_DETECTION_ENABLED) + temp_host->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "failure_prediction_enabled")) { + if(temp_host->modified_attributes & MODATTR_FAILURE_PREDICTION_ENABLED) + temp_host->failure_prediction_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "process_performance_data")) { + if(temp_host->modified_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) + temp_host->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "obsess_over_host")) { + if(temp_host->modified_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) + temp_host->obsess_over_host = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "check_command")) { + if(temp_host->modified_attributes & MODATTR_CHECK_COMMAND) { + + /* make sure the check command still exists... */ + tempval = (char *)strdup(val); + temp_ptr = my_strtok(tempval, "!"); + temp_command = find_command(temp_ptr); + temp_ptr = (char *)strdup(val); + my_free(tempval); + + if(temp_command != NULL && temp_ptr != NULL) { + my_free(temp_host->host_check_command); + temp_host->host_check_command = temp_ptr; + } + else + temp_host->modified_attributes -= MODATTR_CHECK_COMMAND; + } + } + else if(!strcmp(var, "check_period")) { + if(temp_host->modified_attributes & MODATTR_CHECK_TIMEPERIOD) { + + /* make sure the timeperiod still exists... */ + temp_timeperiod = find_timeperiod(val); + temp_ptr = (char *)strdup(val); + + if(temp_timeperiod != NULL && temp_ptr != NULL) { + my_free(temp_host->check_period); + temp_host->check_period = temp_ptr; + } + else + temp_host->modified_attributes -= MODATTR_CHECK_TIMEPERIOD; + } + } + else if(!strcmp(var, "notification_period")) { + if(temp_host->modified_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { + + /* make sure the timeperiod still exists... */ + temp_timeperiod = find_timeperiod(val); + temp_ptr = (char *)strdup(val); + + if(temp_timeperiod != NULL && temp_ptr != NULL) { + my_free(temp_host->notification_period); + temp_host->notification_period = temp_ptr; + } + else + temp_host->modified_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; + } + } + else if(!strcmp(var, "event_handler")) { + if(temp_host->modified_attributes & MODATTR_EVENT_HANDLER_COMMAND) { + + /* make sure the check command still exists... */ + tempval = (char *)strdup(val); + temp_ptr = my_strtok(tempval, "!"); + temp_command = find_command(temp_ptr); + temp_ptr = (char *)strdup(val); + my_free(tempval); + + if(temp_command != NULL && temp_ptr != NULL) { + my_free(temp_host->event_handler); + temp_host->event_handler = temp_ptr; + } + else + temp_host->modified_attributes -= MODATTR_EVENT_HANDLER_COMMAND; + } + } + else if(!strcmp(var, "normal_check_interval")) { + if(temp_host->modified_attributes & MODATTR_NORMAL_CHECK_INTERVAL && strtod(val, NULL) >= 0) + temp_host->check_interval = strtod(val, NULL); + } + else if(!strcmp(var, "retry_check_interval")) { + if(temp_host->modified_attributes & MODATTR_RETRY_CHECK_INTERVAL && strtod(val, NULL) >= 0) + temp_host->retry_interval = strtod(val, NULL); + } + else if(!strcmp(var, "max_attempts")) { + if(temp_host->modified_attributes & MODATTR_MAX_CHECK_ATTEMPTS && atoi(val) >= 1) { + + temp_host->max_attempts = atoi(val); + + /* adjust current attempt number if in a hard state */ + if(temp_host->state_type == HARD_STATE && temp_host->current_state != HOST_UP && temp_host->current_attempt > 1) + temp_host->current_attempt = temp_host->max_attempts; + } + } + + /* custom variables */ + else if(var[0] == '_') { + + if(temp_host->modified_attributes & MODATTR_CUSTOM_VARIABLE) { + + /* get the variable name */ + if((customvarname = (char *)strdup(var + 1))) { + + for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(!strcmp(customvarname, temp_customvariablesmember->variable_name)) { + if((x = atoi(val)) > 0 && strlen(val) > 3) { + my_free(temp_customvariablesmember->variable_value); + temp_customvariablesmember->variable_value = (char *)strdup(val + 2); + temp_customvariablesmember->has_been_modified = (x > 0) ? TRUE : FALSE; + } + break; + } + } + + /* free memory */ + my_free(customvarname); + } + } + + } + } + + } + + break; + + case XRDDEFAULT_SERVICESTATUS_DATA: + + if(temp_service == NULL) { + if(!strcmp(var, "host_name")) { + host_name = (char *)strdup(val); + + /*temp_service=find_service(host_name,service_description);*/ + + /* break out */ + break; + } + else if(!strcmp(var, "service_description")) { + service_description = (char *)strdup(val); + temp_service = find_service(host_name, service_description); + + /* break out */ + break; + } + } + else { + if(!strcmp(var, "modified_attributes")) { + + temp_service->modified_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + temp_service->modified_attributes &= ~service_attribute_mask; + } + if(temp_service->retain_status_information == TRUE) { + if(!strcmp(var, "has_been_checked")) + temp_service->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "check_execution_time")) + temp_service->execution_time = strtod(val, NULL); + else if(!strcmp(var, "check_latency")) + temp_service->latency = strtod(val, NULL); + else if(!strcmp(var, "check_type")) + temp_service->check_type = atoi(val); + else if(!strcmp(var, "current_state")) + temp_service->current_state = atoi(val); + else if(!strcmp(var, "last_state")) + temp_service->last_state = atoi(val); + else if(!strcmp(var, "last_hard_state")) + temp_service->last_hard_state = atoi(val); + else if(!strcmp(var, "current_attempt")) + temp_service->current_attempt = atoi(val); + else if(!strcmp(var, "current_event_id")) + temp_service->current_event_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_event_id")) + temp_service->last_event_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "current_problem_id")) + temp_service->current_problem_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_problem_id")) + temp_service->last_problem_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "state_type")) + temp_service->state_type = atoi(val); + else if(!strcmp(var, "last_state_change")) + temp_service->last_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_hard_state_change")) + temp_service->last_hard_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_ok")) + temp_service->last_time_ok = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_warning")) + temp_service->last_time_warning = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_unknown")) + temp_service->last_time_unknown = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_critical")) + temp_service->last_time_critical = strtoul(val, NULL, 10); + else if(!strcmp(var, "plugin_output")) { + my_free(temp_service->plugin_output); + temp_service->plugin_output = (char *)strdup(val); + } + else if(!strcmp(var, "long_plugin_output")) { + my_free(temp_service->long_plugin_output); + temp_service->long_plugin_output = (char *)strdup(val); + } + else if(!strcmp(var, "performance_data")) { + my_free(temp_service->perf_data); + temp_service->perf_data = (char *)strdup(val); + } + else if(!strcmp(var, "last_check")) + temp_service->last_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_check")) { + if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) + temp_service->next_check = strtoul(val, NULL, 10); + } + else if(!strcmp(var, "check_options")) { + if(use_retained_scheduling_info == TRUE && scheduling_info_is_ok == TRUE) + temp_service->check_options = atoi(val); + } + else if(!strcmp(var, "notified_on_unknown")) + temp_service->notified_on_unknown = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "notified_on_warning")) + temp_service->notified_on_warning = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "notified_on_critical")) + temp_service->notified_on_critical = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "current_notification_number")) + temp_service->current_notification_number = atoi(val); + else if(!strcmp(var, "current_notification_id")) + temp_service->current_notification_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_notification")) + temp_service->last_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "is_flapping")) + was_flapping = atoi(val); + else if(!strcmp(var, "percent_state_change")) + temp_service->percent_state_change = strtod(val, NULL); + else if(!strcmp(var, "check_flapping_recovery_notification")) + temp_service->check_flapping_recovery_notification = atoi(val); + else if(!strcmp(var, "state_history")) { + temp_ptr = val; + for(x = 0; x < MAX_STATE_HISTORY_ENTRIES; x++) { + if((ch = my_strsep(&temp_ptr, ",")) != NULL) + temp_service->state_history[x] = atoi(ch); + else + break; + } + temp_service->state_history_index = 0; + } + else + found_directive = FALSE; + } + if(temp_service->retain_nonstatus_information == TRUE) { + /* null-op speeds up logic */ + if(found_directive == TRUE); + + else if(!strcmp(var, "problem_has_been_acknowledged")) + temp_service->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "acknowledgement_type")) + temp_service->acknowledgement_type = atoi(val); + else if(!strcmp(var, "notifications_enabled")) { + if(temp_service->modified_attributes & MODATTR_NOTIFICATIONS_ENABLED) + temp_service->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "active_checks_enabled")) { + if(temp_service->modified_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) + temp_service->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "passive_checks_enabled")) { + if(temp_service->modified_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) + temp_service->accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "event_handler_enabled")) { + if(temp_service->modified_attributes & MODATTR_EVENT_HANDLER_ENABLED) + temp_service->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "flap_detection_enabled")) { + if(temp_service->modified_attributes & MODATTR_FLAP_DETECTION_ENABLED) + temp_service->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "failure_prediction_enabled")) { + if(temp_service->modified_attributes & MODATTR_FAILURE_PREDICTION_ENABLED) + temp_service->failure_prediction_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "process_performance_data")) { + if(temp_service->modified_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) + temp_service->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "obsess_over_service")) { + if(temp_service->modified_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) + temp_service->obsess_over_service = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "check_command")) { + if(temp_service->modified_attributes & MODATTR_CHECK_COMMAND) { + + /* make sure the check command still exists... */ + tempval = (char *)strdup(val); + temp_ptr = my_strtok(tempval, "!"); + temp_command = find_command(temp_ptr); + temp_ptr = (char *)strdup(val); + my_free(tempval); + + if(temp_command != NULL && temp_ptr != NULL) { + my_free(temp_service->service_check_command); + temp_service->service_check_command = temp_ptr; + } + else + temp_service->modified_attributes -= MODATTR_CHECK_COMMAND; + } + } + else if(!strcmp(var, "check_period")) { + if(temp_service->modified_attributes & MODATTR_CHECK_TIMEPERIOD) { + + /* make sure the timeperiod still exists... */ + temp_timeperiod = find_timeperiod(val); + temp_ptr = (char *)strdup(val); + + if(temp_timeperiod != NULL && temp_ptr != NULL) { + my_free(temp_service->check_period); + temp_service->check_period = temp_ptr; + } + else + temp_service->modified_attributes -= MODATTR_CHECK_TIMEPERIOD; + } + } + else if(!strcmp(var, "notification_period")) { + if(temp_service->modified_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { + + /* make sure the timeperiod still exists... */ + temp_timeperiod = find_timeperiod(val); + temp_ptr = (char *)strdup(val); + + if(temp_timeperiod != NULL && temp_ptr != NULL) { + my_free(temp_service->notification_period); + temp_service->notification_period = temp_ptr; + } + else + temp_service->modified_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; + } + } + else if(!strcmp(var, "event_handler")) { + if(temp_service->modified_attributes & MODATTR_EVENT_HANDLER_COMMAND) { + + /* make sure the check command still exists... */ + tempval = (char *)strdup(val); + temp_ptr = my_strtok(tempval, "!"); + temp_command = find_command(temp_ptr); + temp_ptr = (char *)strdup(val); + my_free(tempval); + + if(temp_command != NULL && temp_ptr != NULL) { + my_free(temp_service->event_handler); + temp_service->event_handler = temp_ptr; + } + else + temp_service->modified_attributes -= MODATTR_EVENT_HANDLER_COMMAND; + } + } + else if(!strcmp(var, "normal_check_interval")) { + if(temp_service->modified_attributes & MODATTR_NORMAL_CHECK_INTERVAL && strtod(val, NULL) >= 0) + temp_service->check_interval = strtod(val, NULL); + } + else if(!strcmp(var, "retry_check_interval")) { + if(temp_service->modified_attributes & MODATTR_RETRY_CHECK_INTERVAL && strtod(val, NULL) >= 0) + temp_service->retry_interval = strtod(val, NULL); + } + else if(!strcmp(var, "max_attempts")) { + if(temp_service->modified_attributes & MODATTR_MAX_CHECK_ATTEMPTS && atoi(val) >= 1) { + + temp_service->max_attempts = atoi(val); + + /* adjust current attempt number if in a hard state */ + if(temp_service->state_type == HARD_STATE && temp_service->current_state != STATE_OK && temp_service->current_attempt > 1) + temp_service->current_attempt = temp_service->max_attempts; + } + } + + /* custom variables */ + else if(var[0] == '_') { + + if(temp_service->modified_attributes & MODATTR_CUSTOM_VARIABLE) { + + /* get the variable name */ + if((customvarname = (char *)strdup(var + 1))) { + + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(!strcmp(customvarname, temp_customvariablesmember->variable_name)) { + if((x = atoi(val)) > 0 && strlen(val) > 3) { + my_free(temp_customvariablesmember->variable_value); + temp_customvariablesmember->variable_value = (char *)strdup(val + 2); + temp_customvariablesmember->has_been_modified = (x > 0) ? TRUE : FALSE; + } + break; + } + } + + /* free memory */ + my_free(customvarname); + } + } + + } + } + } + + break; + + case XRDDEFAULT_CONTACTSTATUS_DATA: + if(temp_contact == NULL) { + if(!strcmp(var, "contact_name")) { + contact_name = (char *)strdup(val); + temp_contact = find_contact(contact_name); + } + } + else { + if(!strcmp(var, "modified_attributes")) { + + temp_contact->modified_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + temp_contact->modified_attributes &= ~contact_attribute_mask; + } + else if(!strcmp(var, "modified_host_attributes")) { + + temp_contact->modified_host_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + temp_contact->modified_host_attributes &= ~contact_host_attribute_mask; + } + else if(!strcmp(var, "modified_service_attributes")) { + temp_contact->modified_service_attributes = strtoul(val, NULL, 10); + + /* mask out attributes we don't want to retain */ + temp_contact->modified_service_attributes &= ~contact_service_attribute_mask; + } + else if(temp_contact->retain_status_information == TRUE) { + if(!strcmp(var, "last_host_notification")) + temp_contact->last_host_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_service_notification")) + temp_contact->last_service_notification = strtoul(val, NULL, 10); + else + found_directive = FALSE; + } + if(temp_contact->retain_nonstatus_information == TRUE) { + /* null-op speeds up logic */ + if(found_directive == TRUE); + + else if(!strcmp(var, "host_notification_period")) { + if(temp_contact->modified_host_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { + + /* make sure the timeperiod still exists... */ + temp_timeperiod = find_timeperiod(val); + temp_ptr = (char *)strdup(val); + + if(temp_timeperiod != NULL && temp_ptr != NULL) { + my_free(temp_contact->host_notification_period); + temp_contact->host_notification_period = temp_ptr; + } + else + temp_contact->modified_host_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; + } + } + else if(!strcmp(var, "service_notification_period")) { + if(temp_contact->modified_service_attributes & MODATTR_NOTIFICATION_TIMEPERIOD) { + + /* make sure the timeperiod still exists... */ + temp_timeperiod = find_timeperiod(val); + temp_ptr = (char *)strdup(val); + + if(temp_timeperiod != NULL && temp_ptr != NULL) { + my_free(temp_contact->service_notification_period); + temp_contact->service_notification_period = temp_ptr; + } + else + temp_contact->modified_service_attributes -= MODATTR_NOTIFICATION_TIMEPERIOD; + } + } + else if(!strcmp(var, "host_notifications_enabled")) { + if(temp_contact->modified_host_attributes & MODATTR_NOTIFICATIONS_ENABLED) + temp_contact->host_notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + else if(!strcmp(var, "service_notifications_enabled")) { + if(temp_contact->modified_service_attributes & MODATTR_NOTIFICATIONS_ENABLED) + temp_contact->service_notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; + } + /* custom variables */ + else if(var[0] == '_') { + + if(temp_contact->modified_attributes & MODATTR_CUSTOM_VARIABLE) { + + /* get the variable name */ + if((customvarname = (char *)strdup(var + 1))) { + + for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(!strcmp(customvarname, temp_customvariablesmember->variable_name)) { + if((x = atoi(val)) > 0 && strlen(val) > 3) { + my_free(temp_customvariablesmember->variable_value); + temp_customvariablesmember->variable_value = (char *)strdup(val + 2); + temp_customvariablesmember->has_been_modified = (x > 0) ? TRUE : FALSE; + } + break; + } + } + + /* free memory */ + my_free(customvarname); + } + } + } + } + } + break; + + case XRDDEFAULT_HOSTCOMMENT_DATA: + case XRDDEFAULT_SERVICECOMMENT_DATA: + if(!strcmp(var, "host_name")) + host_name = (char *)strdup(val); + else if(!strcmp(var, "service_description")) + service_description = (char *)strdup(val); + else if(!strcmp(var, "entry_type")) + entry_type = atoi(val); + else if(!strcmp(var, "comment_id")) + comment_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "source")) + source = atoi(val); + else if(!strcmp(var, "persistent")) + persistent = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "entry_time")) + entry_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "expires")) + expires = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "expire_time")) + expire_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "author")) + author = (char *)strdup(val); + else if(!strcmp(var, "comment_data")) + comment_data = (char *)strdup(val); + break; + + case XRDDEFAULT_HOSTDOWNTIME_DATA: + case XRDDEFAULT_SERVICEDOWNTIME_DATA: + if(!strcmp(var, "host_name")) + host_name = (char *)strdup(val); + else if(!strcmp(var, "service_description")) + service_description = (char *)strdup(val); + else if(!strcmp(var, "downtime_id")) + downtime_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "comment_id")) + comment_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "entry_time")) + entry_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "start_time")) + start_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "flex_downtime_start")) + flex_downtime_start = strtoul(val, NULL, 10); + else if(!strcmp(var, "end_time")) + end_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "fixed")) + fixed = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "triggered_by")) + triggered_by = strtoul(val, NULL, 10); + else if(!strcmp(var, "is_in_effect")) + is_in_effect = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "start_notification_sent")) + start_notification_sent = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "duration")) + duration = strtoul(val, NULL, 10); + else if(!strcmp(var, "author")) + author = (char *)strdup(val); + else if(!strcmp(var, "comment")) + comment_data = (char *)strdup(val); + break; + + default: + break; + } + } + } + + /* free memory and close the file */ + my_free(inputbuf); + mmap_fclose(thefile); + + if(sort_downtime() != OK) + return ERROR; + if(sort_comments() != OK) + return ERROR; + + if(test_scheduling == TRUE) + gettimeofday(&tv[1], NULL); + + if(test_scheduling == TRUE) { + runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + + runtime[1] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); + + printf("RETENTION DATA TIMES\n"); + printf("----------------------------------\n"); + printf("Read and Process: %.6lf sec\n", runtime[0]); + printf(" ============\n"); + printf("TOTAL: %.6lf sec\n", runtime[1]); + printf("\n\n"); + } + + return OK; + } diff --git a/xdata/xrddefault.h b/xdata/xrddefault.h new file mode 100644 index 0000000..c8fab4f --- /dev/null +++ b/xdata/xrddefault.h @@ -0,0 +1,47 @@ +/***************************************************************************** + * + * XRDDEFAULT.H - Header file for default state retention routines + * + * Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 03-01-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _XRDDEFAULT_H +#define _XRDDEFAULT_H + + +#define XRDDEFAULT_NO_DATA 0 +#define XRDDEFAULT_INFO_DATA 1 +#define XRDDEFAULT_PROGRAMSTATUS_DATA 2 +#define XRDDEFAULT_HOSTSTATUS_DATA 3 +#define XRDDEFAULT_SERVICESTATUS_DATA 4 +#define XRDDEFAULT_CONTACTSTATUS_DATA 5 +#define XRDDEFAULT_HOSTCOMMENT_DATA 6 +#define XRDDEFAULT_SERVICECOMMENT_DATA 7 +#define XRDDEFAULT_HOSTDOWNTIME_DATA 8 +#define XRDDEFAULT_SERVICEDOWNTIME_DATA 9 + +int xrddefault_initialize_retention_data(char *); +int xrddefault_cleanup_retention_data(char *); +int xrddefault_grab_config_info(char *); +int xrddefault_grab_config_directives(char *); +int xrddefault_save_state_information(void); /* saves all host and service state information */ +int xrddefault_read_state_information(void); /* reads in initial host and service state information */ + +#endif diff --git a/xdata/xsddefault.c b/xdata/xsddefault.c new file mode 100644 index 0000000..c8d0d20 --- /dev/null +++ b/xdata/xsddefault.c @@ -0,0 +1,1318 @@ +/***************************************************************************** + * + * XSDDEFAULT.C - Default external status data input routines for Nagios + * + * Copyright (c) 2009 Nagios Core Development Team and Community Contributors + * Copyright (c) 2000-2009 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 07-31-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/locations.h" +#include "../include/statusdata.h" +#include "../include/comments.h" +#include "../include/downtime.h" +#include "../include/macros.h" +#include "../include/skiplist.h" + +#ifdef NSCORE +#include "../include/nagios.h" +#endif + +#ifdef NSCGI +#include "../include/cgiutils.h" +#endif + + +/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ +#include "xsddefault.h" + + + +#ifdef NSCGI +time_t program_start; +int daemon_mode; +time_t last_command_check; +time_t last_log_rotation; +int enable_notifications; +int execute_service_checks; +int accept_passive_service_checks; +int execute_host_checks; +int accept_passive_host_checks; +int enable_event_handlers; +int obsess_over_services; +int obsess_over_hosts; +int check_service_freshness; +int check_host_freshness; +int enable_flap_detection; +int enable_failure_prediction; +int process_performance_data; +int nagios_pid; +int buffer_stats[1][3]; +int program_stats[MAX_CHECK_STATS_TYPES][3]; +#endif + +#ifdef NSCORE +extern time_t program_start; +extern int nagios_pid; +extern int daemon_mode; +extern time_t last_command_check; +extern time_t last_log_rotation; +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int enable_flap_detection; +extern int enable_failure_prediction; +extern int process_performance_data; +extern int aggregate_status_updates; +extern int check_external_commands; + +extern time_t last_update_check; +extern char *last_program_version; +extern int update_available; +extern char *last_program_version; +extern char *new_program_version; + +extern int external_command_buffer_slots; +extern circular_buffer external_command_buffer; + +extern host *host_list; +extern service *service_list; +extern contact *contact_list; +extern comment *comment_list; +extern scheduled_downtime *scheduled_downtime_list; + +extern skiplist *object_skiplists[NUM_OBJECT_SKIPLISTS]; + +extern unsigned long next_comment_id; +extern unsigned long next_downtime_id; +extern unsigned long next_event_id; +extern unsigned long next_problem_id; +extern unsigned long next_notification_id; + +extern unsigned long modified_host_process_attributes; +extern unsigned long modified_service_process_attributes; +extern char *global_host_event_handler; +extern char *global_service_event_handler; + +extern check_stats check_statistics[MAX_CHECK_STATS_TYPES]; +#endif + + +char *xsddefault_status_log = NULL; +char *xsddefault_temp_file = NULL; + + + +/******************************************************************/ +/***************** COMMON CONFIG INITIALIZATION ******************/ +/******************************************************************/ + +/* grab configuration information */ +int xsddefault_grab_config_info(char *config_file) { + char *input = NULL; + mmapfile *thefile; +#ifdef NSCGI + char *input2 = NULL; + mmapfile *thefile2; + char *temp_buffer; +#else + nagios_macros *mac; +#endif + + + /*** CORE PASSES IN MAIN CONFIG FILE, CGIS PASS IN CGI CONFIG FILE! ***/ + + /* open the config file for reading */ + if((thefile = mmap_fopen(config_file)) == NULL) + return ERROR; + + /* read in all lines from the main config file */ + while(1) { + + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets_multiline(thefile)) == NULL) + break; + + strip(input); + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == '\x0') + continue; + +#ifdef NSCGI + /* CGI needs to find and read contents of main config file, since it was passed the name of the CGI config file */ + if(strstr(input, "main_config_file") == input) { + + temp_buffer = strtok(input, "="); + temp_buffer = strtok(NULL, "\n"); + if(temp_buffer == NULL) + continue; + + if((thefile2 = mmap_fopen(temp_buffer)) == NULL) + continue; + + /* read in all lines from the main config file */ + while(1) { + + /* free memory */ + my_free(input2); + + /* read the next line */ + if((input2 = mmap_fgets_multiline(thefile2)) == NULL) + break; + + strip(input2); + + /* skip blank lines and comments */ + if(input2[0] == '#' || input2[0] == '\x0') + continue; + + xsddefault_grab_config_directives(input2); + } + + /* free memory and close the file */ + my_free(input2); + mmap_fclose(thefile2); + } +#endif + +#ifdef NSCORE + /* core reads variables directly from the main config file */ + xsddefault_grab_config_directives(input); +#endif + } + + /* free memory and close the file */ + my_free(input); + mmap_fclose(thefile); + + /* initialize locations if necessary */ + if(xsddefault_status_log == NULL) + xsddefault_status_log = (char *)strdup(DEFAULT_STATUS_FILE); + if(xsddefault_temp_file == NULL) + xsddefault_temp_file = (char *)strdup(DEFAULT_TEMP_FILE); + + /* make sure we have what we need */ + if(xsddefault_status_log == NULL) + return ERROR; + if(xsddefault_temp_file == NULL) + return ERROR; + +#ifdef NSCORE + mac = get_global_macros(); + /* save the status file macro */ + my_free(mac->x[MACRO_STATUSDATAFILE]); + if((mac->x[MACRO_STATUSDATAFILE] = (char *)strdup(xsddefault_status_log))) + strip(mac->x[MACRO_STATUSDATAFILE]); +#endif + + return OK; + } + + +/* processes a single directive */ +int xsddefault_grab_config_directives(char *input) { + char *temp_ptr = NULL; + char *varname = NULL; + char *varvalue = NULL; + + /* get the variable name */ + if((temp_ptr = my_strtok(input, "=")) == NULL) + return ERROR; + if((varname = (char *)strdup(temp_ptr)) == NULL) + return ERROR; + + /* get the variable value */ + if((temp_ptr = my_strtok(NULL, "\n")) == NULL) { + my_free(varname); + return ERROR; + } + if((varvalue = (char *)strdup(temp_ptr)) == NULL) { + my_free(varname); + return ERROR; + } + + /* status log definition */ + if(!strcmp(varname, "status_file") || !strcmp(varname, "xsddefault_status_log")) + xsddefault_status_log = (char *)strdup(temp_ptr); + + /* temp file definition */ + else if(!strcmp(varname, "temp_file")) + xsddefault_temp_file = (char *)strdup(temp_ptr); + + /* free memory */ + my_free(varname); + my_free(varvalue); + + return OK; + } + + + +#ifdef NSCORE + +/******************************************************************/ +/********************* INIT/CLEANUP FUNCTIONS *********************/ +/******************************************************************/ + + +/* initialize status data */ +int xsddefault_initialize_status_data(char *config_file) { + int result; + + /* grab configuration data */ + result = xsddefault_grab_config_info(config_file); + if(result == ERROR) + return ERROR; + + /* delete the old status log (it might not exist) */ + if(xsddefault_status_log) + unlink(xsddefault_status_log); + + return OK; + } + + +/* cleanup status data before terminating */ +int xsddefault_cleanup_status_data(char *config_file, int delete_status_data) { + + /* delete the status log */ + if(delete_status_data == TRUE && xsddefault_status_log) { + if(unlink(xsddefault_status_log)) + return ERROR; + } + + /* free memory */ + my_free(xsddefault_status_log); + my_free(xsddefault_temp_file); + + return OK; + } + + +/******************************************************************/ +/****************** STATUS DATA OUTPUT FUNCTIONS ******************/ +/******************************************************************/ + +/* write all status data to file */ +int xsddefault_save_status_data(void) { + char *temp_file = NULL; + customvariablesmember *temp_customvariablesmember = NULL; + host *temp_host = NULL; + service *temp_service = NULL; + contact *temp_contact = NULL; + comment *temp_comment = NULL; + scheduled_downtime *temp_downtime = NULL; + time_t current_time; + int fd = 0; + FILE *fp = NULL; + int used_external_command_buffer_slots = 0; + int high_external_command_buffer_slots = 0; + int result = OK; + + log_debug_info(DEBUGL_FUNCTIONS, 0, "save_status_data()\n"); + + /* open a safe temp file for output */ + if(xsddefault_temp_file == NULL) + return ERROR; + asprintf(&temp_file, "%sXXXXXX", xsddefault_temp_file); + if(temp_file == NULL) + return ERROR; + + log_debug_info(DEBUGL_STATUSDATA, 2, "Writing status data to temp file '%s'\n", temp_file); + + if((fd = mkstemp(temp_file)) == -1) { + + /* log an error */ + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to create temp file for writing status data: %s\n", strerror(errno)); + + /* free memory */ + my_free(temp_file); + + return ERROR; + } + fp = (FILE *)fdopen(fd, "w"); + if(fp == NULL) { + + close(fd); + unlink(temp_file); + + /* log an error */ + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to open temp file '%s' for writing status data: %s\n", temp_file, strerror(errno)); + + /* free memory */ + my_free(temp_file); + + return ERROR; + } + + /* get number of items in the command buffer */ + if(check_external_commands == TRUE) { + pthread_mutex_lock(&external_command_buffer.buffer_lock); + used_external_command_buffer_slots = external_command_buffer.items; + high_external_command_buffer_slots = external_command_buffer.high; + pthread_mutex_unlock(&external_command_buffer.buffer_lock); + } + else { + used_external_command_buffer_slots = 0; + high_external_command_buffer_slots = 0; + } + + /* generate check statistics */ + generate_check_stats(); + + /* write version info to status file */ + fprintf(fp, "########################################\n"); + fprintf(fp, "# NAGIOS STATUS FILE\n"); + fprintf(fp, "#\n"); + fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n"); + fprintf(fp, "# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); + fprintf(fp, "########################################\n\n"); + + time(¤t_time); + + /* write file info */ + fprintf(fp, "info {\n"); + fprintf(fp, "\tcreated=%lu\n", current_time); + fprintf(fp, "\tversion=%s\n", PROGRAM_VERSION); + fprintf(fp, "\tlast_update_check=%lu\n", last_update_check); + fprintf(fp, "\tupdate_available=%d\n", update_available); + fprintf(fp, "\tlast_version=%s\n", (last_program_version == NULL) ? "" : last_program_version); + fprintf(fp, "\tnew_version=%s\n", (new_program_version == NULL) ? "" : new_program_version); + fprintf(fp, "\t}\n\n"); + + /* save program status data */ + fprintf(fp, "programstatus {\n"); + fprintf(fp, "\tmodified_host_attributes=%lu\n", modified_host_process_attributes); + fprintf(fp, "\tmodified_service_attributes=%lu\n", modified_service_process_attributes); + fprintf(fp, "\tnagios_pid=%d\n", nagios_pid); + fprintf(fp, "\tdaemon_mode=%d\n", daemon_mode); + fprintf(fp, "\tprogram_start=%lu\n", program_start); + fprintf(fp, "\tlast_command_check=%lu\n", last_command_check); + fprintf(fp, "\tlast_log_rotation=%lu\n", last_log_rotation); + fprintf(fp, "\tenable_notifications=%d\n", enable_notifications); + fprintf(fp, "\tactive_service_checks_enabled=%d\n", execute_service_checks); + fprintf(fp, "\tpassive_service_checks_enabled=%d\n", accept_passive_service_checks); + fprintf(fp, "\tactive_host_checks_enabled=%d\n", execute_host_checks); + fprintf(fp, "\tpassive_host_checks_enabled=%d\n", accept_passive_host_checks); + fprintf(fp, "\tenable_event_handlers=%d\n", enable_event_handlers); + fprintf(fp, "\tobsess_over_services=%d\n", obsess_over_services); + fprintf(fp, "\tobsess_over_hosts=%d\n", obsess_over_hosts); + fprintf(fp, "\tcheck_service_freshness=%d\n", check_service_freshness); + fprintf(fp, "\tcheck_host_freshness=%d\n", check_host_freshness); + fprintf(fp, "\tenable_flap_detection=%d\n", enable_flap_detection); + fprintf(fp, "\tenable_failure_prediction=%d\n", enable_failure_prediction); + fprintf(fp, "\tprocess_performance_data=%d\n", process_performance_data); + fprintf(fp, "\tglobal_host_event_handler=%s\n", (global_host_event_handler == NULL) ? "" : global_host_event_handler); + fprintf(fp, "\tglobal_service_event_handler=%s\n", (global_service_event_handler == NULL) ? "" : global_service_event_handler); + fprintf(fp, "\tnext_comment_id=%lu\n", next_comment_id); + fprintf(fp, "\tnext_downtime_id=%lu\n", next_downtime_id); + fprintf(fp, "\tnext_event_id=%lu\n", next_event_id); + fprintf(fp, "\tnext_problem_id=%lu\n", next_problem_id); + fprintf(fp, "\tnext_notification_id=%lu\n", next_notification_id); + fprintf(fp, "\ttotal_external_command_buffer_slots=%d\n", external_command_buffer_slots); + fprintf(fp, "\tused_external_command_buffer_slots=%d\n", used_external_command_buffer_slots); + fprintf(fp, "\thigh_external_command_buffer_slots=%d\n", high_external_command_buffer_slots); + fprintf(fp, "\tactive_scheduled_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tactive_ondemand_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tpassive_host_check_stats=%d,%d,%d\n", check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[0], check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[1], check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tactive_scheduled_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tactive_ondemand_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tpassive_service_check_stats=%d,%d,%d\n", check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tcached_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tcached_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\texternal_command_stats=%d,%d,%d\n", check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[0], check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[1], check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[2]); + + fprintf(fp, "\tparallel_host_check_stats=%d,%d,%d\n", check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[0], check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[1], check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\tserial_host_check_stats=%d,%d,%d\n", check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[0], check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[1], check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[2]); + fprintf(fp, "\t}\n\n"); + + + /* save host status data */ + for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { + + fprintf(fp, "hoststatus {\n"); + fprintf(fp, "\thost_name=%s\n", temp_host->name); + + fprintf(fp, "\tmodified_attributes=%lu\n", temp_host->modified_attributes); + fprintf(fp, "\tcheck_command=%s\n", (temp_host->host_check_command == NULL) ? "" : temp_host->host_check_command); + fprintf(fp, "\tcheck_period=%s\n", (temp_host->check_period == NULL) ? "" : temp_host->check_period); + fprintf(fp, "\tnotification_period=%s\n", (temp_host->notification_period == NULL) ? "" : temp_host->notification_period); + fprintf(fp, "\tcheck_interval=%f\n", temp_host->check_interval); + fprintf(fp, "\tretry_interval=%f\n", temp_host->retry_interval); + fprintf(fp, "\tevent_handler=%s\n", (temp_host->event_handler == NULL) ? "" : temp_host->event_handler); + + fprintf(fp, "\thas_been_checked=%d\n", temp_host->has_been_checked); + fprintf(fp, "\tshould_be_scheduled=%d\n", temp_host->should_be_scheduled); + fprintf(fp, "\tcheck_execution_time=%.3f\n", temp_host->execution_time); + fprintf(fp, "\tcheck_latency=%.3f\n", temp_host->latency); + fprintf(fp, "\tcheck_type=%d\n", temp_host->check_type); + fprintf(fp, "\tcurrent_state=%d\n", temp_host->current_state); + fprintf(fp, "\tlast_hard_state=%d\n", temp_host->last_hard_state); + fprintf(fp, "\tlast_event_id=%lu\n", temp_host->last_event_id); + fprintf(fp, "\tcurrent_event_id=%lu\n", temp_host->current_event_id); + fprintf(fp, "\tcurrent_problem_id=%lu\n", temp_host->current_problem_id); + fprintf(fp, "\tlast_problem_id=%lu\n", temp_host->last_problem_id); + fprintf(fp, "\tplugin_output=%s\n", (temp_host->plugin_output == NULL) ? "" : temp_host->plugin_output); + fprintf(fp, "\tlong_plugin_output=%s\n", (temp_host->long_plugin_output == NULL) ? "" : temp_host->long_plugin_output); + fprintf(fp, "\tperformance_data=%s\n", (temp_host->perf_data == NULL) ? "" : temp_host->perf_data); + fprintf(fp, "\tlast_check=%lu\n", temp_host->last_check); + fprintf(fp, "\tnext_check=%lu\n", temp_host->next_check); + fprintf(fp, "\tcheck_options=%d\n", temp_host->check_options); + fprintf(fp, "\tcurrent_attempt=%d\n", temp_host->current_attempt); + fprintf(fp, "\tmax_attempts=%d\n", temp_host->max_attempts); + fprintf(fp, "\tstate_type=%d\n", temp_host->state_type); + fprintf(fp, "\tlast_state_change=%lu\n", temp_host->last_state_change); + fprintf(fp, "\tlast_hard_state_change=%lu\n", temp_host->last_hard_state_change); + fprintf(fp, "\tlast_time_up=%lu\n", temp_host->last_time_up); + fprintf(fp, "\tlast_time_down=%lu\n", temp_host->last_time_down); + fprintf(fp, "\tlast_time_unreachable=%lu\n", temp_host->last_time_unreachable); + fprintf(fp, "\tlast_notification=%lu\n", temp_host->last_host_notification); + fprintf(fp, "\tnext_notification=%lu\n", temp_host->next_host_notification); + fprintf(fp, "\tno_more_notifications=%d\n", temp_host->no_more_notifications); + fprintf(fp, "\tcurrent_notification_number=%d\n", temp_host->current_notification_number); + fprintf(fp, "\tcurrent_notification_id=%lu\n", temp_host->current_notification_id); + fprintf(fp, "\tnotifications_enabled=%d\n", temp_host->notifications_enabled); + fprintf(fp, "\tproblem_has_been_acknowledged=%d\n", temp_host->problem_has_been_acknowledged); + fprintf(fp, "\tacknowledgement_type=%d\n", temp_host->acknowledgement_type); + fprintf(fp, "\tactive_checks_enabled=%d\n", temp_host->checks_enabled); + fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_host->accept_passive_host_checks); + fprintf(fp, "\tevent_handler_enabled=%d\n", temp_host->event_handler_enabled); + fprintf(fp, "\tflap_detection_enabled=%d\n", temp_host->flap_detection_enabled); + fprintf(fp, "\tfailure_prediction_enabled=%d\n", temp_host->failure_prediction_enabled); + fprintf(fp, "\tprocess_performance_data=%d\n", temp_host->process_performance_data); + fprintf(fp, "\tobsess_over_host=%d\n", temp_host->obsess_over_host); + fprintf(fp, "\tlast_update=%lu\n", current_time); + fprintf(fp, "\tis_flapping=%d\n", temp_host->is_flapping); + fprintf(fp, "\tpercent_state_change=%.2f\n", temp_host->percent_state_change); + fprintf(fp, "\tscheduled_downtime_depth=%d\n", temp_host->scheduled_downtime_depth); + /* + fprintf(fp,"\tstate_history="); + for(x=0;x0)?",":"",temp_host->state_history[(x+temp_host->state_history_index)%MAX_STATE_HISTORY_ENTRIES]); + fprintf(fp,"\n"); + */ + /* custom variables */ + for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); + } + fprintf(fp, "\t}\n\n"); + } + + /* save service status data */ + for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { + + fprintf(fp, "servicestatus {\n"); + fprintf(fp, "\thost_name=%s\n", temp_service->host_name); + + fprintf(fp, "\tservice_description=%s\n", temp_service->description); + fprintf(fp, "\tmodified_attributes=%lu\n", temp_service->modified_attributes); + fprintf(fp, "\tcheck_command=%s\n", (temp_service->service_check_command == NULL) ? "" : temp_service->service_check_command); + fprintf(fp, "\tcheck_period=%s\n", (temp_service->check_period == NULL) ? "" : temp_service->check_period); + fprintf(fp, "\tnotification_period=%s\n", (temp_service->notification_period == NULL) ? "" : temp_service->notification_period); + fprintf(fp, "\tcheck_interval=%f\n", temp_service->check_interval); + fprintf(fp, "\tretry_interval=%f\n", temp_service->retry_interval); + fprintf(fp, "\tevent_handler=%s\n", (temp_service->event_handler == NULL) ? "" : temp_service->event_handler); + + fprintf(fp, "\thas_been_checked=%d\n", temp_service->has_been_checked); + fprintf(fp, "\tshould_be_scheduled=%d\n", temp_service->should_be_scheduled); + fprintf(fp, "\tcheck_execution_time=%.3f\n", temp_service->execution_time); + fprintf(fp, "\tcheck_latency=%.3f\n", temp_service->latency); + fprintf(fp, "\tcheck_type=%d\n", temp_service->check_type); + fprintf(fp, "\tcurrent_state=%d\n", temp_service->current_state); + fprintf(fp, "\tlast_hard_state=%d\n", temp_service->last_hard_state); + fprintf(fp, "\tlast_event_id=%lu\n", temp_service->last_event_id); + fprintf(fp, "\tcurrent_event_id=%lu\n", temp_service->current_event_id); + fprintf(fp, "\tcurrent_problem_id=%lu\n", temp_service->current_problem_id); + fprintf(fp, "\tlast_problem_id=%lu\n", temp_service->last_problem_id); + fprintf(fp, "\tcurrent_attempt=%d\n", temp_service->current_attempt); + fprintf(fp, "\tmax_attempts=%d\n", temp_service->max_attempts); + fprintf(fp, "\tstate_type=%d\n", temp_service->state_type); + fprintf(fp, "\tlast_state_change=%lu\n", temp_service->last_state_change); + fprintf(fp, "\tlast_hard_state_change=%lu\n", temp_service->last_hard_state_change); + fprintf(fp, "\tlast_time_ok=%lu\n", temp_service->last_time_ok); + fprintf(fp, "\tlast_time_warning=%lu\n", temp_service->last_time_warning); + fprintf(fp, "\tlast_time_unknown=%lu\n", temp_service->last_time_unknown); + fprintf(fp, "\tlast_time_critical=%lu\n", temp_service->last_time_critical); + fprintf(fp, "\tplugin_output=%s\n", (temp_service->plugin_output == NULL) ? "" : temp_service->plugin_output); + fprintf(fp, "\tlong_plugin_output=%s\n", (temp_service->long_plugin_output == NULL) ? "" : temp_service->long_plugin_output); + fprintf(fp, "\tperformance_data=%s\n", (temp_service->perf_data == NULL) ? "" : temp_service->perf_data); + fprintf(fp, "\tlast_check=%lu\n", temp_service->last_check); + fprintf(fp, "\tnext_check=%lu\n", temp_service->next_check); + fprintf(fp, "\tcheck_options=%d\n", temp_service->check_options); + fprintf(fp, "\tcurrent_notification_number=%d\n", temp_service->current_notification_number); + fprintf(fp, "\tcurrent_notification_id=%lu\n", temp_service->current_notification_id); + fprintf(fp, "\tlast_notification=%lu\n", temp_service->last_notification); + fprintf(fp, "\tnext_notification=%lu\n", temp_service->next_notification); + fprintf(fp, "\tno_more_notifications=%d\n", temp_service->no_more_notifications); + fprintf(fp, "\tnotifications_enabled=%d\n", temp_service->notifications_enabled); + fprintf(fp, "\tactive_checks_enabled=%d\n", temp_service->checks_enabled); + fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_service->accept_passive_service_checks); + fprintf(fp, "\tevent_handler_enabled=%d\n", temp_service->event_handler_enabled); + fprintf(fp, "\tproblem_has_been_acknowledged=%d\n", temp_service->problem_has_been_acknowledged); + fprintf(fp, "\tacknowledgement_type=%d\n", temp_service->acknowledgement_type); + fprintf(fp, "\tflap_detection_enabled=%d\n", temp_service->flap_detection_enabled); + fprintf(fp, "\tfailure_prediction_enabled=%d\n", temp_service->failure_prediction_enabled); + fprintf(fp, "\tprocess_performance_data=%d\n", temp_service->process_performance_data); + fprintf(fp, "\tobsess_over_service=%d\n", temp_service->obsess_over_service); + fprintf(fp, "\tlast_update=%lu\n", current_time); + fprintf(fp, "\tis_flapping=%d\n", temp_service->is_flapping); + fprintf(fp, "\tpercent_state_change=%.2f\n", temp_service->percent_state_change); + fprintf(fp, "\tscheduled_downtime_depth=%d\n", temp_service->scheduled_downtime_depth); + /* + fprintf(fp,"\tstate_history="); + for(x=0;x0)?",":"",temp_service->state_history[(x+temp_service->state_history_index)%MAX_STATE_HISTORY_ENTRIES]); + fprintf(fp,"\n"); + */ + /* custom variables */ + for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); + } + fprintf(fp, "\t}\n\n"); + } + + /* save contact status data */ + for(temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { + + fprintf(fp, "contactstatus {\n"); + fprintf(fp, "\tcontact_name=%s\n", temp_contact->name); + + fprintf(fp, "\tmodified_attributes=%lu\n", temp_contact->modified_attributes); + fprintf(fp, "\tmodified_host_attributes=%lu\n", temp_contact->modified_host_attributes); + fprintf(fp, "\tmodified_service_attributes=%lu\n", temp_contact->modified_service_attributes); + fprintf(fp, "\thost_notification_period=%s\n", (temp_contact->host_notification_period == NULL) ? "" : temp_contact->host_notification_period); + fprintf(fp, "\tservice_notification_period=%s\n", (temp_contact->service_notification_period == NULL) ? "" : temp_contact->service_notification_period); + + fprintf(fp, "\tlast_host_notification=%lu\n", temp_contact->last_host_notification); + fprintf(fp, "\tlast_service_notification=%lu\n", temp_contact->last_service_notification); + fprintf(fp, "\thost_notifications_enabled=%d\n", temp_contact->host_notifications_enabled); + fprintf(fp, "\tservice_notifications_enabled=%d\n", temp_contact->service_notifications_enabled); + /* custom variables */ + for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { + if(temp_customvariablesmember->variable_name) + fprintf(fp, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); + } + fprintf(fp, "\t}\n\n"); + } + + /* save all comments */ + for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) { + + if(temp_comment->comment_type == HOST_COMMENT) + fprintf(fp, "hostcomment {\n"); + else + fprintf(fp, "servicecomment {\n"); + fprintf(fp, "\thost_name=%s\n", temp_comment->host_name); + if(temp_comment->comment_type == SERVICE_COMMENT) + fprintf(fp, "\tservice_description=%s\n", temp_comment->service_description); + fprintf(fp, "\tentry_type=%d\n", temp_comment->entry_type); + fprintf(fp, "\tcomment_id=%lu\n", temp_comment->comment_id); + fprintf(fp, "\tsource=%d\n", temp_comment->source); + fprintf(fp, "\tpersistent=%d\n", temp_comment->persistent); + fprintf(fp, "\tentry_time=%lu\n", temp_comment->entry_time); + fprintf(fp, "\texpires=%d\n", temp_comment->expires); + fprintf(fp, "\texpire_time=%lu\n", temp_comment->expire_time); + fprintf(fp, "\tauthor=%s\n", temp_comment->author); + fprintf(fp, "\tcomment_data=%s\n", temp_comment->comment_data); + fprintf(fp, "\t}\n\n"); + } + + /* save all downtime */ + for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { + + if(temp_downtime->type == HOST_DOWNTIME) + fprintf(fp, "hostdowntime {\n"); + else + fprintf(fp, "servicedowntime {\n"); + fprintf(fp, "\thost_name=%s\n", temp_downtime->host_name); + if(temp_downtime->type == SERVICE_DOWNTIME) + fprintf(fp, "\tservice_description=%s\n", temp_downtime->service_description); + fprintf(fp, "\tdowntime_id=%lu\n", temp_downtime->downtime_id); + fprintf(fp, "\tcomment_id=%lu\n", temp_downtime->comment_id); + fprintf(fp, "\tentry_time=%lu\n", temp_downtime->entry_time); + fprintf(fp, "\tstart_time=%lu\n", temp_downtime->start_time); + fprintf(fp, "\tflex_downtime_start=%lu\n", temp_downtime->flex_downtime_start); + fprintf(fp, "\tend_time=%lu\n", temp_downtime->end_time); + fprintf(fp, "\ttriggered_by=%lu\n", temp_downtime->triggered_by); + fprintf(fp, "\tfixed=%d\n", temp_downtime->fixed); + fprintf(fp, "\tduration=%lu\n", temp_downtime->duration); + fprintf(fp, "\tis_in_effect=%d\n", temp_downtime->is_in_effect); + fprintf(fp, "\tstart_notification_sent=%d\n", temp_downtime->start_notification_sent); + fprintf(fp, "\tauthor=%s\n", temp_downtime->author); + fprintf(fp, "\tcomment=%s\n", temp_downtime->comment); + fprintf(fp, "\t}\n\n"); + } + + + /* reset file permissions */ + fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + + /* flush the file to disk */ + fflush(fp); + + /* close the temp file */ + result = fclose(fp); + + /* fsync the file so that it is completely written out before moving it */ + fsync(fd); + + /* save/close was successful */ + if(result == 0) { + + result = OK; + + /* move the temp file to the status log (overwrite the old status log) */ + if(my_rename(temp_file, xsddefault_status_log)) { + unlink(temp_file); + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to update status data file '%s': %s", xsddefault_status_log, strerror(errno)); + result = ERROR; + } + } + + /* a problem occurred saving the file */ + else { + + result = ERROR; + + /* remove temp file and log an error */ + unlink(temp_file); + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to save status file: %s", strerror(errno)); + } + + /* free memory */ + my_free(temp_file); + + return result; + } + +#endif + + + +#ifdef NSCGI + +/******************************************************************/ +/****************** DEFAULT DATA INPUT FUNCTIONS ******************/ +/******************************************************************/ + +/* read all program, host, and service status information */ +int xsddefault_read_status_data(char *config_file, int options) { +#ifdef NO_MMAP + char input[MAX_PLUGIN_OUTPUT_LENGTH] = ""; + FILE *fp = NULL; +#else + char *input = NULL; + mmapfile *thefile = NULL; +#endif + int data_type = XSDDEFAULT_NO_DATA; + hoststatus *temp_hoststatus = NULL; + servicestatus *temp_servicestatus = NULL; + char *var = NULL; + char *val = NULL; + char *ptr = NULL; + int result = 0; + /* comment and downtime vars */ + unsigned long comment_id = 0; + int persistent = FALSE; + int expires = FALSE; + time_t expire_time = 0L; + int entry_type = USER_COMMENT; + int source = COMMENTSOURCE_INTERNAL; + time_t entry_time = 0L; + char *host_name = NULL; + char *service_description = NULL; + char *author = NULL; + char *comment_data = NULL; + unsigned long downtime_id = 0; + time_t start_time = 0L; + time_t flex_downtime_start = 0L; + time_t end_time = 0L; + int fixed = FALSE; + unsigned long triggered_by = 0; + unsigned long duration = 0L; + int x = 0; + int is_in_effect = FALSE; + int start_notification_sent = FALSE; + + + /* initialize some vars */ + for(x = 0; x < MAX_CHECK_STATS_TYPES; x++) { + program_stats[x][0] = 0; + program_stats[x][1] = 0; + program_stats[x][2] = 0; + } + + /* grab configuration data */ + result = xsddefault_grab_config_info(config_file); + if(result == ERROR) + return ERROR; + + /* open the status file for reading */ +#ifdef NO_MMAP + if((fp = fopen(xsddefault_status_log, "r")) == NULL) + return ERROR; +#else + if((thefile = mmap_fopen(xsddefault_status_log)) == NULL) + return ERROR; +#endif + + /* Big speedup when reading status.dat in bulk */ + defer_downtime_sorting = 1; + defer_comment_sorting = 1; + + /* read all lines in the status file */ + while(1) { + +#ifdef NO_MMAP + strcpy(input, ""); + if(fgets(input, sizeof(input), fp) == NULL) + break; +#else + /* free memory */ + my_free(input); + + /* read the next line */ + if((input = mmap_fgets(thefile)) == NULL) + break; +#endif + + strip(input); + + /* skip blank lines and comments */ + if(input[0] == '#' || input[0] == '\x0') + continue; + + else if(!strcmp(input, "info {")) + data_type = XSDDEFAULT_INFO_DATA; + else if(!strcmp(input, "programstatus {")) + data_type = XSDDEFAULT_PROGRAMSTATUS_DATA; + else if(!strcmp(input, "hoststatus {")) { + data_type = XSDDEFAULT_HOSTSTATUS_DATA; + temp_hoststatus = (hoststatus *)calloc(1, sizeof(hoststatus)); + } + else if(!strcmp(input, "servicestatus {")) { + data_type = XSDDEFAULT_SERVICESTATUS_DATA; + temp_servicestatus = (servicestatus *)calloc(1, sizeof(servicestatus)); + } + else if(!strcmp(input, "contactstatus {")) { + data_type = XSDDEFAULT_CONTACTSTATUS_DATA; + /* unimplemented */ + } + else if(!strcmp(input, "hostcomment {")) + data_type = XSDDEFAULT_HOSTCOMMENT_DATA; + else if(!strcmp(input, "servicecomment {")) + data_type = XSDDEFAULT_SERVICECOMMENT_DATA; + else if(!strcmp(input, "hostdowntime {")) + data_type = XSDDEFAULT_HOSTDOWNTIME_DATA; + else if(!strcmp(input, "servicedowntime {")) + data_type = XSDDEFAULT_SERVICEDOWNTIME_DATA; + + else if(!strcmp(input, "}")) { + + switch(data_type) { + + case XSDDEFAULT_INFO_DATA: + break; + + case XSDDEFAULT_PROGRAMSTATUS_DATA: + break; + + case XSDDEFAULT_HOSTSTATUS_DATA: + add_host_status(temp_hoststatus); + temp_hoststatus = NULL; + break; + + case XSDDEFAULT_SERVICESTATUS_DATA: + add_service_status(temp_servicestatus); + temp_servicestatus = NULL; + break; + + case XSDDEFAULT_CONTACTSTATUS_DATA: + /* unimplemented */ + break; + + case XSDDEFAULT_HOSTCOMMENT_DATA: + case XSDDEFAULT_SERVICECOMMENT_DATA: + + /* add the comment */ + add_comment((data_type == XSDDEFAULT_HOSTCOMMENT_DATA) ? HOST_COMMENT : SERVICE_COMMENT, entry_type, host_name, service_description, entry_time, author, comment_data, comment_id, persistent, expires, expire_time, source); + + /* free temp memory */ + my_free(host_name); + my_free(service_description); + my_free(author); + my_free(comment_data); + + /* reset defaults */ + entry_type = USER_COMMENT; + comment_id = 0; + source = COMMENTSOURCE_INTERNAL; + persistent = FALSE; + entry_time = 0L; + expires = FALSE; + expire_time = 0L; + + break; + + case XSDDEFAULT_HOSTDOWNTIME_DATA: + case XSDDEFAULT_SERVICEDOWNTIME_DATA: + + /* add the downtime */ + if(data_type == XSDDEFAULT_HOSTDOWNTIME_DATA) + add_host_downtime(host_name, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + else + add_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, flex_downtime_start, end_time, fixed, triggered_by, duration, downtime_id, is_in_effect, start_notification_sent); + + /* free temp memory */ + my_free(host_name); + my_free(service_description); + my_free(author); + my_free(comment_data); + + /* reset defaults */ + downtime_id = 0; + entry_time = 0L; + start_time = 0L; + end_time = 0L; + fixed = FALSE; + triggered_by = 0; + duration = 0L; + is_in_effect = FALSE; + start_notification_sent = FALSE; + + break; + + default: + break; + } + + data_type = XSDDEFAULT_NO_DATA; + } + + else if(data_type != XSDDEFAULT_NO_DATA) { + + var = strtok(input, "="); + val = strtok(NULL, "\n"); + if(val == NULL) + continue; + + switch(data_type) { + + case XSDDEFAULT_INFO_DATA: + break; + + case XSDDEFAULT_PROGRAMSTATUS_DATA: + /* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */ + if(!strcmp(var, "nagios_pid")) + nagios_pid = atoi(val); + else if(!strcmp(var, "daemon_mode")) + daemon_mode = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "program_start")) + program_start = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_command_check")) + last_command_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_log_rotation")) + last_log_rotation = strtoul(val, NULL, 10); + else if(!strcmp(var, "enable_notifications")) + enable_notifications = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "active_service_checks_enabled")) + execute_service_checks = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "passive_service_checks_enabled")) + accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "active_host_checks_enabled")) + execute_host_checks = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "passive_host_checks_enabled")) + accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "enable_event_handlers")) + enable_event_handlers = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "obsess_over_services")) + obsess_over_services = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "obsess_over_hosts")) + obsess_over_hosts = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "check_service_freshness")) + check_service_freshness = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "check_host_freshness")) + check_host_freshness = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "enable_flap_detection")) + enable_flap_detection = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "enable_failure_prediction")) + enable_failure_prediction = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "process_performance_data")) + process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; + + else if(!strcmp(var, "total_external_command_buffer_slots")) + buffer_stats[0][0] = atoi(val); + else if(!strcmp(var, "used_external_command_buffer_slots")) + buffer_stats[0][1] = atoi(val); + else if(!strcmp(var, "high_external_command_buffer_slots")) + buffer_stats[0][2] = atoi(val); + + + else if(strstr(var, "_stats")) { + + x = -1; + if(!strcmp(var, "active_scheduled_host_check_stats")) + x = ACTIVE_SCHEDULED_HOST_CHECK_STATS; + if(!strcmp(var, "active_ondemand_host_check_stats")) + x = ACTIVE_ONDEMAND_HOST_CHECK_STATS; + if(!strcmp(var, "passive_host_check_stats")) + x = PASSIVE_HOST_CHECK_STATS; + if(!strcmp(var, "active_scheduled_service_check_stats")) + x = ACTIVE_SCHEDULED_SERVICE_CHECK_STATS; + if(!strcmp(var, "active_ondemand_service_check_stats")) + x = ACTIVE_ONDEMAND_SERVICE_CHECK_STATS; + if(!strcmp(var, "passive_service_check_stats")) + x = PASSIVE_SERVICE_CHECK_STATS; + if(!strcmp(var, "cached_host_check_stats")) + x = ACTIVE_CACHED_HOST_CHECK_STATS; + if(!strcmp(var, "cached_service_check_stats")) + x = ACTIVE_CACHED_SERVICE_CHECK_STATS; + if(!strcmp(var, "external_command_stats")) + x = EXTERNAL_COMMAND_STATS; + if(!strcmp(var, "parallel_host_check_stats")) + x = PARALLEL_HOST_CHECK_STATS; + if(!strcmp(var, "serial_host_check_stats")) + x = SERIAL_HOST_CHECK_STATS; + + if(x >= 0) { + if((ptr = strtok(val, ","))) { + program_stats[x][0] = atoi(ptr); + if((ptr = strtok(NULL, ","))) { + program_stats[x][1] = atoi(ptr); + if((ptr = strtok(NULL, "\n"))) + program_stats[x][2] = atoi(ptr); + } + } + } + } + break; + + case XSDDEFAULT_HOSTSTATUS_DATA: + /* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */ + if(temp_hoststatus != NULL) { + if(!strcmp(var, "host_name")) + temp_hoststatus->host_name = (char *)strdup(val); + else if(!strcmp(var, "has_been_checked")) + temp_hoststatus->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "should_be_scheduled")) + temp_hoststatus->should_be_scheduled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "check_execution_time")) + temp_hoststatus->execution_time = strtod(val, NULL); + else if(!strcmp(var, "check_latency")) + temp_hoststatus->latency = strtod(val, NULL); + else if(!strcmp(var, "check_type")) + temp_hoststatus->check_type = atoi(val); + else if(!strcmp(var, "current_state")) + temp_hoststatus->status = atoi(val); + else if(!strcmp(var, "last_hard_state")) + temp_hoststatus->last_hard_state = atoi(val); + else if(!strcmp(var, "plugin_output")) { + temp_hoststatus->plugin_output = (char *)strdup(val); + unescape_newlines(temp_hoststatus->plugin_output); + } + else if(!strcmp(var, "long_plugin_output")) { + temp_hoststatus->long_plugin_output = (char *)strdup(val); + unescape_newlines(temp_hoststatus->long_plugin_output); + } + else if(!strcmp(var, "performance_data")) + temp_hoststatus->perf_data = (char *)strdup(val); + else if(!strcmp(var, "current_attempt")) + temp_hoststatus->current_attempt = atoi(val); + else if(!strcmp(var, "max_attempts")) + temp_hoststatus->max_attempts = atoi(val); + else if(!strcmp(var, "last_check")) + temp_hoststatus->last_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_check")) + temp_hoststatus->next_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "check_options")) + temp_hoststatus->check_options = atoi(val); + else if(!strcmp(var, "current_attempt")) + temp_hoststatus->current_attempt = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "state_type")) + temp_hoststatus->state_type = atoi(val); + else if(!strcmp(var, "last_state_change")) + temp_hoststatus->last_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_hard_state_change")) + temp_hoststatus->last_hard_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_up")) + temp_hoststatus->last_time_up = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_down")) + temp_hoststatus->last_time_down = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_unreachable")) + temp_hoststatus->last_time_unreachable = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_notification")) + temp_hoststatus->last_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_notification")) + temp_hoststatus->next_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "no_more_notifications")) + temp_hoststatus->no_more_notifications = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "current_notification_number")) + temp_hoststatus->current_notification_number = atoi(val); + else if(!strcmp(var, "notifications_enabled")) + temp_hoststatus->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "problem_has_been_acknowledged")) + temp_hoststatus->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "acknowledgement_type")) + temp_hoststatus->acknowledgement_type = atoi(val); + else if(!strcmp(var, "active_checks_enabled")) + temp_hoststatus->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "passive_checks_enabled")) + temp_hoststatus->accept_passive_host_checks = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "event_handler_enabled")) + temp_hoststatus->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "flap_detection_enabled")) + temp_hoststatus->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "failure_prediction_enabled")) + temp_hoststatus->failure_prediction_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "process_performance_data")) + temp_hoststatus->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "obsess_over_host")) + temp_hoststatus->obsess_over_host = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "last_update")) + temp_hoststatus->last_update = strtoul(val, NULL, 10); + else if(!strcmp(var, "is_flapping")) + temp_hoststatus->is_flapping = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "percent_state_change")) + temp_hoststatus->percent_state_change = strtod(val, NULL); + else if(!strcmp(var, "scheduled_downtime_depth")) + temp_hoststatus->scheduled_downtime_depth = atoi(val); + /* + else if(!strcmp(var,"state_history")){ + temp_ptr=val; + for(x=0;xstate_history[x]=atoi(my_strsep(&temp_ptr,",")); + temp_hoststatus->state_history_index=0; + } + */ + } + break; + + case XSDDEFAULT_SERVICESTATUS_DATA: + /* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */ + if(temp_servicestatus != NULL) { + if(!strcmp(var, "host_name")) + temp_servicestatus->host_name = (char *)strdup(val); + else if(!strcmp(var, "service_description")) + temp_servicestatus->description = (char *)strdup(val); + else if(!strcmp(var, "has_been_checked")) + temp_servicestatus->has_been_checked = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "should_be_scheduled")) + temp_servicestatus->should_be_scheduled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "check_execution_time")) + temp_servicestatus->execution_time = strtod(val, NULL); + else if(!strcmp(var, "check_latency")) + temp_servicestatus->latency = strtod(val, NULL); + else if(!strcmp(var, "check_type")) + temp_servicestatus->check_type = atoi(val); + else if(!strcmp(var, "current_state")) + temp_servicestatus->status = atoi(val); + else if(!strcmp(var, "last_hard_state")) + temp_servicestatus->last_hard_state = atoi(val); + else if(!strcmp(var, "current_attempt")) + temp_servicestatus->current_attempt = atoi(val); + else if(!strcmp(var, "max_attempts")) + temp_servicestatus->max_attempts = atoi(val); + else if(!strcmp(var, "state_type")) + temp_servicestatus->state_type = atoi(val); + else if(!strcmp(var, "last_state_change")) + temp_servicestatus->last_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_hard_state_change")) + temp_servicestatus->last_hard_state_change = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_ok")) + temp_servicestatus->last_time_ok = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_warning")) + temp_servicestatus->last_time_warning = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_unknown")) + temp_servicestatus->last_time_unknown = strtoul(val, NULL, 10); + else if(!strcmp(var, "last_time_critical")) + temp_servicestatus->last_time_critical = strtoul(val, NULL, 10); + else if(!strcmp(var, "plugin_output")) { + temp_servicestatus->plugin_output = (char *)strdup(val); + unescape_newlines(temp_servicestatus->plugin_output); + } + else if(!strcmp(var, "long_plugin_output")) { + temp_servicestatus->long_plugin_output = (char *)strdup(val); + unescape_newlines(temp_servicestatus->long_plugin_output); + } + else if(!strcmp(var, "performance_data")) + temp_servicestatus->perf_data = (char *)strdup(val); + else if(!strcmp(var, "last_check")) + temp_servicestatus->last_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_check")) + temp_servicestatus->next_check = strtoul(val, NULL, 10); + else if(!strcmp(var, "check_options")) + temp_servicestatus->check_options = atoi(val); + else if(!strcmp(var, "current_notification_number")) + temp_servicestatus->current_notification_number = atoi(val); + else if(!strcmp(var, "last_notification")) + temp_servicestatus->last_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "next_notification")) + temp_servicestatus->next_notification = strtoul(val, NULL, 10); + else if(!strcmp(var, "no_more_notifications")) + temp_servicestatus->no_more_notifications = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "notifications_enabled")) + temp_servicestatus->notifications_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "active_checks_enabled")) + temp_servicestatus->checks_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "passive_checks_enabled")) + temp_servicestatus->accept_passive_service_checks = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "event_handler_enabled")) + temp_servicestatus->event_handler_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "problem_has_been_acknowledged")) + temp_servicestatus->problem_has_been_acknowledged = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "acknowledgement_type")) + temp_servicestatus->acknowledgement_type = atoi(val); + else if(!strcmp(var, "flap_detection_enabled")) + temp_servicestatus->flap_detection_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "failure_prediction_enabled")) + temp_servicestatus->failure_prediction_enabled = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "process_performance_data")) + temp_servicestatus->process_performance_data = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "obsess_over_service")) + temp_servicestatus->obsess_over_service = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "last_update")) + temp_servicestatus->last_update = strtoul(val, NULL, 10); + else if(!strcmp(var, "is_flapping")) + temp_servicestatus->is_flapping = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "percent_state_change")) + temp_servicestatus->percent_state_change = strtod(val, NULL); + else if(!strcmp(var, "scheduled_downtime_depth")) + temp_servicestatus->scheduled_downtime_depth = atoi(val); + /* + else if(!strcmp(var,"state_history")){ + temp_ptr=val; + for(x=0;xstate_history[x]=atoi(my_strsep(&temp_ptr,",")); + temp_servicestatus->state_history_index=0; + } + */ + } + break; + + case XSDDEFAULT_CONTACTSTATUS_DATA: + /* unimplemented */ + break; + + case XSDDEFAULT_HOSTCOMMENT_DATA: + case XSDDEFAULT_SERVICECOMMENT_DATA: + if(!strcmp(var, "host_name")) + host_name = (char *)strdup(val); + else if(!strcmp(var, "service_description")) + service_description = (char *)strdup(val); + else if(!strcmp(var, "entry_type")) + entry_type = atoi(val); + else if(!strcmp(var, "comment_id")) + comment_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "source")) + source = atoi(val); + else if(!strcmp(var, "persistent")) + persistent = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "entry_time")) + entry_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "expires")) + expires = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "expire_time")) + expire_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "author")) + author = (char *)strdup(val); + else if(!strcmp(var, "comment_data")) + comment_data = (char *)strdup(val); + break; + + case XSDDEFAULT_HOSTDOWNTIME_DATA: + case XSDDEFAULT_SERVICEDOWNTIME_DATA: + if(!strcmp(var, "host_name")) + host_name = (char *)strdup(val); + else if(!strcmp(var, "service_description")) + service_description = (char *)strdup(val); + else if(!strcmp(var, "downtime_id")) + downtime_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "comment_id")) + comment_id = strtoul(val, NULL, 10); + else if(!strcmp(var, "entry_time")) + entry_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "start_time")) + start_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "flex_downtime_start")) + flex_downtime_start = strtoul(val, NULL, 10); + else if(!strcmp(var, "end_time")) + end_time = strtoul(val, NULL, 10); + else if(!strcmp(var, "fixed")) + fixed = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "triggered_by")) + triggered_by = strtoul(val, NULL, 10); + else if(!strcmp(var, "duration")) + duration = strtoul(val, NULL, 10); + else if(!strcmp(var, "is_in_effect")) + is_in_effect = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "start_notification_sent")) + start_notification_sent = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "author")) + author = (char *)strdup(val); + else if(!strcmp(var, "comment")) + comment_data = (char *)strdup(val); + break; + + default: + break; + } + + } + } + + /* free memory and close the file */ +#ifdef NO_MMAP + fclose(fp); +#else + my_free(input); + mmap_fclose(thefile); +#endif + + /* free memory */ + my_free(xsddefault_status_log); + my_free(xsddefault_temp_file); + + if(sort_downtime() != OK) + return ERROR; + if(sort_comments() != OK) + return ERROR; + + return OK; + } + +#endif + diff --git a/xdata/xsddefault.h b/xdata/xsddefault.h new file mode 100644 index 0000000..0a9eec1 --- /dev/null +++ b/xdata/xsddefault.h @@ -0,0 +1,53 @@ +/***************************************************************************** + * + * XSDDEFAULT.H - Header file for default status data routines + * + * Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 03-01-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _XSDDEFAULT_H +#define _XSDDEFAULT_H + +#ifdef NSCORE +int xsddefault_initialize_status_data(char *); +int xsddefault_cleanup_status_data(char *, int); +int xsddefault_save_status_data(void); +#endif + +#ifdef NSCGI + +#define XSDDEFAULT_NO_DATA 0 +#define XSDDEFAULT_INFO_DATA 1 +#define XSDDEFAULT_PROGRAMSTATUS_DATA 2 +#define XSDDEFAULT_HOSTSTATUS_DATA 3 +#define XSDDEFAULT_SERVICESTATUS_DATA 4 +#define XSDDEFAULT_CONTACTSTATUS_DATA 5 +#define XSDDEFAULT_HOSTCOMMENT_DATA 6 +#define XSDDEFAULT_SERVICECOMMENT_DATA 7 +#define XSDDEFAULT_HOSTDOWNTIME_DATA 8 +#define XSDDEFAULT_SERVICEDOWNTIME_DATA 9 + +int xsddefault_read_status_data(char *, int); +#endif + +int xsddefault_grab_config_info(char *); +int xsddefault_grab_config_directives(char *); + +#endif