Compare commits

...

No commits in common. "pristine-tar" and "master" have entirely different histories.

1011 changed files with 240164 additions and 5 deletions

46
.gitignore vendored Normal file
View File

@ -0,0 +1,46 @@
pkg
subst
pkginfo
Prototype
nagios.SPARC.pkg.tar.gz
autom4te.cache
config.log
config.status
daemon-init
openrc-init
Makefile
tags
.deps/
.libs/
nbproject/
.kdev4/
.settings/
.cproject
.project
*.kdev4
*.o
*.la
*.lo
*.a
*.so
cgi/run*
gmon.out
core.[1-9]*
/Documentation
*.pre-indent
*.swp
*.gcda
*.gcno
*.gcov
coverage-report/
nagioscore.info-file
html/angularjs/angular-1.3.9
html/angularjs/ui-utils-0.2.3
html/bootstrap-3.3.7
html/d3
html/index.php

159
.travis.yml Normal file
View File

@ -0,0 +1,159 @@
language: c
sudo: true
matrix:
include:
- os: linux
dist: trusty
addons:
apt:
packages:
- apache2
- build-essential
- gcovr
- gperf
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=gcc && CXX=g++"
- os: linux
dist: trusty
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- apache2
- build-essential
- gcovr
- gperf
- g++-5
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
- os: linux
dist: trusty
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- apache2
- build-essential
- gcovr
- gperf
- g++-6
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
- os: linux
dist: trusty
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- apache2
- build-essential
- gcovr
- gperf
- g++-7
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- os: linux
dist: trusty
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- apache2
- build-essential
- gcovr
- gperf
- g++-8
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=gcc-8 && CXX=g++-8"
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
packages:
- apache2
- build-essential
- clang-5.0
- gcovr
- gperf
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
- os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages:
- apache2
- build-essential
- clang-6.0
- gcovr
- gperf
- g++-4.9
- lcov
- libgd-dev
- php5
- php5-gd
- unzip
- valgrind
env:
- MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0"
before_install:
- eval "${MATRIX_EVAL}"
script:
- ./configure --enable-testing
- make test
- gcovr -r .

165
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,165 @@
# Contributing
Thank you for considering contributing your time and effort to this Nagios project.
This document serves as our guidelines for contribution. Keep in mind that these
are simply *guidelines* - nothing here is set in stone.
## Questions
If you have a question, you don't need to file an Issue. You can simply connect
with the Nagios Support Team via the
[Nagios Support Forum](https://support.nagios.com/forum/).
Not to say that you **can't** open an Issue - but you'll likely get a much faster
response by posting it on the forum.
## Ideas
If you have an idea your best bet is to open an Issue. This gets it on the radar much
quicker than any other method.
First, let's define what an "Idea" really is. An Idea is simply an
[Enhancement](#enhancements) request in its infancy.
There's really nothing to it!
Something as simple as "I think that this project should somehow connect with a
widget" is a valid Idea.
These are unrefined and raw. That's why you open an issue - so everyone gets a chance
to chime in and come up with a plan!
## Feedback
Feedback can be given via several methods. The *easiest* method is by opening an Issue.
You're more than welcome to leave feedback on the
[Nagios Support Forum](https://support.nagios.com/forum/) as well.
By opening an Issue, however, you're insuring that the maintainers and reviewers are
the first ones to see the feedback. In most cases, this is likely ideal.
## Bugs
Here's where it starts to get serious.
Following the guidelines outlined in this section allows the maintainers, developers, and
community to understand and reproduce your bug report.
Make sure to search existing open and closed [Issues](https://guides.github.com/features/issues/)
before opening a bug report. If you find a closed Issue that seems like it's the same
thing that you're experiencing, open a new Issue and include a link to the original Issue
in the body of the new one.
**If you have a bug, you *NEED* to open an Issue.**
Not only that, but when you open the Issue, this is what we ***absolutely require***:
* Use a clear and concise title for the Issue to identify the problem accurately
* Describe the bug with as much detail as you can
* Include the version of the project containing the bug you're reporting
* Include your operating system information (`uname -a`)
* Include a list of third party modules that are installed and/or loaded
* Explain the behavior you expected to see (and why) vs. what actually happened
Once you've got that covered - there's still more to include if you want to
make a ***killer*** report:
* Describe the ***exact steps*** that reproduce the problem
* Provide **specific** examples to demonstrate those steps
* If your bug is from an older version, make sure test against the latest (and/or the `maint` branch)
* Include any screenshots that can help explain the issue
* Include a file containing `strace` and/or `valgrind` output
* Explain when the problem started happening: was it after an upgrade? or was it always present?
* Define how reliably you can reproduce the bug
* Any other information that you decide is relevant is also welcome
## Enhancements
An enhancement is either a completely new feature or an improvement to existing
functionality. We consider it to be a bit different than idea - based solely
on the fact that it's more detailed than an idea would be.
So you've got an idea for an ehancement? Great!
Following the guidelines outlined in this section allows maintainers, developers, and
the community to understand your enhancement and determine whether or not it's worth
doing and/or what's involved in carrying it out.
Make sure to search open and closed Issues and Pull Requests to determine if
someone has either submitted the enhancement. If you feel like your enhancement
is similar to one found, make sure to link the original in your request.
Enhancements are submitted by opening an Issue.
Unlike an [Idea](#idea), when you decide to submit your enhancement and open
the Issue, we require at least the following information:
* Use a clear and descriptive title to illustrate the enhancement you're requesting
* Describe the current behavior (if it exists) and what changes you think should be made
* Explain the enhancement in detail - make sure it makes sense and is easily understandable
* Specify why the enhancement would be useful and who it would be useful to
* If there is some other project or program where this enhancement already exists, make sure
to link to it
Beyond that, there are a few more things you can do to make sure you **really** get your
point across:
* Create a mockup of the enhancement (if applicable) and attach whatever files you can
* Provide a step-by-step description of the suggested enhancement
* Generate a fully dressed use-case for the enhancement request
* Create a specification for the preferred implementation of the enhancement
* Include a timeline regarding development expectations towards the request
## Submitting Code
Everything else in this document has lead up to this moment - how can ***you*** submit
code to the **project**.
We allow code submissions via [Pull Requests](https://help.github.com/articles/about-pull-requests/).
These let you (and us) discuss and review any changes to code in any repository you've made.
How to create and manage Pull Requests is outside of the scope of this document, but make
sure to check out GitHub's official documentation ([link here](https://help.github.com/))
to get a handle on it.
While you're forking the repository to create a patch or an enhancement, create a *new
branch* to make the change - it will be easier to submit a pull request using a new
branch in your forked repository!
When you submit a Pull Request, make sure you follow the guidelines:
* Make sure you're submitting to the proper branch. Branch `maint` is used for the
**next** bugfix release. The next enhancement release branch will vary.
* ***NEVER*** submit a Pull Request to `master` branch.
* Keep commit messages as concise as possible.
* Update the appropriate files in regards to your changes:
* `Changelog`
* `THANKS`
* End all committed files with a newline.
* Test your changes and include the results as a comment.

519
Changelog Normal file
View File

@ -0,0 +1,519 @@
########################
Nagios Core 4 Change Log
########################
4.4.4 - 2019-07-29
------------------
* Fixed log rotation logic to not repeatedly schedule rotation on a DST change (#610, #626) (Jaroslav Jindrak & Sebastian Wolf)
* Fixed $SERVICEPROBLEMID$ to be reset after service recovery (#621) (Sebastian Wolf)
* Fixed defunct worker processes appearing after nagios was reloaded (#441, #620) (Sebastian Wolf)
* Fixed main nagios thread to release nagios.qh on a closed connection (#635) (Sebastian Wolf)
* Fixed semicolon escaping to remove prepended backslash (\) (#643) (Sebastian Wolf)
* Fixed 'Checks of this host have been disabled' message showing on passive-only hosts (#632) (Vojtěch Širůček & Sebastian Wolf)
* Fixed last_hard_state showing the current hard state when service status is brokered (#633) (Sebastian Wolf)
* Fixed long plugin output (>8KB) occasionally getting truncated (#625) (Sebastian Wolf)
* Fixed check scheduling for objects with large check_intervals and small timeperiods (#647) (Sebastian Wolf)
* Fixed SOFT recoveries sending when services had HARD recovery some time after host recovery (#651) (Sebastian Wolf)
* Fixed incorrect permissions on debugging builds of FreeBSD (#420) (Sebastian Wolf)
* Fixed NEB callback lists being partially orphaned when multiple modules subscribe to one callback (#590) (Sebastian Wolf)
* Fixed memory leaks in run_async_service_check(), run_async_host_check() when checks are brokered (#664) (Sebastian Wolf)
* Fixed potential XSS in main.php, map.php (#671, #672) (Jak Gibb)
* Removed NEB brokering for nagios daemonization, since daemonization occurs before NEB initialization (#591) (Sebastian Wolf)
4.4.3 - 2019-01-15
------------------
FIXES
* Fixed services sending recovery emails when they recover if host in down state (#572) (Scott Wilkerson)
* Fixed a make error when building on the aarch64 architecture (#598) (Gareth Randall)
* Fixed --with-cgibindir and --with-webdir to actually set values given (#585) (lawsontyler)
* Fixed soft recovery states for services (#575) (Jake Omann)
* Fixed XSS vulnerability in Alert Summary report (CVE-2018-18245) (Jake Omann)
* Fixed services in soft states sometimes not switching into hard states (#576) (Jake Omann)
* Fixed last_state_change to update when a state goes from soft -> hard state (#592) (Jake Omann)
* Fixed Map link always being set to undefined host and don't show link for Nagios Process root note (#539) (Jake Omann)
* Fixed notifications sending when services went into hard state on a down or unreachable host (#584) (Jake Omann)
* Fixed log_host_retries not logging the host soft state checks (#599) (Jake Omann)
* Fixed stalking_options N option to properly log only when a notification is actually sent (#604) (Jake Omann)
* Fixed issue with service status totals being zero when servicegroup=all on servicegroup status page (#579) (Jake Omann)
* Fixed escalation notifications logic and recovery notifications not going out (#582) (Jake Omann)
* Fixed not finding child index causing duplicate hosts showing in the Map (#471) (Jake Omann)
* Fixed Map configuration popup checkboxes not working and Root Node not populating (#543) (Jake Omann)
* Fixed cleanup and deinit of neb modules on reload (#573) (Jake Omann)
4.4.2 - 2018-08-16
------------------
FIXES
* Fix comment data being duplicated after a `service nagios reload` or similar (#549) (Bryan Heden)
* Fix check_interval and retry_interval not changing at the appropriate times (#551) (Scott Wilkerson)
* Fixed passive checks sending recovery email when host was previously UP (#552) (Scott Wilkerson)
* Fixed flapping comments duplication on nagios reload (#554) (Christian Jung)
* Fix for CVE-2018-13441, CVE-2018-13458, CVE-2018-13457 null pointer dereference (Trevor McDonald)
* Fixed syntax error in file: default-init.in (#558) (Christian Zettel)
* Reset current notification number and state flags when the host recovers, reset all service variables when they recover fixes (#557) (Scott Wilkerson)
* Fixed wrong counting of service status totals when showing servicegroup details (#548) (Christian Zettel, Bryan Heden)
* Fixed avail.cgi not printing CSV output when checkbox is checked (for any type: host/service/hostgroup/servicegroup) (#570) (Bryan Heden)
* Fixed nagios not logging SOFT state changes after 1 (Scott Wilkerson)
4.4.1 - 2018-06-25
------------------
FIXES
* Revert some macro->kvvec changes causing problems when `enable_environment_macros` was enabled (Bryan Heden)
* Adjust `process_macro_r` function logic so that it handles macros properly (Bryan Heden)
* Fix spec file for systemd (Karsten Weiss, Fr3dY, Bryan Heden)
* Fix bug where `ssize_t` typedef to int on some systems (Bryan Heden)
4.4.0 - 2018-06-19
------------------
ENHANCEMENTS
* new status for check dependencies (John Frickson)
* Allow more flexible requirements for comments (John Frickson)
* Add a `statusCRITICALACK` class for the status column (John Frickson)
* CSV output based on groups (all options) (John Frickson)
* New Macro(s) to generate URL for host / service object to be used in notifications (John Frickson)
* New Macro(s) to determine if host/service notifications are enabled (#419) (Bryan Heden)
* New Macro(s) for obtaining the host/service notification periods (#350) (Bryan Heden)
* enable_page_tour interface option (Bryan Heden)
* Code cleanups in important sections (Workers, Handling Results) (Bryan Heden)
* Automatic mail program detection (with same /bin/mail failback) (Bryan Heden)
* Incorporated [autoconf-macros](https://github.com/NagiosEnterprises/autoconf-macros) into Core (Bryan Heden)
* Lots of enhancements/additions to configure/make process. (Bryan Heden)
* Moved all files to startup/
* Added upstart job
* Added system limit detection (RLIMIT_NPROC) to check for anticipated fork() failures (#434) (Bryan Heden)
* Added stalking on notifications (`N` or `notifications` option when specifying `stalking_options`) (#342) (Bryan Heden)
* Added automatic `systemctl daemon-reload` and `initctl reload-configuration` where applicable on `make install-init` (Bryan Heden)
* Added case-insentive command submission. (#373) (Bryan Heden)
* Enabled `check_external_commands` by default (Bryan Heden)
FIXES
* Command line macro detection skips potential macros with no ending dollar sign (Bryan Heden, Jake Omann)
* Fixed a lockup condition sometimes encountered on shutdown or restart (Aaron Beck)
* Fixed negative time offset calculations computing incorrectly sometimes (bbeutel)
* Fixed reloads causing defunct (zombie) processes (#441) (Bryan Heden)
* Fixed wait3(), wait4() implementations (replaced with waitpid()) (#326) (Bryan Heden)
* Fixed additive inheritance not testing for duplicates in hosts/services/(+escalations) (#392) (Bryan Heden)
* Fixed very very (around 600k chars or greater) large plugin output crashing Nagios (#432) (Bryan Heden)
* Fixed first_notification_delay not beeing calculated from last_hard_state_change (#425) (Christian Zettel)
* Fixed duplicate downtime ID occuring from downtimes in retention file (#506) (Franz [feisenko])
* Fixed segfault when navbarsearch was used in status.cgi for something other than a host (#489) (Bryan Heden)
* Fixed some miscellaneous ./configure issues on Solaris (Bryan Heden, Troy Lea)
* Fixed "Locate host on map" link (#496) (Troy Lea)
* Fixed service groups defined with unknown service members (that aren't first in the list) not erroring out (#500) (Bryan Heden)
* Fixed tac.cgi to have consistent behavior with the other cgis (#481) (Bryan Heden, Matt Capra)
* Fixed clear_host/service_flapping command logic to broker/notify properly (#525) (Bryan Heden, Karsten Weiss)
4.3.4 - 2017-08-24
------------------
* Improved config file parsing (Mark Felder)
* Fixed configure script to check for existence of /run for lock file (in regards to CVE-2017-12847, Bryan Heden)
* Use absolute paths when deleting check results files (Emmanuel Dreyfus)
* Add sanity checking in reassign_worker (sq5bpf)
4.3.3 - 2017-08-12
------------------
* xodtemplate.c wrong option-deprecation code warning (alex2grad / John Frickson)
* On-demand host check always use cached host state (John Frickson)
* 'á' causes Service Status Information to not be displayed (John Frickson)
* New Macro(s) to generate URL for host / service object (John Frickson)
* Fix minor map issues (Troy Lea)
* Fix lockfile issues (Bryan Heden)
* Switch order of daemon_init and drop_priveleges (CVE-2017-12847, Bryan Heden)
* Add an OpenRC init script (Michael Orlitzky)
4.3.2 - 2017-05-09
------------------
FIXES
* Every 15sec /var/log/messages is flooded with "nagios: set_environment_var" (John Frickson)
* Changed release date to ISO format (yyyy-mm-dd) (John Frickson)
* `make all` fails if unzip is not installed (John Frickson)
* Quick Search no longer allows search by Alias (John Frickson)
* flexible downtime on a service immediately turns off notifications (John Frickson)
* Fix to allow url_encode to be called twice (Z. Liu)
* Update timeperiods.cfg.in (spelling) (Parth Laxmikant Kolekar)
* Spelling fixes (Josh Soref)
* Vent command pipe before remove to avoid deadlocks on writing end (Kai Kunstmann)
* CGI utility cgiutil.c does not process relative config file path names properly (John Frickson)
* xdata/xodtemplate.c bug in option-deprecation code (John Frickson)
* Wildcard searching causes service status links to not work properly (John Frickson)
* Quick search with no hits shows a permission denied error (John Frickson)
* Setting a service as its own parent is not caught by the sanity checker (-v) and causes a segfault (John Frickson)
4.3.1 - 2017-02-23
------------------
FIXES
* Service hard state generation and host hard or soft down status (John Frickson)
* Comments are duplicated through Nagios reload (John Frickson)
* host hourly value is incorrectly dumped as json boolean (John Frickson)
* Bug - Quick Search no longer allows search by IP (John Frickson)
* Config: status_update_interval can not be set to 1 (John Frickson)
* Check attempts not increasing if nagios is reloaded (John Frickson)
* nagios hangs on reload while sending external command to cmd file (John Frickson)
* Feature Request: return code xxx out of bounds - include message as well (John Frickson)
4.3.0 - 2017-02-21
------------------
SECURITY FIXES
* Fix for CVE-2016-6209 - The "corewindow" parameter (as in
http://localhost/nagios?corewindow=www.somewhere.com) has been disabled by
default. See the UPGRADING document for how to enable it. (John Frickson)
FIXES
* Fix early event scheduling (pmalek / John Frickson)
* on-demand host checks triggered by service checks cause attempt number increments (fredericve)
* Service notification not being send when host is in soft down state (John Frickson)
* configure does not error if no perl installed on CentOS 7 (John Frickson)
* failed passive requests leave .ok files in checkresults dir (caronc)
* Services don't show in status.cgi if "noheader" specified (John Frickson)
* Standardized check interval config file names (John Frickson)
* "Event Log" (showlog.cgi) could not open log file (John Frickson)
* "nagios_check_command" has been deprecated since v3.0. Last vestiges removed (John Frickson)
ENHANCEMENTS
* Added new flag to cgi.cfg: tac_cgi_hard_only to show only HARD states (John Frickson)
* Add broker-event for the end of a timed event (NEBTYPE_TIMEDEVENT_END) (John Frickson)
* There is no Macro to retrieve addresses of hostgroup members (now $HOSTGROUPMEMBERADDRESSES$) (John Frickson)
* Add "Page Tour" videos to several of the core web pages (John Frickson)
* Added a login page, and a `Logoff` links (John Frickson)
* On the status map, the host name will be colored if services are not all OK. (John Frickson)
* Added "Clear flapping state" command on host and services detail pages. (John Frickson)
* User-entered comment now displays below generated comment for downtime (John Frickson)
4.2.4 - 2016-12-07
------------------
SECURITY FIXES
* Fixed another root privilege escalation (CVE-2016-9566) Thanks for bringing this
to our attention go to Dawid Golunski (http://legalhackers.com).
4.2.3 - 2016-11-21
-------------------
SECURITY FIXES
* Fixed a root privilege escalation (CVE-2016-8641) (John Frickson)
FIXES
* external command during reload doesn't work (John Frickson)
* Nagios provides no error condition as to why it fails on the verify for serviceescalation (John Frickson)
* No root group in FreeBSD and Apple OS X (John Frickson)
* jsonquery.html doesn't display scheduled_time_ok correctly (John Frickson)
* daemon_dumps_core=1 has no effect on Linux when Nagios started as root (John Frickson)
* Configuration check in hostgroup - misspelled hostname does not error (John Frickson)
* contacts or contact_groups directive with no value should not be allowed (John Frickson)
* Compile 64-bit on SPARC produces LD error (John Frickson)
* HOSTSTATEID returns 0 even if host does not exist (John Frickson)
* Submitting UNREACHABLE passive result for host sets it as DOWN if the host has no parents (John Frickson)
* nagios: job XX (pid=YY): read() returned error 11 (changed from LOG_ERR to LOG_NOTICE) (John Frickson)
* Fix for quick search not showing services if wildcard used (John Frickson)
4.2.2 - 2016-10-24
------------------
SECURITY FIXES
* There was a fix to vulnerability CVE-2008-4796 in the 4.2.0 release on
August 1, 2016. The fix was apparently incomplete, as there was still a
problem. However, we are now getting all RSS feeds using AJAX calls
instead of the (outdated) MagpieRSS package. Thanks for bringing this to
our attention go to Dawid Golunski (http://legalhackers.com).
ENHANCEMENTS
* Update status.c to display passive check icon for hosts when passive checks
are enabled and actives disabled (John Frickson)
FIXES
* Fix permissions for Host Groups reports (status.cgi) (Patrik Halfar)
* Service Parents does not appear to be functioning as intended (lev)
* Availability report mixes up scheduled and unscheduled warning percentages (Helmut Mikulcik)
* Invalid values for saved_stamp in compute_subject_downtime_times() (John Frickson)
* Remove deprecated "framespacing" (John Frickson)
* The nagios tarball contains two identical jquery copies (John Frickson)
* extinfo.cgi does not set content-type (most cgi's don't) (John Frickson)
* Timeperiods are corrupted by external command CHANGE_SVC_CHECK_TIMEPERIOD (xoubih)
* Quick search doesn't show hosts without services (service status detail page) (John Frickson)
* In host/services details view, if exactly 100 entries would not show last one (John Frickson)
* nagios host URL parameter for NEW map doesn`t work - Network Map for All Hosts (John Frickson)
* next_problem_id is improperly initialized (gherteg)
* Passive problems not showing as "unhandled" (John Frickson)
* September reported as Sept instead of Sep (Rostislav Opočenský)
* Notifications are not sent for active alerts after scheduled downtime ends (John Frickson)
* Nagios 4.2.0 not working on Solaris (John Frickson)
* install-exfoliation and install-classicui don't work FreeBSD and Mac OS X (John Frickson)
* Updated makefile to delete some no-longer-needed files (John Frickson)
4.2.1 - 2016-09-06
------------------
FIXES
* Fix undefined variable php error (John Frickson)
* Links on the sidebar menu under 'Problems' are indented too far (John Frickson)
* Using $ARGn$ Macros in perfdata (John Frickson)
* using a wildcard in search returns service status total all zero's (John Frickson)
* read_only does not take priority (deppy)
* Running nagios -v on 4.2.0 takes 90+ seconds (John Frickson)
* Bare "make" invoked in subtarget (mjo)
* Theme images/stylesheets installed with inconsistent permissions (mjo / John Frickson)
* Missing Image for Host and Service State Trends in Availability Report (nichokap / John Frickson)
* Maintain non-persistent comments through reload (John Frickson)
* Servicegroup availability report ignores includesoftstates in service report links (PriceChild)
* error: format not a string literal and no format arguments (Karsten Weiss)
* Synced config.guess and config.sub with GNU (Zakhar Kleyman)
4.2.0 - 2016-08-01
------------------
SECURITY FIXES
* Fixed vulnerability CVE-2008-4796 (John Frickson)
* Fixed vulnerability CVE-2013-4214 (John Frickson)
* web interface vulnerable to Cross-Site Request Forgery attacks (John Frickson)
ENHANCEMENTS
* Increase socket queue length for listen()
* Added host name to the website page title (leres / John Frickson)
* Added additional icons for NetBSD and SuSE (John Frickson)
* The new Status Map will now use cgi.cfg options (John Frickson)
default_statusmap_layout will default to "6" for the new map
* The new Status Map will now show some valid values in the popup for "Nagios Process" (John Frickson)
FIXES
* Network outage view without access to all hosts (John Frickson)
* Core workers looping (John Frickson)
* service query returns duplicate host_name and description fields in the returned data (John Frickson)
* HTML output of plug-ins is parsed in wrong way => webgui unusable (John Frickson)
* Command worker fails to handle SIGPIPE
* "View Status" links under "Map" broken in Nagios Core Version 4.1.1 (John Frickson)
* Can't send big buffer - wproc: Core Worker seems to be choked (velripn / John Frickson)
* Too big CPU load on FreeBSD and other systems using poll() interface (cejkar)
* Flexible downtime recorded as unscheduled downtime (John Frickson)
* Service Flexible downtimes produce 1 notification before entering (John Frickson)
* Once you "set flap_detection_enabled 0" it should remove flapping state from the host/services page (John Frickson)
* New map doesn't finish loading if a logo image is not found (John Frickson)
* Extraneous Div end tag in map.html (Scott Wilkerson)
* Issue with "Problems" section (John Frickson)
* Status Map icons and online/offline status dots disappear in IE11 (John Frickson)
* New network map overlays the nagios process with objects (John Frickson)
* Added Default-Start and Default-Stop to the init script (John Frickson)
* Compile / logging issues with BSD 6
* Related to above, Fixed a lot of incorrectly handled time_t's in *printf's (John Frickson)
* New map not working for RU locale (actually, most locales) (John Frickson)
* Replaced all instances of signal() with sigaction() + blocking (John Frickson)
* UTF-8 characters like german ä are not processed properly by function url_encode (John Frickson)
* nagios worker processes can hog CPU (huxley / John Frickson)
* custom time periods that include special characters were not being handled in reports (John Frickson)
* Fixed init script to wait up to 90 seconds then kill the nagios process (John Frickson)
* No Host Groups results in wrong error message (John Frickson)
* Setup Nagios users to view specific host is not working in the new network map (John Frickson)
* statusjson.cgi fails glibc realloc truncate response output (John Frickson)
* Report Time Period does not work if an @ character is in the timeperiod name (John Frickson)
* State History does not use actual plugin long_output (John Frickson)
* Time period corruption (xoubih)
* Tactical Overview - Disabled Flap Detection Link (John Frickson)
4.1.1 - 08/19/2015
------------------
FIXES
* CGI Could not read object configuration data (broken by error in 4.1.0)
* exclude (!) not working (broken by mis-applied fix for 4.1.0)
4.1.0 - 08/18/2015
------------------
ENHANCEMENTS
* Promoted JSON CGIs to released status (Eric Stanley)
* New graphical CGI displays: statusmap, trends, histogram (Eric Stanley)
* Make sticky status for acks and comments configurable enhancement #20 (Trevor McDonald / Scott Wilkerson)
* Add host_down_disable_service_checks directive to nagios.cfg #44 (Trevor McDonald / Scott Wilkerson)
* httpd.conf doesn't support Apache versions > 2.3 (DanielB / John Frickson)
FIXES
* Fix for not all service dependencies created (John Frickson)
* Fix SIGSEGV with empty custom variable (orbis / John Frickson)
* Fix contact macros in environment variables (dvoryanchikov)
* Fixed host's current attempt goes to 1 after going to hard state (John Frickson)
* Fixed two bugs/problems: Replace use of %zd in base/utils.c & incorrect va_start() in cgi/jsonutils.c (Peter Eriksson)
* Fixed: Let remove_specialized actually remove all workers (Phil Mayers)
* Fixed log file spam caused when using perfdata command directives in nagios.cfg (shashikanthbussa)
* Fixed off-by-one error in bounds check leads to segfault (Phil Mayers)
* Added links for legacy graphical displays (Eric Stanley)
* Update embedded URL's to https versions of Nagios websites (scottwilkerson)
* Fixed doxygen comments to work with latest doxygen 1.8.9.1 #30 (Trevor McDonald)
* Fixed makefile target "html" to PHONY to fix GitHub issue #28 (Trevor McDonald)
* Fixed typo as per GitHub issue #27 (Trevor McDonald)
* Fixed jsonquery.php 404 not found error, and disabled Send Query button until form populates #43 (Scott Wilkerson)
* Fixed linking in Tactical Overview for several of the Host entries in Featured section #48 (Scott Wilkerson)
* Fixed passing limit and sort options to pagination and sort links #42 (Scott Wilkerson)
* Added form field for icon URL and clean-up when it changes in CGI Status Map. (Eric Stanley)
* Added options to cgi.cfg to uncheck sticky and send when acknowledging a problem (Trevor McDonald)
* Low impact changes to automate the generation of RPMs from nagios.spec file. (T.J. Yang)
* Update index.php (Trevor McDonald)
* Fixed escaping of corewindow parameter to account for possible XSS injection (Scott Wilkerson)
* Typo correction (T.J. Yang)
* Make getCoreStatus respect cgi_base_url (Moritz Schlarb)
* Adjusted map layout to work within frames (Eric Stanley)
* Fixed map displays are now the full size of browser window (Eric Stanley)
* Fixed labels and icons on circular markup no longer scale on zoom (Eric Stanley)
* Got all maps except circular markup working with icons (Eric Stanley)
* Fixes to make legacy CGIs work again. (Eric Stanley)
* Fixes to make all/html target tolerant of being run multiple times (Eric Stanley)
* For user-supplied maps, converted node group to have transform (Eric Stanley)
* Fixed issue transitioning from circular markup map to other maps (Eric Stanley)
* Fix displayForm to trigger on the button press (Scott Wilkerson)
* Fix fo getBBox crash on Firefox (Eric Stanley)
* Fixed map now resets zoom when form apply()'d (Eric Stanley)
* Fixed so close box on dialogs actually closes dialog (Eric Stanley)
* Corrected directive in trends display (Eric Stanley)
* Fixed minor issue with link in trends links (Eric Stanley)
* Fixed issue with map displaying on Firefox (Eric Stanley)
* Added exclusions for ctags generation (Eric Stanley)
* Update map-popup.html (Scott Wilkerson)
* Initial commit of new graphical CGIs (Eric Stanley)
* Fixed Github bug #18 - archivejson.cgi returns wrong host for state change query (Eric Stanley)
* Status JSON: Added next_check to service details (Eric Stanley)
* Fixed escaping of keys for scalar values in JSON CGIs (Eric Stanley)
* build: Include <sys/loadavg.h> if it exists. (Eric J. Mislivec)
* lib-tests: test-io{cache|broker} need -lsocket to link. (Eric J. Mislivec)
* lib-tests: test-runcmd assumes GNU echo. (Eric J. Mislivec)
* lib-tests: Signal handlers don't return int on most platforms, and using a cast was the wrong way to resolve this. (Eric J. Mislivec)
* Fix some type/format mismatch warnings for pid_t. (Eric J. Mislivec)
* Fix build on Solaris. (Eric J. Mislivec)
* runcmd: Fix build when we don't HAVE_SETENV. (Eric J. Mislivec)
* Fixed checkresult output processing (Eric Mislivec)
* Corrected escaping of long output macros (Eric Mislivec)
* Fixed null pointer dereferences in archive JSON (Eric Stanley)
* Fixed memory overwrite issue in JSON string escaping (Eric Stanley)
* JSON CGI: Now escaping object and array keys (Eric Stanley)
KNOWN ISSUES
* New map does not account for multiple parents, leaving "legacy" map as an option in the menu
4.0.8 - 08/12/2014
------------------
ENHANCEMENTS
* Removed 8 kB string size limitation in JSON CGIs (Eric Stanley)
* Re-implemented auto-rescheduling of checks (Eric Mislivec)
* Avoid bunching of checks delayed due to timeperiod constraints (Eric Stanley)
* Limit the number of autocalculated core workers to not spawn too many on large systems (Eric Mislivec, Janice Singh)
FIXES
* Removed quotes from numeric duration values in JSON CGIs (Eric Stanley)
* Fixed escaping in JSON CGIs so all required characters are escaped, and in the correct order (Eric Stanley)
* Fixed segfault in archive JSON CGI when plugin output was empty (Eric Stanley)
* Fixed several possibilities for buffer overflow (Eric Mislivec, Dirkjan Bussink)
* Fixed Tracker #582, #626: Handle VAR=VAL assignments at the start of simple commands (Eric Mislivec, Phil Randal)
* Fixed Tracker #630: Recognize '<' and '>' as redirection operators (Eric Mislivec)
* Corrected worker communication protocol documentation (Phil Mayers)
* Fixed init script to leave config test log in a better location, let sysconfig override init script variables, and not remove nagios.cmd when attempting to start with another instance running (Eric Mislivec, Robin Kearney)
* Fixed Tracker #361: Downtime notifications not displayed properly (Andrew Widdersheim)
4.0.7 - 06/03/2014
------------------
ENHANCEMENTS
* Added value of custom variables to Object JSON output for hosts, services and contacts (Eric Stanley)
FIXES
* Fixed bug #616: Unescape plugin output read from checkresult files, fix multiline perf data concatenation, and avoid extra memory allocation and copies. (Eric Mislivec)
* Fixed bug #609: Image on home page doesn't have correct image path prefix. (Derek Brewer)
* Fixed bug #608: Extra newline in service check timeout output string. (Mauno Pihelgas)
* Fixed bug #596: Crashes checking contact authorization for host escalations. (Alexey Dvoryanchikov - duplicates #590, #586)
* Fixed bug #496: Syntax error in exfoliation's common.css. (Karsten Weiss)
4.0.6 - 04/29/2014
------------------
ENHANCEMENTS
* Added name of authenticated user to JSON CGI results object (Eric Stanley)
* Added Nagios Core version to the Status JSON CGI programstatus query (Eric Stanley)
* Added daemon status to main page (Eric Mislivec)
FIXES
* Fixed bug #600: Service Check Timeout State always returns OK (0) status (Mauno Pihelgas, Eric Stanley)
* Fixed bug #583: Status Check Output of (No output on stdout) stderr: (Eric
Stanley - duplicate of bug #573)
* Fixed bug #573: Service checks returns (No output on stdout) stderr (Eric Stanley)
* Fixed bug #438: Reloads during downtime causes wrong availability calculations (Eric Stanley)
* Fixed feed updates when daemon can not access external networks (Eric Mislivec)
* Archive JSON: Fixed bugs calculating availability (Eric Stanley)
* Archive JSON: Allow missing logs to be skipped (Eric Stanley)
4.0.5 - 04/11/2014
------------------
* Fixed bug #595: Nagios 4 security fix (Alexey Dvoryanchikov, Eric Stanley)
* Fixed bug #594: Nagios 4 fix contactgroups parsing (Alexey Dvoryanchikov, Eric Stanley)
* Fixed bug #577: Nagios 4 checks stalled when write to socket failed (Alexey Dvoryanchikov)
* Fixed bug #580: Nagios 4 memory leak (Eric Stanley)
* Fixed init script to remove the switching of users when performing configuration verification which was causing failures if nagios user was set to nologin (Scott Wilkerson)
* Fixed auto creation of RAMDISK via environment variables in init script to properly check existence using $RAMDISK_DIR environment variable. (Scott Wilkerson)
* Fixed unreferenced variable NagiosVarDir in daemon-init (Eric Mislivec)
* Fixed bug where audio alerts wouldn't work with a 0 height and width - https://support.nagios.com/forum/viewtopic.php?t=26387 (Scott Wilkerson)
4.0.4 - 03/14/2014
------------------
ENHANCEMENTS
* JSON CGIs moved to beta status (Eric Stanley)
FIXES
* Fixed bug #491,#553: Rebuilt the daemon-init scripts back to something that should work on all systems (Scott Wilkerson)
4.0.3 - 02/28/2014
------------------
ENHANCEMENTS
* Aliased hourly_value to importance and minimum_value to minimum_importance and deprecated the former (Eric Stanley)
* Added host and service importance macros (Eric Stanley)
* Added notifications on flexible downtime expiration (Dan Wittenberg)
FIXES
* Bug #548: Temporary fix that rejects all external command during restart to prevent Core from crashing (Eric Stanley)
* Corrected calculation of host importance and importance defaults (Eric Stanley)
* Fixed bug #498: Nagios 4 enable_environment_macros=1 not working (Eric Stanley, Alexey Dvoryanchikov)
* No longer checks whether logs can be written when verifying configuration (Eric Stanley)
* Fixed CGI bug where the CGI could read past the end of the list of CGI variables, potentially crashing the CGI (Scott Wilkerson)
* Fixed inheritance of hourly_value from host and service templates (Scott Wilkerson)
* Fixed bug #502: 4.0.0: Configuration -> Service Escalations = incomplete list (Eric Stanley)
* Fixed bug #523: quotes and double quotes in plugin message are converted to HTML escapes in Nagios 4.0 (duplicate of bug #524)
* Fixed bug #524: URLs returned in plugin check results are not correctly displayed (Eric Stanley)
* Fixed bug where passive service checks would return "Service check timed out after 0.00 seconds" (Scott Wilkerson)
4.0.2 - 11/25/2013
------------------
FIXES
* Fixed bug 528: Nagios 4.0.1: Logrotation: Only current host- and servicestates saved in rotated logfiles (duplicate of 507)
* Fixed bug 507: Nagios 4.0.0 - Problem during log rotate (Stefano Ghelfi)
* Fixed bug 530: RPM spec file sets wrong permissions on plugins directory (duplicate of bug 494)
* Fixed bug 494: nagios.spec fixes (with patch) (Karsten Weiss)
* Fixed bug 515: Segsegv after starting up nagios (duplicate of bug 526)
* Fixed bug 513: Crash while entering downtime for service (duplicate of bug 526)
* Fixed bug 529: Core Worker failed to reap child in 4.0.1 Description
* Fixed bug 514: scheduled downtime not showing in web interface (Eric Stanley)
* Fixed bug 526: sort_downtime() corrupts scheduled_downtime_list causing segfault (Adam James)
* Fixed bug 492: Nagios 4 fails to remove/add checks upon reload (Eric Stanley)
* Fixed Bug 484: Beta4.0.0b4 service checks returning (No output on stdout) (Eric Stanley)
* Fixed Bug 470: statusmap doesn't display info (Cameron Moore)
* Fixed Bug 499: Security issue in daemon-init.in, function check_config (Tómas Edwardsson)
4.0.1 - 10/15/2013
------------------
ENHANCEMENTS
* Added compiler flags in RPM spec file to reduce compiler noise (Dan Wittenberg)
* Added logging of failure in dlclose() call (Anton Lofgren)
* Added a simple query handler interface, nagios-qh.rb (Dan Wittenberg)
* Multiple code simplifications, additional error handling in downtime code (Andreas Ericsson)
FIXES
* Reverted commit f99a9a7b which set check_interval to 1 if it was configured as zero.
* Corrected order of arguments when logging unknown hosts/services (Scott Wilkerson)
* Downtime initialized before retention data read (Eric Stanley)
* Patches to make RPM build again (Dan Wittenberg)
* Ensure that scheduled_downtime_depth never drops below zero (Andreas Ericsson)
4.0.0 - 09/20/2013
------------------
See https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/whatsnew.html for a
list of the changes in Nagios Core 4

17
INSTALLING Normal file
View File

@ -0,0 +1,17 @@
Nagios Installation Instructions
--------------------------------
A quickstart installation guide can now be found in the HTML
documentation. You can find the quickstart guide (quickstart.html)
in the following subdirectory:
html/docs/
The quickstart covers all the basic steps you need to follow
to install Nagios, the Nagios plugins, and start out monitoring
the machine that Nagios is installed on.
Good luck!

20
LEGAL Normal file
View File

@ -0,0 +1,20 @@
Copyright(c) 1999-2009:
Ethan Galstad <egalstad@nagios.org>
Copyright(c) 2009 until further notice:
Nagios Core Development Team and Nagios Community Contributors
For detailed authorship information, refer to the source control
management history and pay particular attention to commit messages
and the THANKS file.
All source code, binaries, documentation, information, and other files
contained in this distribution are provided AS IS with NO WARRANTY OF
ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS
FOR A PARTICULAR PURPOSE.
Nagios and the Nagios logo are trademarks, servicemarks, registered
trademarks or registered servicemarks owned by Nagios Enterprises, LLC.
All other trademarks, servicemarks, registered trademarks, and
registered servicemarks are the property of their respective owner(s).

340
LICENSE Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

496
Makefile.in Normal file
View File

@ -0,0 +1,496 @@
###############################
# Makefile for Nagios
#
###############################
# Source code directories
SRC_BASE=@srcdir@/base
SRC_LIB=@srcdir@/lib
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
SRC_WORKERS=@srcdir@/worker
CC=@CC@
CFLAGS=@CFLAGS@ @DEFS@
LDFLAGS=@LDFLAGS@ @LIBS@
prefix=@prefix@
exec_prefix=@exec_prefix@
LOGDIR=@localstatedir@
CHECKRESULTDIR=@CHECKRESULTDIR@
CFGDIR=@sysconfdir@
BINDIR=@bindir@
CGIDIR=@cgibindir@
LIBEXECDIR=@libexecdir@
LIBDIR=@libdir@
INCLUDEDIR=@includedir@/nagios
HTMLDIR=@webdir@
datarootdir=@datarootdir@
LN_S=@LN_S@
INSTALL=@INSTALL@
INSTALL_OPTS=@INSTALL_OPTS@
COMMAND_OPTS=@COMMAND_OPTS@
HTTPD_CONF=@HTTPD_CONF@
LN_HTTPD_SITES_ENABLED=@LN_HTTPD_SITES_ENABLED@
INIT_DIR=@initdir@
INIT_OPTS=@INIT_OPTS@
CGICFGDIR=$(CGIDIR)
NAGIOS_USER=@nagios_user@
NAGIOS_GRP=@nagios_grp@
DIST=@dist_type@
SRC_INIT=@src_init@
INIT_FILE=@initname@
INIT_TYPE=@init_type@
USE_EVENTBROKER=@USE_EVENTBROKER@
USE_LIBTAP=@USE_LIBTAP@
CGIEXTRAS=@CGIEXTRAS@
CP=@CP@
@SET_MAKE@
none:
@echo "Please supply a command line argument (i.e. 'make all'). Other targets are:"
@echo " nagios cgis contrib modules workers"
@echo " test"
@echo " install install-base"
@echo " install-cgis install-html"
@echo " install-webconf install-config"
@echo " install-init install-daemoninit"
@echo " install-commandmode install-groups-users"
@echo " install-exfoliation install-classicui"
@echo " install-basic install-unstripped"
@echo " fullinstall"
# @echo " uninstall"
@echo " clean"
# 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 --exclude=html/angularjs --exclude=html/d3 --exclude=t-tap
all:
cd $(SRC_BASE) && $(MAKE)
cd $(SRC_CGI) && $(MAKE)
cd $(SRC_HTM) && $(MAKE)
if [ x$(USE_EVENTBROKER) = xyes ]; then \
cd $(SRC_MODULE) && $(MAKE); \
fi
cd $(SRC_WORKERS) && $(MAKE) $@
@echo ""
@echo "*** Compile finished ***"
@echo ""
@echo "If the main program and CGIs compiled without any errors, you"
@echo "can continue with testing or installing Nagios as follows (type"
@echo "'make' without any arguments for a list of all possible options):"
@echo ""
@echo " make test"
@echo " - This runs the test suite"
@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-daemoninit"
@echo " - This will initialize the init script"
@echo " in $(DESTDIR)$(INIT_DIR)"
@echo ""
@echo " make install-groups-users"
@echo " - This adds the users and groups if they do not exist"
@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 " https://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 " https://support.nagios.com"
@echo ""
@echo "*************************************************************"
@echo ""
@echo "Enjoy."
@echo ""
$(SRC_LIB)/libnagios.a:
cd $(SRC_LIB) && $(MAKE)
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)
workers:
cd $(SRC_WORKERS) && $(MAKE) all
clean:
cd $(SRC_LIB) && $(MAKE) $@
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) $@
cd $(SRC_WORKERS) && $(MAKE) $@
rm -f *.cfg core
rm -f *~ *.*~ */*~ */*.*~ */*/*.*~
rm -f nagioscore.info-file
rm -f *.gcno */*.gcno */*/*.gcno
rm -f *.gcda */*.gcda */*/*.gcda
rm -f *.gcov */*.gcov */*/*.gcov
rm -rf coverage-report
distclean: clean
cd $(SRC_LIB) && $(MAKE) $@
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) $@
cd $(SRC_WORKERS) && $(MAKE) $@
rm -f sample-config/*.cfg sample-config/*.conf sample-config/template-object/*.cfg
rm -f daemon-init daemon-service daemon-openrc pkginfo
rm -f Makefile subst
rm -f config.log config.status config.cache
rm -f tags
devclean: distclean
test: nagios cgis
cd $(SRC_LIB) && $(MAKE) 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
coverage: test
@if ! which lcov >/dev/null 2>&1; then \
echo "ERROR: You must install lcov and genhtml first"; \
else \
lcov -c -d . -o nagioscore.info-file; \
genhtml nagioscore.info-file -o coverage-report; \
echo "Your coverage report is in coverage-report/index.html"; \
fi
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 $(COMMAND_OPTS) -d $(DESTDIR)$(CHECKRESULTDIR)
chmod g+s $(DESTDIR)$(CHECKRESULTDIR)
@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-groups-users:
@autoconf-macros/add_group_user $(DIST) $(NAGIOS_USER) $(NAGIOS_GRP) 1
install-webconf:
$(INSTALL) -m 644 sample-config/httpd.conf $(DESTDIR)$(HTTPD_CONF)/nagios.conf
if [ $(LN_HTTPD_SITES_ENABLED) -eq 1 ]; then \
$(LN_S) $(DESTDIR)$(HTTPD_CONF)/nagios.conf $(DESTDIR)/etc/apache2/sites-enabled/nagios.conf; \
fi
@echo ""
@echo "*** Nagios/Apache conf file installed ***"
@echo ""
install-exfoliation:
@cd contrib/exfoliation; \
$(INSTALL) $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/stylesheets; \
for file in $$(find ./stylesheets/ -type f); do \
$(INSTALL) -m 644 $(INSTALL_OPTS) $${file} $(DESTDIR)$(HTMLDIR)/$${file}; \
done; \
$(INSTALL) $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/images; \
for file in $$(find ./images -type f); do \
$(INSTALL) -m 644 $(INSTALL_OPTS) $${file} $(DESTDIR)$(HTMLDIR)/$${file}; \
done; \
cd ../..
@echo ""
@echo "*** Exfoliation theme installed ***"
@echo "NOTE: Use 'make install-classicui' to revert to classic Nagios theme";
@echo ""
install-classicui:
@cd html; \
$(INSTALL) $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/stylesheets; \
for file in $$(find ./stylesheets/ -type f); do \
$(INSTALL) -m 644 $(INSTALL_OPTS) $${file} $(DESTDIR)$(HTMLDIR)/$${file}; \
done; \
$(INSTALL) $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/images; \
for file in $$(find ./images -type f); do \
$(INSTALL) -m 644 $(INSTALL_OPTS) $${file} $(DESTDIR)$(HTMLDIR)/$${file}; \
done; \
cd ..
@echo ""
@echo "*** Classic theme installed ***"
@echo "NOTE: Use 'make install-exfoliation' to use new Nagios theme";
@echo ""
install-init:
$(INSTALL) -m 755 -d $(INIT_OPTS) $(DESTDIR)$(INIT_DIR)
$(INSTALL) -m 755 $(INIT_OPTS) startup/$(SRC_INIT) $(DESTDIR)$(INIT_DIR)/$(INIT_FILE)
install-daemoninit: install-init
@if [ x$(INIT_TYPE) = xsysv ]; then \
if which chkconfig >/dev/null 2>&1; then \
chkconfig --add nagios; \
elif which update-rc.d >/dev/null 2>&1; then \
update-rc.d nagios defaults; \
fi \
elif [ x$(INIT_TYPE) = xsystemd ]; then \
if which systemctl >/dev/null 2>&1; then \
systemctl daemon-reload; \
systemctl enable nagios.service; \
fi; \
chmod 0644 $(INIT_DIR)/$(INIT_FILE); \
elif [ x$(INIT_TYPE) = xupstart ]; then \
if which initctl >/dev/null 2>&1; then \
initctl reload-configuration; \
fi \
elif [ x$(INIT_TYPE) = xopenrc ]; then \
if which rc-update >/dev/null 2>&1; then \
rc-update add nagios default; \
fi \
fi
@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 ""
install-devel: install-headers install-lib
install-headers:
$(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)
$(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)/lib
$(INSTALL) -m 644 include/*.h $(DESTDIR)$(INCLUDEDIR)
$(INSTALL) -m 644 lib/*.h $(DESTDIR)$(INCLUDEDIR)/lib
rm -f $(DESTDIR)$(INCLUDEDIR)/config*.h
install-lib: $(SRC_LIB)/libnagios.a
$(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)
$(INSTALL) -m 644 $(SRC_LIB)/libnagios.a $(DESTDIR)$(LIBDIR)
dox:
@rm -rf Documentation
doxygen doxy.conf
fullinstall: install install-init install-commandmode install-webconf install-devel
# 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
dist: distclean
rm -f nagios-$(VERSION)
ln -s . nagios-$(VERSION)
tar zhcf nagios-$(VERSION).tar.gz --exclude nagios-$(VERSION)/nagios-$(VERSION).tar.gz --exclude nagios-$(VERSION)/nagios-$(VERSION) --exclude RCS --exclude CVS --exclude build-* --exclude *~ --exclude .git* nagios-$(VERSION)/
rm -f nagios-$(VERSION)
# Targets that always get built
.PHONY: indent clean clean distclean dox test html

83
README.md Normal file
View File

@ -0,0 +1,83 @@
Nagios 4.x
==========
![Nagios!](https://www.nagios.com/wp-content/uploads/2015/05/Nagios-Black-500x124.png)
[![Build Status](https://travis-ci.org/NagiosEnterprises/nagioscore.svg?branch=master)](https://travis-ci.org/NagiosEnterprises/nagioscore)
Nagios is a host/service/network monitoring program written in C and
released under the GNU General Public License, version 2. CGI programs
are included to allow you to view the current status, history, etc via
a web interface if you so desire.
Visit the Nagios homepage at https://www.nagios.org for documentation,
new releases, bug reports, information on discussion forums, and more.
[Features](https://www.nagios.org/about/features/)
-----------------------------------------------
* Monitoring of network services (via SMTP, POP3, HTTP, PING, etc).
* Monitoring of host resources (processor load, disk usage, etc.).
* A plugin interface to allow for user-developed service monitoring
methods.
* Ability to define network host hierarchy using "parent" hosts,
allowing detection of and distinction between hosts that are down
and those that are unreachable.
* Notifications when problems occur and get resolved (via email,
pager, or user-defined method).
* Ability to define event handlers for proactive problem resolution.
* Automatic log file rotation/archiving.
* Optional web interface for viewing current network status,
notification and problem history, log file, etc.
Changes
-------
See the
[Changelog](https://raw.githubusercontent.com/NagiosEnterprises/nagioscore/master/Changelog)
for a summary of important changes and fixes, or the
[commit history](https://github.com/NagiosEnterprises/nagioscore/commits/master)
for more detail.
Download
--------
Latest releases can be downloaded from https://www.nagios.org/download/
Installation
------------
[Quickstart installation guides](http://nagios.sourceforge.net/docs/nagioscore/4/en/quickstart.html)
are available to help you get Nagios up and monitoring.
Documentation & Support
-----------------------
* [User Guide](http://nagios.sourceforge.net/docs/nagioscore/4/en/)
* [Nagios Core Documentation Library](https://library.nagios.com/library/products/nagioscore/)
* [Support Forums](https://support.nagios.com/forum/viewforum.php?f=7)
* [Additional Support Resources](https://www.nagios.org/support/)
Contributing
------------
The Nagios source code is hosted on GitHub:
https://github.com/NagiosEnterprises/nagioscore
Do you have an idea or feature request to make Nagios better? Join or start a
discussion on the [Nagios Core Development forum](https://support.nagios.com/forum/viewforum.php?f=34).
Bugs can be reported by [opening an issue on GitHub](https://github.com/NagiosEnterprises/nagioscore/issues/new).
If you have identified a security related issue in Nagios, please contact
security@nagios.com.
Patches and GitHub pull requests are welcome. Pull requests on GitHub
link commits in version control to review and discussion of the
changes, helping to show how and why changes were made, in addition to
who was involved.
Created by Ethan Galstad, the success of Nagios has been due to the
fantastic community members that support it and provide bug reports,
patches, and great ideas. See the
[THANKS file](https://raw.githubusercontent.com/NagiosEnterprises/nagioscore/master/THANKS)
for some of the many who have contributed since 1999.

351
THANKS Normal file
View File

@ -0,0 +1,351 @@
=======
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, misspelled it or otherwise got it
wrong, please let me know.
* Aaron Beck
* Adam Bowen
* Ahmon Dancy
* Alain Radix
* Albrecht Dress
* Alessandro Ren
* Alex Peeters
* Alexios Chouhoulas
* Allan Clark
* Alok Dubey
* Aman Gupta
* Amir Rosenblatt
* Anders K. Lindgren
* Andreas Ericsson
* Andreas Kirchwitz
* Andrew Kaplan
* Andrew Widdersheim
* Andy Finkenstadt
* Andy Shellam
* Anton Lofgren
* Ari Edelkind
* Armin Wolfermann
* Arne Hinrichsen
* Badri Pillai
* Bastian Friedrich
* Ben Bell
* Ben Heavner
* Bernard Li
* Bernd Arnold
* Bill Pier
* Bo Kersey
* Bob (Netshell)
* Bob Rentschler
* Bogdan Sandu
* Brad Werschler
* Brandon Knitter
* Brian Riggs
* Brian Seklecki
* Burkhard Klaus
* Carlos Velasco
* Cary Petterborg
* Charlie Cook
* Chris Bensend
* Chris Kolquist
* Chris Rothecker
* Chris Witterholt
* Christian Jung
* Christian Masopust
* Christian Mies
* Christian Zettel
* Christoph Biedl
* Christoph Kron
* Christoph Maser
* Cliff Woolley
* Dan Gailey
* Daniel Burke
* Daniel Koffler
* Daniel Pouzzner
* Daniel Wittenberg
* Darren Gamble
* Dave Viner
* David Allan
* David Kmoch
* David Schlecht
* David Tilloy
* David Walser
* Dawid Golunski
* Dean Lane
* Denis Seleznyov
* Dennis Biringer
* Derrick Bennett
* Devin Bayer
* Dietmar Rieder
* Dirkjan Bussink
* Don Carroll
* Duncan Ferguson
* Eirik Robertstad
* Emanuel Massano
* Ernst-Deiter Martin
* Erwan Arzur
* Esteban Manchado Velazquez
* Evan Winter
* Felipe Almeida
* Florian Weimer
* Fr3dY
* Fran Boon
* Franky Van Liedekerke
* Frederic Schaer
* Frederic Van Espen
* Gareth Randall
* Garry Cook
* Gary Berger
* Gary Miller
* Gavin Adams
* Geert Vanderkelen
* Gennaro Tortone
* Geoff Montee
* Gerd Mueller
* Gerhard Lausser
* gherteg
* Glenn Thompson
* Gordon Messmer
* Gordon Smith
* Grant Byers
* Greg Abrams
* Greg Woods
* Hayakawa Shinya
* Helmut Mikulcik
* Hendrik Baecker
* Henning Brauer
* Herbert Straub
* Hiren Patel
* Holger Weiss
* Horvath Tamas
* Hugo Gayosso
* Hugo Hallqvist
* Ian Blenke
* Ian Cass
* Igno Kley
* Ingo Lantschner
* Ivan Kuncl
* Jacob Lundqvist
* Jak Gibb
* James "Showkilr" Peterson
* James Maddison
* James Moseley
* Jan David
* Jan Grant
* Jan Vejvalka
* Janet Post
* Janice Singh
* Jason Blakey
* Jason Hedden
* Jean Gabes
* Jean-Eric Cuendet
* Jeff Cours
* Jeff Johnson
* Jeffrey Blank
* Jeffrey Goldschrafe
* Jeremy Bouse
* Jeremy Weatherford
* Jim Crilley
* Jim Dumser
* Jim Popovitch
* Jiri Kostern
* Jochen Bern
* Joel Berry
* Joel Crisp
* Joerg Linge
* John Calcote
* John Rouillard
* Jon Andrews
* Jonathan Clarke
* Jonathan Kamens
* Jonathan Saggau
* Jorge Sanchez
* Joseph Maiorana
* Josh Soref
* Josh Thorstad
* Justin Clarke
* Kai Kunstmann
* Kai Ung
* Karel Salavec
* Karl DeBisschop
* Karl Hegbloom
* Karsten Weiss
* Kenneth Ray
* Kevin Benton
* Kevin Stone
* Larry Low
* Lars Hansson
* Lars Hecking
* Lars Kellogg-Stedman
* Lars Michelson
* Lars Vogdt
* lev
* Lonny Selinger
* Lou Sneddon
* Ludo Bosmans
* Luigi Balzano
* Luiz Felipe R E
* Luke Ross
* Emmanuel Dreyfus
* Manuel Lanctot
* Marc Powell
* Marcus Fleige
* Marcus Hildenbrand
* Mario Trangoni
* Mark DeTrano
* Mark Felder
* Mark Frost
* Mark Goldfinch
* Mark Schenker
* Mark Spieth
* Markus Almroth
* Markus Baertschi
* Marlo Bell
* Martin Green
* Martin Mielke
* Mathieu Gagne
* Matt Ezell
* Matthew Grant
* Matthew Richardson
* Matthias Cramer
* Matthias Eble
* Matthias Eichler
* Matthias Flacke
* Matthias Flittner
* Matthias Kerk
* Matthieu Kermagoret
* Matthieu Kermagoret
* Mattias Ryrlen
* Max Schubert
* Max Sikstrom
* Michael Anthon
* Michael Bailey
* Michael Bunk
* Michael Little
* Michael Lubben
* Michael Marineau
* Michael O'Reilly
* Michael Orlitzky
* Michael Smedius
* Michal Zimen
* Michelle Craft
* Mika Fischer
* Mike Bird
* Mike Dorman
* Mike McHenry
* Mindaugas Riauba
* Mitch Wright
* Moshe Sharon
* Nate Shafer
* Nathan Grennan
* Nicholas Tang
* Nick Cleaton
* Nick Reinking
* Nick Shore
* Nikola Vassilev
* Olivier Beytrison
* Olivier Jan
* Parth Laxmikant Kolekar
* Patrick Proy
* Patrik Halfar
* Paul Kent
* Paul Pot
* Pavel Satrapa
* Pawel Zuzelski
* Pedro Leite
* Percy Jahn
* Perry Clarke
* Peter Ringe
* Peter Valdemar Morch
* Peter Westlake
* Petr Adamec
* Petya Kohts
* Phil Mayers
* Phil Randal
* Phil Walther
* Ralph Rossner
* Ray Bengen
* Remi Paulmier
* Rémi Verschelde
* Rene Klootwijk
* Ricardo Maraschini
* Richard Mayhew
* Rob Enders
* Rob Patrick
* Rob Remus
* Robert August Vincent II
* Robert Gash
* Robert Thompson
* Roberto Marrodan
* Robin Kearney
* Robin Sonefors
* Ronald Ho
* Rostislav Opočenský
* Russell Scibetti
* Ryan Skorstad
* Ryoji Kobayashi
* Sam Howard
* Sean Finney
* Sebastian Guarino
* Sebastian Wolf
* Sebastien Barbereau
* Sergio Guzman
* Shad Lords
* Simon Beale
* sq5bpf
* Stanley Hopcroft
* Stefan Rompf
* Stefan Schurtz
* Stephane Urbanovski
* Stephen Davies
* Stephen Gran
* Steve Underwood
* Steven Pokrandt
* Stewart James
* Stig Jacobsen
* Subhendu Ghosh
* SUSE Linux Team
* Sven Nierlein
* Sven Strickroth
* Sven-Göran Bergh
* Sylvain Falardeau
* Szabo Gabor
* Thomas Dohl
* Thomas Dunkel
* Thomas Guyot-Sionnest
* Thomas Hepper
* Thomas Sebastien
* Thomas Stolle
* Tim Starling
* Tim Wilde
* Time Niemueller
* Tobias Klausmann
* Tobias Mucke
* Todd Green
* Todd Wheeler
* Tom Bertelson
* Tom De Blende
* Tom Ryder
* Tom Welsh
* Tomer Okavi
* Ton Voon
* Torsten Huebler
* Troy Lea
* Tyler Lund
* Uwe Knop
* Uwe Knop
* Vadim Okun
* Vojtěch Širůček
* Volkan Yazici
* Volker Aust
* William Leibzon
* William Preston
* Wolfgang Barth
* xoubih
* Yves Rubin
* Zakhar Kleyman
* Z. Liu

26
UPGRADING Normal file
View File

@ -0,0 +1,26 @@
Upgrading Nagios Core
=====================
nagios-4.3.0 - 2017-02-21
-------------------------
If you use "corewindow", as in
http://localhost/nagios?corewindow=www.somewhere.com
note that this functionality has been disabled by default in this
release. If you still want to use it, run ./configure with the
parameter --enable-corewindow
nagios-3.0
----------
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)

7
aclocal.m4 vendored Executable file
View File

@ -0,0 +1,7 @@
m4_include([autoconf-macros/ax_nagios_get_os])
m4_include([autoconf-macros/ax_nagios_get_distrib])
m4_include([autoconf-macros/ax_nagios_get_init])
m4_include([autoconf-macros/ax_nagios_get_inetd])
m4_include([autoconf-macros/ax_nagios_get_paths])
m4_include([autoconf-macros/ax_nagios_get_files])
m4_include([autoconf-macros/ax_nagios_get_ssl])

1
autoconf-macros/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
nbproject/

View File

@ -0,0 +1,7 @@
1.0.1
-----
* Fix bug determining inetd,xinetd if neither are running (Bryan Heden)
1.0.0
-----
* Initial Release (John Frickson)

264
autoconf-macros/LICENSE Normal file
View File

@ -0,0 +1,264 @@
The GNU General Public License, Version 2, June 1991 (GPLv2)
============================================================
> Copyright (C) 1989, 1991 Free Software Foundation, Inc.
> 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 Lesser 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.
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.

1
autoconf-macros/LICENSE.md Symbolic link
View File

@ -0,0 +1 @@
LICENSE

199
autoconf-macros/README.md Normal file
View File

@ -0,0 +1,199 @@
autoconf-macros
===============
The purpose of Nagios autoconf-macros is to have a central place for
autoconf macros that can be maintained in one place, but be used by any
of the Nagios software. It is intended to be used as a git subtree.
See the [Usage](#usage) and [References](#references) sections below.
Since this project will be included in several parent projects, any
changes must be as project-neutral as possible.
Make sure to check out the [CHANGELOG](CHANGELOG.md) for relevant
information, as well.
Contents
--------
The collection consists of the following macros:
### AX_NAGIOS_GET_OS alias AC_NAGIOS_GET_OS
> Output Variable : `opsys`
This macro detects the operating system, and transforms it into a generic
label. The most common OS's that use Nagios software are recognized and
used in subsequent macros.
### AX_NAGIOS_GET_DISTRIB_TYPE alias AC_NAGIOS_GET_DISTRIB_TYPE
> Output Variables : `dist_type`, `dist_ver`
This macro detects the distribution type. For Linux, this would be rh
(for Red Hat and derivatives), suse (OpenSUSE, SLES, derivatives), gentoo
(Gentoo and derivatives), debian (Debian and derivatives), and so on.
For BSD, this would be openbsd, netbsd, freebsd, dragonfly, etc. It can
also be aix, solaris, osx, and so on for Unix operating systems.
### AX_NAGIOS_GET_INIT alias AC_NAGIOS_GET_INIT
> Output Variable : `init_type`
This macro detects what software is used to start daemons on bootup
or on request, generally knows as the "init system". The init_type
will generally be one of sysv (many), bsd (Slackware), newbsd (*BSD),
launchd (OS X), smf10 or smf11 (Solaris), systemd (newer Linux),
gentoo (older Gentoo), upstart (several), or unknown.
### AX_NAGIOS_GET_INETD alias AC_NAGIOS_GET_INETD
> Output Variable : `inetd_type`
This macro detects what software is used to start daemons or services
on demand, which historically has been "inetd". The inetd_type
will generally be one of inetd, xinetd, launchd (OS X), smf10 or smf11
(Solaris), systemd (newer Linux), upstart (several), or unknown.
### AX_NAGIOS_GET_PATHS alias AC_NAGIOS_GET_PATHS
> Output Variables : **many!**
This macro determines the installation paths for binaries, config files,
PID files, and so on. For a "standard" install of Nagios, NRPE, NDO Utils,
etc., most will be in the /usr/local/nagios hierarchy with startup files
located in /etc. For distributions or software repositories, the
"--enable-install-method=os" option can be used. This will determine the
O/S dependent directories, such as /usr/bin, /usr/sbin, /var/lib/nagios,
/usr/lib/nagios, etc. or for OS X, /Library/LaunchDaemons.
### AX_NAGIOS_GET_FILES alias AC_NAGIOS_GET_FILES
> Output Variables : `src_init`, `src_inetd`, `src_tmpfile`
Each Nagios project will have a top-level directory named "/startup/".
In that directory will be "*.in" files for the various "init_type" and
"inetd_type" systems. This macro will determine which file(s) from
that directory will be needed.
### AX_NAGIOS_GET_SSL alias AC_NAGIOS_GET_SSL
> Output Variables : `HAVE_KRB5_H`, `HAVE_SSL`, `SSL_INC_DIR`, `SSL_LIB_DIR`, `CFLAGS`, `LDFLAGS`, `LIBS`
This macro checks various directories for SSL libraries and header files.
The searches are based on known install locations on various operating
systems and distributions, for openssl, gnutls-openssl, and nss_compat_ossl.
If it finds the headers and libraries, it will then do an `AC_LINK_IFELSE`
on a simple program to make sure a compile and link will work correctly.
Usage
-----
This repo is intended to be used as a git subtree, so changes will
automatically propagate, and still be reasonably easy to use.
* First, Create, checkout, clone, or branch your project. If you do an
`ls -AF` it might look something like this:
.git/ .gitignore ChangeLog LICENSE Makefile.in
README configure.ac include/ src/
* Then make a reference to _this_ project inside your project.
git remote add autoconf-macros git@github.com:NagiosEnterprises/autoconf-macros
git subtree add --prefix=macros/ autoconf-macros master
* After executing the above two commands, if you do an `ls -AF` now,
it should look like this:
.git/ .gitignore ChangeLog LICENSE Makefile.in
README configure.ac include/ macros/ src/
* The `macros/` directory has been added.
* Now do a `git push` to save everything.
* If you make any changes to autoconf-macros, commit them separately
from any parent-project changes to keep from polluting the commit
history with unrelated comments.
* To submit your changes to autoconf-macros:
git subtree push --prefix=macros autoconf-macros peters-updates
This will create a new branch called `peters-updates`. You then need to
create a _pull request_ to get your changes merged into autoconf-macros
master.
* To get the latest version of `autoconf-macros` into your parent project:
git subtgree pull --squash --prefix=macros autoconf-macros master
References
----------
Now that autoconf-macros is available to your project, you will need to
reference it.
* Create (or add these lines to) file `YourProject/aclocal.m4`
m4_include([macros/ax_nagios_get_os])
m4_include([macros/ax_nagios_get_distrib])
m4_include([macros/ax_nagios_get_init])
m4_include([macros/ax_nagios_get_inetd])
m4_include([macros/ax_nagios_get_paths])
m4_include([macros/ax_nagios_get_files])
m4_include([macros/ax_nagios_get_ssl])
* In your `YourProject/configure.ac` add the following lines. A good place
to put them would be right after any `AC_PROG_*` entries:
AC_NAGIOS_GET_OS
AC_NAGIOS_GET_DISTRIB_TYPE
AC_NAGIOS_GET_INIT
AC_NAGIOS_GET_INETD
AC_NAGIOS_GET_PATHS
AC_NAGIOS_GET_FILES
* If you need SSL functionality, add the following to `YourProject/configure.ac`
where you want to check for SSL:
AC_NAGIOS_GET_SSL
* You will now be able to reference any of the variables in `config.h.in`
and any files listed in the `AC_CONFIG_FILES` macro in `configure.ac`.
License Notice
--------------
Copyright (c) 2016-2017 Nagios Enterprises, LLC
This work is made available to you under the terms of Version 2 of
the GNU General Public License. A copy of that license should have
been provided with this software, but in any event can be obtained
from http://www.fsf.org.
This work 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 or visit their web page on the internet at
http://www.fsf.org.
Questions?
----------
If you have questions about this addon, or problems getting things
working, first try searching the nagios-users mailing list archives.
Details on searching the list archives can be found at
http://www.nagios.org
If you don't find an answer there, post a message in the Nagios
Plugin Development forum at https://support.nagios.com/forum/viewforum.php?f=35

164
autoconf-macros/add_group_user Executable file
View File

@ -0,0 +1,164 @@
#!/bin/sh
#----------------------
# Initialize variables
#----------------------
dist="$1"
uid="$2"
gid="$3"
rc=0
#------------------------------------------------------------------
# Determine if the user should be created with a shell environment
# 0 = no shell (more secure)
# 1 = shell (less secure but sometimes required)
#------------------------------------------------------------------
shell=0
if [ $# -eq 4 ]; then
if [ x$4 = x1 ]; then
shell=1
fi
fi
#-------------------------------------
# Check if the specified group exists
#-------------------------------------
group_exists(){
case $dist in
osx) rc=`dscl . -read /Groups/$gid >/dev/null 2>&1; echo $?` ;;
hpux) rc=`grget -n $gid >/dev/null 2>&1; echo $?` ;;
aix) rc=`lsgroup -a $gid >/dev/null 2>&1; echo $?` ;;
*) rc=`getent group $gid > /dev/null 2>&1; echo $?` ;;
esac
echo $rc
}
#------------------------
# Add the specified user
#------------------------
add_user(){
rc=`id "$uid" > /dev/null 2>&1; echo $?`
if test $rc -eq 0; then
echo "User $uid already exists" > /dev/stderr
echo 0
return
fi
case $dist in
aix)
echo useradd -g $gid $uid > /dev/stderr
rc=`useradd -g $gid $uid; echo $?`
;;
hpux)
echo useradd -m -g $gid $uid > /dev/stderr
rc=`useradd -m -g $gid $uid; echo $?`
;;
solaris)
echo useradd -m -d /export/home/$uid -g $gid $uid > /dev/stderr
rc=`useradd -m -d /export/home/$uid -g $gid $uid; echo $?`
;;
osx)
newid=`dscl . -list /Users UniqueID | tr -s ' ' | cut -d' ' -f2 | sort -n | tail -1`
newid=`expr 1 + $newid`
echo dscl . -create /Users/$uid > /dev/stderr
dscl . -create /Users/$uid
echo dscl . -create /Users/$uid UniqueID $newid > /dev/stderr
dscl . -create /Users/$uid UniqueID $newid
if [ $shell = 0 ]; then
echo dscl . -create /Users/$uid UserShell /usr/bin/false > /dev/stderr
dscl . -create /Users/$uid UserShell /usr/bin/false
fi
echo dscl . -create /Users/$uid PrimaryGroupID 20 > /dev/stderr
dscl . -create /Users/$uid PrimaryGroupID 20
echo dscl . -append /Groups/$gid GroupMembership $uid > /dev/stderr
rc=`dscl . -append /Groups/$gid GroupMembership $uid; echo $?`
;;
freebsd)
if [ $shell = 0 ]; then
echo pw add user $uid -g $gid -s /usr/bin/false > /dev/stderr
rc=`pw add user $uid -g $gid -s /usr/bin/false; echo $?`
else
echo pw add user $uid -g $gid > /dev/stderr
rc=`pw add user $uid -g $gid; echo $?`
fi
;;
netbsd|openbsd)
echo useradd -g $gid $uid > /dev/stderr
rc=`useradd -g $gid $uid; echo $?`
;;
*)
if [ $shell = 0 ]; then
echo useradd -r -g $gid $uid > /dev/stderr
rc=`useradd -r -g $gid $uid; echo $?`
else
echo useradd -g $gid $uid > /dev/stderr
rc=`useradd -g $gid $uid; echo $?`
fi
;;
esac
echo $rc
}
#-------------------------
# Add the specified group
#-------------------------
add_group(){
rc=`group_exists`
if test $rc -eq 0; then
echo "Group $gid already exists" > /dev/stderr
echo 0
return
fi
case $dist in
aix)
echo mkgroup $gid > /dev/stderr
rc=`mkgroup "$gid"; echo $?`
;;
hpux|solaris)
echo groupadd $gid > /dev/stderr
rc=`groupadd "$gid"; echo $?`
;;
osx)
newid=`dscl . -list /Groups gid | tr -s ' ' | cut -d' ' -f2 | sort -n | tail -1`
newid=`expr 1 + $newid`
echo dscl . -create /Groups/$gid gid $newid > /dev/stderr
rc=`dscl . -create /Groups/$gid gid $newid; echo $?`
;;
freebsd)
echo pw add group $gid > /dev/stderr
rc=`pw add group $gid; echo $?`
;;
netbsd|openbsd)
echo groupadd $gid > /dev/stderr
rc=`groupadd $gid; echo $?`
;;
*)
echo groupadd -r $gid > /dev/stderr
rc=`groupadd -r $gid; echo $?`
;;
esac
echo $rc
}
rc=`add_group`
if test $rc -ne 0; then
exit 1;
fi
rc=`add_user`
exit $rc

View File

@ -0,0 +1,160 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_DISTRIB_TYPE
#
# DESCRIPTION
#
# This macro determines the O/S distribution of the computer it is run on.
# $dist_type will be set and will be one of:
# unknown (could not be determined)
# freebsd, netbsd, openbsd, dragonfly, etc (The BSDs)
# suse, rh, debian, gentoo (and possibly their descendants)
# Other major Linux distributions (and possibly their descendants)
# The O/S name for the rest
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_DISTRIB_TYPE], [AX_NAGIOS_GET_DISTRIB_TYPE])
AC_DEFUN([AX_NAGIOS_GET_DISTRIB_TYPE],
[
AC_SUBST(dist_type)
AC_SUBST(dist_ver)
#
# Get user hints for possible cross-compile
#
AC_MSG_CHECKING(what the distribution type is )
AC_ARG_WITH(dist-type, AC_HELP_STRING([--with-dist-type=type],
[specify distribution type (suse, rh, debian, etc.)]),
[
#
# Run this if --with was specified
#
if test "x$withval" = x -o x$withval = xno; then
dist_type_wanted=yes
else
dist_type_wanted=no
dist_type="$withval"
dist_ver="unknown"
AC_MSG_RESULT($dist_type)
fi
], [
#
# Run this if --with was not specified
#
dist_type_wanted=yes
])
if test x$dist_type = xno; then
dist_type_wanted=yes
elif test x$dist_type = xyes; then
AC_MSG_ERROR([you must enter a distribution type if '--with-dist-type' is specified])
fi
#
# Determine distribution type if it wasn't supplied
#
dist_ver="unknown"
if test $dist_type_wanted=yes; then
dist_type="unknown"
if test "$opsys" != "linux"; then
dist_type="$opsys"
AS_CASE([$opsys],
[bsd],
dist_type=`uname -s | tr ["[A-Z]" "[a-z]"]`
dist_ver=`uname -r`,
[aix],
dist_ver="`uname -v`.`uname -r`",
[hp-ux],
dist_ver=`uname -r | cut -d'.' -f1-3`,
[solaris],
dist_ver=`uname -r | cut -d'.' -f2`,
[*],
dist_ver=$OSTYPE
)
else
if test -r "/etc/gentoo-release"; then
dist_type="gentoo"
dist_ver=`cat /etc/gentoo-release`
elif test -r "/etc/os-release"; then
. /etc/os-release
if test x"$ID_LIKE" != x; then
dist_type=`echo $ID_LIKE | cut -d' ' -f1 | tr ["[A-Z]" "[a-z]"]`
elif test x"$ID" = xol; then
dist_type=rh
else
dist_type=`echo $ID | tr ["[A-Z]" "[a-z]"]`
fi
if test x"$dist_type" = sles; then
dist_type=suse
fi
if test x"$VERSION_ID" != x; then
dist_ver=$VERSION_ID
elif test x"$VERSION" != x; then
dist_ver=`echo $VERSION | cut -d'.' -f1 | tr -d [:alpha:][:blank:][:punct:]`
fi
elif test -r "/etc/redhat-release"; then
dist_type=rh
dist_ver=`cat /etc/redhat-release`
elif test -r "/etc/debian_version"; then
dist_type="debian"
if test -r "/etc/lsb-release"; then
. /etc/lsb-release
dist_ver=`echo "$DISTRIB_RELEASE"`
else
dist_ver=`cat /etc/debian_version`
fi
elif test -r "/etc/SuSE-release"; then
dist_type=suse
dist_ver=`grep VERSION /etc/SuSE-release`
fi
fi
if test "$dist_ver" != "unknown"; then
dist_ver=`echo "$dist_ver" | cut -d'.' -f1 | tr -d [:alpha:][:blank:][:punct:]`
fi
fi
AC_MSG_RESULT($dist_type)
])

View File

@ -0,0 +1,131 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_FILES
#
# DESCRIPTION
#
# This macro figures out which init and/or inetd files to use based
# on the results of the AX_NAGIOS_GET_OS, AX_NAGIOS_GET_DISTRIB_TYPE,
# AX_NAGIOS_GET_INIT and AX_NAGIOS_GET_INETD macros. It will select
# the appropriate files(s) from the 'startup' directory and copy it.
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_FILES], [AX_NAGIOS_GET_FILES])
AC_DEFUN([AX_NAGIOS_GET_FILES],
[
AC_SUBST(src_init)
AC_SUBST(src_inetd)
AC_SUBST(src_tmpfile)
AC_SUBST(bsd_enable)
src_inetd=""
src_init=""
bsd_enable=""
AC_MSG_CHECKING(for which init file to use )
AS_CASE([$init_type],
[sysv],
src_init=default-init,
[systemd],
src_tmpfile=tmpfile.conf
src_init=default-service,
[bsd],
src_init=bsd-init,
[newbsd],
if test $dist_type = freebsd ; then
bsd_enable="_enable"
src_init=default-init
elif test $dist_type = openbsd ; then
bsd_enable="_flags"
src_init=openbsd-init
elif test $dist_type = netbsd ; then
bsd_enable=""
src_init=newbsd-init
fi,
# [gentoo],
[openrc],
src_init=openrc-init,
[smf*],
src_init="solaris-init.xml"
src_inetd="solaris-inetd.xml",
[upstart],
if test $dist_type = rh ; then
src_init=rh-upstart-init
else
src_init=upstart-init
fi,
[launchd],
src_init="mac-init.plist",
[*],
src_init="unknown"
)
AC_MSG_RESULT($src_init)
AC_MSG_CHECKING(for which inetd files to use )
if test x$src_inetd = x; then
AS_CASE([$inetd_type],
[inetd*],
src_inetd=default-inetd,
[xinetd],
src_inetd=default-xinetd,
[systemd],
src_inetd=default-socket,
[launchd],
src_inetd="mac-inetd.plist",
[*],
src_inetd="unknown"
)
fi
AC_MSG_RESULT($src_inetd)
])

View File

@ -0,0 +1,146 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_INETD
#
# DESCRIPTION
#
# This macro determines whether inetd or xinetd is being used
# The argument are:
# the init type as determined by AX_NAGIOS_GET_INIT
# $inetd_type will be set and will be one of:
# unknown (could not be determined)
# launchd (Mac OS X)
# smf10 (Solaris)
# smf11 (Solaris)
# upstart (Older Debian)
# xinetd (Most Linux, BSD)
# inetd (The rest)
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_INETD], [AX_NAGIOS_GET_INETD])
AC_DEFUN([AX_NAGIOS_GET_INETD],
[
AC_SUBST(inetd_type)
#
# Get user hints for possible cross-compile
#
AC_MSG_CHECKING(what inetd is being used )
AC_ARG_WITH(inetd_type, AC_HELP_STRING([--with-inetd-type=type],
[which super-server the system runs (inetd, xinetd, systemd, launchd,
smf10, smf11, etc.)]),
[
inetd_type_wanted=yes
#
# Run this if --with was specified
#
if test "x$withval" = x -o x$withval = xno; then
inetd_type_wanted=yes
else
inetd_type_wanted=no
inetd_type="$withval"
AC_MSG_RESULT($inetd_type)
fi
], [
#
# Run this if --with was not specified
#
inetd_type_wanted=yes
])
if test x$inetd_type = xno; then
inetd_type_wanted=yes
elif test x$inetd_type = xyes; then
AC_MSG_ERROR([you must enter an inetd type if '--with-inetd-type' is specified])
fi
#
# Determine inetd type if it wasn't supplied
#
if test $inetd_type_wanted = yes; then
inetd_disabled=""
AS_CASE([$dist_type],
[solaris],
if test x"$init_type" = "xsmf10" -o x"$init_type" = "xsmf11"; then
inetd_type="$init_type"
else
inetd_type="inetd"
fi,
[*bsd*],
inetd_type=`ps -A -o comm -c | grep inetd`,
[osx],
inetd_type=`launchd`,
[aix|hp-ux],
inetd_type=`UNIX95= ps -A -o comm | grep inetd | head -1`,
[*],
inetd_type=[`ps -C "inetd,xinetd" -o fname | grep -vi COMMAND | head -1`])
if test x"$inetd_type" = x; then
if test -f /etc/xinetd.conf -a -d /etc/xinetd.d; then
inetd_disabled="(Not running)"
inetd_type=xinetd
elif test -f /etc/inetd.conf -o -f /usr/sbin/inetd; then
inetd_type=inetd
inetd_disabled="(Not running)"
fi
fi
if test x"$inetd_type" = x; then
if test x"$init_type" = "xupstart"; then
inetd_type="upstart"
fi
fi
if test x"$inetd_type" = x; then
if test x"$init_type" = "xsystemd"; then
inetd_type="systemd"
else
inetd_type="unknown"
fi
fi
if test -n "$inetd_disabled"; then
AC_MSG_RESULT($inetd_type $inetd_disabled)
else
AC_MSG_RESULT($inetd_type)
fi
fi
])

View File

@ -0,0 +1,200 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_INIT
#
# DESCRIPTION
#
# This macro determines the O/S distribution of the computer it is run on.
# $init_type will be set and will be one of:
# unknown (could not be determined)
# launchd (Mac OS X)
# bsd (Slackware Linux)
# newbsd (FreeBSD, OpenBSD, NetBSD, Dragonfly, etc)
# smf10 (Solaris)
# smf11 (Solaris)
# systemd (Linux SystemD)
# gentoo (Older Gentoo)
# openrc (Recent Gentoo and some others)
# upstart (Older Debian)
# sysv (The rest)
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_INIT], [AX_NAGIOS_GET_INIT])
AC_DEFUN([AX_NAGIOS_GET_INIT],
[
AC_SUBST(init_type)
#
# Get user hints for possible cross-compile
#
AC_MSG_CHECKING(what init system is being used )
AC_ARG_WITH(init_type,AC_HELP_STRING([--with-init-type=type],
[specify init type (bsd, sysv, systemd, launchd, smf10, smf11, upstart,
openrc, etc.)]),
[
#
# Run this if --with was specified
#
if test "x$withval" = x -o x$withval = xno; then
init_type_wanted=yes
else
init_type_wanted=no
init_type="$withval"
AC_MSG_RESULT($init_type)
fi
], [
#
# Run this if --with was not specified
#
init_type_wanted=yes
])
if test x$init_type = xno; then
init_type_wanted=yes
elif test x$init_type = xyes; then
AC_MSG_ERROR([you must enter an init type if '--with-init-type' is specified])
fi
#
# Determine init type if it wasn't supplied
#
if test $init_type_wanted = yes; then
init_type=""
if test x"$opsys" = x; then
init_type="unknown"
init_type_wanted=no
elif test x"$dist_type" = x; then
init_type="unknown"
init_type_wanted=no
elif test "$opsys" = "osx"; then
init_type="launchd"
init_type_wanted=no
elif test "$opsys" = "bsd"; then
init_type="newbsd"
init_type_wanted=no
elif test "$dist_type" = "solaris"; then
if test -d "/lib/svc/manifest"; then
init_type="smf11"
init_type_wanted=no
elif test -d "/lib/svc/monitor"; then
init_type="smf10"
init_type_wanted=no
else
init_type="sysv"
init_type_wanted=no
fi
elif test "$dist_type" = "slackware"; then
init_type="bsd"
init_type_wanted=no
elif test "$dist_type" = "aix"; then
init_type="bsd"
init_type_wanted=no
elif test "$dist_type" = "hp-ux"; then
init_type="unknown"
init_type_wanted=no
fi
fi
PSCMD="ps -p1 -o args"
if test $dist_type = solaris; then
PSCMD="env UNIX95=1; ps -p1 -o args"
fi
if test "$init_type_wanted" = yes; then
pid1=`$PSCMD | grep -vi COMMAND | cut -d' ' -f1`
if test x"$pid1" = "x"; then
init_type="unknown"
init_type_wanted=no
fi
if `echo $pid1 | grep "systemd" > /dev/null`; then
init_type="systemd"
init_type_wanted=no
fi
if test "$init_type_wanted" = yes; then
if test "$pid1" = "init"; then
if test -e "/sbin/init"; then
pid1="/sbin/init";
elif test -e "/usr/sbin/init"; then
pid1="/usr/sbin/init"
else
init_type="unknown"
init_type_wanted=no
fi
fi
if test -L "$pid1"; then
pid1=`readlink "$pid1"`
fi
fi
if test "$init_type_wanted" = yes; then
if `echo $pid1 | grep "systemd" > /dev/null`; then
init_type="systemd"
init_type_wanted=no
elif test -f "/sbin/rc"; then
if test -f /sbin/runscript; then
init_type_wanted=no
if `/sbin/start-stop-daemon -V | grep "OpenRC" > /dev/null`; then
init_type="openrc"
else
init_type="gentoo"
fi
fi
fi
fi
if test "$init_type_wanted" = yes; then
if test "$pid1" = "/sbin/init" -o "$pid1" = "/usr/sbin/init"; then
if `$pid1 --version 2>/dev/null | grep "upstart" >/dev/null`; then
init_type="upstart"
init_type_wanted=no
elif test -f "/etc/rc" -a ! -L "/etc/rc"; then
init_type="newbsd"
init_type_wanted=no
else
init_type="sysv"
init_type_wanted=no
fi
fi
fi
if test "$init_type_wanted" = yes; then
init_type="unknown"
fi
fi
AC_MSG_RESULT($init_type)
])

View File

@ -0,0 +1,101 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_OS
#
# DESCRIPTION
#
# This macro determines the operating system of the computer it is run on.
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_OS], [AX_NAGIOS_GET_OS])
AC_DEFUN([AX_NAGIOS_GET_OS],
[
AC_SUBST(opsys)
AC_SUBST(arch)
#
# Get user hints
#
AC_MSG_CHECKING(what the operating system is )
AC_ARG_WITH(opsys, AC_HELP_STRING([--with-opsys=OS],
[specify operating system (linux, osx, bsd, solaris, irix, cygwin,
aix, hp-ux, etc.)]),
[
#
# Run this if --with was specified
#
if test "x$withval" = x -o x$withval = xno; then
opsys_wanted=yes
else
opsys_wanted=no
opsys="$withval"
AC_MSG_RESULT($opsys)
fi
], [
#
# Run this if --with was not specified
#
opsys_wanted=yes
])
if test x$opsys = xno; then
opsys=""
opsys_wanted=yes
elif test x$opsys = xyes; then
AC_MSG_ERROR([you must enter an O/S type if '--with-opsys' is specified])
fi
#
# Determine operating system if it wasn't supplied
#
if test $opsys_wanted=yes; then
opsys=`uname -s | tr ["[A-Z]" "[a-z]"]`
if test x"$opsys" = "x"; then opsys="unknown"; fi
AS_CASE([$opsys],
[darwin*], opsys="osx",
[*bsd*], opsys="bsd",
[dragonfly], opsys="bsd",
[sunos], opsys="solaris",
[gnu/hurd], opsys="linux",
[irix*], opsys="irix",
[cygwin*], opsys="cygwin",
[mingw*], opsys="mingw",
[msys*], opsys="msys")
fi
arch=`uname -m | tr ["[A-Z]" "[a-z]"]`
AC_MSG_RESULT($opsys)
])

View File

@ -0,0 +1,783 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_PATHS
#
# DESCRIPTION
#
# This macro figures out the installation & run paths for various systems
# The argument are:
# the O/S determined by the AX_NAGIOS_GET_OS macro.
# the distribution type as determined by AX_NAGIOS_GET_DISTRIB_TYPE
# the init type as determined by AX_NAGIOS_GET_INIT
# the inetd type as determined by AX_NAGIOS_GET_INETD
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_PATHS], [AX_NAGIOS_GET_PATHS])
AC_DEFUN([AX_NAGIOS_GET_PATHS],
[
AC_SUBST(pkgsysconfdir)
AC_SUBST(objsysconfdir)
AC_SUBST(initname)
AC_SUBST(inetdname)
AC_SUBST(pluginsdir)
AC_SUBST(brokersdir)
AC_SUBST(cgibindir)
AC_SUBST(webdir)
AC_SUBST(privatesysconfdir)
AC_SUBST(pkglocalstatedir)
AC_SUBST(logdir)
AC_SUBST(piddir)
AC_SUBST(pipedir)
AC_SUBST(spooldir)
AC_SUBST(initdir)
AC_SUBST(initdiroverridden)
AC_SUBST(inetddir)
AC_SUBST(tmpfilesd)
AC_SUBST(subsyslockdir)
AC_SUBST(subsyslockfile)
if test x$DBG_PATHS != x; then
echo
echo Incoming paths:
echo " prefix $prefix"
echo " exec_prefix $exec_prefix"
echo " bindir $bindir"
echo " libexecdir $libexecdir"
echo " sysconfdir $sysconfdir"
echo " localstatedir $localstatedir"
echo " datarootdir $datarootdir"
echo " datadir $datadir"
echo " localedir $localedir"
echo
fi
AC_MSG_CHECKING(for which paths to use )
AC_ARG_ENABLE(install_method,
AC_HELP_STRING([--enable-install-method=<method>],
[sets the install method to use: 'default' (the default) will install to
/usr/local/nagios, 'os' will try to determine which method to use based
on OS type and distribution. Fine tuning using the '--bindir', etc.
overrides above will still work]),
install_method=$enableval,
install_method=default
)
AC_ARG_ENABLE(showdirs_only,
AC_HELP_STRING([--enable-showdirs-only=yes],
[This option will cause 'configure' to stop after determining the install
locations based on '--enable-install-method', so you can see the
destinations before a full './configure', 'make', 'make install'
process.]),
showdirs_only=$enableval,
showdirs_only=no
)
AS_CASE([$install_method],
[yes], install_method="os",
[no], install_method="default",
[default|os], :,
[*], echo >&6; AC_MSG_ERROR(['--enable-install-method=$install_method' is invalid])
)
if test $showdirs_only != "no"; then showdirs_only="yes"; fi
AS_CASE([$dist_type],
[*solaris*|*hp-ux*|*aix*|*osx*], opsys=unix)
# Does this package need to know:
need_cgi=no # where the cgi-bin directory is
need_web=no # where the website directory is
need_brk=no # where the event broker modules directory is
need_plg=no # where the plugins directory is
need_pipe=no # where the pipe directory is
need_spl=no # where the spool directory is
need_loc=no # where the locale directory is
need_log_subdir=no # where the loc sub-directory is
need_etc_subdir=no # where the etc sub-directory is
need_pls_dir=no # where the package locate state directory is
if test x"$INIT_PROG" = x; then
INIT_PROG="$PKG_NAME"
fi
AS_CASE([$PKG_NAME],
[nagios],
need_log_subdir=yes
need_etc_subdir=yes
need_pls_dir=yes
need_brk=yes
need_pipe=yes
need_spl=yes
need_loc=yes
need_cgi=yes
need_web=yes,
[ndoutils],
need_brk=yes
need_spl=yes,
[nrpe],
need_plg=yes,
[nsca],
need_cgi=no,
[plugins],
need_loc=yes
need_plg=yes
)
AC_ARG_WITH(pkgsysconfdir, AC_HELP_STRING([--with-pkgsysconfdir=DIR],
[where configuration files should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
pkgsysconfdir="$withval"
fi)
AC_ARG_WITH(objsysconfdir, AC_HELP_STRING([--with-objsysconfdir=DIR],
[where object configuration files should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
objsysconfdir="$withval"
fi)
AC_ARG_WITH(privatesysconfdir, AC_HELP_STRING([--with-privatesysconfdir=DIR],
[where private configuration files should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
privatesysconfdir="$withval"
fi)
AC_ARG_WITH(webdir, AC_HELP_STRING([--with-webdir=DIR],
[where the website files should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
webdir="$withval"
fi)
AC_ARG_WITH(pluginsdir, AC_HELP_STRING([--with-pluginsdir=DIR],
[where the plugins should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
pluginsdir="$withval"
fi)
AC_ARG_WITH(brokersdir, AC_HELP_STRING([--with-brokersdir=DIR],
[where the broker modules should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
brokersdir="$withval"
fi)
AC_ARG_WITH(cgibindir, AC_HELP_STRING([--with-cgibindir=DIR],
[where the CGI programs should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
cgibindir="$withval"
fi)
AC_ARG_WITH(logdir, AC_HELP_STRING([--with-logdir=DIR],
[where log files should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
logdir="$withval"
fi)
AC_ARG_WITH(piddir, AC_HELP_STRING([--with-piddir=DIR],
[where the PID file should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
piddir="$withval"
fi)
AC_ARG_WITH(pipedir, AC_HELP_STRING([--with-pipedir=DIR],
[where socket and pipe files should be placed]),
if test x$withval != x -a x$withval != xno -a x$withval != xyes; then
pipedir="$withval"
fi)
#
# Setup the base directory
#
if test $install_method = "default"; then
if test $opsys = "unix"; then
if test x"$prefix" = "xNONE"; then prefix="/usr/local/nagios"; fi
else
if test x"$prefix" = "xNONE"; then prefix=${ac_default_prefix}; fi
fi
datarootdir=${datarootdir="$prefix"}
else
if test x"$datadir" = x'${datarootdir}'; then AS_UNSET(datadir); fi
if test x"$sysconfdir" = x'${prefix}/etc'; then AS_UNSET(sysconfdir); fi
if test x"$prefix" = "xNONE"; then
if test $dist_type = freebsd -o $dist_type = openbsd -o $dist_type = osx; then
prefix="/usr/local"
elif test $dist_type = netbsd; then
prefix="/usr/pkg"
else
prefix="/usr"
fi
fi
if test x"$exec_prefix" = "xNONE"; then exec_prefix=$prefix; fi
if test x"$localstatedir" = x'${prefix}/var'; then
if test $dist_type = "osx"; then
localstatedir="/private/var"
else
localstatedir="/var"
fi
fi
if test $opsys = "unix"; then
if test x"$datarootdir" = x'${prefix}/share'; then
if test $dist_type = "hp-ux"; then
datarootdir="/usr/local/share"
if test x"$libexecdir" = x'${exec_prefix}/libexec'; then
libexecdir="/usr/nagios"
fi
elif test $dist_type = "osx"; then
datarootdir="/usr/local/share"
if test x"$libexecdir" = x'${exec_prefix}/libexec'; then
libexecdir="/usr/local/nagios"
fi
elif test x"$libexecdir" = x'${exec_prefix}/libexec'; then
libexecdir="/usr/lib/nagios"
fi
fi
if test $dist_type = "osx"; then
if test x"$libexecdir" = x'${exec_prefix}/libexec'; then
libexecdir="/usr/local/libexec/nagios"
fi
fi
elif test $opsys = "bsd"; then
if test x"$libexecdir" = x'${exec_prefix}/libexec'; then
libexecdir=${exec_prefix}/libexec/nagios;
fi
elif test x"$libexecdir" = x'${exec_prefix}/lib'; then
libexecdir=${libexecdir}/nagios;
elif test x"$libexecdir" = x'${exec_prefix}/libexec'; then
libexecdir=${exec_prefix}/lib/nagios;
fi
fi
if test x"$exec_prefix" = "xNONE"; then exec_prefix=${prefix}; fi
tmpfilesd=${tmpfilesd="/usr/lib/tmpfiles.d"}
if test ! -d "$tmpfilesd"; then
tmpfilesd="N/A"
else
tmpfilesd="$tmpfilesd/$INIT_PROG.conf"
fi
subsyslockdir=${subsyslockdir="/run"}
if test ! -d "$subsyslockdir"; then
subsyslockdir="N/A"
subsyslockfile="N/A"
else
subsyslockfile="$subsyslockdir/$INIT_PROG.lock"
fi
if test "$need_loc" = no; then
localedir="N/A"
fi
if test $install_method = "default" ; then
#
# Do the default setup
#
datadir=${datadir="$datarootdir"}
if test $need_web = yes; then
webdir=${webdir="$datadir"}
else
webdir="N/A"
fi
if test $opsys = "unix"; then
sysconfdir=${sysconfdir="/etc/opt"}
fi
pkgsysconfdir=${pkgsysconfdir="$sysconfdir"}
if test $need_etc_subdir = yes; then
objsysconfdir=${objsysconfdir="$pkgsysconfdir/objects"}
else
objsysconfdir="N/A"
fi
privatesysconfdir=${privatesysconfdir="$pkgsysconfdir"}
logdir=${logdir="$localstatedir"}
piddir=${piddir="$localstatedir"}
if test "$need_pipe" = yes; then
pipedir=${pipedir="$localstatedir/rw"}
else
pipedir="N/A"
fi
if test "$need_pls_dir" = yes; then
pkglocalstatedir=${pkglocalstatedir="$localstatedir"}
else
pkglocalstatedir="N/A"
fi
if test "$need_spl" = yes; then
spooldir=${spooldir="$localstatedir/var"}
else
spooldir="N/A"
fi
if test $need_brk = yes; then
brokersdir=${brokersdir="$bindir"}
else
brokersdir="N/A"
fi
if test $need_plg = yes; then
pluginsdir=${pluginsdir="$libexecdir"}
else
pluginsdir="N/A"
fi
if test $need_cgi = yes; then
cgibindir=${cgibindir="$prefix/sbin"}
else
cgibindir="N/A"
fi
elif test $opsys = "linux"; then
#
# Linux "Standard" install
#
install_method="$install_method : FHS"
datadir=${datadir="$datarootdir/nagios"}
if test $need_web = yes; then
webdir=${webdir="$datadir/html"}
else
webdir="N/A"
fi
sysconfdir=${sysconfdir="/etc"}
pkgsysconfdir=${pkgsysconfdir="$sysconfdir/nagios"}
if test $need_etc_subdir = yes; then
objsysconfdir=${objsysconfdir="$pkgsysconfdir/objects"}
else
objsysconfdir="N/A"
fi
privatesysconfdir=${privatesysconfdir="$pkgsysconfdir/private"}
if test $need_log_subdir = yes; then
logdir=${logdir="$localstatedir/log/$INIT_PROG"}
else
logdir=${logdir="$localstatedir/log"}
fi
piddir=${piddir="$localstatedir/run/${INIT_PROG}"}
if test "$need_pipe" = yes; then
pipedir=${pipedir="$localstatedir/run/${INIT_PROG}"}
else
pipedir="N/A"
fi
if test "$need_pls_dir" = yes; then
pkglocalstatedir=${pkglocalstatedir="$localstatedir/lib/$INIT_PROG"}
else
pkglocalstatedir="N/A"
fi
if test "$need_spl" = yes; then
spooldir=${spooldir="$localstatedir/spool/$INIT_PROG"}
else
spooldir="N/A"
fi
if test $need_brk = yes; then
brokersdir=${brokersdir="$libexecdir/brokers"}
else
brokersdir="N/A"
fi
if test $need_plg = yes; then
pluginsdir=${pluginsdir="$libexecdir/plugins"}
else
pluginsdir="N/A"
fi
if test $need_cgi = yes; then
cgibindir=${cgibindir="$libexecdir/cgi-bin"}
else
cgibindir="N/A"
fi
elif test $opsys = "unix"; then
#
# "Standard" Unix install
#
install_method="$install_method : Unix Standard"
if test $dist_type = osx; then
install_method="$install_method : OS X Standard"
fi
datadir=${datadir="$datarootdir/nagios"}
if test $need_web = yes; then
webdir=${webdir="$datadir/html"}
else
webdir="N/A"
fi
if test $dist_type = osx; then
sysconfdir=${sysconfdir="/private/etc"}
else
sysconfdir=${sysconfdir="/etc"}
fi
pkgsysconfdir=${pkgsysconfdir="$sysconfdir/nagios"}
if test $need_etc_subdir = yes; then
objsysconfdir=${objsysconfdir="$pkgsysconfdir/objects"}
else
objsysconfdir="N/A"
fi
privatesysconfdir=${privatesysconfdir="$pkgsysconfdir/private"}
if test "$need_pls_dir" = yes; then
pkglocalstatedir=${pkglocalstatedir="$localstatedir/lib/$INIT_PROG"}
else
pkglocalstatedir="N/A"
fi
if test "$need_loc" = yes; then
localedir=${localedir="/usr/local/share/locale/<lang>/LC_MESSAGES/nagios-plugins.mo"}
fi
if test "$need_spl" = yes; then
spooldir=${spooldir="$localstatedir/spool/$INIT_PROG"}
else
spooldir="N/A"
fi
if test $need_brk = yes; then
brokersdir=${brokersdir="$libexecdir/brokers"}
else
brokersdir="N/A"
fi
if test $need_plg = yes; then
pluginsdir=${pluginsdir="$libexecdir/plugins"}
else
pluginsdir="N/A"
fi
if test $need_cgi = yes; then
cgibindir=${cgibindir="$libexecdir/cgi-bin"}
else
cgibindir="N/A"
fi
AS_CASE([$dist_type],
[*hp-ux*],
piddir=${piddir="$pkgsysconfdir"}
pipedir=${pipedir="$pkglocalstatedir"}
logdir=${logdir="$pkglocalstatedir/log"},
[*],
piddir=${piddir="$localstatedir/run/${INIT_PROG}"}
if test "$need_pipe" = yes; then
pipedir=${pipedir="$localstatedir/run/${INIT_PROG}"}
else
pipedir="N/A"
fi
if test $need_log_subdir = yes; then
logdir=${logdir="$localstatedir/log/$INIT_PROG"}
else
logdir=${logdir="$localstatedir/log"}
fi
)
elif test $opsys = "bsd"; then
#
# "Standard" BSD install
#
install_method="$install_method : BSD"
if test $dist_type = freebsd -o $dist_type = openbsd; then
prefix=${prefix="/usr/local"}
exec_prefix=${exec_prefix="/usr/local"}
if test $dist_type = freebsd; then
install_method="$install_method : FreeBSD"
else
install_method="$install_method : OpenBSD"
fi
elif test $dist_type = netbsd; then
prefix=${prefix="/usr/pkg"}
exec_prefix=${exec_prefix="/usr/pkg"}
install_method="$install_method : NetBSD"
fi
datadir=${datadir="$datarootdir/nagios"}
if test $need_web = yes -o $need_cgi = yes; then
if test $dist_type = freebsd; then
webdir=${webdir="$prefix/www/nagios"}
elif test $dist_type = netbsd; then
webdir=${webdir="$prefix/share/nagios"}
elif test $dist_type = openbsd; then
webdir=${webdir="/var/www/nagios"}
fi
else
webdir="N/A"
fi
if test $dist_type = freebsd; then
sysconfdir=${sysconfdir="/usr/local/etc"}
else
sysconfdir=${sysconfdir="/etc"}
fi
pkgsysconfdir=${pkgsysconfdir="$sysconfdir/nagios"}
if test $need_etc_subdir = yes; then
objsysconfdir=${objsysconfdir="$pkgsysconfdir/objects"}
else
objsysconfdir="N/A"
fi
privatesysconfdir=${privatesysconfdir="$pkgsysconfdir/private"}
if test "$need_pls_dir" = yes; then
pkglocalstatedir=${pkglocalstatedir="$localstatedir/lib/$INIT_PROG"}
else
pkglocalstatedir="N/A"
fi
if test "$need_loc" = yes; then
localedir=${localedir="/usr/local/share/locale/<lang>/LC_MESSAGES/nagios-plugins.mo"}
fi
if test "$need_spl" = yes; then
spooldir=${spooldir="$localstatedir/spool/$INIT_PROG"}
else
spooldir="N/A"
fi
if test $need_brk = yes; then
brokersdir=${brokersdir="$libexecdir/brokers"}
else
brokersdir="N/A"
fi
if test $need_plg = yes; then
pluginsdir=${pluginsdir="$libexecdir/plugins"}
else
pluginsdir="N/A"
fi
if test $need_cgi = yes; then
if test $dist_type = freebsd; then
cgibindir=${cgibindir="$webdir/cgi-bin"}
elif test $dist_type = netbsd; then
cgibindir=${pluginsdir="$libexecdir/cgi-bin"}
elif test $dist_type = openbsd; then
cgibindir=${pluginsdir="/var/www/cgi-bin/nagios"}
fi
else
cgibindir="N/A"
fi
piddir=${piddir="$localstatedir/run/${INIT_PROG}"}
if test "$need_pipe" = yes; then
pipedir=${pipedir="$localstatedir/run/${INIT_PROG}"}
else
pipedir="N/A"
fi
if test $need_log_subdir = yes; then
logdir=${logdir="$localstatedir/log/$INIT_PROG"}
else
logdir=${logdir="$localstatedir/log"}
fi
else
#
# Unknown install
#
install_method="unknown"
webdir=unknown
pkgsysconfdir=unknown
objsysconfdir=unknown
privatesysconfdir=unknown
logdir=unknown
piddir=unknown
pipedir=unknown
pkglocalstatedir=unknown
spooldir=unknown
brokersdir=unknown
pluginsdir=unknown
cgibindir=unknown
fi
eval prefix=$prefix
eval exec_prefix=$exec_prefix
eval bindir=$bindir
eval datarootdir=$datarootdir
eval datadir=$datadir
eval libexecdir=$libexecdir
eval brokersdir=$brokersdir
eval pluginsdir=$pluginsdir
eval cgibindir=$cgibindir
eval localstatedir=$localstatedir
eval pkglocalstatedir=$pkglocalstatedir
eval webdir=$webdir
eval localedir=$localedir
eval sysconfdir=$sysconfdir
eval pkgsysconfdir=$pkgsysconfdir
eval piddir=$piddir
# We test systemd first because in case
# someone tries to install Nagios on a
# system with a newer version, that doesn't
# have the defined versions ..we can just
# (hopefully) fall back to SysV
# And if that doesn't work, well...
AS_CASE([$init_type],
[systemd],
if test -d "/lib/systemd/system"; then
initdir=${initdir="/lib/systemd/system"}
elif test -d "/usr/lib/systemd/system"; then
initdir=${initdir="/usr/lib/systemd/system"}
elif test -d "/usr/local/lib/systemd/system"; then
initdir=${initdir="/usr/local/lib/systemd/system"}
elif test -d "/run/systemd/system"; then
initdir=${initdir="/run/systemd/system"}
elif test -d "/etc/systemd/system"; then
initdir=${initdir="/etc/systemd/system"}
elif test -d "/etc/systemd/user"; then
initdir=${initdir="/etc/systemd/user"}
elif test -d "/run/systemd/user"; then
initdir=${initdir="/run/systemd/user"}
elif test -d "/usr/lib/systemd/user"; then
initdir=${initdir="/usr/lib/systemd/user"}
elif test -d "/usr/local/lib/systemd/user"; then
initdir=${initdir="/usr/local/lib/systemd/user"}
elif test -d "/usr/share/systemd/user"; then
initdir=${initdir="/usr/share/systemd/user"}
elif test -d "/usr/local/share/systemd/user"; then
initdir=${initdir="/usr/local/share/systemd/user"}
elif test -d "$HOME/.config/systemd/user"; then
initdir=${initdir="$HOME/.config/systemd/user"}
elif test -d "$HOME/.local/share/systemd/user"; then
initdir=${initdir="$HOME/.local/share/systemd/user"}
elif test -d "$XDG_CONFIG_HOME/systemd/user/"; then
initdir=${initdir="$XDG_CONFIG_HOME/systemd/user/"}
elif test -d "$XDG_RUNTIME_DIR/systemd/user/"; then
initdir=${initdir="$XDG_RUNTIME_DIR/systemd/user/"}
elif test -d "$XDG_DATA_HOME/systemd/user/"; then
initdir=${initdir="$XDG_DATA_HOME/systemd/user/"}
else
init_type="sysv"
fi
initname=${initname="$INIT_PROG.service"},
)
#
# Init scripts/files
#
AS_CASE([$init_type],
[sysv],
if test $dist_type = "hp-ux"; then
initdir=${initdir="/sbin/init.d"}
else
initdir=${initdir="/etc/init.d"}
fi
initname=${initname="$INIT_PROG"}
initconfdir=${initconfdir="/etc/conf.d"}
initconf=${initconf="$initconfdir/$INIT_PROG"},
[bsd],
if test $dist_type = "aix"; then
initdir=${initdir="/sbin/rc.d/init.d"}
initname=${initname="$INIT_PROG"}
else
initdir=${initdir="/etc/rc.d"}
initname=${initname="rc.$INIT_PROG"}
fi,
[newbsd],
initdir=${initdir="/usr/local/etc/rc.d"}
initname=${initname="$INIT_PROG"},
[gentoo],
initdir=${initdir="/etc/init.d"}
initname=${initname="$INIT_PROG"}
initconfdir=${initconfdir="/etc/init.d"}
initconf=${initconf="$initconfdir/$INIT_PROG"},
[openrc],
initdir=${initdir="/etc/init.d"}
initname=${initname="$INIT_PROG"}
initconfdir=${initconfdir="/etc/conf.d"}
initconf=${initconf="$initconfdir/$INIT_PROG"},
[smf*],
if test $init_type = smf10; then
initdir=${initdir="/var/svc/manifest/network/nagios"}
else
initdir=${initdir="/lib/svc/manifest/network/nagios"}
fi
initname=${initname="$INIT_PROG.xml"}
initconfdir=unknown
initconf=unknown,
[upstart],
initdir=${initdir="/etc/init"}
initname=${initname="$INIT_PROG.conf"}
initconfdir=${initconfdir="/etc/default"}
initconf=${initconf="$initconfdir/$INIT_PROG"},
[launchd],
initdir=${initdir="/Library/LaunchDaemons"}
initname=${initname="org.nagios.$INIT_PROG.plist"},
# initconfdir=${initconfdir="/private/etc"}
# initconf=${initconf="$initconfdir/$INIT_PROG"},
[systemd],
init_type=systemd,
[*],
initdir=unknown
initname=unknown)
# Now see if they supplied any overwriting values
initdiroverridden=no
AC_ARG_WITH(initdir,
AC_HELP_STRING([--with-initdir=<path>],
[overrides path for initdir]),
initdir=$withval
initdiroverridden=yes,
initdir=$initdir
)
#
# Inetd (per connection) scripts/files
#
AS_CASE([$inetd_type],
[inetd*],
inetddir=${inetddir="/etc"}
inetdname=${inetdname="inetd.conf"},
[xinetd],
inetddir=${inetddir="/etc/xinetd.d"}
inetdname=${inetdname="$INIT_PROG"},
[systemd],
if test $dist_type = "debian"; then
inetddir=${inetddir="/lib/systemd/system"}
else
inetddir=${inetddir="/usr/lib/systemd/system"}
fi
netdname=${inetdname="$INIT_PROG.socket"},
[smf*],
if test $init_type = smf10; then
inetddir=${inetddir="/var/svc/manifest/network/nagios"}
else
inetddir=${inetddir="/lib/svc/manifest/network/nagios"}
fi
inetdname=${inetdname="$INIT_PROG.xml"},
# [upstart],
# inetddir=${inetddir="/etc/init.d"}
# inetdname=${inetdname="$INIT_PROG"},
[launchd],
inetddir=${inetddir="/Library/LaunchDaemons"}
inetdname=${inetdname="org.nagios.$INIT_PROG.plist"},
[*],
inetddir=${inetddir="unknown"}
inetdname=${inetdname="unknown"})
AC_MSG_RESULT($install_method)
])

View File

@ -0,0 +1,303 @@
# ===========================================================================
# SYNOPSIS
#
# AX_NAGIOS_GET_SSL
#
# DESCRIPTION
#
# This macro finds the openssl binary, the header files directory and
# the library files directory. It will also search for the gnutls
# compatibility library/headers and the nss compatibility library/headers.
#
# LICENSE
#
# Copyright (c) 2016 Nagios Core Development Team
#
# 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# ===========================================================================
AU_ALIAS([AC_NAGIOS_GET_SSL], [AX_NAGIOS_GET_SSL])
AC_DEFUN([AX_NAGIOS_GET_SSL],
[
# -------------------------------
# SSL library and include paths
# -------------------------------
SSL_TYPE=openssl
try_pkg_config=1
ssl_dir=
ssl_inc_dir=
ssl_lib_dir=
SSL_INC_DIR=
SSL_INC_PREFIX=
SSL_HDR=
SSL_LIB_DIR=
AC_SUBST(HAVE_SSL)
AC_SUBST(SSL_TYPE)
AC_SUBST(SSL_INC_DIR)
AC_SUBST(SSL_HDR)
AC_SUBST(SSL_INC_PREFIX)
AC_SUBST(SSL_LIB_DIR)
# gnutls/openssl.h
# nss_compat_ossl/nss_compat_ossl.h
dnl # Which type - openssl, gnutls-openssl, nss
dnl AC_ARG_WITH([ssl-type],
dnl dnl AS_HELP_STRING([--with-ssl-type=TYPE],[replace TYPE with gnutls or nss to use one of these instead of openssl]),
dnl AS_HELP_STRING([--with-ssl-type=TYPE],[replace TYPE with gnutls to use that instead of openssl]),
dnl [SSL_TYPE=$withval])
AC_ARG_WITH([ssl],
AS_HELP_STRING([--with-ssl=DIR],[sets location of the SSL installation]),
[ssl_dir=$withval])
AC_ARG_WITH([ssl-inc],
AS_HELP_STRING([--with-ssl-inc=DIR],
[sets location of the SSL include files]),
[ssl_inc_dir=$withval])
AC_ARG_WITH([ssl-lib],
AS_HELP_STRING([--with-ssl-lib=DIR],[sets location of the SSL libraries]),
[ssl_lib_dir=$withval])
if test x$ssl_inc_dir != x -o x$ssl_lib_dir != x; then
try_pkg_config=0
fi
AC_ARG_WITH([kerberos-inc],
AS_HELP_STRING([--with-kerberos-inc=DIR],
[sets location of the Kerberos include files]),
[kerberos_inc_dir=$withval])
if test x$SSL_TYPE = xyes; then
SSL_TYPE=openssl
fi
dflt_hdrs="$ssl_inc_dir $ssl_dir $ssl_inc_dir/include $ssl_dir/include \
/usr/local/opt/{BBB} /usr/include/{BBB} /usr/local/include/{BBB} \
/usr/local/{AAA} /usr/local/{BBB} /usr/lib/{AAA} /usr/lib/{BBB} \
/usr/{AAA} /usr/pkg /usr/local /usr /usr/freeware/lib/{BBB} \
/usr/sfw /usr/sfw/include /opt/{BBB}"
dflt_libs="$ssl_lib_dir {ssldir} {ssldir}/lib {ssldir}/lib64 /usr/lib64 \
/usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/i386-linux-gnu \
/usr/local/lib /usr/lib/{AAA} /usr/{AAA}/lib /usr/{BBB}/lib \
/usr/pkg/lib /usr/freeware/lib/{BBB} /usr/sfw/lib /opt/freeware/lib \
/opt/{BBB}/lib/hpux64 /opt/{BBB}/lib/pa20_64 /opt/{BBB}/lib/hpux32 \
/opt/{BBB}/lib /opt/{BBB}";
AS_CASE([$SSL_TYPE],
[no], [SSL_TYPE=NONE],
[yes|openssl],
[ssl_hdr_dirs=`echo "$dflt_hdrs" | sed -e 's/{AAA}/ssl/g' | sed -e 's/{BBB}/openssl/g'`
ssl_lib_dirs=`echo "$dflt_libs" | sed -e 's/{AAA}/ssl/g' | sed -e 's/{BBB}/openssl/g'`
SSL_INC_PREFIX=openssl
SSL_HDR=ssl.h
ssl_lib=libssl],
[gnutls],
[ssl_hdr_dirs=`echo "$dflt_hdrs" | sed -e 's/{AAA}/gnutls/g' | sed -e 's/{BBB}/gnutls/g'`
ssl_lib_dirs=`echo "$dflt_libs" | sed -e 's/{AAA}/gnutls/g' | sed -e 's/{BBB}/gnutls/g'`
SSL_INC_PREFIX=gnutls
SSL_TYPE=gnutls_compat
SSL_HDR=compat.h
ssl_lib=libgnutls],
[nss],
[ssl_hdr_dirs=`echo "$dflt_hdrs" | sed -e 's/{AAA}/nss_compat_ossl/g' | sed -e 's/{BBB}/nss_compat_ossl/g'`
ssl_lib_dirs=`echo "$dflt_libs" | sed -e 's/{AAA}/nss_compat_ossl/g' | sed -e 's/{BBB}/nss_compat_ossl/g'`
SSL_HDR=nss_compat_ossl.h
ssl_lib=libnss_compat],
[*], echo >&6; AC_MSG_ERROR(['--with-ssl-type=$SSL_TYPE' is invalid])
)
# Check for SSL support
if test x$SSL_TYPE != xNONE; then
found_ssl=no
# RedHat 8.0 and 9.0 include openssl compiled with kerberos,
# so we must include header file
# Must come before openssl checks for Redhat EL 3
AC_MSG_CHECKING(for Kerberos include files)
found_kerberos=no
for dir in $kerberos_inc_dir /usr/kerberos/include /usr/include/krb5 \
/usr/include; do
kerbdir="$dir"
if test -f "$dir/krb5.h"; then
found_kerberos=yes
CFLAGS="$CFLAGS -I$kerbdir"
AC_DEFINE_UNQUOTED(HAVE_KRB5_H,[1],[Have the krb5.h header file])
break
fi
done
if test x_$found_kerberos != x_yes; then
AC_MSG_WARN(could not find include files)
else
AC_MSG_RESULT(found Kerberos include files in $kerbdir)
fi
# First, try using pkg_config
AC_CHECK_TOOL([PKG_CONFIG], [pkg-config])
if test x"$PKG_CONFIG" != x -a $try_pkg_config -ne 0 ; then
cflags=`$PKG_CONFIG $SSL_TYPE --cflags-only-I 2>/dev/null`
if test $? -eq 0; then
CFLAGS="$CFLAGS $cflags"
LDFLAGS="$LDFLAGS `$PKG_CONFIG $SSL_TYPE --libs-only-L 2>/dev/null`"
LIBS="$LIBS `$PKG_CONFIG $SSL_TYPE --libs-only-l 2>/dev/null`"
found_ssl=yes
AC_DEFINE_UNQUOTED(HAVE_SSL,[1],[Have SSL support])
fi
fi
if test x_$found_ssl != x_yes; then
# Find the SSL Headers
AC_MSG_CHECKING(for SSL headers)
for dir in $ssl_hdr_dirs; do
if test "$dir" = "/include"; then
continue
fi
ssldir="$dir"
if test -f "$dir/include/$SSL_INC_PREFIX/$SSL_HDR"; then
found_ssl=yes
CFLAGS="$CFLAGS -I$dir/include/$SSL_INC_PREFIX -I$ssldir/include"
SSL_INC_DIR="$dir/include/$SSL_INC_PREFIX"
break
fi
if test -f "$dir/include/$SSL_HDR"; then
found_ssl=yes
if test "$SSL_HDR" != compat.h ; then
SSL_INC_PREFIX=""
fi
CFLAGS="$CFLAGS -I$dir/include"
SSL_INC_DIR="$dir/include"
break
fi
if test -f "$dir/$SSL_HDR"; then
found_ssl=yes
SSL_INC_PREFIX=""
CFLAGS="$CFLAGS -I$dir"
SSL_INC_DIR="$dir"
break
fi
if test -f "$dir/$SSL_INC_PREFIX/$SSL_HDR"; then
found_ssl=yes
CFLAGS="$CFLAGS -I$dir/$SSL_INC_PREFIX"
SSL_INC_DIR="$dir/$SSL_INC_PREFIX"
ssldir="$dir/.."
break
fi
done
if test x_$found_ssl != x_yes; then
AC_MSG_ERROR(Cannot find ssl headers)
else
AC_MSG_RESULT(found in $ssldir)
# Now try and find SSL libraries
AC_MSG_CHECKING(for SSL libraries)
found_ssl=no
ssl_lib_dirs=`echo "$ssl_lib_dirs" | sed -e "s|{ssldir}|$ssldir|g"`
if test "`uname -s`" = "Darwin" ; then
soext="dylib"
elif test "`uname -s`" = "HP-UX" ; then
if test x$arch = "xia64"; then
soext="so"
else
soext="sl"
fi
elif test "`uname -s`" = "AIX" ; then
soext="a"
else
soext="so"
fi
for dir in $ssl_lib_dirs; do
if test -f "$dir/$ssl_lib.$soext"; then
found_ssl=yes
SSL_LIB_DIR="$dir"
break
fi
done
if test x_$found_ssl != x_yes; then
AC_MSG_ERROR(Cannot find ssl libraries)
else
AC_MSG_RESULT(found in $SSL_LIB_DIR)
LDFLAGS="$LDFLAGS -L$SSL_LIB_DIR";
LIBS="$LIBS -l`echo $ssl_lib | sed -e 's/^lib//'` -lcrypto";
AC_DEFINE_UNQUOTED(HAVE_SSL,[1],[Have SSL support])
fi
fi
fi
if test x$found_ssl = xyes ; then
if test -n "$SSL_INC_PREFIX" ; then
SSL_INC_PREFIX="${SSL_INC_PREFIX}/"
fi
# try to compile and link to see if SSL is set up properly
AC_MSG_CHECKING([whether compiling and linking against SSL works])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <${SSL_INC_PREFIX}${SSL_HDR}>], [SSL_new(NULL)])],
[
AC_MSG_RESULT([yes])
$1
], [
AC_MSG_ERROR([no])
$2
])
fi
if test x$found_ssl = xyes -a x$need_dh = xyes; then
# Find the openssl program
if test x$need_dh = xyes; then
AC_PATH_PROG(sslbin,openssl,value-if-not-found,$ssl_dir/sbin$PATH_SEPARATOR$ssl_dir/bin$PATH_SEPARATOR$PATH)
AC_DEFINE(USE_SSL_DH)
# Generate DH parameters
if test -f "$sslbin"; then
echo ""
echo "*** Generating DH Parameters for SSL/TLS ***"
# awk to strip off meta data at bottom of dhparam output
$sslbin dhparam -C 2048 | awk '/^-----/ {exit} {print}' > include/dh.h
fi
fi
fi
fi
])

3
base/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
nagios
nagiostats

185
base/Makefile.in Normal file
View File

@ -0,0 +1,185 @@
############################
# Makefile for Nagios
#
############################
# Source code directories
SRC_COMMON=../common
SRC_INCLUDE=../include
SRC_XDATA=../xdata
SRC_LIB=../lib
CC=@CC@
CFLAGS=-Wall -I.. @CFLAGS@ @DEFS@ -DNSCORE
# Compiler flags for use with gprof
#CFLAGS=-pg -I.. -DHAVE_CONFIG_H -DNSCORE
# Compiler flags for use with Valgrind
#CFLAGS=-O0 -I.. -g -DHAVE_CONFIG_H -DNSCORE
# Compiler flags for optimization (overrides default)
#CFLAGS=-O3 -Wall -I.. -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=@cgibindir@
HTMLDIR=@webdir@
INSTALL=@INSTALL@
INSTALL_OPTS=@INSTALL_OPTS@
COMMAND_OPTS=@COMMAND_OPTS@
STRIP=@STRIP@
CGIURL=@cgiurl@
HTMURL=@htmurl@
MATHLIBS=-lm
SOCKETLIBS=@SOCKETLIBS@
BROKERLIBS=@BROKERLIBS@
BROKER_LDFLAGS=@BROKER_LDFLAGS@
CP=@CP@
# Extra base code
BASEEXTRALIBS=@BASEEXTRALIBS@
# Generated automatically from configure script
BROKER_O=@BROKER_O@
BROKER_H=@BROKER_H@
# Object data
ODATALIBS=objects-base.o xobjects-base.o
ODATAHDRS=
ODATADEPS=$(ODATALIBS)
# Retention data
RDATALIBS=retention-base.o xretention-base.o
RDATAHDRS=
RDATADEPS=$(RDATALIBS)
# Comment data
CDATALIBS=comments-base.o xcomments-base.o
CDATAHDRS=
CDATADEPS=$(CDATALIBS)
# Status data
SDATALIBS=statusdata-base.o xstatusdata-base.o
SDATAHDRS=
SDATADEPS=$(SDATALIBS)
# Performance data
PDATALIBS=perfdata-base.o xperfdata-base.o
PDATAHDRS=
PDATADEPS=$(PDATALIBS)
# Downtime data
DDATALIBS=downtime-base.o
DDATAHDRS=
DDATADEPS=$(DDATALIBS)
OBJS=$(BROKER_O) $(SRC_COMMON)/shared.o @NERD_O@ query-handler.o workers.o checks.o config.o commands.o events.o flapping.o logging.o macros-base.o netutils.o notifications.o sehandlers.o utils.o $(RDATALIBS) $(CDATALIBS) $(ODATALIBS) $(SDATALIBS) $(PDATALIBS) $(DDATALIBS) $(BASEEXTRALIBS)
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
objects-base.o: $(SRC_COMMON)/objects.c $(SRC_INCLUDE)/objects.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/objects.c
xobjects-base.o: $(SRC_XDATA)/xodtemplate.c $(SRC_XDATA)/xodtemplate.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xodtemplate.c
statusdata-base.o: $(SRC_COMMON)/statusdata.c $(SRC_INCLUDE)/statusdata.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/statusdata.c
xstatusdata-base.o: $(SRC_XDATA)/xsddefault.c $(SRC_XDATA)/xsddefault.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xsddefault.c
comments-base.o: $(SRC_COMMON)/comments.c $(SRC_INCLUDE)/comments.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/comments.c
xcomments-base.o: $(SRC_XDATA)/xcddefault.c $(SRC_XDATA)/xcddefault.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xcddefault.c
downtime-base.o: $(SRC_COMMON)/downtime.c $(SRC_INCLUDE)/downtime.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/downtime.c
perfdata-base.o: perfdata.c $(SRC_INCLUDE)/perfdata.h
$(CC) $(CFLAGS) -c -o $@ perfdata.c
xperfdata-base.o: $(SRC_XDATA)/xpddefault.c $(SRC_XDATA)/xpddefault.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xpddefault.c
retention-base.o: sretention.c $(SRC_INCLUDE)/sretention.h
$(CC) $(CFLAGS) -c -o $@ sretention.c
xretention-base.o: $(SRC_XDATA)/xrddefault.c $(SRC_XDATA)/xrddefault.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xrddefault.c
$(SRC_COMMON)/shared.o: $(SRC_COMMON)/shared.c
$(CC) $(CFLAGS) -c -o $@ $<
workers.o: workers.c wpres-phash.h
$(CC) $(CFLAGS) -c -o $@ $<
wpres-phash.h: wpres.gperf
gperf -S 1 -t -H wpres_key_phash -N wpres_get_key $< > $@
########## NAGIOS ##########
libnagios:
$(MAKE) -C $(SRC_LIB)
nagios.o: nagios.c $(SRC_INCLUDE)/nagios.h $(SRC_INCLUDE)/locations.h
$(CC) $(CFLAGS) -c -o $@ nagios.c
nagios: nagios.o $(OBJS) $(OBJDEPS) libnagios
$(CC) $(CFLAGS) -o $@ $< $(OBJS) $(BROKER_LDFLAGS) $(LDFLAGS) $(MATHLIBS) $(SOCKETLIBS) $(BROKERLIBS) $(LIBS) $(SRC_LIB)/libnagios.a
nagiostats: nagiostats.c $(SRC_INCLUDE)/locations.h libnagios
$(CC) $(CFLAGS) -o $@ nagiostats.c $(LDFLAGS) $(MATHLIBS) $(LIBS) $(SRC_LIB)/libnagios.a
$(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
rm -f wpres-phash.h
install:
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(BINDIR)
$(INSTALL) -s -m 774 $(INSTALL_OPTS) @nagios_name@ $(DESTDIR)$(BINDIR)
$(INSTALL) -s -m 774 $(INSTALL_OPTS) @nagiostats_name@ $(DESTDIR)$(BINDIR)
install-unstripped:
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(BINDIR)
$(INSTALL) -m 774 $(INSTALL_OPTS) nagios $(DESTDIR)$(BINDIR)
$(INSTALL) -m 774 $(INSTALL_OPTS) nagiostats $(DESTDIR)$(BINDIR)
.PHONY: libnagios

989
base/broker.c Normal file
View File

@ -0,0 +1,989 @@
/*****************************************************************************
*
* BROKER.C - Event broker routines for Nagios
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
#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"
#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, check_result *cr) {
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;
ds.check_result_ptr = cr;
/* 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, check_result *cr) {
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;
ds.check_result_ptr = cr;
/* 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_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.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;
ds.longoutput = temp_service->long_plugin_output;
}
else {
temp_host = (host *)data;
ds.host_name = temp_host->name;
ds.service_description = NULL;
ds.output = temp_host->plugin_output;
ds.longoutput = temp_host->long_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

3579
base/checks.c Normal file

File diff suppressed because it is too large Load Diff

5441
base/commands.c Normal file

File diff suppressed because it is too large Load Diff

2307
base/config.c Normal file

File diff suppressed because it is too large Load Diff

1749
base/events.c Normal file

File diff suppressed because it is too large Load Diff

780
base/flapping.c Normal file
View File

@ -0,0 +1,780 @@
/*****************************************************************************
*
* FLAPPING.C - State flap detection and handling routines for Nagios
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
/*********** 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"
/******************************************************************/
/******************** 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(!should_flap_detect(svc))
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 or for this service */
if(enable_flap_detection == FALSE || svc->flap_detection_enabled == FALSE) {
if(svc->is_flapping == TRUE)
clear_service_flap(svc, curved_percent_change, high_threshold, low_threshold, 1);
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, 0);
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(&current_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->flap_detection_options & (1 << hst->current_state)))
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 or for this service */
if(enable_flap_detection == FALSE || hst->flap_detection_enabled == FALSE) {
if(hst->is_flapping == TRUE)
clear_host_flap(hst, curved_percent_change, high_threshold, low_threshold, 1);
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, 0);
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);
if (svc->flapping_comment_id == 0) {
/* 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, int is_disabled) {
log_debug_info(DEBUGL_FUNCTIONS, 0, "clear_service_flap()\n");
if(svc == NULL)
return;
if (is_disabled == 0) {
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);
} else {
log_debug_info(DEBUGL_FLAPPING, 1, "Disabled flap detection for service '%s' on host '%s'.\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; Disabled flap detection for service\n", svc->host_name, svc->description);
}
/* 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
if (is_disabled == 0) {
/* 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);
if (hst->flapping_comment_id == 0) {
/* 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, int is_disabled) {
log_debug_info(DEBUGL_FUNCTIONS, 0, "clear_host_flap()\n");
if(hst == NULL)
return;
if (is_disabled == 0) {
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);
} else {
log_debug_info(DEBUGL_FLAPPING, 1, "Disabled flap detection for host '%s'.\n", hst->name);
/* log a notice - this one is parsed by the history CGI */
logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;STOPPED; Disabled flap detection\n", hst->name);
}
/* 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
if (is_disabled == 0) {
/* 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) {
unsigned int i;
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(i = 0; i < num_objects.hosts; i++)
check_for_host_flapping(host_ary[i], FALSE, FALSE, TRUE);
for(i = 0; i < num_objects.services; i++)
check_for_service_flapping(service_ary[i], FALSE, TRUE);
}
/* disables flap detection on a program wide basis */
void disable_flap_detection_routines(void) {
unsigned int i;
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(i = 0; i < num_objects.hosts; i++)
handle_host_flap_detection_disabled(host_ary[i]);
for(i = 0; i < num_objects.services; i++)
handle_service_flap_detection_disabled(service_ary[i]);
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;
}

571
base/logging.c Normal file
View File

@ -0,0 +1,571 @@
/*****************************************************************************
*
* LOGGING.C - Log file functions for use with 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/statusdata.h"
#include "../include/macros.h"
#include "../include/nagios.h"
#include "../include/broker.h"
#include <fcntl.h>
static FILE *debug_file_fp;
static FILE *log_fp;
/******************************************************************/
/************************ 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);
}
static FILE *open_log_file(void)
{
int fh;
struct stat st;
if(log_fp) /* keep it open unless we rotate */
return log_fp;
if ((fh = open(log_file, O_RDWR|O_APPEND|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
if (daemon_mode == FALSE)
printf("Warning: Cannot open log file '%s' for writing\n", log_file);
return NULL;
}
log_fp = fdopen(fh, "a+");
if(log_fp == NULL) {
if (daemon_mode == FALSE)
printf("Warning: Cannot open log file '%s' for writing\n", log_file);
return NULL;
}
if ((fstat(fh, &st)) == -1) {
log_fp = NULL;
close(fh);
if (daemon_mode == FALSE)
printf("Warning: Cannot fstat log file '%s'\n", log_file);
return NULL;
}
if (st.st_nlink != 1 || (st.st_mode & S_IFMT) != S_IFREG) {
log_fp = NULL;
close(fh);
if (daemon_mode == FALSE)
printf("Warning: log file '%s' has an invalid mode\n", log_file);
return NULL;
}
(void)fcntl(fileno(log_fp), F_SETFD, FD_CLOEXEC);
return log_fp;
}
int fix_log_file_owner(uid_t uid, gid_t gid)
{
int r1 = 0, r2 = 0;
if (!(log_fp = open_log_file()))
return -1;
r1 = fchown(fileno(log_fp), uid, gid);
if (open_debug_log() != OK)
return -1;
if (debug_file_fp)
r2 = fchown(fileno(debug_file_fp), uid, gid);
/* return 0 if both are 0 and otherwise < 0 */
return r1 < r2 ? r1 : r2;
}
int close_log_file(void)
{
if(!log_fp)
return 0;
fflush(log_fp);
fclose(log_fp);
log_fp = NULL;
return 0;
}
/* write something to the nagios log file */
int write_to_log(char *buffer, unsigned long data_type, time_t *timestamp) {
FILE *fp;
time_t log_time = 0L;
if(buffer == NULL)
return ERROR;
/* don't log anything if we're not actually running... */
if(verify_config || test_scheduling == TRUE)
return OK;
/* make sure we can log this type of entry */
if(!(data_type & logging_options))
return OK;
fp = open_log_file();
if (fp == NULL)
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, "[%llu] %s\n", (unsigned long long)log_time, buffer);
fflush(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 || 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);
free(temp_buffer);
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;
struct stat archive_stat;
int archive_stat_result;
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);
close_log_file();
/* 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);
/* HACK: If the archive exists, don't overwrite it. This is a hack
because the real problem is that some log rotations are executed
early and as a result the next log rotation is scheduled for
the same time as the one that ran early */
archive_stat_result = stat(log_archive, &archive_stat);
if((0 == archive_stat_result) ||
((-1 == archive_stat_result) && (ENOENT != errno))) {
return OK;
}
/* rotate the log file */
rename_result = my_rename(log_file, log_archive);
log_fp = open_log_file();
if (log_fp == NULL)
return ERROR;
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 if activated */
if(log_current_states==TRUE) {
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)
{
int fh;
struct stat st;
/* don't do anything if we're not actually running... */
if(verify_config || test_scheduling == TRUE)
return OK;
/* don't do anything if we're not debugging */
if(debug_level == DEBUGL_NONE)
return OK;
if ((fh = open(debug_file, O_RDWR|O_APPEND|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR)) == -1)
return ERROR;
if((debug_file_fp = fdopen(fh, "a+")) == NULL)
return ERROR;
if ((fstat(fh, &st)) == -1) {
debug_file_fp = NULL;
close(fh);
return ERROR;
}
if (st.st_nlink != 1 || (st.st_mode & S_IFMT) != S_IFREG) {
debug_file_fp = NULL;
close(fh);
return ERROR;
}
(void)fcntl(fh, F_SETFD, FD_CLOEXEC);
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 *tmppath = 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;
/* write the timestamp */
gettimeofday(&current_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(&tmppath, "%s.old", debug_file);
if(tmppath) {
/* unlink the old debug file */
unlink(tmppath);
/* rotate the debug file */
my_rename(debug_file, tmppath);
/* free memory */
my_free(tmppath);
}
/* open a new file */
open_debug_log();
}
return OK;
}

939
base/nagios.c Normal file
View File

@ -0,0 +1,939 @@
/*****************************************************************************
*
* NAGIOS.C - Core Program Code For Nagios
*
* Program: Nagios Core
* License: GPL
*
* First Written: 01-28-1999 (start of development)
*
* 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"
#include "../include/workers.h"
/*#define DEBUG_MEMORY 1*/
#ifdef DEBUG_MEMORY
#include <mcheck.h>
#endif
static int is_worker;
static void set_loadctl_defaults(void)
{
struct rlimit rlim;
/* Workers need to up 'em, master needs to know 'em */
getrlimit(RLIMIT_NOFILE, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit(RLIMIT_NOFILE, &rlim);
loadctl.nofile_limit = rlim.rlim_max;
#ifdef RLIMIT_NPROC
getrlimit(RLIMIT_NPROC, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit(RLIMIT_NPROC, &rlim);
loadctl.nproc_limit = rlim.rlim_max;
#else
loadctl.nproc_limit = loadctl.nofile_limit / 2;
#endif
/*
* things may have been configured already. Otherwise we
* set some sort of sane defaults here
*/
if (!loadctl.jobs_max) {
loadctl.jobs_max = loadctl.nproc_limit - 100;
if (!is_worker && loadctl.jobs_max > (loadctl.nofile_limit - 50) * wproc_num_workers_online) {
loadctl.jobs_max = (loadctl.nofile_limit - 50) * wproc_num_workers_online;
}
}
if (!loadctl.jobs_limit)
loadctl.jobs_limit = loadctl.jobs_max;
if (!loadctl.backoff_limit)
loadctl.backoff_limit = online_cpus() * 2.5;
if (!loadctl.rampup_limit)
loadctl.rampup_limit = online_cpus() * 0.8;
if (!loadctl.backoff_change)
loadctl.backoff_change = loadctl.jobs_limit * 0.3;
if (!loadctl.rampup_change)
loadctl.rampup_change = loadctl.backoff_change * 0.25;
if (!loadctl.check_interval)
loadctl.check_interval = 60;
if (!loadctl.jobs_min)
loadctl.jobs_min = online_cpus() * 20; /* pessimistic */
}
static int test_path_access(const char *program, int mode)
{
char *envpath, *p, *colon;
int ret, our_errno = 1500; /* outside errno range */
if (program[0] == '/' || !(envpath = getenv("PATH")))
return access(program, mode);
if (!(envpath = strdup(envpath))) {
errno = ENOMEM;
return -1;
}
for (p = envpath; p; p = colon + 1) {
char *path;
colon = strchr(p, ':');
if (colon)
*colon = 0;
asprintf(&path, "%s/%s", p, program);
ret = access(path, mode);
free(path);
if (!ret)
break;
if (ret < 0) {
if (errno == ENOENT)
continue;
if (our_errno > errno)
our_errno = errno;
}
if (!colon)
break;
}
free(envpath);
if (!ret)
errno = 0;
else
errno = our_errno;
return ret;
}
static int nagios_core_worker(const char *path)
{
int sd, ret;
char response[128];
is_worker = 1;
set_loadctl_defaults();
sd = nsock_unix(path, NSOCK_TCP | NSOCK_CONNECT);
if (sd < 0) {
printf("Failed to connect to query socket '%s': %s: %s\n",
path, nsock_strerror(sd), strerror(errno));
return 1;
}
ret = nsock_printf_nul(sd, "@wproc register name=Core Worker %ld;pid=%ld", (long)getpid(), (long)getpid());
if (ret < 0) {
printf("Failed to register as worker.\n");
return 1;
}
ret = read(sd, response, 3);
if (ret != 3) {
printf("Failed to read response from wproc manager\n");
return 1;
}
if (memcmp(response, "OK", 3)) {
read(sd, response + 3, sizeof(response) - 4);
response[sizeof(response) - 2] = 0;
printf("Failed to register with wproc manager: %s\n", response);
return 1;
}
enter_worker(sd, start_cmd);
free_worker_memory(WPROC_FORCE);
free_memory(get_global_macros());
return 0;
}
/*
* only handles logfile for now, which we stash in macros to
* make sure we can log *somewhere* in case the new path is
* completely inaccessible.
*/
static int test_configured_paths(void)
{
FILE *fp;
nagios_macros *mac;
mac = get_global_macros();
fp = fopen(log_file, "a+");
if (!fp) {
/*
* we do some variable trashing here so logit() can
* open the old logfile (if any), in case we got a
* restart command or a SIGHUP
*/
char *value_absolute = log_file;
log_file = mac->x[MACRO_LOGFILE];
logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to open logfile '%s' for writing: %s\n", value_absolute, strerror(errno));
return ERROR;
}
fclose(fp);
/* save the macro */
mac->x[MACRO_LOGFILE] = log_file;
return OK;
}
int main(int argc, char **argv) {
int result;
int error = FALSE;
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;
const char *worker_socket = NULL;
int i;
#ifdef HAVE_SIGACTION
struct sigaction sig_action;
#endif
#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'},
{"precache-objects", no_argument, 0, 'p'},
{"use-precached-objects", no_argument, 0, 'u'},
{"enable-timing-point", no_argument, 0, 'T'},
{"worker", required_argument, 0, 'W'},
{0, 0, 0, 0}
};
#define getopt(argc, argv, o) getopt_long(argc, argv, o, long_options, &option_index)
#endif
memset(&loadctl, 0, sizeof(loadctl));
mac = get_global_macros();
/* make sure we have the correct number of command line arguments */
if(argc < 2)
error = TRUE;
/* get all command line arguments */
while(1) {
c = getopt(argc, argv, "+hVvdspuxTW");
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++;
break;
case 's': /* scheduling check */
test_scheduling = TRUE;
break;
case 'd': /* daemon mode */
daemon_mode = TRUE;
break;
case 'p': /* precache object config */
precache_objects = TRUE;
break;
case 'u': /* use precached object config */
use_precached_objects = TRUE;
break;
case 'T':
enable_timing_point = TRUE;
break;
case 'W':
worker_socket = optarg;
break;
case 'x':
printf("Warning: -x is deprecated and will be removed\n");
break;
default:
break;
}
}
#ifdef DEBUG_MEMORY
mtrace();
#endif
/* if we're a worker we can skip everything below */
if(worker_socket) {
exit(nagios_core_worker(worker_socket));
}
/* Initialize configuration variables */
init_main_cfg_vars(1);
init_shared_cfg_vars(1);
if(daemon_mode == FALSE) {
printf("\nNagios Core %s\n", PROGRAM_VERSION);
printf("Copyright (c) 2009-present 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: https://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");
cleanup();
exit(OK);
}
/* make sure we got the main config file on the command line... */
if(optind >= argc)
error = TRUE;
/* if there are no command line options (or if we encountered an error), print usage */
if(error == TRUE || display_help == TRUE) {
printf("Usage: %s [options] <main_config_file>\n", argv[0]);
printf("\n");
printf("Options:\n");
printf("\n");
printf(" -v, --verify-config Verify all configuration data (-v -v for more info)\n");
printf(" -s, --test-scheduling Shows projected/recommended check scheduling and other\n");
printf(" diagnostic info based on the current configuration files.\n");
printf(" -T, --enable-timing-point Enable timed commentary on initialization\n");
printf(" -x, --dont-verify-paths Deprecated (Don't check for circular object paths)\n");
printf(" -p, --precache-objects Precache object configuration\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(" -W, --worker /path/to/socket Act as a worker for an already running daemon\n");
printf("\n");
printf("Visit the Nagios website at https://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");
cleanup();
exit(ERROR);
}
/*
* config file is last argument specified.
* Make sure it uses an absolute path
*/
config_file = nspath_absolute(argv[optind], NULL);
if(config_file == NULL) {
printf("Error allocating memory.\n");
cleanup();
exit(ERROR);
}
config_file_dir = nspath_absolute_dirname(config_file, NULL);
/*
* Set the signal handler for the SIGXFSZ signal here because
* we may encounter this signal before the other signal handlers
* are set.
*/
#ifdef HAVE_SIGACTION
sig_action.sa_sigaction = NULL;
sig_action.sa_handler = handle_sigxfsz;
sigfillset(&sig_action.sa_mask);
sig_action.sa_flags = SA_NODEFER|SA_RESTART;
sigaction(SIGXFSZ, &sig_action, NULL);
#else
signal(SIGXFSZ, handle_sigxfsz);
#endif
/*
* let's go to town. We'll be noisy if we're verifying config
* or running scheduling tests.
*/
if(verify_config || test_scheduling || precache_objects) {
reset_variables();
/*
* if we don't beef up our resource limits as much as
* we can, it's quite possible we'll run headlong into
* EAGAIN due to too many processes when we try to
* drop privileges later.
*/
set_loadctl_defaults();
if(verify_config)
printf("Reading configuration data...\n");
/* read our config file */
result = read_main_config_file(config_file);
if(result != OK) {
printf(" Error processing main config file!\n\n");
cleanup();
exit(EXIT_FAILURE);
}
if(verify_config)
printf(" Read main config file okay...\n");
/* drop privileges */
if((result = drop_privileges(nagios_user, nagios_group)) == ERROR) {
printf(" Failed to drop privileges. Aborting.");
cleanup();
exit(EXIT_FAILURE);
}
/*
* this must come after dropping privileges, so we make
* sure to test access permissions as the right user.
*/
if (!verify_config && test_configured_paths() == ERROR) {
printf(" One or more path problems detected. Aborting.\n");
cleanup();
exit(EXIT_FAILURE);
}
/* read object config files */
result = read_all_object_data(config_file);
if(result != OK) {
printf(" Error processing object config files!\n\n");
/* 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 '%s'\n", DEFAULT_CONFIG_FILE);
}
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 definitions. 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");
cleanup();
exit(EXIT_FAILURE);
}
if(verify_config) {
printf(" Read object config files okay...\n\n");
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("\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 definitions. 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");
cleanup();
exit(EXIT_FAILURE);
}
if(verify_config) {
printf("\nThings look okay - No serious problems were detected during the pre-flight check\n");
}
/* scheduling tests need a bit more than config verifications */
if(test_scheduling == TRUE) {
/* we'll need the event queue here so we can time insertions */
init_event_queue();
timing_point("Done initializing event queue\n");
/* read initial service and host state information */
initialize_retention_data(config_file);
read_initial_state_information();
timing_point("Retention data and initial state parsed\n");
/* initialize the event timing loop */
init_timing_loop();
timing_point("Timing loop initialized\n");
/* display scheduling information */
display_scheduling_info();
}
if(precache_objects) {
result = fcache_objects(object_precache_file);
timing_point("Done precaching objects\n");
if(result == OK) {
printf("Object precache file created:\n%s\n", object_precache_file);
}
else {
printf("Failed to precache objects to '%s': %s\n", object_precache_file, strerror(errno));
}
}
/* clean up after ourselves */
cleanup();
/* exit */
timing_point("Exiting\n");
/* make valgrind shut up about still reachable memory */
neb_free_module_list();
cleanup();
my_free(config_file);
my_free(config_file_dir);
exit(result);
}
/* else start to monitor things... */
else {
/*
* if we're called with a relative path we must make
* it absolute so we can launch our workers.
* If not, we needn't bother, as we're using execvp()
*/
if (strchr(argv[0], '/'))
nagios_binary_path = nspath_absolute(argv[0], NULL);
else
nagios_binary_path = strdup(argv[0]);
if (!nagios_binary_path) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to allocate memory for nagios_binary_path\n");
cleanup();
exit(EXIT_FAILURE);
}
if (!(nagios_iobs = iobroker_create())) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to create IO broker set: %s\n",
strerror(errno));
cleanup();
exit(EXIT_FAILURE);
}
/* keep monitoring things until we get a shutdown command */
do {
/* reset internal book-keeping (in case we're restarting) */
wproc_num_workers_spawned = wproc_num_workers_online = 0;
caught_signal = sigshutdown = FALSE;
sig_id = 0;
/* reset program variables */
reset_variables();
timing_point("Variables reset\n");
/* get PID */
nagios_pid = (int)getpid();
/* read in the configuration files (main and resource config files) */
result = read_main_config_file(config_file);
if (result != OK) {
logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to process config file '%s'. Aborting\n", config_file);
cleanup();
exit(EXIT_FAILURE);
}
timing_point("Main config file read\n");
/* 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], "%llu", (unsigned long long)program_start);
/* 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());
cleanup();
exit(EXIT_FAILURE);
}
/* get new PID */
nagios_pid = (int)getpid();
}
/* 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);
}
if (test_path_access(nagios_binary_path, X_OK)) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: failed to access() %s: %s\n", nagios_binary_path, strerror(errno));
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Spawning workers will be impossible. Aborting.\n");
cleanup();
exit(EXIT_FAILURE);
}
if (test_configured_paths() == ERROR) {
/* error has already been logged */
cleanup();
exit(EXIT_FAILURE);
}
/* 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);
/* open debug log now that we're the right user */
open_debug_log();
#ifdef USE_EVENT_BROKER
/* initialize modules */
neb_init_modules();
neb_init_callback_list();
#endif
timing_point("NEB module API initialized\n");
/* handle signals (interrupts) before we do any socket I/O */
setup_sighandler();
/*
* Initialize query handler and event subscription service.
* This must be done before modules are initialized, so
* the modules can use our in-core stuff properly
*/
if (qh_init(qh_socket_path ? qh_socket_path : DEFAULT_QUERY_SOCKET) != OK) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to initialize query handler. Aborting\n");
exit(EXIT_FAILURE);
}
timing_point("Query handler initialized\n");
#ifdef ENABLE_NERD
nerd_init();
timing_point("NERD initialized\n");
#endif
/* initialize check workers */
if(init_workers(num_check_workers) < 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Failed to spawn workers. Aborting\n");
exit(EXIT_FAILURE);
}
timing_point("%u workers spawned\n", wproc_num_workers_spawned);
i = 0;
while (i < 50 && wproc_num_workers_online < wproc_num_workers_spawned) {
iobroker_poll(nagios_iobs, 50);
i++;
}
timing_point("%u workers connected\n", wproc_num_workers_online);
/* now that workers have arrived we can set the defaults */
set_loadctl_defaults();
#ifdef USE_EVENT_BROKER
/* load modules */
if (neb_load_all_modules() != OK) {
logit(NSLOG_CONFIG_ERROR, ERROR, "Error: Module loading failed. Aborting.\n");
/* if we're dumping core, we must remove all dl-files */
if (daemon_dumps_core)
neb_unload_all_modules(NEBMODULE_FORCE_UNLOAD, NEBMODULE_NEB_SHUTDOWN);
cleanup();
exit(EXIT_FAILURE);
}
timing_point("Modules loaded\n");
/* send program data to broker */
broker_program_state(NEBTYPE_PROCESS_PRELAUNCH, NEBFLAG_NONE, NEBATTR_NONE, NULL);
timing_point("First callback made\n");
#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(TRUE);
}
#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);
}
timing_point("Object configuration parsed and understood\n");
#ifdef DETECT_RLIMIT_PROBLEM
/* lets do a quick system limit detection
to determine if we're likely to run into any
problems. */
rlimit_problem_detection(num_check_workers);
timing_point("Limit detection");
#endif
/* write the objects.cache file */
fcache_objects(object_cache_file);
timing_point("Objects cached\n");
init_event_queue();
timing_point("Event queue initialized\n");
#ifdef USE_EVENT_BROKER
/* send program data to broker */
broker_program_state(NEBTYPE_PROCESS_START, NEBFLAG_NONE, NEBATTR_NONE, NULL);
#endif
/* initialize status data only if we're starting (no restarts) */
if(sigrestart == FALSE) {
initialize_status_data(config_file);
timing_point("Status data initialized\n");
}
/* initialize scheduled downtime data */
initialize_downtime_data();
timing_point("Downtime data initialized\n");
/* read initial service and host state information */
initialize_retention_data(config_file);
timing_point("Retention data initialized\n");
read_initial_state_information();
timing_point("Initial state information read\n");
/* initialize comment data */
initialize_comment_data();
timing_point("Comment data initialized\n");
/* initialize performance data */
initialize_performance_data(config_file);
timing_point("Performance data initialized\n");
/* initialize the event timing loop */
init_timing_loop();
timing_point("Event timing loop initialized\n");
/* initialize check statistics */
init_check_stats();
timing_point("check stats initialized\n");
/* check for updates */
check_for_nagios_updates(FALSE, TRUE);
timing_point("Update check concluded\n");
/* update all status data (with retained information) */
update_all_status_data();
timing_point("Status data updated\n");
/* log initial host and service state */
log_host_states(INITIAL_STATES, NULL);
log_service_states(INITIAL_STATES, NULL);
timing_point("Initial states logged\n");
/* reset the restart flag */
sigrestart = FALSE;
/* fire up command file worker */
launch_command_file_worker();
timing_point("Command file worker launched\n");
#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], "%llu", (unsigned long long)event_start);
timing_point("Entering event execution loop\n");
/***** start monitoring all services *****/
/* (doesn't return until a restart or shutdown signal is encountered) */
event_execution_loop();
/*
* immediately deinitialize the query handler so it
* can remove modules that have stashed data with it
*/
qh_deinit(qh_socket_path ? qh_socket_path : DEFAULT_QUERY_SOCKET);
/* 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 lose them */
/* did we catch a signal? */
if(caught_signal == TRUE) {
if(sig_id == SIGHUP)
logit(NSLOG_PROCESS_INFO, TRUE, "Caught SIGHUP, restarting...\n");
}
#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();
/* clean up performance data */
cleanup_performance_data();
/* clean up the scheduled downtime data */
cleanup_downtime_data();
/* clean up comment data */
free_comment_data();
/* clean up the status data if we are not restarting */
if(sigrestart == FALSE) {
cleanup_status_data(TRUE);
}
free_worker_memory(WPROC_FORCE);
/* shutdown stuff... */
if(sigshutdown == TRUE) {
shutdown_command_file_worker();
iobroker_destroy(nagios_iobs, IOBROKER_CLOSE_SOCKETS);
nagios_iobs = NULL;
/* log a shutdown message */
logit(NSLOG_PROCESS_INFO, TRUE, "Successfully shutdown... (PID=%d)\n", (int)getpid());
}
/* try and collect any zombie processes */
if (sigrestart == TRUE) {
sleep(1);
int status = 0;
pid_t child_pid;
log_debug_info(DEBUGL_PROCESS, 1, "Calling waitpid() on all children...\n");
while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
log_debug_info(DEBUGL_PROCESS, 2, " * child PID: (%d), status: (%d)\n", child_pid, status);
}
log_debug_info(DEBUGL_PROCESS, 1, "All children have been wait()ed on\n");
cleanup();
}
/* close debug log */
close_debug_log();
}
while(sigrestart == TRUE && sigshutdown == FALSE);
if(daemon_mode == TRUE)
unlink(lock_file);
/* free misc memory */
cleanup();
my_free(lock_file);
my_free(config_file);
my_free(config_file_dir);
my_free(nagios_binary_path);
}
return OK;
}

1403
base/nagiostats.c Normal file

File diff suppressed because it is too large Load Diff

589
base/nebmods.c Normal file
View File

@ -0,0 +1,589 @@
/*****************************************************************************
*
* NEBMODS.C - Event Broker Module Functions
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
#include "../include/config.h"
#include "../include/common.h"
#include "../include/nebmods.h"
#include "../include/neberrors.h"
#include "../include/nagios.h"
#ifdef USE_EVENT_BROKER
static nebmodule *neb_module_list;
static nebcallback **neb_callback_list;
/* compat stuff for USE_LTDL */
#ifdef USE_LTDL
# define dlopen(p, flags) lt_dlopen(p)
# define dlclose(p) lt_dlclose(p)
# define dlerror() lt_dlerror()
# define dlsym(hdl, sym) lt_dlsym(hdl, sym)
# define RTLD_NOW 0
# define RTLD_GLOBAL 0
#else
# define lt_dlinit() 0
# define lt_dlexit() 0
#endif
/****************************************************************************/
/****************************************************************************/
/* INITIALIZATION/CLEANUP FUNCTIONS */
/****************************************************************************/
/****************************************************************************/
/* initialize module routines */
int neb_init_modules(void) {
if(lt_dlinit())
return ERROR;
return OK;
}
/* deinitialize module routines */
int neb_deinit_modules(void) {
if(lt_dlexit())
return ERROR;
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 *)calloc(1, 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;
/* 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;
}
int neb_add_core_module(nebmodule *mod) {
mod->should_be_loaded = FALSE;
mod->is_currently_loaded = TRUE;
mod->core_module = TRUE;
#ifdef USE_LTDL
mod->module_handle = (lt_dlhandle)mod;
#else
mod->module_handle = mod;
#endif
mod->next = neb_module_list;
neb_module_list = mod;
return 0;
}
/* 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; temp_module = next_module) {
next_module = temp_module->next;
for(x = 0; x < NEBMODULE_MODINFO_NUMITEMS; x++)
my_free(temp_module->info[x]);
/* don't free this stuff for core modules */
if (temp_module->core_module)
continue;
my_free(temp_module->filename);
my_free(temp_module->args);
my_free(temp_module);
}
neb_module_list = NULL;
return OK;
}
/****************************************************************************/
/****************************************************************************/
/* LOAD/UNLOAD FUNCTIONS */
/****************************************************************************/
/****************************************************************************/
/* load all modules */
int neb_load_all_modules(void) {
nebmodule *temp_module = NULL;
int ret, errors = 0;
for(temp_module = neb_module_list; temp_module; temp_module = temp_module->next) {
ret = neb_load_module(temp_module);
if (ret != OK) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to load module '%s'.\n", temp_module->filename ? temp_module->filename : "(no file?)");
errors++;
}
}
return errors ? ERROR : OK;
}
/* load a particular module */
int neb_load_module(nebmodule *mod) {
int (*initfunc)(int, char *, void *);
int *module_version_ptr = NULL;
int result = OK;
if(mod == 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 || mod->filename == NULL)
return ERROR;
/* load the module */
mod->module_handle = dlopen(mod->filename, RTLD_NOW | RTLD_GLOBAL);
if(mod->module_handle == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not load module '%s' -> %s\n", mod->filename, dlerror());
return ERROR;
}
/* mark the module as being loaded */
mod->is_currently_loaded = TRUE;
/* find module API version */
module_version_ptr = (int *)dlsym(mod->module_handle, "__neb_api_version");
/* check the module API version */
if(module_version_ptr == NULL || ((*module_version_ptr) != CURRENT_NEB_API_VERSION)) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "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 */
mod->init_func = dlsym(mod->module_handle, "nebmodule_init");
/* if the init function could not be located, unload the module */
if(mod->init_func == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "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, TRUE, "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, TRUE, "Event broker module '%s' initialized successfully.\n", mod->filename);
/* locate the de-initialization function (may or may not be present) */
mod->deinit_func = dlsym(mod->module_handle, "nebmodule_deinit");
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);
/* remove the module's demand-loaded file */
if(daemon_dumps_core == TRUE && mod->dl_file) {
(void)unlink(mod->dl_file);
my_free(mod->dl_file);
}
/* 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);
if(mod->core_module == FALSE) {
/* unload the module */
result = dlclose(mod->module_handle);
if (result != 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not unload module '%s' -> %s\n", mod->filename, dlerror());
return ERROR;
}
}
/* 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(temp_module->module_handle == 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(temp_module->module_handle == 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 = mod_handle;
new_callback->callback_func = callback_func;
new_callback->next = NULL;
/* add new function to callback list, sorted by priority (first come, first served for same priority) */
for(last_callback = NULL, temp_callback = neb_callback_list[callback_type];
temp_callback != NULL;
last_callback = temp_callback, temp_callback = temp_callback->next) {
if(new_callback->priority < temp_callback->priority) {
break;
}
}
new_callback->next = temp_callback;
if(last_callback == NULL) {
neb_callback_list[callback_type] = new_callback;
}
else {
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(temp_callback->module_handle == 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 == 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

502
base/nerd.c Normal file
View File

@ -0,0 +1,502 @@
#ifdef ENABLE_NERD
/*
* Nagios Event Radio Dispatcher
*
* This is a subscriber service which initiates a unix domain socket,
* listens to it and lets other programs connect to it and subscribe
* to various channels using a simple text-based syntax.
*
* This code uses the eventbroker api to get its data, which means
* we're finally eating our own dogfood in that respect.
*
* Note: Disabled by default as of 4.4.0
* ./configure --enable-nerd
* to enable!
*/
#define _GNU_SOURCE 1
#include <stdio.h>
#include "include/config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include "lib/libnagios.h"
#include "include/common.h"
#include "include/objects.h"
#include "include/broker.h"
#include "include/nebmods.h"
#include "include/nebmodules.h"
#include "include/nebstructs.h"
struct nerd_channel {
const char *name; /* name of this channel */
const char *description; /* user-presentable string to document the purpouse of this channel */
unsigned int id; /* channel id (might vary between invocations) */
unsigned int required_options; /* event_broker_options required for this channel */
unsigned int num_callbacks;
unsigned int callbacks[NEBCALLBACK_NUMITEMS];
int (*handler)(int , void *); /* callback handler for this channel */
objectlist *subscriptions; /* subscriber list */
};
static nebmodule nerd_mod; /* fake module to get our callbacks accepted */
static struct nerd_channel **channels;
static unsigned int num_channels, alloc_channels;
static unsigned int chan_host_checks_id, chan_service_checks_id;
static unsigned int chan_opath_checks_id;
static struct nerd_channel *find_channel(const char *name)
{
unsigned int i;
for(i = 0; i < num_channels; i++) {
struct nerd_channel *chan = channels[i];
if(!strcmp(name, chan->name)) {
return chan;
}
}
return NULL;
}
int nerd_get_channel_id(const char *name)
{
struct nerd_channel *chan;
chan = find_channel(name);
if (!chan)
return -1;
return chan->id;
}
static struct nerd_channel *nerd_get_channel(unsigned int chan_id)
{
return chan_id >= num_channels ? NULL : channels[chan_id];
}
objectlist *nerd_get_subscriptions(int chan_id)
{
struct nerd_channel *chan = nerd_get_channel(chan_id);
return chan ? chan->subscriptions : NULL;
}
static int nerd_register_channel_callbacks(struct nerd_channel *chan)
{
unsigned int i;
for(i = 0; i < chan->num_callbacks; i++) {
int result = neb_register_callback(chan->callbacks[i], &nerd_mod, 0, chan->handler);
if(result != 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "nerd: Failed to register callback %d for channel '%s': %d\n",
chan->callbacks[i], chan->name, result);
return -1;
}
}
return 0;
}
static int nerd_deregister_channel_callbacks(struct nerd_channel *chan)
{
unsigned int i;
for(i = 0; i < chan->num_callbacks; i++) {
neb_deregister_callback(chan->callbacks[i], chan->handler);
}
return 0;
}
static int subscribe(int sd, struct nerd_channel *chan, char *fmt)
{
struct nerd_subscription *subscr;
if(!(subscr = calloc(1, sizeof(*subscr))))
return -1;
subscr->sd = sd;
subscr->chan = chan;
subscr->format = fmt ? strdup(fmt) : NULL;
if(!chan->subscriptions) {
nerd_register_channel_callbacks(chan);
}
prepend_object_to_objectlist(&chan->subscriptions, subscr);
return 0;
}
static int cancel_channel_subscription(struct nerd_channel *chan, int sd)
{
objectlist *list, *next, *prev = NULL;
int cancelled = 0;
if(!chan)
return -1;
for(list = chan->subscriptions; list; list = next) {
struct nerd_subscription *subscr = (struct nerd_subscription *)list->object_ptr;
next = list->next;
if(subscr->sd == sd) {
cancelled++;
free(list);
free(subscr);
if(prev) {
prev->next = next;
} else {
chan->subscriptions = next;
}
continue;
}
prev = list;
}
if(cancelled) {
logit(NSLOG_INFO_MESSAGE, TRUE, "nerd: Cancelled %d subscription%s to channel '%s' for %d\n",
cancelled, cancelled == 1 ? "" : "s", chan->name, sd);
}
if(chan->subscriptions == NULL)
nerd_deregister_channel_callbacks(chan);
return 0;
}
static int unsubscribe(int sd, struct nerd_channel *chan)
{
objectlist *list, *next, *prev = NULL;
for(list = chan->subscriptions; list; list = next) {
struct nerd_subscription *subscr = (struct nerd_subscription *)list->object_ptr;
next = list->next;
if(subscr->sd == sd) {
/* found it, so remove it */
free(subscr);
free(list);
if(!prev) {
chan->subscriptions = next;
continue;
} else {
prev->next = next;
}
continue;
}
prev = list;
}
if(chan->subscriptions == NULL) {
nerd_deregister_channel_callbacks(chan);
}
return 0;
}
/* removes a subscriber entirely and closes its socket */
int nerd_cancel_subscriber(int sd)
{
unsigned int i;
for(i = 0; i < num_channels; i++) {
cancel_channel_subscription(channels[i], sd);
}
iobroker_close(nagios_iobs, sd);
return 0;
}
int nerd_broadcast(unsigned int chan_id, void *buf, unsigned int len)
{
struct nerd_channel *chan;
objectlist *list, *next;
if (!(chan = nerd_get_channel(chan_id)))
return -1;
for(list = chan->subscriptions; list; list = next) {
struct nerd_subscription *subscr = (struct nerd_subscription *)list->object_ptr;
int result;
next = list->next;
result = send(subscr->sd, buf, len, 0);
if(result < 0) {
if (errno == EAGAIN)
return 0;
nerd_cancel_subscriber(subscr->sd);
return 500;
}
}
return 0;
}
static int chan_host_checks(int cb, void *data)
{
nebstruct_host_check_data *ds = (nebstruct_host_check_data *)data;
check_result *cr = (check_result *)ds->check_result_ptr;
host *h;
char *buf;
int len;
if(ds->type != NEBTYPE_HOSTCHECK_PROCESSED)
return 0;
if(channels[chan_host_checks_id]->subscriptions == NULL)
return 0;
h = (host *)ds->object_ptr;
len = asprintf(&buf, "%s from %d -> %d: %s\n", h->name, h->last_state, h->current_state, cr->output);
nerd_broadcast(chan_host_checks_id, buf, len);
free(buf);
return 0;
}
static int chan_service_checks(int cb, void *data)
{
nebstruct_service_check_data *ds = (nebstruct_service_check_data *)data;
check_result *cr = (check_result *)ds->check_result_ptr;
service *s;
char *buf;
int len;
if(ds->type != NEBTYPE_SERVICECHECK_PROCESSED)
return 0;
s = (service *)ds->object_ptr;
len = asprintf(&buf, "%s;%s from %d -> %d: %s\n", s->host_name, s->description, s->last_state, s->current_state, cr->output);
nerd_broadcast(chan_service_checks_id, buf, len);
free(buf);
return 0;
}
static char **host_parent_path_cache;
static const char *host_parent_path(host *leaf, char sep)
{
char *ret;
unsigned int len = 0, pos = 0;
objectlist *stack = NULL, *list, *next;
host *h = leaf;
if(!h->parent_hosts)
return h->name;
if(!host_parent_path_cache) {
host_parent_path_cache = calloc(num_objects.hosts, sizeof(char *));
}
if(host_parent_path_cache[h->id]) {
return host_parent_path_cache[h->id];
}
while(h) {
len += strlen(h->name) + 2; /* room for separator */
prepend_object_to_objectlist(&stack, h->name);
if(h->parent_hosts && h->parent_hosts->host_ptr)
h = h->parent_hosts->host_ptr;
else
break;
}
ret = malloc(len + 1);
for(list = stack; list; list = next) {
char *ppart = (char *)list->object_ptr;
next = list->next;
free(list);
ret[pos++] = sep;
memcpy(ret + pos, ppart, strlen(ppart));
pos += strlen(ppart);
}
ret[pos++] = 0;
host_parent_path_cache[leaf->id] = ret;
return ret;
}
static int chan_opath_checks(int cb, void *data)
{
const int red = 0xff0000, green = 0xff00, blue = 0xff, pale = 0x555555;
unsigned int color;
check_result *cr;
host *h;
const char *name = "_HOST_";
char *buf = NULL;
if(cb == NEBCALLBACK_HOST_CHECK_DATA) {
nebstruct_host_check_data *ds = (nebstruct_host_check_data *)data;
if(ds->type != NEBTYPE_HOSTCHECK_PROCESSED)
return 0;
cr = ds->check_result_ptr;
h = ds->object_ptr;
color = red | green;
} else if(cb == NEBCALLBACK_SERVICE_CHECK_DATA) {
nebstruct_service_check_data *ds = (nebstruct_service_check_data *)data;
service *s;
if(ds->type != NEBTYPE_SERVICECHECK_PROCESSED)
return 0;
s = (service *)ds->object_ptr;
h = s->host_ptr;
cr = ds->check_result_ptr;
color = (red | green | blue) ^ pale;
name = s->description;
} else
return 0;
asprintf(&buf, "%lu|%s|M|%s/%s|%06X\n", cr->finish_time.tv_sec,
check_result_source(cr), host_parent_path(h, '/'), name, color);
nerd_broadcast(chan_opath_checks_id, buf, strlen(buf));
free(buf);
return 0;
}
static int nerd_deinit(void)
{
unsigned int i;
if(host_parent_path_cache) {
for(i = 0; i < num_objects.hosts; i++) {
my_free(host_parent_path_cache[i]);
}
my_free(host_parent_path_cache);
}
for(i = 0; i < num_channels; i++) {
struct nerd_channel *chan = channels[i];
objectlist *list, *next;
for(list = chan->subscriptions; list; list = next) {
struct nerd_subscription *subscr = (struct nerd_subscription *)list->object_ptr;
iobroker_close(nagios_iobs, subscr->sd);
next = list->next;
free(list);
free(subscr);
}
chan->subscriptions = NULL;
my_free(chan);
}
my_free(channels);
num_channels = 0;
alloc_channels = 0;
return 0;
}
int nerd_mkchan(const char *name, const char *description, int (*handler)(int, void *), unsigned int callbacks)
{
struct nerd_channel *chan, **ptr;
int i;
if(num_channels + 1 >= alloc_channels) {
alloc_channels = alloc_nr(alloc_channels);
ptr = realloc(channels, alloc_channels * sizeof(struct nerd_channel *));
if(!ptr)
return -1;
channels = ptr;
}
if(!(chan = calloc(1, sizeof(*chan))))
return -1;
chan->name = name;
chan->description = description;
chan->handler = handler;
for(i = 0; callbacks && i < NEBCALLBACK_NUMITEMS; i++) {
if(!(callbacks & (1 << i)))
continue;
chan->callbacks[chan->num_callbacks++] = i;
}
channels[num_channels++] = chan;
logit(NSLOG_INFO_MESSAGE, TRUE, "nerd: Channel %s registered successfully\n", chan->name);
return num_channels - 1;
}
#define NERD_SUBSCRIBE 0
#define NERD_UNSUBSCRIBE 1
static int nerd_qh_handler(int sd, char *request, unsigned int len)
{
char *chan_name, *fmt;
struct nerd_channel *chan;
int action;
if (!*request || !strcmp(request, "help")) {
nsock_printf_nul(sd, "Manage subscriptions to NERD channels.\n"
"Valid commands:\n"
" list list available channels\n"
" subscribe <channel> subscribe to a channel\n"
" unsubscribe <channel> unsubscribe to a channel\n");
return 0;
}
if (!strcmp(request, "list")) {
unsigned int i;
for (i = 0; i < num_channels; i++) {
chan = channels[i];
nsock_printf(sd, "%-15s %s\n", chan->name, chan->description);
}
nsock_printf(sd, "%c", 0);
return 0;
}
chan_name = strchr(request, ' ');
if(!chan_name)
return 400;
*chan_name = 0;
chan_name++;
if(!strcmp(request, "subscribe"))
action = NERD_SUBSCRIBE;
else if(!strcmp(request, "unsubscribe"))
action = NERD_UNSUBSCRIBE;
else {
return 400;
}
/* might have a format-string */
if((fmt = strchr(chan_name, ':')))
*(fmt++) = 0;
chan = find_channel(chan_name);
if(!chan) {
return 400;
}
if(action == NERD_SUBSCRIBE)
subscribe(sd, chan, fmt);
else
unsubscribe(sd, chan);
return 0;
}
/* nebmod_init(), but loaded even if no modules are */
int nerd_init(void)
{
nerd_mod.deinit_func = nerd_deinit;
nerd_mod.filename = (char *)"NERD"; /* something to log */
if(qh_register_handler("nerd", "Nagios Event Radio Dispatcher - Subscriber Service", 0, nerd_qh_handler) < 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "nerd: Failed to register with query handler\n");
return ERROR;
}
neb_add_core_module(&nerd_mod);
chan_host_checks_id = nerd_mkchan("hostchecks",
"Host check results",
chan_host_checks, nebcallback_flag(NEBCALLBACK_HOST_CHECK_DATA));
chan_service_checks_id = nerd_mkchan("servicechecks",
"Service check results",
chan_service_checks, nebcallback_flag(NEBCALLBACK_SERVICE_CHECK_DATA));
chan_opath_checks_id = nerd_mkchan("opathchecks",
"Host and service checks in gource's log format",
chan_opath_checks, nebcallback_flag(NEBCALLBACK_HOST_CHECK_DATA) | nebcallback_flag(NEBCALLBACK_SERVICE_CHECK_DATA));
logit(NSLOG_INFO_MESSAGE, TRUE, "nerd: Fully initialized and ready to rock!\n");
return 0;
}
#endif

290
base/netutils.c Normal file
View File

@ -0,0 +1,290 @@
/*****************************************************************************
*
* NETUTILS.C - Network connection utility functions for Nagios
*
* Portions Copyright (c) 1999-2008 Nagios Plugin development team
*
* 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(const 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, const 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(&current_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(&current_time);
if(current_time - start_time > timeout) {
result = ERROR;
break;
}
}
/* return number of bytes actually received here */
*len = total_received;
return result;
}

2131
base/notifications.c Normal file

File diff suppressed because it is too large Load Diff

91
base/perfdata.c Normal file
View File

@ -0,0 +1,91 @@
/*****************************************************************************
*
* PERFDATA.C - Performance data routines for Nagios
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
/*********** COMMON HEADER FILES ***********/
#include "../include/config.h"
#include "../include/common.h"
#include "../include/objects.h"
#include "../include/perfdata.h"
#include "../include/macros.h"
#include "../xdata/xpddefault.h"
/******************************************************************/
/************** INITIALIZATION & CLEANUP FUNCTIONS ****************/
/******************************************************************/
/* initializes performance data */
int initialize_performance_data(const char *cfgfile) {
return xpddefault_initialize_performance_data(cfgfile);
}
/* cleans up performance data */
int cleanup_performance_data(void) {
return xpddefault_cleanup_performance_data();
}
/******************************************************************/
/****************** 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! */
xpddefault_update_service_performance_data(svc);
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! */
xpddefault_update_host_performance_data(hst);
return OK;
}

544
base/query-handler.c Normal file
View File

@ -0,0 +1,544 @@
#include "include/config.h"
#include "include/nagios.h"
#include "lib/libnagios.h"
#include "lib/nsock.h"
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
/* A registered handler */
struct query_handler {
const char *name; /* also "address" of this handler. Must be unique */
const char *description; /* short description of this handler */
unsigned int options;
qh_handler handler;
struct query_handler *prev_qh, *next_qh;
};
static struct query_handler *qhandlers;
static int qh_listen_sock = -1; /* the listening socket */
static unsigned int qh_running;
unsigned int qh_max_running = 0; /* defaults to unlimited */
static dkhash_table *qh_table;
/* the echo service. stupid, but useful for testing */
static int qh_echo(int sd, char *buf, unsigned int len)
{
int result = 0;
if (buf == NULL || !strcmp(buf, "help")) {
nsock_printf_nul(sd,
"Query handler that simply echoes back what you send it.");
return 0;
}
result = write(sd, buf, len);
if (result == -1) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: qh_echo() error on write(sd,buf=[%s],len=%d): %s\n", buf, len, strerror(errno));
}
return 0;
}
static struct query_handler *qh_find_handler(const char *name)
{
return (struct query_handler *)dkhash_get(qh_table, name, NULL);
}
/* subset of http error codes */
const char *qh_strerror(int code)
{
if (code < 0) {
return "Low-level system error";
}
if (code == 100) {
return "Continue";
}
if (code == 101) {
return "Switching protocols";
}
if (code < 300) {
return "OK";
}
if (code < 400) {
return "Redirected (possibly deprecated address)";
}
switch (code) {
/* client errors */
case 400: return "Bad request";
case 401: return "Unauthorized";
case 403: return "Forbidden (disabled by config)";
case 404: return "Not found";
case 405: return "Method not allowed";
case 406: return "Not acceptable";
case 407: return "Proxy authentication required";
case 408: return "Request timed out";
case 409: return "Conflict";
case 410: return "Gone";
case 411: return "Length required";
case 412: return "Precondition failed";
case 413: return "Request too large";
case 414: return "Request-URI too long";
/* server errors */
case 500: return "Internal server error";
case 501: return "Not implemented";
case 502: return "Bad gateway";
case 503: return "Service unavailable";
case 504: return "Gateway timeout";
case 505: return "Version not supported";
}
return "Unknown error";
}
static int qh_input(int sd, int events, void *ioc_)
{
iocache * ioc = (iocache *) ioc_;
int result = 0;
/*
input on main socket, so accept one
this is when a worker initially connects
we create the iocache and then register
that to a new socket descriptor and this function
so that ioc_ != NULL next time
*/
if (sd == qh_listen_sock) {
struct sockaddr sa;
socklen_t slen = 0;
int nsd = 0;
/* shut valgrind up */
memset(&sa, 0, sizeof(sa));
nsd = accept(sd, &sa, &slen);
if (qh_max_running && qh_running >= qh_max_running) {
nsock_printf(nsd, "503: Server full");
close(nsd);
return 0;
}
ioc = iocache_create(16384);
if (ioc == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to create iocache for inbound request\n");
nsock_printf(nsd, "500: Internal server error");
close(nsd);
return 0;
}
/*
* @todo: Stash the iocache and the socket in some
* addressable list so we can release them on deinit
*/
result = iobroker_register(nagios_iobs, nsd, ioc, qh_input);
if (result < 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to register input socket %d with I/O broker: %s\n", nsd, strerror(errno));
iocache_destroy(ioc);
close(nsd);
return 0;
}
/* make it non-blocking, but leave kernel buffers unchanged */
worker_set_sockopts(nsd, 0);
qh_running++;
return 0;
}
/*
this is when an existing connection
sends more data after they've already made
the connection
*/
else {
unsigned long len = 0;
unsigned int query_len = 0;
struct query_handler * qh = NULL;
char * buf = NULL;
char * space = NULL;
char * handler = NULL;
char * query = NULL;
result = iocache_read(ioc, sd);
/* disconnect? */
if (result == 0 || (result < 0 && errno == EPIPE)) {
iocache_destroy(ioc);
iobroker_close(nagios_iobs, sd);
qh_running--;
return 0;
}
/*
* A request looks like this: '[@|#]<qh>[<SP>][<query>]\0'.
* That is, optional '#' (oneshot) or '@' (keepalive),
* followed by the name of a registered handler, followed by
* an optional space and an optional query. If the handler
* has no "default" handler, a query is required or an error
* will be thrown.
*/
/* Use data up to the first nul byte */
buf = iocache_use_delim(ioc, "\0", 1, &len);
if (buf == NULL) {
return 0;
}
/* Identify handler part and any magic query bytes */
if (*buf == '@' || *buf == '#') {
handler = buf + 1;
}
/* Locate query (if any) */
space = strchr(buf, ' ');
if (space != NULL) {
*space = 0;
query = space + 1;
query_len = len - (unsigned long)(query - buf);
}
/* locate the handler */
qh = qh_find_handler(handler);
/* not found. that's a 404 */
if (qh == NULL) {
nsock_printf(sd, "404: %s: No such handler", handler);
iobroker_close(nagios_iobs, sd);
iocache_destroy(ioc);
return 0;
}
/* strip trailing newlines */
while (query_len > 0
&& (query[query_len - 1] == 0 || query[query_len - 1] == '\n')) {
query[--query_len] = 0;
}
/* now pass the query to the handler */
result = qh->handler(sd, query, query_len);
if (result >= 100) {
nsock_printf_nul(sd, "%d: %s", result, qh_strerror(result));
}
/* error code or one-shot query */
if (result >= 300 || *buf == '#') {
iobroker_close(nagios_iobs, sd);
iocache_destroy(ioc);
return 0;
}
/* check for magic handler codes */
switch (result) {
/* oneshot handler */
case QH_CLOSE:
/* general error */
case -1:
iobroker_close(nagios_iobs, sd);
/* fallthrough */
/* handler takes over */
case QH_TAKEOVER:
/* switch protocol (takeover + message) */
case 101:
iocache_destroy(ioc);
break;
}
}
return 0;
}
int qh_deregister_handler(const char *name)
{
struct query_handler *qh = NULL;
struct query_handler *next = NULL;
struct query_handler *prev = NULL;
qh = dkhash_remove(qh_table, name, NULL);
if (qh != NULL) {
return 0;
}
next = qh->next_qh;
prev = qh->prev_qh;
if (next != NULL) {
next->prev_qh = prev;
}
if (prev != NULL) {
prev->next_qh = next;
}
else {
qhandlers = next;
}
free(qh);
return 0;
}
int qh_register_handler(const char *name, const char *description, unsigned int options, qh_handler handler)
{
struct query_handler *qh = NULL;
int result = 0;
if (name == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to register handler with no name\n");
return -1;
}
if (handler == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to register handler '%s': No handler function specified\n", name);
return -1;
}
if (strlen(name) > 128) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to register handler '%s': Name too long\n", name);
return -ENAMETOOLONG;
}
/* names must be unique */
if (qh_find_handler(name)) {
logit(NSLOG_RUNTIME_WARNING, TRUE, "qh: Handler '%s' registered more than once\n", name);
return -1;
}
qh = calloc(1, sizeof(*qh));
if (qh == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to allocate memory for handler '%s'\n", name);
return -errno;
}
qh->name = name;
qh->description = description;
qh->handler = handler;
qh->options = options;
qh->next_qh = qhandlers;
if (qhandlers) {
qhandlers->prev_qh = qh;
}
qhandlers = qh;
result = dkhash_insert(qh_table, qh->name, NULL, qh);
if (result < 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE,
"qh: Failed to insert query handler '%s' (%p) into hash table %p (%d): %s\n",
name, qh, qh_table, result, strerror(errno));
free(qh);
return result;
}
return 0;
}
void qh_deinit(const char *path)
{
struct query_handler *qh = NULL;
for (qh = qhandlers; qh != NULL; qh = qh->next_qh) {
qh_deregister_handler(qh->name);
}
dkhash_destroy(qh_table);
qh_table = NULL;
qhandlers = NULL;
if (path == NULL) {
return;
}
unlink(path);
}
static int qh_help(int sd, char *buf, unsigned int len)
{
struct query_handler *qh = NULL;
if (buf == NULL || !strcmp(buf, "help")) {
nsock_printf_nul(sd,
" help <name> show help for handler <name>\n"
" help list list registered handlers\n");
return 0;
}
if (!strcmp(buf, "list")) {
for (qh = qhandlers; qh != NULL; qh = qh->next_qh) {
nsock_printf(sd, "%-10s %s\n", qh->name, qh->description ? qh->description : "(No description available)");
}
nsock_printf(sd, "%c", 0);
return 0;
}
qh = qh_find_handler(buf);
if (qh == NULL) {
nsock_printf_nul(sd, "No handler named '%s' is registered\n", buf);
} else if (qh->handler(sd, "help", 4) > 200) {
nsock_printf_nul(sd, "The handler %s doesn't have any help yet.", buf);
}
return 0;
}
static int qh_core(int sd, char *buf, unsigned int len)
{
char *space;
if (buf == NULL || !strcmp(buf, "help")) {
nsock_printf_nul(sd,
"Query handler for manipulating nagios core.\n"
"Available commands:\n"
" loadctl Print information about current load control settings\n"
" loadctl <options> Configure nagios load control.\n"
" The options are the same parameters and format as\n"
" returned above.\n"
" squeuestats scheduling queue statistics\n"
);
return 0;
}
space = memchr(buf, ' ', len);
if (space != NULL) {
*(space++) = 0;
}
if (space == NULL) {
if (!strcmp(buf, "loadctl")) {
nsock_printf_nul(sd,
"jobs_max=%u;jobs_min=%u;"
"jobs_running=%u;jobs_limit=%u;"
"load=%.2f;"
"backoff_limit=%.2f;backoff_change=%u;"
"rampup_limit=%.2f;rampup_change=%u;"
"nproc_limit=%u;nofile_limit=%u;"
"options=%u;changes=%u;",
loadctl.jobs_max, loadctl.jobs_min,
loadctl.jobs_running, loadctl.jobs_limit,
loadctl.load[0],
loadctl.backoff_limit, loadctl.backoff_change,
loadctl.rampup_limit, loadctl.rampup_change,
loadctl.nproc_limit, loadctl.nofile_limit,
loadctl.options, loadctl.changes
);
return 0;
}
else if (!strcmp(buf, "squeuestats")) {
return dump_event_stats(sd);
}
}
/* space != NULL: */
else {
len -= (unsigned long)(space - buf);
if (!strcmp(buf, "loadctl")) {
return set_loadctl_options(space, len) == OK ? 200 : 400;
}
}
/* No matching command found */
return 404;
}
int qh_init(const char *path)
{
int result = 0;
int old_umask = 0;
if (qh_listen_sock >= 0) {
iobroker_close(nagios_iobs, qh_listen_sock);
}
if (path == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: query_socket is NULL. What voodoo is this?\n");
return ERROR;
}
old_umask = umask(0117);
errno = 0;
qh_listen_sock = nsock_unix(path, NSOCK_TCP | NSOCK_UNLINK);
umask(old_umask);
if (qh_listen_sock < 0) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to init socket '%s'. %s: %s\n",
path, nsock_strerror(qh_listen_sock), strerror(errno));
return ERROR;
}
/* plugins shouldn't have this socket */
result = fcntl(qh_listen_sock, F_SETFD, FD_CLOEXEC);
if (result == -1) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to fcntl() query handler socket\n");
}
/* most likely overkill, but it's small, so... */
qh_table = dkhash_create(1024);
if (qh_table == NULL) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to create hash table\n");
close(qh_listen_sock);
return ERROR;
}
errno = 0;
result = iobroker_register(nagios_iobs, qh_listen_sock, NULL, qh_input);
if (result < 0) {
dkhash_destroy(qh_table);
close(qh_listen_sock);
logit(NSLOG_RUNTIME_ERROR, TRUE, "qh: Failed to register socket with io broker: %s; errno=%d: %s\n", iobroker_strerror(result), errno, strerror(errno));
return ERROR;
}
logit(NSLOG_INFO_MESSAGE, FALSE, "qh: Socket '%s' successfully initialized\n", path);
/* now register our the in-core handlers */
result = qh_register_handler("core", "Nagios Core control and info", 0, qh_core);
if (result == OK) {
logit(NSLOG_INFO_MESSAGE, FALSE, "qh: core query handler registered\n");
}
result = qh_register_handler("echo", "The Echo Service - What You Put Is What You Get", 0, qh_echo);
if (result == OK) {
logit(NSLOG_INFO_MESSAGE, FALSE, "qh: echo service query handler registered\n");
}
result = qh_register_handler("help", "Help for the query handler", 0, qh_help);
if (result == OK) {
logit(NSLOG_INFO_MESSAGE, FALSE, "qh: help for the query handler registered\n");
}
return 0;
}

649
base/sehandlers.c Normal file
View File

@ -0,0 +1,649 @@
/*****************************************************************************
*
* SEHANDLERS.C - Service and host event and state handlers for Nagios
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
#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"
#include "../include/workers.h"
#ifdef USE_EVENT_BROKER
#include "../include/neberrors.h"
#endif
/******************************************************************/
/************* 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 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 || svc->obsess == 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 through a worker */
wproc_run_service_job(WPJOB_OCSP, ocsp_timeout, svc, processed_command, &mac);
/* free memory */
clear_volatile_macros_r(&mac);
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 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 || hst->obsess == 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 through a worker */
wproc_run_host_job(WPJOB_OCHP, ochp_timeout, hst, processed_command, &mac);
/* free memory */
clear_volatile_macros_r(&mac);
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);
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 through a worker */
/* XXX FIXME make base/workers.c handle the eventbroker stuff below */
result = wproc_run(WPJOB_GLOBAL_SVC_EVTHANDLER, processed_command, event_handler_timeout, mac);
/* 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 through a worker */
/* XXX FIXME make base/workers.c handle the eventbroker stuff below */
result = wproc_run(WPJOB_SVC_EVTHANDLER, processed_command, event_handler_timeout, mac);
/* 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);
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 through a worker */
/* XXX FIXME make base/workers.c handle the eventbroker stuff below */
wproc_run(WPJOB_GLOBAL_HOST_EVTHANDLER, processed_command, event_handler_timeout, mac);
/* 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 through a worker */
result = wproc_run(WPJOB_HOST_EVTHANDLER, processed_command, event_handler_timeout, mac);
/* 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;
}

107
base/sretention.c Normal file
View File

@ -0,0 +1,107 @@
/*****************************************************************************
*
* SRETENTION.C - State retention routines for Nagios
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
/*********** 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"
#include "../xdata/xrddefault.h" /* default routines */
/******************************************************************/
/************* TOP-LEVEL STATE INFORMATION FUNCTIONS **************/
/******************************************************************/
/* initializes retention data at program start */
int initialize_retention_data(const char *cfgfile) {
return xrddefault_initialize_retention_data(cfgfile);
}
/* cleans up retention data before program termination */
int cleanup_retention_data(void) {
return xrddefault_cleanup_retention_data();
}
/* 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
result = xrddefault_save_state_information();
#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
result = xrddefault_read_state_information();
#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;
}

3803
base/utils.c Normal file

File diff suppressed because it is too large Load Diff

1308
base/workers.c Normal file

File diff suppressed because it is too large Load Diff

98
base/wp-phash.c Normal file
View File

@ -0,0 +1,98 @@
#define WPRES_type 4
#define WPRES_outerr 6
#define WPRES_timeout 7
#define WPRES_ru_nswap 8
#define WPRES_error_msg 9
#define WPRES_error_code 10
#define WPRES_ru_nsignals 11
#define WPRES_command 12
#define WPRES_ru_majflt 14
#define WPRES_start 15
#define WPRES_outstd 16
#define WPRES_ru_stime 18
#define WPRES_exited_ok 19
#define WPRES_ru_inblock 20
#define WPRES_job_id 21
#define WPRES_ru_minflt 24
#define WPRES_ru_oublock 25
#define WPRES_wait_status 26
#define WPRES_runtime 27
#define WPRES_stop 29
#define WPRES_ru_utime 33
/* C code produced by gperf version 3.0.4 */
/* Command-line: gperf -H wp_phash wproc-strings */
/* Computed positions: -k'4-5' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
static inline unsigned int
wp_phash(register const char *str, register unsigned int len)
{
/* the last 136 entries have been cut, as we don't need them */
static unsigned char asso_values[256] =
{
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 5, 34, 0, 34, 34,
34, 0, 34, 34, 34, 10, 34, 34, 34, 5,
0, 0, 25, 34, 0, 0, 10, 15, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34,
};
register int hval = len;
switch (hval) {
default:
hval += asso_values[(unsigned char)str[4]];
/*FALLTHROUGH*/
case 4:
hval += asso_values[(unsigned char)str[3]];
break;
}
return hval;
}

320
base/wpres-phash.h Normal file
View File

@ -0,0 +1,320 @@
/* C code produced by gperf version 3.0.3 */
/* Command-line: gperf -S 1 -t -H wpres_key_phash -N wpres_get_key wpres.gperf */
/* Computed positions: -k'4-5,7' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
#endif
#line 1 "wpres.gperf"
enum {
WPRES_job_id,
WPRES_type,
WPRES_command,
WPRES_timeout,
WPRES_wait_status,
WPRES_start,
WPRES_stop,
WPRES_outstd,
WPRES_outerr,
WPRES_exited_ok,
WPRES_error_msg,
WPRES_error_code,
WPRES_runtime,
WPRES_ru_utime,
WPRES_ru_stime,
WPRES_ru_maxrss,
WPRES_ru_ixrss,
WPRES_ru_idrss,
WPRES_ru_isrss,
WPRES_ru_minflt,
WPRES_ru_majflt,
WPRES_ru_nswap,
WPRES_ru_inblock,
WPRES_ru_oublock,
WPRES_ru_msgsnd,
WPRES_ru_msgrcv,
WPRES_ru_nsignals,
WPRES_ru_nvcsw,
WPRES_ru_nivcsw,
};
#include <string.h> /* for strcmp() */
#line 35 "wpres.gperf"
struct wpres_key {
const char *name;
int code;
};
#define TOTAL_KEYWORDS 29
#define MIN_WORD_LENGTH 4
#define MAX_WORD_LENGTH 11
#define MIN_HASH_VALUE 4
#define MAX_HASH_VALUE 64
/* maximum key range = 61, duplicates = 0 */
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static unsigned int
wpres_key_phash (str, len)
register const char *str;
register unsigned int len;
{
static unsigned char asso_values[] =
{
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 15, 65, 25, 65, 3,
10, 0, 30, 0, 65, 0, 65, 65, 0, 0,
0, 20, 5, 65, 0, 5, 0, 0, 30, 65,
15, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65
};
register int hval = len;
switch (hval)
{
default:
hval += asso_values[(unsigned char)str[6]];
/*FALLTHROUGH*/
case 6:
case 5:
hval += asso_values[(unsigned char)str[4]];
/*FALLTHROUGH*/
case 4:
hval += asso_values[(unsigned char)str[3]];
break;
}
return hval;
}
#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
struct wpres_key *
wpres_get_key (str, len)
register const char *str;
register unsigned int len;
{
static struct wpres_key wordlist[] =
{
#line 41 "wpres.gperf"
{"type", WPRES_type},
#line 45 "wpres.gperf"
{"start", WPRES_start},
#line 48 "wpres.gperf"
{"outerr", WPRES_outerr},
#line 52 "wpres.gperf"
{"runtime", WPRES_runtime},
#line 53 "wpres.gperf"
{"ru_utime", WPRES_ru_utime},
#line 46 "wpres.gperf"
{"stop", WPRES_stop},
#line 62 "wpres.gperf"
{"ru_inblock", WPRES_ru_inblock},
#line 47 "wpres.gperf"
{"outstd", WPRES_outstd},
#line 68 "wpres.gperf"
{"ru_nivcsw", WPRES_ru_nivcsw},
#line 54 "wpres.gperf"
{"ru_stime", WPRES_ru_stime},
#line 65 "wpres.gperf"
{"ru_msgrcv", WPRES_ru_msgrcv},
#line 66 "wpres.gperf"
{"ru_nsignals", WPRES_ru_nsignals},
#line 58 "wpres.gperf"
{"ru_isrss", WPRES_ru_isrss},
#line 64 "wpres.gperf"
{"ru_msgsnd", WPRES_ru_msgsnd},
#line 40 "wpres.gperf"
{"job_id", WPRES_job_id},
#line 57 "wpres.gperf"
{"ru_idrss", WPRES_ru_idrss},
#line 49 "wpres.gperf"
{"exited_ok", WPRES_exited_ok},
#line 44 "wpres.gperf"
{"wait_status", WPRES_wait_status},
#line 43 "wpres.gperf"
{"timeout", WPRES_timeout},
#line 56 "wpres.gperf"
{"ru_ixrss", WPRES_ru_ixrss},
#line 50 "wpres.gperf"
{"error_msg", WPRES_error_msg},
#line 63 "wpres.gperf"
{"ru_oublock", WPRES_ru_oublock},
#line 51 "wpres.gperf"
{"error_code", WPRES_error_code},
#line 55 "wpres.gperf"
{"ru_maxrss", WPRES_ru_maxrss},
#line 61 "wpres.gperf"
{"ru_nswap", WPRES_ru_nswap},
#line 59 "wpres.gperf"
{"ru_minflt", WPRES_ru_minflt},
#line 42 "wpres.gperf"
{"command", WPRES_command},
#line 67 "wpres.gperf"
{"ru_nvcsw", WPRES_ru_nvcsw},
#line 60 "wpres.gperf"
{"ru_majflt", WPRES_ru_majflt}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
register int key = wpres_key_phash (str, len);
if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
{
register struct wpres_key *resword;
switch (key - 4)
{
case 0:
resword = &wordlist[0];
goto compare;
case 1:
resword = &wordlist[1];
goto compare;
case 2:
resword = &wordlist[2];
goto compare;
case 3:
resword = &wordlist[3];
goto compare;
case 4:
resword = &wordlist[4];
goto compare;
case 5:
resword = &wordlist[5];
goto compare;
case 6:
resword = &wordlist[6];
goto compare;
case 7:
resword = &wordlist[7];
goto compare;
case 8:
resword = &wordlist[8];
goto compare;
case 9:
resword = &wordlist[9];
goto compare;
case 10:
resword = &wordlist[10];
goto compare;
case 12:
resword = &wordlist[11];
goto compare;
case 14:
resword = &wordlist[12];
goto compare;
case 15:
resword = &wordlist[13];
goto compare;
case 17:
resword = &wordlist[14];
goto compare;
case 19:
resword = &wordlist[15];
goto compare;
case 20:
resword = &wordlist[16];
goto compare;
case 22:
resword = &wordlist[17];
goto compare;
case 23:
resword = &wordlist[18];
goto compare;
case 24:
resword = &wordlist[19];
goto compare;
case 25:
resword = &wordlist[20];
goto compare;
case 26:
resword = &wordlist[21];
goto compare;
case 29:
resword = &wordlist[22];
goto compare;
case 30:
resword = &wordlist[23];
goto compare;
case 34:
resword = &wordlist[24];
goto compare;
case 35:
resword = &wordlist[25];
goto compare;
case 38:
resword = &wordlist[26];
goto compare;
case 39:
resword = &wordlist[27];
goto compare;
case 60:
resword = &wordlist[28];
goto compare;
}
return 0;
compare:
{
register const char *s = resword->name;
if (*str == *s && !strcmp (str + 1, s + 1))
return resword;
}
}
}
return 0;
}

68
base/wpres.gperf Normal file
View File

@ -0,0 +1,68 @@
%{
enum {
WPRES_job_id,
WPRES_type,
WPRES_command,
WPRES_timeout,
WPRES_wait_status,
WPRES_start,
WPRES_stop,
WPRES_outstd,
WPRES_outerr,
WPRES_exited_ok,
WPRES_error_msg,
WPRES_error_code,
WPRES_runtime,
WPRES_ru_utime,
WPRES_ru_stime,
WPRES_ru_maxrss,
WPRES_ru_ixrss,
WPRES_ru_idrss,
WPRES_ru_isrss,
WPRES_ru_minflt,
WPRES_ru_majflt,
WPRES_ru_nswap,
WPRES_ru_inblock,
WPRES_ru_oublock,
WPRES_ru_msgsnd,
WPRES_ru_msgrcv,
WPRES_ru_nsignals,
WPRES_ru_nvcsw,
WPRES_ru_nivcsw,
};
#include <string.h> /* for strcmp() */
%}
struct wpres_key {
const char *name;
int code;
};
%%
job_id, WPRES_job_id
type, WPRES_type
command, WPRES_command
timeout, WPRES_timeout
wait_status, WPRES_wait_status
start, WPRES_start
stop, WPRES_stop
outstd, WPRES_outstd
outerr, WPRES_outerr
exited_ok, WPRES_exited_ok
error_msg, WPRES_error_msg
error_code, WPRES_error_code
runtime, WPRES_runtime
ru_utime, WPRES_ru_utime
ru_stime, WPRES_ru_stime
ru_maxrss, WPRES_ru_maxrss
ru_ixrss, WPRES_ru_ixrss
ru_idrss, WPRES_ru_idrss
ru_isrss, WPRES_ru_isrss
ru_minflt, WPRES_ru_minflt
ru_majflt, WPRES_ru_majflt
ru_nswap, WPRES_ru_nswap
ru_inblock, WPRES_ru_inblock
ru_oublock, WPRES_ru_oublock
ru_msgsnd, WPRES_ru_msgsnd
ru_msgrcv, WPRES_ru_msgrcv
ru_nsignals, WPRES_ru_nsignals
ru_nvcsw, WPRES_ru_nvcsw
ru_nivcsw, WPRES_ru_nivcsw

3
cgi/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
*.cgi
Makefile

211
cgi/Makefile.in Normal file
View File

@ -0,0 +1,211 @@
###############################
# Makefile for Nagios CGIs
#
###############################
# Source code directories
SRC_COMMON=../common
SRC_INCLUDE=../include
SRC_XDATA=../xdata
SRC_LIB=../lib
prefix=@prefix@
exec_prefix=@exec_prefix@
LOGDIR=@localstatedir@
CFGDIR=@sysconfdir@
BINDIR=@bindir@
CGIDIR=@cgibindir@
HTMLDIR=@webdir@
INSTALL=@INSTALL@
INSTALL_OPTS=@INSTALL_OPTS@
COMMAND_OPTS=@COMMAND_OPTS@
STRIP=@STRIP@
CGIEXTRAS=@CGIEXTRAS@
CP=@CP@
CC=@CC@
CFLAGS=-Wall -I.. @CFLAGS@ @DEFS@ -DNSCGI
JSONFLAGS=-DJSON_NAGIOS_4X
# 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=archivejson.cgi avail.cgi cmd.cgi config.cgi extinfo.cgi history.cgi notifications.cgi objectjson.cgi outages.cgi showlog.cgi status.cgi statusjson.cgi statuswml.cgi summary.cgi tac.cgi $(CGIEXTRAS)
# 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 $(SNPRINTF_O) $(ODATALIBS) $(SDATALIBS) $(SRC_LIB)/libnagios.a
CGIHDRS=$(SRC_INCLUDE)/config.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/locations.h
CGIDEPS=$(CGILIBS) $(ODATADEPS) $(SDATADEPS) $(SRC_LIB)/libnagios.a
MATHLIBS=-lm
GDLIBS=@GDLIBS@
all cgis: $(CGIS)
$(CGILIBS): $(CGIHDRS)
######## REQUIRED LIBRARIES ##########
$(SRC_LIB)/libnagios.a:
$(MAKE) -C $(SRC_LIB)
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)/xodtemplate.c $(SRC_XDATA)/xodtemplate.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xodtemplate.c
statusdata-cgi.o: $(SRC_COMMON)/statusdata.c $(SRC_INCLUDE)/statusdata.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/statusdata.c
xstatusdata-cgi.o: $(SRC_XDATA)/xsddefault.c $(SRC_XDATA)/xsddefault.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/xsddefault.c
comments-cgi.o: $(SRC_COMMON)/comments.c $(SRC_INCLUDE)/comments.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/comments.c
downtime-cgi.o: $(SRC_COMMON)/downtime.c $(SRC_INCLUDE)/downtime.h
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/downtime.c
$(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)
########## JSON CGIS ##########
jsonutils.o: jsonutils.c $(SRC_INCLUDE)/jsonutils.h
$(CC) $(CFLAGS) $(JSONFLAGS) -c -o $@ jsonutils.c
archiveutils.o: archiveutils.c $(SRC_INCLUDE)/archiveutils.h
$(CC) $(CFLAGS) $(JSONFLAGS) -c -o $@ archiveutils.c
archivejson.cgi: archivejson.c $(CGIDEPS) archiveutils.o jsonutils.o $(SRC_INCLUDE)/archivejson.h
$(CC) $(CFLAGS) $(JSONFLAGS) $(LDFLAGS) -o $@ archivejson.c $(CGILIBS) archiveutils.o jsonutils.o $(LIBS)
objectjson.cgi: objectjson.c $(CGIDEPS) jsonutils.o $(SRC_INCLUDE)/objectjson.h
$(CC) $(CFLAGS) $(JSONFLAGS) $(LDFLAGS) -o $@ objectjson.c $(CGILIBS) jsonutils.o $(LIBS)
statusjson.cgi: statusjson.c $(CGIDEPS) jsonutils.o $(SRC_INCLUDE)/statusjson.h
$(CC) $(CFLAGS) $(JSONFLAGS) $(LDFLAGS) -o $@ statusjson.c $(CGILIBS) jsonutils.o $(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
install-unstripped:
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CGIDIR)
for file in *.cgi; do \
$(INSTALL) -m 775 $(INSTALL_OPTS) $$file $(DESTDIR)$(CGIDIR); \
done
install-basic:
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CGIDIR)
for file in *.cgi; do \
$(INSTALL) -s -m 775 $(INSTALL_OPTS) $$file $(DESTDIR)$(CGIDIR); \
done
.PHONY: libnagios

4622
cgi/archivejson.c Normal file

File diff suppressed because it is too large Load Diff

1650
cgi/archiveutils.c Normal file

File diff suppressed because it is too large Load Diff

5445
cgi/avail.c Normal file

File diff suppressed because it is too large Load Diff

605
cgi/cgiauth.c Normal file
View File

@ -0,0 +1,605 @@
/*****************************************************************************
*
* CGIAUTH.C - Authorization utilities for Nagios CGIs
*
*
* 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 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;
}

2135
cgi/cgiutils.c Normal file

File diff suppressed because it is too large Load Diff

2849
cgi/cmd.c Normal file

File diff suppressed because it is too large Load Diff

2439
cgi/config.c Normal file

File diff suppressed because it is too large Load Diff

212
cgi/extcmd_list.c Normal file
View File

@ -0,0 +1,212 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "../include/common.h"
#include "../include/cgiutils.h"
#define ALT_CMD_DEF(name)
#define CMD_DEF(name, cmd_opt, dflt_comment) \
{ #name, CMD_ ## name, cmd_opt, dflt_comment }
/* { #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, 2, NULL),
CMD_DEF(DEL_HOST_COMMENT, 0, NULL),
CMD_DEF(ADD_SVC_COMMENT, 2, 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, 2, NULL),
CMD_DEF(ACKNOWLEDGE_SVC_PROBLEM, 2, 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, 2, NULL),
CMD_DEF(SCHEDULE_SVC_DOWNTIME, 2, 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(DEL_HOST_DOWNTIME, 0, NULL),
CMD_DEF(DEL_SVC_DOWNTIME, 0, NULL),
CMD_DEF(ENABLE_PERFORMANCE_DATA, 0, NULL),
CMD_DEF(DISABLE_PERFORMANCE_DATA, 0, NULL),
CMD_DEF(SCHEDULE_HOSTGROUP_HOST_DOWNTIME, 2, NULL),
CMD_DEF(SCHEDULE_HOSTGROUP_SVC_DOWNTIME, 2, NULL),
CMD_DEF(SCHEDULE_HOST_SVC_DOWNTIME, 2, 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, 2, NULL),
CMD_DEF(SCHEDULE_SERVICEGROUP_SVC_DOWNTIME, 2, 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, 2, NULL),
CMD_DEF(SEND_CUSTOM_SVC_NOTIFICATION, 2, 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(CLEAR_HOST_FLAPPING_STATE, 0, NULL),
CMD_DEF(CLEAR_SVC_FLAPPING_STATE, 0, NULL),
};
#undef CMD_DEF
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif
struct nagios_extcmd* extcmd_get_command_id(int id)
{
unsigned 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;
}
return NULL;
}
struct nagios_extcmd* extcmd_get_command_name(const char *name)
{
unsigned int i;
for(i = 0; i < ARRAY_SIZE(in_core_commands); i++) {
struct nagios_extcmd *ecmd;
ecmd = &in_core_commands[i];
if(!strcmp(ecmd->name, name))
return ecmd;
}
return NULL;
}
const char *extcmd_get_name(int id) {
struct nagios_extcmd *ecmd = extcmd_get_command_id(id);
if (!ecmd)
return NULL;
return ecmd->name;
}

3167
cgi/extinfo.c Normal file

File diff suppressed because it is too large Load Diff

545
cgi/getcgi.c Normal file
View File

@ -0,0 +1,545 @@
/******************************************
*
* GETCGI.C - Nagios CGI Input Routines
*
*
*****************************************/
#include "../include/config.h"
#include "../include/getcgi.h"
#include <stdio.h>
#include <stdlib.h>
#undef PARANOID_CGI_INPUT
/* Remove potentially harmful characters from CGI input that we don't need or want */
void sanitize_cgi_input(char **cgivars) {
char *strptr;
int x, y, i;
int keep;
/* don't strip for now... */
return;
for(strptr = cgivars[i = 0]; strptr != NULL; strptr = cgivars[++i]) {
for(x = 0, y = 0; strptr[x] != '\x0'; x++) {
keep = 1;
/* remove potentially nasty characters */
if(strptr[x] == ';' || strptr[x] == '|' || strptr[x] == '&' || strptr[x] == '<' || strptr[x] == '>')
keep = 0;
#ifdef PARANOID_CGI_INPUT
else if(strptr[x] == '/' || strptr[x] == '\\')
keep = 0;
#endif
if(keep == 1)
strptr[y++] = strptr[x];
}
strptr[y] = '\x0';
}
}
/* 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';
}
/* 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_lang;
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;
char *cookies, *formid;
/* initialize char variable(s) */
cgiinput = "";
/* Attempt to set the locale */
accept_lang = getenv("HTTP_ACCEPT_LANGUAGE");
process_language(accept_lang);
/* 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, "&");
}
/* See if there is a NagFormId cookie & get it if it's available */
cookies = getenv("HTTP_COOKIE");
if (cookies && *cookies) {
formid = strstr(cookies, "NagFormId=");
if (formid) {
if(!(paircount % 256)) {
pairlist = (char **)realloc(pairlist, (paircount + 1) * sizeof(char *));
if(pairlist == NULL) {
printf("getcgivars(): Could not re-allocate memory for name-value pairlist.\n");
exit(1);
}
}
formid = strtok(formid, ";");
if (strlen(formid) > 10 && strlen(formid) < 21) {
for (i = strlen(formid) - 1; i > 9; --i)
if (!isxdigit(formid[i]))
break;
if (i == 9) {
pairlist[paircount] = strdup(formid);
if (!pairlist[paircount]) {
printf("getcgivars(): Could not allocate memory for name-value pair #%d.\n", paircount);
exit(1);
}
paircount++;
}
}
}
}
/* terminate the list */
pairlist[paircount] = NULL;
/* 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] = NULL;
/* free allocated memory */
free(cgiinput);
for(i = 0; pairlist[i]; 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_lang) {
accept_languages *accept_langs = NULL;
int x;
char locale_string[ 64];
char * locale = NULL;
char * locale_failsafe[] = { "en_US.utf8", "POSIX", "C" };
if( accept_lang != NULL) {
accept_langs = parse_accept_languages( accept_lang);
}
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++) {
accept_language *l;
l = accept_langs->languages[x];
if (!l || !l->locality || !l->language)
continue;
snprintf( locale_string, sizeof( locale_string), "%s_%s.%s",
l->language, l->locality, "utf8");
locale = setlocale( LC_ALL, locale_string);
}
free_accept_languages( accept_langs);
}
if( NULL == locale) { /* Still isn't set */
/* Try the fail safe locales */
for( x = 0; (( x < (int)( sizeof( locale_failsafe) / sizeof( char *))) &&
( NULL == locale)); x++) {
locale = setlocale( LC_ALL, 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 < (int)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);
}
/* free() memory allocated to storing the CGI variables */
void free_cgivars(char **cgivars) {
register int x;
for(x = 0; cgivars[x]; x++)
free(cgivars[x]);
free(cgivars);
}

2507
cgi/histogram.c Normal file

File diff suppressed because it is too large Load Diff

941
cgi/history.c Normal file
View File

@ -0,0 +1,941 @@
/***********************************************************************
*
* HISTORY.C - Nagios History CGI
*
*
* 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 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) {
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();
cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, 0);
document_header(TRUE);
/* get authentication information */
get_authentication_information(&current_authdata);
/* determine what log file we should be using */
get_log_archive_to_use(log_archive, log_file_to_use, (int)sizeof(log_file_to_use));
if(display_header == TRUE) {
/* begin top table */
printf("<table border=0 width=100%%>\n");
printf("<tr>\n");
/* left column of the first row */
printf("<td align=left valign=top width=33%%>\n");
if(display_type == DISPLAY_SERVICES)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Alert History");
else if(show_all_hosts == TRUE)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Alert History");
else
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Alert History");
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
display_info_table(temp_buffer, FALSE, &current_authdata);
printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
printf("<TR><TD CLASS='linkBox'>\n");
if(display_type == DISPLAY_HOSTS) {
printf("<A HREF='%s?host=%s'>View Status Detail For %s</A><BR />\n", STATUS_CGI, (show_all_hosts == TRUE) ? "all" : url_encode(host_name), (show_all_hosts == TRUE) ? "All Hosts" : "This Host");
printf("<A HREF='%s?host=%s'>View Notifications For %s</A><BR />\n", NOTIFICATIONS_CGI, (show_all_hosts == TRUE) ? "all" : url_encode(host_name), (show_all_hosts == TRUE) ? "All Hosts" : "This Host");
#ifdef USE_TRENDS
if(show_all_hosts == FALSE)
printf("<A HREF='%s?host=%s'>View Trends For This Host</A>\n", TRENDS_CGI, url_encode(host_name));
#endif
}
else {
printf("<A HREF='%s?host=%s&", NOTIFICATIONS_CGI, url_encode(host_name));
printf("service=%s'>View Notifications For This Service</A><BR />\n", url_encode(svc_description));
#ifdef USE_TRENDS
printf("<A HREF='%s?host=%s&", TRENDS_CGI, url_encode(host_name));
printf("service=%s'>View Trends For This Service</A><BR />\n", url_encode(svc_description));
#endif
printf("<A HREF='%s?host=%s'>View History For This Host</A>\n", HISTORY_CGI, url_encode(host_name));
}
printf("</TD></TR>\n");
printf("</TABLE>\n");
printf("</td>\n");
/* middle column of top row */
printf("<td align=center valign=top width=33%%>\n");
printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
if(display_type == DISPLAY_SERVICES)
printf("Service '%s' On Host '%s'", svc_description, host_name);
else if(show_all_hosts == TRUE)
printf("All Hosts and Services");
else
printf("Host '%s'", host_name);
printf("</DIV>\n");
printf("<BR />\n");
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%shost=%s&type=%d&statetype=%d&", HISTORY_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "", url_encode(host_name), history_options, state_options);
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
if(display_type == DISPLAY_SERVICES) {
snprintf(temp_buffer2, sizeof(temp_buffer2) - 1, "service=%s&", url_encode(svc_description));
temp_buffer2[sizeof(temp_buffer2) - 1] = '\x0';
strncat(temp_buffer, temp_buffer2, sizeof(temp_buffer) - strlen(temp_buffer) - 1);
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
}
display_nav_table(temp_buffer, log_archive);
printf("</td>\n");
/* right hand column of top row */
printf("<td align=right valign=top width=33%%>\n");
printf("<form method=\"GET\" action=\"%s\">\n", HISTORY_CGI);
printf("<table border=0 CLASS='optBox'>\n");
printf("<input type='hidden' name='host' value='%s'>\n", (show_all_hosts == TRUE) ? "all" : escape_string(host_name));
if(display_type == DISPLAY_SERVICES)
printf("<input type='hidden' name='service' value='%s'>\n", escape_string(svc_description));
printf("<input type='hidden' name='archive' value='%d'>\n", log_archive);
printf("<tr>\n");
printf("<td align=left CLASS='optBoxItem'>State type options:</td>\n");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left CLASS='optBoxItem'><select name='statetype'>\n");
printf("<option value=%d %s>All state types</option>\n", STATE_ALL, (state_options == STATE_ALL) ? "selected" : "");
printf("<option value=%d %s>Soft states</option>\n", STATE_SOFT, (state_options == STATE_SOFT) ? "selected" : "");
printf("<option value=%d %s>Hard states</option>\n", STATE_HARD, (state_options == STATE_HARD) ? "selected" : "");
printf("</select></td>\n");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left CLASS='optBoxItem'>History detail level for ");
if(display_type == DISPLAY_HOSTS)
printf("%s host%s", (show_all_hosts == TRUE) ? "all" : "this", (show_all_hosts == TRUE) ? "s" : "");
else
printf("service");
printf(":</td>\n");
printf("</tr>\n")
;
printf("<tr>\n");
printf("<td align=left CLASS='optBoxItem'><select name='type'>\n");
if(display_type == DISPLAY_HOSTS)
printf("<option value=%d %s>All alerts</option>\n", HISTORY_ALL, (history_options == HISTORY_ALL) ? "selected" : "");
printf("<option value=%d %s>All service alerts</option>\n", HISTORY_SERVICE_ALL, (history_options == HISTORY_SERVICE_ALL) ? "selected" : "");
if(display_type == DISPLAY_HOSTS)
printf("<option value=%d %s>All host alerts</option>\n", HISTORY_HOST_ALL, (history_options == HISTORY_HOST_ALL) ? "selected" : "");
printf("<option value=%d %s>Service warning</option>\n", HISTORY_SERVICE_WARNING, (history_options == HISTORY_SERVICE_WARNING) ? "selected" : "");
printf("<option value=%d %s>Service unknown</option>\n", HISTORY_SERVICE_UNKNOWN, (history_options == HISTORY_SERVICE_UNKNOWN) ? "selected" : "");
printf("<option value=%d %s>Service critical</option>\n", HISTORY_SERVICE_CRITICAL, (history_options == HISTORY_SERVICE_CRITICAL) ? "selected" : "");
printf("<option value=%d %s>Service recovery</option>\n", HISTORY_SERVICE_RECOVERY, (history_options == HISTORY_SERVICE_RECOVERY) ? "selected" : "");
if(display_type == DISPLAY_HOSTS) {
printf("<option value=%d %s>Host down</option>\n", HISTORY_HOST_DOWN, (history_options == HISTORY_HOST_DOWN) ? "selected" : "");
printf("<option value=%d %s>Host unreachable</option>\n", HISTORY_HOST_UNREACHABLE, (history_options == HISTORY_HOST_UNREACHABLE) ? "selected" : "");
printf("<option value=%d %s>Host recovery</option>\n", HISTORY_HOST_RECOVERY, (history_options == HISTORY_HOST_RECOVERY) ? "selected" : "");
}
printf("</select></td>\n");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='noflapping' %s> Hide Flapping Alerts</td>", (display_flapping_alerts == FALSE) ? "checked" : "");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='nodowntime' %s> Hide Downtime Alerts</td>", (display_downtime_alerts == FALSE) ? "checked" : "");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='nosystem' %s> Hide Process Messages</td>", (display_system_messages == FALSE) ? "checked" : "");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s> Older Entries First</td>", (use_lifo == FALSE) ? "checked" : "");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
printf("</tr>\n");
/* display context-sensitive help */
printf("<tr>\n");
printf("<td align=right>\n");
display_context_help(CONTEXTHELP_HISTORY);
printf("</td>\n");
printf("</tr>\n");
printf("</table>\n");
printf("</form>\n");
printf("</td>\n");
/* end of top table */
printf("</tr>\n");
printf("</table>\n");
}
/* display history */
get_history();
document_footer();
/* free allocated memory */
free_memory();
return OK;
}
void document_header(int use_stylesheet) {
char date_time[MAX_DATETIME_LENGTH];
time_t current_time;
time_t expire_time;
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
time(&current_time);
get_time_string(&current_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; charset=utf-8\r\n\r\n");
if(embedded == TRUE)
return;
printf("<html>\n");
printf("<head>\n");
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
printf("<title>\n");
printf("Nagios History\n");
printf("</title>\n");
if(use_stylesheet == TRUE) {
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, HISTORY_CSS);
}
printf("</head>\n");
printf("<BODY CLASS='history'>\n");
/* include user SSI header */
include_ssi_files(HISTORY_CGI, SSI_HEADER);
return;
}
void document_footer(void) {
if(embedded == TRUE)
return;
/* include user SSI footer */
include_ssi_files(HISTORY_CGI, SSI_FOOTER);
printf("</body>\n");
printf("</html>\n");
return;
}
int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
for(x = 0; variables[x]; x++) {
/* do some basic length checking on the variable identifier to prevent buffer overflows */
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1)
continue;
/* we found the host argument */
else if(!strcmp(variables[x], "host")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((host_name = (char *)strdup(variables[x])) == NULL)
host_name = "";
strip_html_brackets(host_name);
display_type = DISPLAY_HOSTS;
if(!strcmp(host_name, "all"))
show_all_hosts = TRUE;
else
show_all_hosts = FALSE;
}
/* we found the service argument */
else if(!strcmp(variables[x], "service")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((svc_description = (char *)strdup(variables[x])) == NULL)
svc_description = "";
strip_html_brackets(svc_description);
display_type = DISPLAY_SERVICES;
}
/* we found the history type argument */
else if(!strcmp(variables[x], "type")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
history_options = atoi(variables[x]);
}
/* we found the history state type argument */
else if(!strcmp(variables[x], "statetype")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
state_options = atoi(variables[x]);
}
/* we found the log archive argument */
else if(!strcmp(variables[x], "archive")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
log_archive = atoi(variables[x]);
if(log_archive < 0)
log_archive = 0;
}
/* we found the order argument */
else if(!strcmp(variables[x], "oldestfirst")) {
use_lifo = FALSE;
}
/* we found the embed option */
else if(!strcmp(variables[x], "embedded"))
embedded = TRUE;
/* we found the noheader option */
else if(!strcmp(variables[x], "noheader"))
display_header = FALSE;
/* we found the nofrills option */
else if(!strcmp(variables[x], "nofrills"))
display_frills = FALSE;
/* we found the notimebreaks option */
else if(!strcmp(variables[x], "notimebreaks"))
display_timebreaks = FALSE;
/* we found the no system messages option */
else if(!strcmp(variables[x], "nosystem"))
display_system_messages = FALSE;
/* we found the no flapping alerts option */
else if(!strcmp(variables[x], "noflapping"))
display_flapping_alerts = FALSE;
/* we found the no downtime alerts option */
else if(!strcmp(variables[x], "nodowntime"))
display_downtime_alerts = FALSE;
}
/* free memory allocated to the CGI variables */
free_cgivars(variables);
return error;
}
void get_history(void) {
mmapfile *thefile = NULL;
char image[MAX_INPUT_BUFFER];
char image_alt[MAX_INPUT_BUFFER];
char *input = NULL;
char *input2 = NULL;
char match1[MAX_INPUT_BUFFER];
char match2[MAX_INPUT_BUFFER];
int found_line = FALSE;
int system_message = FALSE;
int display_line = FALSE;
time_t t;
char date_time[MAX_DATETIME_LENGTH];
char *temp_buffer = NULL;
int history_type = SERVICE_HISTORY;
int history_detail_type = HISTORY_SERVICE_CRITICAL;
char *entry_host_name = NULL;
char *entry_service_desc = NULL;
host *temp_host = NULL;
service *temp_service = NULL;
int result = 0;
char last_message_date[MAX_INPUT_BUFFER] = "";
char current_message_date[MAX_INPUT_BUFFER] = "";
struct tm *time_ptr = NULL;
if(use_lifo == TRUE) {
result = read_file_into_lifo(log_file_to_use);
if(result != LIFO_OK) {
if(result == LIFO_ERROR_MEMORY) {
printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying history in natural order...</DIV></P>\n");
}
else if(result == LIFO_ERROR_FILE) {
printf("<HR><P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P><HR>", log_file_to_use);
return;
}
use_lifo = FALSE;
}
}
if(use_lifo == FALSE) {
if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
printf("<HR><P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P><HR>", log_file_to_use);
return;
}
}
printf("<P><DIV CLASS='logEntries'>\n");
while(1) {
my_free(input);
my_free(input2);
if(use_lifo == TRUE) {
if((input = pop_lifo()) == NULL)
break;
}
else {
if((input = mmap_fgets(thefile)) == NULL)
break;
}
strip(input);
strcpy(image, "");
strcpy(image_alt, "");
system_message = FALSE;
if((input2 = (char *)strdup(input)) == NULL)
continue;
/* service state alerts */
if(strstr(input, "SERVICE ALERT:")) {
history_type = SERVICE_HISTORY;
/* get host and service names */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_host_name = strdup(temp_buffer + 1);
else
entry_host_name = NULL;
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_service_desc = strdup(temp_buffer);
else
entry_service_desc = NULL;
if(strstr(input, ";CRITICAL;")) {
strncpy(image, CRITICAL_ICON, sizeof(image));
strncpy(image_alt, CRITICAL_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_SERVICE_CRITICAL;
}
else if(strstr(input, ";WARNING;")) {
strncpy(image, WARNING_ICON, sizeof(image));
strncpy(image_alt, WARNING_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_SERVICE_WARNING;
}
else if(strstr(input, ";UNKNOWN;")) {
strncpy(image, UNKNOWN_ICON, sizeof(image));
strncpy(image_alt, UNKNOWN_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_SERVICE_UNKNOWN;
}
else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) {
strncpy(image, OK_ICON, sizeof(image));
strncpy(image_alt, OK_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_SERVICE_RECOVERY;
}
}
/* service flapping alerts */
else if(strstr(input, "SERVICE FLAPPING ALERT:")) {
if(display_flapping_alerts == FALSE)
continue;
history_type = SERVICE_FLAPPING_HISTORY;
/* get host and service names */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_host_name = strdup(temp_buffer + 1);
else
entry_host_name = NULL;
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_service_desc = strdup(temp_buffer);
else
entry_service_desc = NULL;
strncpy(image, FLAPPING_ICON, sizeof(image));
if(strstr(input, ";STARTED;"))
strncpy(image_alt, "Service started flapping", sizeof(image_alt));
else if(strstr(input, ";STOPPED;"))
strncpy(image_alt, "Service stopped flapping", sizeof(image_alt));
else if(strstr(input, ";DISABLED;"))
strncpy(image_alt, "Service flap detection disabled", sizeof(image_alt));
}
/* service downtime alerts */
else if(strstr(input, "SERVICE DOWNTIME ALERT:")) {
if(display_downtime_alerts == FALSE)
continue;
history_type = SERVICE_DOWNTIME_HISTORY;
/* get host and service names */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_host_name = strdup(temp_buffer + 1);
else
entry_host_name = NULL;
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_service_desc = strdup(temp_buffer);
else
entry_service_desc = NULL;
strncpy(image, SCHEDULED_DOWNTIME_ICON, sizeof(image));
if(strstr(input, ";STARTED;"))
strncpy(image_alt, "Service entered a period of scheduled downtime", sizeof(image_alt));
else if(strstr(input, ";STOPPED;"))
strncpy(image_alt, "Service exited from a period of scheduled downtime", sizeof(image_alt));
else if(strstr(input, ";CANCELLED;"))
strncpy(image_alt, "Service scheduled downtime has been cancelled", sizeof(image_alt));
}
/* host state alerts */
else if(strstr(input, "HOST ALERT:")) {
history_type = HOST_HISTORY;
/* get host name */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_host_name = strdup(temp_buffer + 1);
else
entry_host_name = NULL;
if(strstr(input, ";DOWN;")) {
strncpy(image, HOST_DOWN_ICON, sizeof(image));
strncpy(image_alt, HOST_DOWN_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_HOST_DOWN;
}
else if(strstr(input, ";UNREACHABLE;")) {
strncpy(image, HOST_UNREACHABLE_ICON, sizeof(image));
strncpy(image_alt, HOST_UNREACHABLE_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_HOST_UNREACHABLE;
}
else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) {
strncpy(image, HOST_UP_ICON, sizeof(image));
strncpy(image_alt, HOST_UP_ICON_ALT, sizeof(image_alt));
history_detail_type = HISTORY_HOST_RECOVERY;
}
}
/* host flapping alerts */
else if(strstr(input, "HOST FLAPPING ALERT:")) {
if(display_flapping_alerts == FALSE)
continue;
history_type = HOST_FLAPPING_HISTORY;
/* get host name */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_host_name = strdup(temp_buffer + 1);
else
entry_host_name = NULL;
strncpy(image, FLAPPING_ICON, sizeof(image));
if(strstr(input, ";STARTED;"))
strncpy(image_alt, "Host started flapping", sizeof(image_alt));
else if(strstr(input, ";STOPPED;"))
strncpy(image_alt, "Host stopped flapping", sizeof(image_alt));
else if(strstr(input, ";DISABLED;"))
strncpy(image_alt, "Host flap detection disabled", sizeof(image_alt));
}
/* host downtime alerts */
else if(strstr(input, "HOST DOWNTIME ALERT:")) {
if(display_downtime_alerts == FALSE)
continue;
history_type = HOST_DOWNTIME_HISTORY;
/* get host name */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
if(temp_buffer)
entry_host_name = strdup(temp_buffer + 1);
else
entry_host_name = NULL;
strncpy(image, SCHEDULED_DOWNTIME_ICON, sizeof(image));
if(strstr(input, ";STARTED;"))
strncpy(image_alt, "Host entered a period of scheduled downtime", sizeof(image_alt));
else if(strstr(input, ";STOPPED;"))
strncpy(image_alt, "Host exited from a period of scheduled downtime", sizeof(image_alt));
else if(strstr(input, ";CANCELLED;"))
strncpy(image_alt, "Host scheduled downtime has been cancelled", sizeof(image_alt));
}
else if(display_system_messages == FALSE)
continue;
/* program start */
else if(strstr(input, " starting...")) {
strncpy(image, START_ICON, sizeof(image));
strncpy(image_alt, START_ICON_ALT, sizeof(image_alt));
system_message = TRUE;
}
/* normal program termination */
else if(strstr(input, " shutting down...")) {
strncpy(image, STOP_ICON, sizeof(image));
strncpy(image_alt, STOP_ICON_ALT, sizeof(image_alt));
system_message = TRUE;
}
/* abnormal program termination */
else if(strstr(input, "Bailing out")) {
strncpy(image, STOP_ICON, sizeof(image));
strncpy(image_alt, STOP_ICON_ALT, sizeof(image_alt));
system_message = TRUE;
}
/* program restart */
else if(strstr(input, " restarting...")) {
strncpy(image, RESTART_ICON, sizeof(image));
strncpy(image_alt, RESTART_ICON_ALT, sizeof(image_alt));
system_message = TRUE;
}
image[sizeof(image) - 1] = '\x0';
image_alt[sizeof(image_alt) - 1] = '\x0';
/* get the timestamp */
temp_buffer = strtok(input, "]");
t = (temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);
time_ptr = localtime(&t);
strftime(current_message_date, sizeof(current_message_date), "%B %d, %Y %H:00\n", time_ptr);
current_message_date[sizeof(current_message_date) - 1] = '\x0';
get_time_string(&t, date_time, sizeof(date_time), SHORT_DATE_TIME);
strip(date_time);
temp_buffer = strtok(NULL, "\n");
if(strcmp(image, "")) {
display_line = FALSE;
if(system_message == TRUE)
display_line = TRUE;
else if(display_type == DISPLAY_HOSTS) {
if(history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) {
snprintf(match1, sizeof( match1),
" HOST ALERT: %s;", host_name);
snprintf(match2, sizeof( match2),
" SERVICE ALERT: %s;", host_name);
}
else if(history_type == HOST_FLAPPING_HISTORY || history_type == SERVICE_FLAPPING_HISTORY) {
snprintf(match1, sizeof( match1),
" HOST FLAPPING ALERT: %s;", host_name);
snprintf(match2, sizeof( match2),
" SERVICE FLAPPING ALERT: %s;", host_name);
}
else if(history_type == HOST_DOWNTIME_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY) {
snprintf(match1, sizeof( match1),
" HOST DOWNTIME ALERT: %s;", host_name);
snprintf(match2, sizeof( match2),
" SERVICE DOWNTIME ALERT: %s;", host_name);
}
if(show_all_hosts == TRUE)
display_line = TRUE;
else if(strstr(temp_buffer, match1))
display_line = TRUE;
else if(strstr(temp_buffer, match2))
display_line = TRUE;
if(display_line == TRUE) {
if(history_options == HISTORY_ALL)
display_line = TRUE;
else if(history_options == HISTORY_HOST_ALL && (history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY))
display_line = TRUE;
else if(history_options == HISTORY_SERVICE_ALL && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
display_line = TRUE;
else if((history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) && (history_detail_type & history_options))
display_line = TRUE;
else
display_line = FALSE;
}
/* check alert state types */
if(display_line == TRUE && (history_type == HOST_HISTORY || history_type == SERVICE_HISTORY)) {
if(state_options == STATE_ALL)
display_line = TRUE;
else if((state_options & STATE_SOFT) && strstr(temp_buffer, ";SOFT;"))
display_line = TRUE;
else if((state_options & STATE_HARD) && strstr(temp_buffer, ";HARD;"))
display_line = TRUE;
else
display_line = FALSE;
}
}
else if(display_type == DISPLAY_SERVICES) {
if(history_type == SERVICE_HISTORY)
snprintf(match1, sizeof( match1), " SERVICE ALERT: %s;%s;", host_name, svc_description);
else if(history_type == SERVICE_FLAPPING_HISTORY)
snprintf(match1, sizeof( match1), " SERVICE FLAPPING ALERT: %s;%s;", host_name, svc_description);
else if(history_type == SERVICE_DOWNTIME_HISTORY)
snprintf(match1, sizeof( match1), " SERVICE DOWNTIME ALERT: %s;%s;", host_name, svc_description);
if(strstr(temp_buffer, match1) && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
display_line = TRUE;
if(display_line == TRUE) {
if(history_options == HISTORY_ALL || history_options == HISTORY_SERVICE_ALL)
display_line = TRUE;
else if(history_options & history_detail_type)
display_line = TRUE;
else
display_line = FALSE;
}
/* check alert state type */
if(display_line == TRUE && history_type == SERVICE_HISTORY) {
if(state_options == STATE_ALL)
display_line = TRUE;
else if((state_options & STATE_SOFT) && strstr(temp_buffer, ";SOFT;"))
display_line = TRUE;
else if((state_options & STATE_HARD) && strstr(temp_buffer, ";HARD;"))
display_line = TRUE;
else
display_line = FALSE;
}
}
/* make sure user is authorized to view this host or service information */
if(system_message == FALSE) {
if(history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY) {
temp_host = find_host(entry_host_name);
if(is_authorized_for_host(temp_host, &current_authdata) == FALSE)
display_line = FALSE;
}
else {
temp_service = find_service(entry_host_name, entry_service_desc);
if(is_authorized_for_service(temp_service, &current_authdata) == FALSE)
display_line = FALSE;
}
}
/* display the entry if we should... */
if(display_line == TRUE) {
if(strcmp(last_message_date, current_message_date) != 0 && display_timebreaks == TRUE) {
printf("</DIV><BR CLEAR='all' />\n");
printf("<DIV CLASS='dateTimeBreak'>\n");
printf("<table border=0 width=95%%><tr>");
printf("<td width=40%%><hr width=100%%></td>");
printf("<td align=center CLASS='dateTimeBreak'>%s</td>", current_message_date);
printf("<td width=40%%><hr width=100%%></td>");
printf("</tr></table>\n");
printf("</DIV>\n");
printf("<BR CLEAR='all' /><DIV CLASS='logEntries'>\n");
strncpy(last_message_date, current_message_date, sizeof(last_message_date));
last_message_date[sizeof(last_message_date) - 1] = '\x0';
}
if(display_frills == TRUE)
printf("<img align='left' src='%s%s' alt='%s' title='%s' />", url_images_path, image, image_alt, image_alt);
printf("[%s] %s", date_time, html_encode(temp_buffer, FALSE));
if(enable_splunk_integration == TRUE) {
printf("&nbsp;&nbsp;&nbsp;");
display_splunk_generic_url(temp_buffer, 2);
}
printf("<br clear='all' />\n");
found_line = TRUE;
}
}
/* free memory */
free(entry_host_name);
entry_host_name = NULL;
free(entry_service_desc);
entry_service_desc = NULL;
}
printf("</DIV></P>\n");
if(found_line == FALSE) {
printf("<HR>\n");
printf("<P><DIV CLASS='warningMessage'>No history information was found ");
if(display_type == DISPLAY_HOSTS)
printf("%s", (show_all_hosts == TRUE) ? "" : "for this host ");
else
printf("for this service ");
printf("in %s log file</DIV></P>", (log_archive == 0) ? "the current" : "this archived");
}
printf("<HR>\n");
my_free(input);
my_free(input2);
if(use_lifo == TRUE)
free_lifo_memory();
else
mmap_fclose(thefile);
return;
}

1483
cgi/jsonutils.c Normal file

File diff suppressed because it is too large Load Diff

755
cgi/notifications.c Normal file
View File

@ -0,0 +1,755 @@
/************************************************************************
*
* NOTIFICATIONS.C - Nagios Notifications CGI
*
*
* 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];
#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) {
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();
cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, 0);
document_header(TRUE);
/* get authentication information */
get_authentication_information(&current_authdata);
/* determine what log file we should use */
get_log_archive_to_use(log_archive, log_file_to_use, (int)sizeof(log_file_to_use));
if(display_header == TRUE) {
/* begin top table */
printf("<table border=0 width=100%%>\n");
printf("<tr>\n");
/* left column of top row */
printf("<td align=left valign=top width=33%%>\n");
if(query_type == FIND_SERVICE)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Notifications");
else if(query_type == FIND_HOST) {
if(find_all == TRUE)
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Notifications");
else
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Notifications");
}
else
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Contact Notifications");
display_info_table(temp_buffer, FALSE, &current_authdata);
if(query_type == FIND_HOST || query_type == FIND_SERVICE) {
printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
printf("<TR><TD CLASS='linkBox'>\n");
if(query_type == FIND_HOST) {
printf("<A HREF='%s?host=%s'>View Status Detail For %s</A><BR>\n", STATUS_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name), (find_all == TRUE) ? "All Hosts" : "This Host");
printf("<A HREF='%s?host=%s'>View History For %s</A><BR>\n", HISTORY_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name), (find_all == TRUE) ? "All Hosts" : "This Host");
#ifdef USE_TRENDS
if(find_all == FALSE)
printf("<A HREF='%s?host=%s'>View Trends For This Host</A><BR>\n", TRENDS_CGI, url_encode(query_host_name));
#endif
}
else if(query_type == FIND_SERVICE) {
printf("<A HREF='%s?host=%s&", HISTORY_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name));
printf("service=%s'>View History For This Service</A><BR>\n", url_encode(query_svc_description));
#ifdef USE_TRENDS
printf("<A HREF='%s?host=%s&", TRENDS_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name));
printf("service=%s'>View Trends For This Service</A><BR>\n", url_encode(query_svc_description));
#endif
}
printf("</TD></TR>\n");
printf("</TABLE>\n");
}
printf("</td>\n");
/* middle column of top row */
printf("<td align=center valign=top width=33%%>\n");
printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
if(query_type == FIND_SERVICE)
printf("Service '%s' On Host '%s'", query_svc_description, query_host_name);
else if(query_type == FIND_HOST) {
if(find_all == TRUE)
printf("All Hosts and Services");
else
printf("Host '%s'", query_host_name);
}
else {
if(find_all == TRUE)
printf("All Contacts");
else
printf("Contact '%s'", query_contact_name);
}
printf("</DIV>\n");
printf("<BR>\n");
if(query_type == FIND_SERVICE) {
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%shost=%s&", NOTIFICATIONS_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "", url_encode(query_host_name));
snprintf(temp_buffer2, sizeof(temp_buffer2) - 1, "service=%s&type=%d&", url_encode(query_svc_description), notification_options);
strncat(temp_buffer, temp_buffer2, sizeof(temp_buffer) - strlen(temp_buffer) - 1);
}
else
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%s%s=%s&type=%d&", NOTIFICATIONS_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "", (query_type == FIND_HOST) ? "host" : "contact", (query_type == FIND_HOST) ? url_encode(query_host_name) : url_encode(query_contact_name), notification_options);
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
display_nav_table(temp_buffer, log_archive);
printf("</td>\n");
/* right hand column of top row */
printf("<td align=right valign=top width=33%%>\n");
printf("<form method='GET' action='%s'>\n", NOTIFICATIONS_CGI);
if(query_type == FIND_SERVICE) {
printf("<input type='hidden' name='host' value='%s'>\n", escape_string(query_host_name));
printf("<input type='hidden' name='service' value='%s'>\n", escape_string(query_svc_description));
}
else
printf("<input type='hidden' name='%s' value='%s'>\n", (query_type == FIND_HOST) ? "host" : "contact", (query_type == FIND_HOST) ? escape_string(query_host_name) : escape_string(query_contact_name));
printf("<input type='hidden' name='archive' value='%d'>\n", log_archive);
printf("<table border=0 CLASS='optBox'>\n");
printf("<tr>\n");
if(query_type == FIND_SERVICE)
printf("<td align=left colspan=2 CLASS='optBoxItem'>Notification detail level for this service:</td>");
else
printf("<td align=left colspan=2 CLASS='optBoxItem'>Notification detail level for %s %s%s:</td>", (find_all == TRUE) ? "all" : "this", (query_type == FIND_HOST) ? "host" : "contact", (find_all == TRUE) ? "s" : "");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left colspan=2 CLASS='optBoxItem'><select name='type'>\n");
printf("<option value=%d %s>All notifications\n", NOTIFICATION_ALL, (notification_options == NOTIFICATION_ALL) ? "selected" : "");
if(query_type != FIND_SERVICE) {
printf("<option value=%d %s>All service notifications\n", NOTIFICATION_SERVICE_ALL, (notification_options == NOTIFICATION_SERVICE_ALL) ? "selected" : "");
printf("<option value=%d %s>All host notifications\n", NOTIFICATION_HOST_ALL, (notification_options == NOTIFICATION_HOST_ALL) ? "selected" : "");
}
printf("<option value=%d %s>Service custom\n", NOTIFICATION_SERVICE_CUSTOM, (notification_options == NOTIFICATION_SERVICE_CUSTOM) ? "selected" : "");
printf("<option value=%d %s>Service acknowledgements\n", NOTIFICATION_SERVICE_ACK, (notification_options == NOTIFICATION_SERVICE_ACK) ? "selected" : "");
printf("<option value=%d %s>Service warning\n", NOTIFICATION_SERVICE_WARNING, (notification_options == NOTIFICATION_SERVICE_WARNING) ? "selected" : "");
printf("<option value=%d %s>Service unknown\n", NOTIFICATION_SERVICE_UNKNOWN, (notification_options == NOTIFICATION_SERVICE_UNKNOWN) ? "selected" : "");
printf("<option value=%d %s>Service critical\n", NOTIFICATION_SERVICE_CRITICAL, (notification_options == NOTIFICATION_SERVICE_CRITICAL) ? "selected" : "");
printf("<option value=%d %s>Service recovery\n", NOTIFICATION_SERVICE_RECOVERY, (notification_options == NOTIFICATION_SERVICE_RECOVERY) ? "selected" : "");
printf("<option value=%d %s>Service flapping\n", NOTIFICATION_SERVICE_FLAP, (notification_options == NOTIFICATION_SERVICE_FLAP) ? "selected" : "");
printf("<option value=%d %s>Service downtime\n", NOTIFICATION_SERVICE_DOWNTIME, (notification_options == NOTIFICATION_SERVICE_DOWNTIME) ? "selected" : "");
if(query_type != FIND_SERVICE) {
printf("<option value=%d %s>Host custom\n", NOTIFICATION_HOST_CUSTOM, (notification_options == NOTIFICATION_HOST_CUSTOM) ? "selected" : "");
printf("<option value=%d %s>Host acknowledgements\n", NOTIFICATION_HOST_ACK, (notification_options == NOTIFICATION_HOST_ACK) ? "selected" : "");
printf("<option value=%d %s>Host down\n", NOTIFICATION_HOST_DOWN, (notification_options == NOTIFICATION_HOST_DOWN) ? "selected" : "");
printf("<option value=%d %s>Host unreachable\n", NOTIFICATION_HOST_UNREACHABLE, (notification_options == NOTIFICATION_HOST_UNREACHABLE) ? "selected" : "");
printf("<option value=%d %s>Host recovery\n", NOTIFICATION_HOST_RECOVERY, (notification_options == NOTIFICATION_HOST_RECOVERY) ? "selected" : "");
printf("<option value=%d %s>Host flapping\n", NOTIFICATION_HOST_FLAP, (notification_options == NOTIFICATION_HOST_FLAP) ? "selected" : "");
printf("<option value=%d %s>Host downtime\n", NOTIFICATION_HOST_DOWNTIME, (notification_options == NOTIFICATION_HOST_DOWNTIME) ? "selected" : "");
}
printf("</select></td>\n");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left CLASS='optBoxItem'>Older Entries First:</td>\n");
printf("<td></td>\n");
printf("</tr>\n");
printf("<tr>\n");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s></td>", (use_lifo == FALSE) ? "checked" : "");
printf("<td align=right CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
printf("</tr>\n");
/* display context-sensitive help */
printf("<tr><td></td><td align=right valign=bottom>\n");
display_context_help(CONTEXTHELP_NOTIFICATIONS);
printf("</td></tr>\n");
printf("</table>\n");
printf("</form>\n");
printf("</td>\n");
/* end of top table */
printf("</tr>\n");
printf("</table>\n");
}
/* display notifications */
display_notifications();
document_footer();
/* free allocated memory */
free_memory();
return OK;
}
void document_header(int use_stylesheet) {
char date_time[MAX_DATETIME_LENGTH];
time_t current_time;
time_t expire_time;
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
time(&current_time);
get_time_string(&current_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; charset=utf-8\r\n\r\n");
if(embedded == TRUE)
return;
printf("<html>\n");
printf("<head>\n");
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
printf("<title>\n");
printf("Alert Notifications\n");
printf("</title>\n");
if(use_stylesheet == TRUE) {
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, NOTIFICATIONS_CSS);
}
printf("</head>\n");
printf("<body CLASS='notifications'>\n");
/* include user SSI header */
include_ssi_files(NOTIFICATIONS_CGI, SSI_HEADER);
return;
}
void document_footer(void) {
if(embedded == TRUE)
return;
/* include user SSI footer */
include_ssi_files(NOTIFICATIONS_CGI, SSI_FOOTER);
printf("</body>\n");
printf("</html>\n");
return;
}
int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
for(x = 0; variables[x]; 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")) {
query_type = FIND_HOST;
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((query_host_name = strdup(variables[x])) == NULL)
query_host_name = "";
strip_html_brackets(query_host_name);
if(!strcmp(query_host_name, "all"))
find_all = TRUE;
else
find_all = FALSE;
}
/* we found the contact argument */
else if(!strcmp(variables[x], "contact")) {
query_type = FIND_CONTACT;
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((query_contact_name = strdup(variables[x])) == NULL)
query_contact_name = "";
strip_html_brackets(query_contact_name);
if(!strcmp(query_contact_name, "all"))
find_all = TRUE;
else
find_all = FALSE;
}
/* we found the service argument */
else if(!strcmp(variables[x], "service")) {
query_type = FIND_SERVICE;
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((query_svc_description = strdup(variables[x])) == NULL)
query_svc_description = "";
strip_html_brackets(query_svc_description);
}
/* we found the notification type argument */
else if(!strcmp(variables[x], "type")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
notification_options = atoi(variables[x]);
}
/* we found the log archive argument */
else if(!strcmp(variables[x], "archive")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
log_archive = atoi(variables[x]);
if(log_archive < 0)
log_archive = 0;
}
/* we found the order argument */
else if(!strcmp(variables[x], "oldestfirst")) {
use_lifo = FALSE;
}
/* we found the embed option */
else if(!strcmp(variables[x], "embedded"))
embedded = TRUE;
/* we found the noheader option */
else if(!strcmp(variables[x], "noheader"))
display_header = FALSE;
}
/*
* Set some default values if not already set.
* Done here as they won't be set if variable
* not provided via cgi parameters
* Only required for hosts & contacts, not services
* as there is no service_name=all option
*/
if(query_type == FIND_HOST && strlen(query_host_name) == 0) {
query_host_name = "all";
find_all = TRUE;
}
if(query_type == FIND_CONTACT && strlen(query_contact_name) == 0) {
query_contact_name = "all";
find_all = TRUE;
}
/* free memory allocated to the CGI variables */
free_cgivars(variables);
return error;
}
void display_notifications(void) {
mmapfile *thefile = NULL;
char *input = NULL;
char *temp_buffer;
char date_time[MAX_DATETIME_LENGTH];
char alert_level[MAX_INPUT_BUFFER];
char alert_level_class[MAX_INPUT_BUFFER];
char contact_name[MAX_INPUT_BUFFER];
char service_name[MAX_INPUT_BUFFER];
char host_name[MAX_INPUT_BUFFER];
char method_name[MAX_INPUT_BUFFER];
int show_entry;
int total_notifications;
int notification_type = SERVICE_NOTIFICATION;
int notification_detail_type = NOTIFICATION_SERVICE_CRITICAL;
int odd = 0;
time_t t;
host *temp_host;
service *temp_service;
int result;
if(use_lifo == TRUE) {
result = read_file_into_lifo(log_file_to_use);
if(result != LIFO_OK) {
if(result == LIFO_ERROR_MEMORY) {
printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying notifications in natural order...</DIV></P>");
}
else if(result == LIFO_ERROR_FILE) {
printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>", log_file_to_use);
return;
}
use_lifo = FALSE;
}
}
if(use_lifo == FALSE) {
if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>", log_file_to_use);
return;
}
}
printf("<p>\n");
printf("<div align='center'>\n");
printf("<table border=0 CLASS='notifications'>\n");
printf("<tr>\n");
printf("<th CLASS='notifications'>Host</th>\n");
printf("<th CLASS='notifications'>Service</th>\n");
printf("<th CLASS='notifications'>Type</th>\n");
printf("<th CLASS='notifications'>Time</th>\n");
printf("<th CLASS='notifications'>Contact</th>\n");
printf("<th CLASS='notifications'>Notification Command</th>\n");
printf("<th CLASS='notifications'>Information</th>\n");
printf("</tr>\n");
total_notifications = 0;
while(1) {
free(input);
if(use_lifo == TRUE) {
if((input = pop_lifo()) == NULL)
break;
}
else {
if((input = mmap_fgets(thefile)) == NULL)
break;
}
strip(input);
/* see if this line contains the notification event string */
if(strstr(input, HOST_NOTIFICATION_STRING) || strstr(input, SERVICE_NOTIFICATION_STRING)) {
if(strstr(input, HOST_NOTIFICATION_STRING))
notification_type = HOST_NOTIFICATION;
else
notification_type = SERVICE_NOTIFICATION;
/* get the date/time */
temp_buffer = (char *)strtok(input, "]");
t = (time_t)(temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);
get_time_string(&t, date_time, (int)sizeof(date_time), SHORT_DATE_TIME);
strip(date_time);
/* get the contact name */
temp_buffer = (char *)strtok(NULL, ":");
temp_buffer = (char *)strtok(NULL, ";");
snprintf(contact_name, sizeof(contact_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer + 1);
contact_name[sizeof(contact_name) - 1] = '\x0';
/* get the host name */
temp_buffer = (char *)strtok(NULL, ";");
snprintf(host_name, sizeof(host_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
host_name[sizeof(host_name) - 1] = '\x0';
/* get the service name */
if(notification_type == SERVICE_NOTIFICATION) {
temp_buffer = (char *)strtok(NULL, ";");
snprintf(service_name, sizeof(service_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
service_name[sizeof(service_name) - 1] = '\x0';
}
/* get the alert level */
temp_buffer = (char *)strtok(NULL, ";");
snprintf(alert_level, sizeof(alert_level), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
alert_level[sizeof(alert_level) - 1] = '\x0';
if(notification_type == SERVICE_NOTIFICATION) {
if(!strcmp(alert_level, "CRITICAL")) {
notification_detail_type = NOTIFICATION_SERVICE_CRITICAL;
strcpy(alert_level_class, "CRITICAL");
}
else if(!strcmp(alert_level, "WARNING")) {
notification_detail_type = NOTIFICATION_SERVICE_WARNING;
strcpy(alert_level_class, "WARNING");
}
else if(!strcmp(alert_level, "RECOVERY") || !strcmp(alert_level, "OK")) {
strcpy(alert_level, "OK");
notification_detail_type = NOTIFICATION_SERVICE_RECOVERY;
strcpy(alert_level_class, "OK");
}
else if(strstr(alert_level, "CUSTOM (")) {
notification_detail_type = NOTIFICATION_SERVICE_CUSTOM;
strcpy(alert_level_class, "CUSTOM");
}
else if(strstr(alert_level, "ACKNOWLEDGEMENT (")) {
notification_detail_type = NOTIFICATION_SERVICE_ACK;
strcpy(alert_level_class, "ACKNOWLEDGEMENT");
}
else if(strstr(alert_level, "FLAPPINGSTART (")) {
strcpy(alert_level, "FLAPPING START");
notification_detail_type = NOTIFICATION_SERVICE_FLAP;
strcpy(alert_level_class, "UNKNOWN");
}
else if(strstr(alert_level, "FLAPPINGSTOP (")) {
strcpy(alert_level, "FLAPPING STOP");
notification_detail_type = NOTIFICATION_SERVICE_FLAP;
strcpy(alert_level_class, "UNKNOWN");
}
else if(strstr(alert_level, "DOWNTIME")) {
notification_detail_type = NOTIFICATION_SERVICE_DOWNTIME;
strcpy(alert_level_class, "DOWNTIME");
}
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;
}
else if(strstr(alert_level, "DOWNTIME")) {
strcpy(alert_level_class, "DOWNTIME");
notification_detail_type = NOTIFICATION_HOST_DOWNTIME;
}
}
/* 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, &current_authdata) == FALSE)
show_entry = FALSE;
}
else {
temp_service = find_service(host_name, service_name);
if(is_authorized_for_service(temp_service, &current_authdata) == FALSE)
show_entry = FALSE;
}
if(show_entry == TRUE) {
total_notifications++;
if(odd) {
odd = 0;
printf("<tr CLASS='notificationsOdd'>\n");
}
else {
odd = 1;
printf("<tr CLASS='notificationsEven'>\n");
}
printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s'>%s</a></td>\n", (odd) ? "Even" : "Odd", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(host_name), host_name);
if(notification_type == SERVICE_NOTIFICATION) {
printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s", (odd) ? "Even" : "Odd", EXTINFO_CGI, DISPLAY_SERVICE_INFO, url_encode(host_name));
printf("&service=%s'>%s</a></td>\n", url_encode(service_name), service_name);
}
else
printf("<td CLASS='notifications%s'>N/A</td>\n", (odd) ? "Even" : "Odd");
printf("<td CLASS='notifications%s'>%s</td>\n", alert_level_class, alert_level);
printf("<td CLASS='notifications%s'>%s</td>\n", (odd) ? "Even" : "Odd", date_time);
printf("<td CLASS='notifications%s'><a href='%s?type=contacts#%s'>%s</a></td>\n", (odd) ? "Even" : "Odd", CONFIG_CGI, url_encode(contact_name), contact_name);
printf("<td CLASS='notifications%s'><a href='%s?type=commands#%s'>%s</a></td>\n", (odd) ? "Even" : "Odd", CONFIG_CGI, url_encode(method_name), method_name);
printf("<td CLASS='notifications%s'>%s</td>\n", (odd) ? "Even" : "Odd", html_encode(temp_buffer, FALSE));
printf("</tr>\n");
}
}
}
printf("</table>\n");
printf("</div>\n");
printf("</p>\n");
if(total_notifications == 0) {
printf("<P><DIV CLASS='errorMessage'>No notifications have been recorded");
if(find_all == FALSE) {
if(query_type == FIND_SERVICE)
printf(" for this service");
else if(query_type == FIND_CONTACT)
printf(" for this contact");
else
printf(" for this host");
}
printf(" in %s log file</DIV></P>", (log_archive == 0) ? "the current" : "this archived");
}
free(input);
if(use_lifo == TRUE)
free_lifo_memory();
else
mmap_fclose(thefile);
return;
}

6027
cgi/objectjson.c Normal file

File diff suppressed because it is too large Load Diff

657
cgi/outages.c Normal file
View File

@ -0,0 +1,657 @@
/**************************************************************************
*
* OUTAGES.C - Nagios Network Outages CGI
*
*
* 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 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];
/* 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) {
/* get the arguments passed in the URL */
process_cgivars();
/* reset internal variables */
reset_cgi_vars();
cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, READ_ALL_STATUS_DATA);
document_header(TRUE);
/* get authentication information */
get_authentication_information(&current_authdata);
if(display_header == TRUE) {
/* begin top table */
printf("<table border=0 width=100%%>\n");
printf("<tr>\n");
/* left column of the first row */
printf("<td align=left valign=top width=33%%>\n");
display_info_table("Network Outages", TRUE, &current_authdata);
printf("</td>\n");
/* middle column of top row */
printf("<td align=center valign=top width=33%%>\n");
printf("</td>\n");
/* right column of top row */
printf("<td align=right valign=bottom width=33%%>\n");
/* display context-sensitive help */
display_context_help(CONTEXTHELP_OUTAGES);
printf("</td>\n");
/* end of top table */
printf("</tr>\n");
printf("</table>\n");
}
/* display network outage info */
display_network_outages();
document_footer();
/* free memory allocated to comment data */
free_comment_data();
/* free all allocated memory */
free_memory();
return OK;
}
void document_header(int use_stylesheet) {
char date_time[MAX_DATETIME_LENGTH];
time_t current_time;
time_t expire_time;
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
printf("Refresh: %d\r\n", refresh_rate);
time(&current_time);
get_time_string(&current_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; charset=utf-8\r\n\r\n");
if(embedded == TRUE)
return;
printf("<html>\n");
printf("<head>\n");
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
printf("<title>\n");
printf("Network Outages\n");
printf("</title>\n");
if(use_stylesheet == TRUE) {
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>", url_stylesheets_path, COMMON_CSS);
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>", url_stylesheets_path, OUTAGES_CSS);
}
printf("</head>\n");
printf("<body CLASS='outages'>\n");
/* include user SSI header */
include_ssi_files(OUTAGES_CGI, SSI_HEADER);
return;
}
void document_footer(void) {
if(embedded == TRUE)
return;
/* include user SSI footer */
include_ssi_files(OUTAGES_CGI, SSI_FOOTER);
printf("</body>\n");
printf("</html>\n");
return;
}
int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
for(x = 0; variables[x]; 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 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;
const char *bg_class = "";
const 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(&current_authdata) == FALSE) {
printf("<P><DIV CLASS='errorMessage'>It appears as though you do not have permission to view information you requested...</DIV></P>\n");
printf("<P><DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
printf("and check the authorization options in your CGI configuration file.</DIV></P>\n");
return;
}
*/
/* find all hosts that are causing network outages */
find_hosts_causing_outages();
/* calculate outage effects */
calculate_outage_effects();
/* sort the outage list by severity */
sort_hostoutages();
/* count the number of top-level hosts that are down and the ones that are actually blocking children hosts */
for(temp_hostoutage = hostoutage_list; temp_hostoutage != NULL; temp_hostoutage = temp_hostoutage->next) {
number_of_problem_hosts++;
if(temp_hostoutage->affected_child_hosts > 1)
number_of_blocking_problem_hosts++;
}
/* display the problem hosts... */
printf("<P><DIV ALIGN=CENTER>\n");
printf("<DIV CLASS='dataTitle'>Blocking Outages</DIV>\n");
printf("<TABLE BORDER=0 CLASS='data'>\n");
printf("<TR>\n");
printf("<TH CLASS='data'>Severity</TH><TH CLASS='data'>Host</TH><TH CLASS='data'>State</TH><TH CLASS='data'>Notes</TH><TH CLASS='data'>State Duration</TH><TH CLASS='data'># Hosts Affected</TH><TH CLASS='data'># Services Affected</TH><TH CLASS='data'>Actions</TH>\n");
printf("</TR>\n");
for(temp_hostoutagesort = hostoutagesort_list; temp_hostoutagesort != NULL; temp_hostoutagesort = temp_hostoutagesort->next) {
temp_hostoutage = temp_hostoutagesort->outage;
if(temp_hostoutage == NULL)
continue;
/* skip hosts that are not blocking anyone */
if(temp_hostoutage->affected_child_hosts <= 1)
continue;
temp_hoststatus = find_hoststatus(temp_hostoutage->hst->name);
if(temp_hoststatus == NULL)
continue;
/* make sure we only caught valid state types */
if(temp_hoststatus->status != SD_HOST_DOWN && temp_hoststatus->status != SD_HOST_UNREACHABLE)
continue;
total_entries++;
if(odd == 0) {
odd = 1;
bg_class = "dataOdd";
}
else {
odd = 0;
bg_class = "dataEven";
}
if(temp_hoststatus->status == SD_HOST_UNREACHABLE)
status = "UNREACHABLE";
else if(temp_hoststatus->status == SD_HOST_DOWN)
status = "DOWN";
printf("<TR CLASS='%s'>\n", bg_class);
printf("<TD CLASS='%s'>%d</TD>\n", bg_class, temp_hostoutage->severity);
printf("<TD CLASS='%s'><A HREF='%s?type=%d&host=%s'>%s</A></TD>\n", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hostoutage->hst->name), temp_hostoutage->hst->name);
printf("<TD CLASS='host%s'>%s</TD>\n", status, status);
total_comments = number_of_host_comments(temp_hostoutage->hst->name);
if(total_comments > 0) {
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "This host has %d comment%s associated with it", total_comments, (total_comments == 1) ? "" : "s");
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
printf("<TD CLASS='%s'><A HREF='%s?type=%d&host=%s#comments'><IMG SRC='%s%s' BORDER=0 ALT='%s' TITLE='%s'></A></TD>\n", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hostoutage->hst->name), url_images_path, COMMENT_ICON, temp_buffer, temp_buffer);
}
else
printf("<TD CLASS='%s'>N/A</TD>\n", bg_class);
current_time = time(NULL);
if(temp_hoststatus->last_state_change == (time_t)0)
t = current_time - program_start;
else
t = current_time - temp_hoststatus->last_state_change;
get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds);
snprintf(state_duration, sizeof(state_duration) - 1, "%2dd %2dh %2dm %2ds%s", days, hours, minutes, seconds, (temp_hoststatus->last_state_change == (time_t)0) ? "+" : "");
state_duration[sizeof(state_duration) - 1] = '\x0';
printf("<TD CLASS='%s'>%s</TD>\n", bg_class, state_duration);
printf("<TD CLASS='%s'>%d</TD>\n", bg_class, temp_hostoutage->affected_child_hosts);
printf("<TD CLASS='%s'>%d</TD>\n", bg_class, temp_hostoutage->affected_child_services);
printf("<TD CLASS='%s'>", bg_class);
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View status detail for this host' TITLE='View status detail for this host'></A>\n", STATUS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUS_DETAIL_ICON);
#ifdef USE_STATUSMAP
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View status map for this host and its children' TITLE='View status map for this host and its children'></A>\n", STATUSMAP_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUSMAP_ICON);
#endif
#ifdef USE_STATUSWRL
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View 3-D status map for this host and its children' TITLE='View 3-D status map for this host and its children'></A>\n", STATUSWORLD_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUSWORLD_ICON);
#endif
#ifdef USE_TRENDS
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View trends for this host' TITLE='View trends for this host'></A>\n", TRENDS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, TRENDS_ICON);
#endif
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View alert history for this host' TITLE='View alert history for this host'></A>\n", HISTORY_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, HISTORY_ICON);
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View notifications for this host' TITLE='View notifications for this host'></A>\n", NOTIFICATIONS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, NOTIFICATION_ICON);
printf("</TD>\n");
printf("</TR>\n");
}
printf("</TABLE>\n");
printf("</DIV></P>\n");
if(total_entries == 0)
printf("<DIV CLASS='itemTotalsTitle'>%d Blocking Outages Displayed</DIV>\n", total_entries);
/* free memory allocated to the host outage list */
free_hostoutage_list();
free_hostoutagesort_list();
return;
}
/* determine what hosts are causing network outages */
void find_hosts_causing_outages(void) {
hoststatus *temp_hoststatus;
host *temp_host;
/* check all hosts */
for(temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) {
/* check only hosts that are not up and not pending */
if(temp_hoststatus->status != SD_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 (!is_authorized_for_host(temp_host, &current_authdata))
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 == SD_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;
}

518
cgi/showlog.c Normal file
View File

@ -0,0 +1,518 @@
/***********************************************************************
*
* SHOWLOG.C - Nagios Log File CGI
*
*
* 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 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) {
char temp_buffer[MAX_INPUT_BUFFER];
/* get the CGI variables passed in the URL */
process_cgivars();
/* reset internal variables */
reset_cgi_vars();
cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, 0);
document_header(TRUE);
/* get authentication information */
get_authentication_information(&current_authdata);
/* determine what log file we should be using */
get_log_archive_to_use(log_archive, log_file_to_use, (int)sizeof(log_file_to_use));
if(display_header == TRUE) {
/* begin top table */
printf("<table border=0 width=100%% cellpadding=0 cellspacing=0>\n");
printf("<tr>\n");
/* left column of top table - info box */
printf("<td align=left valign=top width=33%%>\n");
display_info_table((log_rotation_method == LOG_ROTATION_NONE || log_archive == 0) ? "Current Event Log" : "Archived Event Log", FALSE, &current_authdata);
printf("</td>\n");
/* middle column of top table - log file navigation options */
printf("<td align=center valign=top width=33%%>\n");
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%s", SHOWLOG_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "");
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
display_nav_table(temp_buffer, log_archive);
printf("</td>\n");
/* right hand column of top row */
printf("<td align=right valign=top width=33%%>\n");
printf("<form method='GET' action='%s'>\n", SHOWLOG_CGI);
printf("<input type='hidden' name='archive' value='%d'>\n", log_archive);
printf("<table border=0 cellspacing=0 cellpadding=0 CLASS='optBox'>\n");
printf("<tr>");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s> Older Entries First:</td>", (use_lifo == FALSE) ? "checked" : "");
printf("</tr>\n");
printf("<tr>");
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
printf("</tr>\n");
/* display context-sensitive help */
printf("<tr>\n");
printf("<td align=right>\n");
display_context_help(CONTEXTHELP_LOG);
printf("</td>\n");
printf("</tr>\n");
printf("</table>\n");
printf("</form>\n");
printf("</td>\n");
/* end of top table */
printf("</tr>\n");
printf("</table>\n");
printf("</p>\n");
}
/* display the contents of the log file */
display_log();
document_footer();
/* free allocated memory */
free_memory();
return OK;
}
void document_header(int use_stylesheet) {
char date_time[MAX_DATETIME_LENGTH];
time_t current_time;
time_t expire_time;
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
time(&current_time);
get_time_string(&current_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; charset=utf-8\r\n\r\n");
if(embedded == TRUE)
return;
printf("<HTML>\n");
printf("<HEAD>\n");
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
printf("<TITLE>\n");
printf("Nagios Log File\n");
printf("</TITLE>\n");
if(use_stylesheet == TRUE) {
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, SHOWLOG_CSS);
}
printf("</HEAD>\n");
printf("<BODY CLASS='showlog'>\n");
/* include user SSI header */
include_ssi_files(SHOWLOG_CGI, SSI_HEADER);
return;
}
void document_footer(void) {
if(embedded == TRUE)
return;
/* include user SSI footer */
include_ssi_files(SHOWLOG_CGI, SSI_FOOTER);
printf("</BODY>\n");
printf("</HTML>\n");
return;
}
int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
for(x = 0; variables[x]; 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(&current_authdata) == FALSE) {
printf("<HR>\n");
printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view the log file...</DIV><br><br>\n");
printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>and check the authorization options in your CGI configuration file.</DIV>\n");
printf("<HR>\n");
return ERROR;
}
error = FALSE;
if(use_lifo == TRUE) {
error = read_file_into_lifo(log_file_to_use);
if(error != LIFO_OK) {
if(error == LIFO_ERROR_MEMORY) {
printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying log in natural order...</DIV></P>");
error = FALSE;
}
else
error = TRUE;
use_lifo = FALSE;
}
else
error = FALSE;
}
if(use_lifo == FALSE) {
if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
printf("<HR>\n");
printf("<P><DIV CLASS='errorMessage'>Error: Could not open log file '%s' for reading!</DIV></P>", log_file_to_use);
printf("<HR>\n");
error = TRUE;
}
}
if(error == FALSE) {
printf("<P><DIV CLASS='logEntries'>\n");
while(1) {
free(input);
if(use_lifo == TRUE) {
if((input = pop_lifo()) == NULL)
break;
}
else if((input = mmap_fgets(thefile)) == NULL)
break;
strip(input);
if(strstr(input, " starting...")) {
strcpy(image, START_ICON);
strcpy(image_alt, START_ICON_ALT);
}
else if(strstr(input, " shutting down...")) {
strcpy(image, STOP_ICON);
strcpy(image_alt, STOP_ICON_ALT);
}
else if(strstr(input, "Bailing out")) {
strcpy(image, STOP_ICON);
strcpy(image_alt, STOP_ICON_ALT);
}
else if(strstr(input, " restarting...")) {
strcpy(image, RESTART_ICON);
strcpy(image_alt, RESTART_ICON_ALT);
}
else if(strstr(input, "HOST ALERT:") && strstr(input, ";DOWN;")) {
strcpy(image, HOST_DOWN_ICON);
strcpy(image_alt, HOST_DOWN_ICON_ALT);
}
else if(strstr(input, "HOST ALERT:") && strstr(input, ";UNREACHABLE;")) {
strcpy(image, HOST_UNREACHABLE_ICON);
strcpy(image_alt, HOST_UNREACHABLE_ICON_ALT);
}
else if(strstr(input, "HOST ALERT:") && (strstr(input, ";RECOVERY;") || strstr(input, ";UP;"))) {
strcpy(image, HOST_UP_ICON);
strcpy(image_alt, HOST_UP_ICON_ALT);
}
else if(strstr(input, "HOST NOTIFICATION:")) {
strcpy(image, HOST_NOTIFICATION_ICON);
strcpy(image_alt, HOST_NOTIFICATION_ICON_ALT);
}
else if(strstr(input, "SERVICE ALERT:") && strstr(input, ";CRITICAL;")) {
strcpy(image, CRITICAL_ICON);
strcpy(image_alt, CRITICAL_ICON_ALT);
}
else if(strstr(input, "SERVICE ALERT:") && strstr(input, ";WARNING;")) {
strcpy(image, WARNING_ICON);
strcpy(image_alt, WARNING_ICON_ALT);
}
else if(strstr(input, "SERVICE ALERT:") && strstr(input, ";UNKNOWN;")) {
strcpy(image, UNKNOWN_ICON);
strcpy(image_alt, UNKNOWN_ICON_ALT);
}
else if(strstr(input, "SERVICE ALERT:") && (strstr(input, ";RECOVERY;") || strstr(input, ";OK;"))) {
strcpy(image, OK_ICON);
strcpy(image_alt, OK_ICON_ALT);
}
else if(strstr(input, "SERVICE NOTIFICATION:")) {
strcpy(image, NOTIFICATION_ICON);
strcpy(image_alt, NOTIFICATION_ICON_ALT);
}
else if(strstr(input, "SERVICE EVENT HANDLER:")) {
strcpy(image, SERVICE_EVENT_ICON);
strcpy(image_alt, SERVICE_EVENT_ICON_ALT);
}
else if(strstr(input, "HOST EVENT HANDLER:")) {
strcpy(image, HOST_EVENT_ICON);
strcpy(image_alt, HOST_EVENT_ICON_ALT);
}
else if(strstr(input, "EXTERNAL COMMAND:")) {
strcpy(image, EXTERNAL_COMMAND_ICON);
strcpy(image_alt, EXTERNAL_COMMAND_ICON_ALT);
}
else if(strstr(input, "PASSIVE SERVICE CHECK:")) {
strcpy(image, PASSIVE_ICON);
strcpy(image_alt, "Passive Service Check");
}
else if(strstr(input, "PASSIVE HOST CHECK:")) {
strcpy(image, PASSIVE_ICON);
strcpy(image_alt, "Passive Host Check");
}
else if(strstr(input, "LOG ROTATION:")) {
strcpy(image, LOG_ROTATION_ICON);
strcpy(image_alt, LOG_ROTATION_ICON_ALT);
}
else if(strstr(input, "active mode...")) {
strcpy(image, ACTIVE_ICON);
strcpy(image_alt, ACTIVE_ICON_ALT);
}
else if(strstr(input, "standby mode...")) {
strcpy(image, STANDBY_ICON);
strcpy(image_alt, STANDBY_ICON_ALT);
}
else if(strstr(input, "SERVICE FLAPPING ALERT:") && strstr(input, ";STARTED;")) {
strcpy(image, FLAPPING_ICON);
strcpy(image_alt, "Service started flapping");
}
else if(strstr(input, "SERVICE FLAPPING ALERT:") && strstr(input, ";STOPPED;")) {
strcpy(image, FLAPPING_ICON);
strcpy(image_alt, "Service stopped flapping");
}
else if(strstr(input, "SERVICE FLAPPING ALERT:") && strstr(input, ";DISABLED;")) {
strcpy(image, FLAPPING_ICON);
strcpy(image_alt, "Service flap detection disabled");
}
else if(strstr(input, "HOST FLAPPING ALERT:") && strstr(input, ";STARTED;")) {
strcpy(image, FLAPPING_ICON);
strcpy(image_alt, "Host started flapping");
}
else if(strstr(input, "HOST FLAPPING ALERT:") && strstr(input, ";STOPPED;")) {
strcpy(image, FLAPPING_ICON);
strcpy(image_alt, "Host stopped flapping");
}
else if(strstr(input, "HOST FLAPPING ALERT:") && strstr(input, ";DISABLED;")) {
strcpy(image, FLAPPING_ICON);
strcpy(image_alt, "Host flap detection disabled");
}
else if(strstr(input, "SERVICE DOWNTIME ALERT:") && strstr(input, ";STARTED;")) {
strcpy(image, SCHEDULED_DOWNTIME_ICON);
strcpy(image_alt, "Service entered a period of scheduled downtime");
}
else if(strstr(input, "SERVICE DOWNTIME ALERT:") && strstr(input, ";STOPPED;")) {
strcpy(image, SCHEDULED_DOWNTIME_ICON);
strcpy(image_alt, "Service exited a period of scheduled downtime");
}
else if(strstr(input, "SERVICE DOWNTIME ALERT:") && strstr(input, ";CANCELLED;")) {
strcpy(image, SCHEDULED_DOWNTIME_ICON);
strcpy(image_alt, "Service scheduled downtime has been cancelled");
}
else if(strstr(input, "HOST DOWNTIME ALERT:") && strstr(input, ";STARTED;")) {
strcpy(image, SCHEDULED_DOWNTIME_ICON);
strcpy(image_alt, "Host entered a period of scheduled downtime");
}
else if(strstr(input, "HOST DOWNTIME ALERT:") && strstr(input, ";STOPPED;")) {
strcpy(image, SCHEDULED_DOWNTIME_ICON);
strcpy(image_alt, "Host exited a period of scheduled downtime");
}
else if(strstr(input, "HOST DOWNTIME ALERT:") && strstr(input, ";CANCELLED;")) {
strcpy(image, SCHEDULED_DOWNTIME_ICON);
strcpy(image_alt, "Host scheduled downtime has been cancelled");
}
else {
strcpy(image, INFO_ICON);
strcpy(image_alt, INFO_ICON_ALT);
}
temp_buffer = strtok(input, "]");
t = (temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);
time_ptr = localtime(&t);
strftime(current_message_date, sizeof(current_message_date), "%B %d, %Y %H:00\n", time_ptr);
current_message_date[sizeof(current_message_date) - 1] = '\x0';
if(strcmp(last_message_date, current_message_date) != 0 && display_timebreaks == TRUE) {
printf("<BR CLEAR='all'>\n");
printf("<DIV CLASS='dateTimeBreak'>\n");
printf("<table border=0 width=95%%><tr>");
printf("<td width=40%%><hr width=100%%></td>");
printf("<td align=center CLASS='dateTimeBreak'>%s</td>", current_message_date);
printf("<td width=40%%><hr width=100%%></td>");
printf("</tr></table>\n");
printf("</DIV>\n");
printf("<BR CLEAR='all'><DIV CLASS='logEntries'>\n");
strncpy(last_message_date, current_message_date, sizeof(last_message_date));
last_message_date[sizeof(last_message_date) - 1] = '\x0';
}
get_time_string(&t, date_time, (int)sizeof(date_time), SHORT_DATE_TIME);
strip(date_time);
temp_buffer = strtok(NULL, "\n");
if(display_frills == TRUE)
printf("<img align='left' src='%s%s' alt='%s' title='%s'>", url_images_path, image, image_alt, image_alt);
printf("[%s] %s", date_time, (temp_buffer == NULL) ? "" : html_encode(temp_buffer, FALSE));
if(enable_splunk_integration == TRUE) {
printf("&nbsp;&nbsp;&nbsp;");
display_splunk_generic_url(temp_buffer, 2);
}
printf("<br clear='all'>\n");
}
printf("</DIV></P>\n");
printf("<HR>\n");
free(input);
if(use_lifo == FALSE)
mmap_fclose(thefile);
}
if(use_lifo == TRUE)
free_lifo_memory();
return OK;
}

5603
cgi/status.c Normal file

File diff suppressed because it is too large Load Diff

4962
cgi/statusjson.c Normal file

File diff suppressed because it is too large Load Diff

2871
cgi/statusmap.c Normal file

File diff suppressed because it is too large Load Diff

1512
cgi/statuswml.c Normal file

File diff suppressed because it is too large Load Diff

1293
cgi/statuswrl.c Normal file

File diff suppressed because it is too large Load Diff

2771
cgi/summary.c Normal file

File diff suppressed because it is too large Load Diff

1597
cgi/tac.c Normal file

File diff suppressed because it is too large Load Diff

3071
cgi/trends.c Normal file

File diff suppressed because it is too large Load Diff

1
common/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
Makefile

38
common/Makefile.in Normal file
View File

@ -0,0 +1,38 @@
############################
# Makefile for Nagios
#
############################
# 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=@cgibindir@
HTMLDIR=@webdir@
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:

671
common/comments.c Normal file
View File

@ -0,0 +1,671 @@
/*****************************************************************************
*
* COMMENTS.C - Comment functions for Nagios
*
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****************************************************************************/
#include "../include/config.h"
#include "../include/common.h"
#include "../include/comments.h"
#include "../include/objects.h"
#include "../xdata/xcddefault.h"
#ifdef NSCORE
#include "../include/nagios.h"
#include "../include/broker.h"
#endif
#ifdef NSCGI
#include "../include/cgiutils.h"
#endif
nagios_comment *comment_list = NULL;
int defer_comment_sorting = 0;
nagios_comment **comment_hashlist = NULL;
#ifdef NSCORE
/******************************************************************/
/**************** INITIALIZATION/CLEANUP FUNCTIONS ****************/
/******************************************************************/
/* initializes comment data */
int initialize_comment_data(void) {
return xcddefault_initialize_comment_data();
}
/******************************************************************/
/****************** 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;
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;
unsigned long new_comment_id = 0L;
result = xcddefault_add_new_host_comment(entry_type, host_name, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);
/* 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;
unsigned long new_comment_id = 0L;
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);
/* 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) {
nagios_comment *this_comment = NULL;
nagios_comment *last_comment = NULL;
nagios_comment *next_comment = NULL;
int hashslot = 0;
nagios_comment *this_hash = NULL;
nagios_comment *last_hash = NULL;
/* 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;
}
if(this_comment == NULL)
return ERROR;
/* remove the comment from the list in memory */
#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);
return OK;
}
/* 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;
nagios_comment *temp_comment = NULL;
nagios_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;
nagios_comment *temp_comment = NULL;
nagios_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;
nagios_comment *temp_comment = NULL;
nagios_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;
nagios_comment *temp_comment = NULL;
nagios_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) {
nagios_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(nagios_comment *new_comment) {
nagios_comment *temp_comment = NULL;
nagios_comment *lastpointer = NULL;
int hashslot = 0;
/* initialize hash list */
if(comment_hashlist == NULL) {
int i;
comment_hashlist = (nagios_comment **)malloc(sizeof(nagios_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) {
nagios_comment *new_comment = NULL;
nagios_comment *last_comment = NULL;
nagios_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 = (nagios_comment *)calloc(1, sizeof(nagios_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 */
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
#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) {
nagios_comment *c1 = *(nagios_comment **)p1;
nagios_comment *c2 = *(nagios_comment **)p2;
return c1->comment_id - c2->comment_id;
}
int sort_comments(void) {
nagios_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) {
nagios_comment *this_comment = NULL;
nagios_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) {
nagios_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) {
nagios_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 ************************/
/******************************************************************/
nagios_comment *get_first_comment_by_host(char *host_name) {
return get_next_comment_by_host(host_name, NULL);
}
nagios_comment *get_next_comment_by_host(char *host_name, nagios_comment *start) {
nagios_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 */
nagios_comment *find_service_comment(unsigned long comment_id) {
return find_comment(comment_id, SERVICE_COMMENT);
}
/* find a host comment by id */
nagios_comment *find_host_comment(unsigned long comment_id) {
return find_comment(comment_id, HOST_COMMENT);
}
/* find a comment by id */
nagios_comment *find_comment(unsigned long comment_id, int comment_type) {
nagios_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;
}

1393
common/downtime.c Normal file

File diff suppressed because it is too large Load Diff

3544
common/macros.c Normal file

File diff suppressed because it is too large Load Diff

3547
common/objects.c Normal file

File diff suppressed because it is too large Load Diff

641
common/shared.c Normal file
View File

@ -0,0 +1,641 @@
#include "../include/config.h"
#include "../include/common.h"
#include "../include/locations.h"
#include "../include/defaults.h"
/*
* This file holds random utility functions shared by cgi's and
* core, as well as all global variables needed by both.
*/
int date_format;
int interval_length;
char *illegal_output_chars;
char illegal_output_char_map[] = CHAR_MAP_INIT(0);
time_t program_start = 0L;
int check_external_commands;
int log_rotation_method;
char *object_cache_file;
struct object_count num_objects;
int process_performance_data;
char *status_file;
int nagios_pid = 0;
int daemon_mode = FALSE;
time_t last_log_rotation = 0L;
int check_external_commands;
int enable_timing_point = FALSE; /* cgi's never set this to TRUE */
int enable_flap_detection;
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;
char *config_file_dir = NULL;
void init_shared_cfg_vars(int first_time) {
date_format = DATE_FORMAT_US;
interval_length = DEFAULT_INTERVAL_LENGTH;
if(first_time) {
/* Not sure why these are not reset in reset_variables() */
illegal_output_chars = NULL;
}
program_start = 0L;
log_rotation_method = LOG_ROTATION_NONE;
object_cache_file = strdup(DEFAULT_OBJECT_CACHE_FILE);
process_performance_data = DEFAULT_PROCESS_PERFORMANCE_DATA;
status_file = NULL;
check_external_commands = DEFAULT_CHECK_EXTERNAL_COMMANDS;
enable_flap_detection = DEFAULT_ENABLE_FLAP_DETECTION;
enable_notifications = TRUE;
execute_service_checks = TRUE;
accept_passive_service_checks = TRUE;
execute_host_checks = TRUE;
accept_passive_host_checks = TRUE;
enable_event_handlers = TRUE;
obsess_over_services = FALSE;
obsess_over_hosts = FALSE;
return;
}
/* silly debug-ish helper used to track down hotspots in config parsing */
void timing_point(const char *fmt, ...) {
static struct timeval last = {0, 0}, first = {0, 0};
struct timeval now;
va_list ap;
if(!enable_timing_point)
return;
if(first.tv_sec == 0) {
gettimeofday(&first, NULL);
last.tv_sec = first.tv_sec;
last.tv_usec = first.tv_usec;
printf("[0.0000 (+0.0000)] ");
}
else {
gettimeofday(&now, NULL);
printf("[%.4f (+%.4f)] ", tv_delta_f(&first, &now), tv_delta_f(&last, &now));
last.tv_sec = now.tv_sec;
last.tv_usec = now.tv_usec;
}
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
/* fix the problem with strtok() skipping empty options between tokens */
char *my_strtok(char *buffer, const 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;
}
/* fix the problem with my_strtok() strduping and causing intermittent memory leaks
* use as regular my_strtok, specifying FALSE for free_orig
* when done (before calling again), specify TRUE for free_orig for it to handle the free() */
char *my_strtok_with_free(char *buffer, const char *tokens, int free_orig) {
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;
}
else if (free_orig == TRUE) {
my_free(original_my_strtok_buffer);
return NULL;
}
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(const 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;
const char *weekdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
const char *months[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"
};
const 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 = 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;
}

505
common/statusdata.c Normal file
View File

@ -0,0 +1,505 @@
/*****************************************************************************
*
* STATUSDATA.C - External status data for Nagios CGIs
*
*
* 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 "../xdata/xsddefault.h" /* default routines */
#ifdef NSCGI
#include "../include/cgiutils.h"
#else
#include "../include/nagios.h"
#include "../include/broker.h"
#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(const char *cfgfile) {
return xsddefault_initialize_status_data(cfgfile);
}
/* 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
result = xsddefault_save_status_data();
#ifdef USE_EVENT_BROKER
/* send data to event broker */
broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_ENDDUMP, NEBFLAG_NONE, NEBATTR_NONE, NULL);
#endif
return result;
}
/* cleans up status data before program termination */
int cleanup_status_data(int delete_status_data) {
return xsddefault_cleanup_status_data(delete_status_data);
}
/* 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
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
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
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
return OK;
}
#endif
#ifdef NSCGI
/******************************************************************/
/******************* TOP-LEVEL INPUT FUNCTIONS ********************/
/******************************************************************/
/* reads in all status data */
int read_status_data(const char *status_file_name, int options) {
return xsddefault_read_status_data(status_file_name, options);
}
/******************************************************************/
/****************** 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 = SD_HOST_UP;
break;
case 1:
new_hoststatus->status = SD_HOST_DOWN;
break;
case 2:
new_hoststatus->status = SD_HOST_UNREACHABLE;
break;
default:
new_hoststatus->status = SD_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

1456
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1823
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

8952
configure vendored Executable file

File diff suppressed because it is too large Load Diff

994
configure.ac Normal file
View File

@ -0,0 +1,994 @@
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 lib/snprintf.h lib/iobroker.h)
AC_PREFIX_DEFAULT(/usr/local/nagios)
PKG_NAME=nagios
PKG_VERSION="4.4.4"
PKG_HOME_URL="https://www.nagios.org/"
PKG_REL_DATE="2019-07-29"
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
AC_CONFIG_FILES([html/index.php])
dnl Checks for programs.
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_LN_S
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)
AC_CHECK_HEADERS(libgen.h limits.h math.h netdb.h netinet/in.h pwd.h regex.h)
AC_CHECK_HEADERS(signal.h socket.h stdarg.h string.h strings.h sys/loadavg.h)
AC_CHECK_HEADERS(sys/mman.h sys/types.h sys/time.h sys/resource.h sys/wait.h)
AC_CHECK_HEADERS(sys/socket.h sys/stat.h sys/timeb.h sys/un.h sys/ipc.h)
AC_CHECK_HEADERS(sys/msg.h sys/poll.h syslog.h uio.h unistd.h locale.h wchar.h)
AC_CHECK_HEADERS(sys/prctl.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 Get Nagios autoconf-macros
AC_NAGIOS_GET_OS
AC_NAGIOS_GET_DISTRIB_TYPE
AC_NAGIOS_GET_INIT
AC_NAGIOS_GET_INETD
AC_NAGIOS_GET_PATHS
AC_NAGIOS_GET_FILES
dnl We only have these options available so we need to make them work until there are more
if test "x$src_init" != "xdefault-init" -a \
"x$src_init" != "xdefault-service" -a \
"x$src_init" != "xopenrc-init" -a \
"x$src_init" != "xnewbsd-init" -a \
"x$src_init" != "xopenbsd-init" -a \
"x$src_init" != "xupstart-init"; then
src_init="default-init"
init_type="sysv"
initname="nagios"
if test "x$initdiroverridden" != "xyes"; then
initdir="/etc/init.d"
fi
fi
dnl We need to check for a lock file specified
dnl And if the built in check didn't work (the N/A)
dnl then we need to find one!
if test "x$subsyslockdir" = "xN/A"; then
if test -d "/var/run"; then
subsyslockdir="/var/run"
subsyslockfile="/var/run/$INIT_PROG.lock"
else
subsyslockdir="/usr/local/nagios/var/"
subsyslockfile="/usr/local/nagios/var/$INIT_PROG.lock"
fi
fi
AC_ARG_WITH(lockfile,
AC_HELP_STRING([--with-lockfile=<path>],
[sets path for lockfile]),
subsyslockfile=$withval,
subsyslockfile=$subsyslockfile
)
dnl Check for asprintf() and friends...
AC_CACHE_CHECK([for va_copy],ac_cv_HAVE_VA_COPY,[
AC_TRY_LINK([#include <stdarg.h>
va_list ap1,ap2;], [va_copy(ap1,ap2);],
ac_cv_HAVE_VA_COPY=yes,
ac_cv_HAVE_VA_COPY=no)])
if test "x$ac_cv_HAVE_VA_COPY" = "xyes"; then
AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
else
AC_CACHE_CHECK([for __va_copy],ac_cv_HAVE___VA_COPY,[
AC_TRY_LINK([#include <stdarg.h>
va_list ap1,ap2;], [__va_copy(ap1,ap2);],
ac_cv_HAVE___VA_COPY=yes,
ac_cv_HAVE___VA_COPY=no)])
if test "x$ac_cv_HAVE___VA_COPY" = "xyes"; then
AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available])
fi
fi
AC_CHECK_FUNC(vsnprintf,,SNPRINTF_O=../lib/snprintf.o)
AC_CHECK_FUNC(snprintf,,SNPRINTF_O=../lib/snprintf.o)
AC_CHECK_FUNC(asprintf,,SNPRINTF_O=../lib/snprintf.o)
AC_CHECK_FUNC(vasprintf,,SNPRINTF_O=../lib/snprintf.o)
AC_CHECK_FUNCS(sigaction)
AC_CACHE_CHECK([for C99 vsnprintf],ac_cv_HAVE_C99_VSNPRINTF,[
AC_TRY_RUN([
#include <sys/types.h>
#include <stdarg.h>
void foo(const char *format, ...) {
va_list ap;
int len;
char buf[5];
va_start(ap, format);
len = vsnprintf(buf, 0, format, ap);
va_end(ap);
if (len != 5) exit(1);
va_start(ap, format);
len = vsnprintf(0, 0, format, ap);
va_end(ap);
if (len != 5) exit(1);
if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
exit(0);
}
main() { foo("hello"); }
],
ac_cv_HAVE_C99_VSNPRINTF=yes,ac_cv_HAVE_C99_VSNPRINTF=no,ac_cv_HAVE_C99_VSNPRINTF=cross)])
if test "x$ac_cv_HAVE_C99_VSNPRINTF" = "xyes"; 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 "x$ac_cv_search_getservbyname" != "xnone required"; then
SOCKETLIBS="$SOCKETLIBS -lnsl"
fi])
AC_SEARCH_LIBS([connect],[socket],
[if test "x$ac_cv_search_connect" != "xnone required"; then
SOCKETLIBS="$SOCKETLIBS -lsocket"
fi])
AC_SUBST(SOCKETLIBS)
AC_CHECK_FUNCS(initgroups setenv strdup strstr strtoul unsetenv)
AC_MSG_CHECKING(for type of socket size)
AC_TRY_COMPILE([#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
],
[int a = send(1, (const void *) 0, (size_t) 0, (int) 0);],
[AC_DEFINE(SOCKET_SIZE_TYPE, size_t, [typedef for socket size]) AC_MSG_RESULT(size_t)],
[AC_DEFINE(SOCKET_SIZE_TYPE, int, [typedef for socket size]) AC_MSG_RESULT(int)])
dnl Solaris needs rt or posix4 libraries for nanosleep()
AC_SEARCH_LIBS(nanosleep,[rt posix4],,[
echo "Error: nanosleep() needed for timing operations."
exit 1
])
dnl TODO: host_os needs changed to reflect AC_NAGIOS
case $host_os in
*bsd*|darwin*)
root_grp=wheel
;;
*)
root_grp=root
;;
esac
AC_ARG_WITH(root_group,AC_HELP_STRING([--with-root-group=<grp>],[sets group name for installing init]),root_grp=$withval)
AC_SUBST(root_grp)
INIT_OPTS="-o root -g $root_grp"
AC_SUBST(INIT_OPTS)
dnl Just enable all of the testing things
dnl --enable-debugging --enable-coverage --with-this-user
dnl This is here because if not, the user override doesnt happen
ENABLE_TESTING=no
AC_ARG_ENABLE(testing,AC_HELP_STRING([--enable-testing],[DEBUGGING ONLY - Enable testing options]),
[ENABLE_TESTING=$enableval])
not_a_user="^^^^^"
AC_ARG_WITH(this_user,AC_HELP_STRING([--with-this-user],[sets all user/group info for current user running ./configure]),this_user=$USER,this_user=$not_a_user)
if test "x$ENABLE_TESTING" = "xyes"; then
this_user=$USER
fi
AC_ARG_WITH(nagios_user,AC_HELP_STRING([--with-nagios-user=<user>],[sets user name to run nagios]),nagios_user=$withval,nagios_user=nagios)
AC_ARG_WITH(nagios_group,AC_HELP_STRING([--with-nagios-group=<grp>],[sets group name to run nagios]),nagios_grp=$withval,nagios_grp=nagios)
if test "x$this_user" != "x$not_a_user"; then
nagios_user=$this_user
nagios_grp=$this_user
fi
AC_SUBST(nagios_user)
AC_SUBST(nagios_grp)
AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_USER,"$nagios_user",[user name to run nagios])
AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_GROUP,"$nagios_grp",[group name to run nagios])
INSTALL_OPTS="-o $nagios_user -g $nagios_grp"
AC_SUBST(INSTALL_OPTS)
AC_ARG_WITH(command_user,AC_HELP_STRING([--with-command-user=<user>],[sets user name for command access]),command_user=$withval,command_user=$nagios_user)
AC_ARG_WITH(command_group,AC_HELP_STRING([--with-command-group=<grp>],[sets group name for command access]),command_grp=$withval,command_grp=$nagios_grp)
if test "x$this_user" != "x$not_a_user"; then
command_user=$this_user
command_grp=$this_user
fi
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,
AC_HELP_STRING([--with-mail=<path_to_mail>],
[sets path to equivalent program to mail]),
MAIL_PROG=$withval,
MAIL_PROG=no
)
if test "x$MAIL_PROG" = "xno"; then
AC_PATH_PROG(MAIL_PROG,mail)
fi
dnl Fix for systems that don't (yet) have mail/mailx installed...
if test "x$MAIL_PROG" = "x"; then
if which mail >/dev/null; then
MAIL_PROG=`which mail`
elif which sendmail >/dev/null; then
MAIL_PROG=`which sendmail`
else
MAIL_PROG="/bin/mail"
fi
fi
AC_SUBST(MAIL_PROG)
dnl Determine location of the rm binary
BIN_RM=`which rm`
if test $? -ne 0; then
BIN_RM='/bin/rm'
fi
AC_SUBST(BIN_RM)
dnl Determine location of the kill binary
BIN_KILL=`which kill`
if test $? -ne 0; then
BIN_KILL='/bin/kill'
fi
AC_SUBST(BIN_KILL)
dnl Check for location of Apache conf.d directory
HTTP_CONF=no
AC_ARG_WITH(httpd_conf,
AC_HELP_STRING([--with-httpd-conf=<path_to_conf>],
[sets path to Apache conf.d directory]),
HTTPD_CONF=$withval,
HTTPD_CONF=no
)
LN_HTTPD_SITES_ENABLED=0
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/apache2/sites-available"; then
HTTPD_CONF="/etc/apache2/sites-available"
if test -d "/etc/apache2/sites-enabled"; then
LN_HTTPD_SITES_ENABLED=1
fi
elif test -d "/etc/apache2/sites-enabled"; then
HTTPD_CONF="/etc/apache2/sites-enabled"
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)
AC_SUBST(LN_HTTPD_SITES_ENABLED)
dnl Check if RLIMIT_PROC exists
AC_TRY_COMPILE([#ifdef __STDC__
#include <sys/time.h>
#include <sys/resource.h>
#endif],
[struct rlimit rlim;
int ilim = getrlimit(RLIMIT_NPROC, &rlim);],
[AC_DEFINE(DETECT_RLIMIT_PROBLEM,1,[System has RLIMIT_PROC]) AC_MSG_RESULT([checking for RLIMIT_PROC... yes])],
[AC_MSG_RESULT([checking for RLIMIT_PROC... no])])
dnl Location of check result path
CHECKRESULTDIR=no
AC_ARG_WITH(checkresult-dir,
AC_HELP_STRING([--with-checkresult-dir=<path>],
[sets path to check results spool directory]),
CHECKRESULTDIR=$withval,
CHECKRESULTDIR=no
)
if test "x$CHECKRESULTDIR" = "xno"; then
CHECKRESULTDIR="$localstatedir/spool/checkresults"
fi
AC_SUBST(CHECKRESULTDIR)
dnl Location of check result path
dnl TODO: this should be moved to autoconf-macros
TMPDIR=no
AC_ARG_WITH(temp-dir,
AC_HELP_STRING([--with-temp-dir=<path>],
[sets path to temp directory]),
TMPDIR=$withval,
TMPDIR=no
)
if test "x$TMPDIR" = "xno"; then
TMPDIR="/tmp"
fi
AC_SUBST(TMPDIR)
dnl Determine the library to be used by the iobroker
dnl epoll_*() is linux specific and was added to glibc 2.3.2, so we
dnl check for 2.4 and use epoll() if we're on that version or later.
dnl But we still need to set the variable GLIBC_NEWER_2_4 since
dnl it is used later in calculations perhaps by OSes not linux
GLIBC_NEWER_2_4=0
case $host_os in
linux*)
AC_MSG_CHECKING(for glibc at least version 2.4)
AC_TRY_CPP(
[
#include <stdio.h>
#if defined(__GLIBC__) && defined(__linux)
#include <features.h>
# if !__GLIBC_PREREQ(2, 4)
# error GLIBC too old
# endif
#else
# error Not using GLIBC
#endif
],
[GLIBC_NEWER_2_4=1; AC_MSG_RESULT(yes)],
[GLIBC_NEWER_2_4=0; AC_MSG_RESULT(no)]
)
if test "$GLIBC_NEWER_2_4" -eq 1; then
AC_CHECK_HEADER([sys/epoll.h])
fi
;;
esac
AC_CHECK_HEADER([sys/select.h])
AC_ARG_WITH(iobroker,
AC_HELP_STRING([--with-iobroker=<method>],
[specify the method to use with iobroker: epoll, poll, or select]),
IOBROKER_METHOD=$withval,
IOBROKER_METHOD="none"
)
case $IOBROKER_METHOD in
epoll*)
if test "$GLIBC_NEWER_2_4" -eq 1 -a "x$ac_cv_header_sys_epoll_h" = "xyes"; then
AC_DEFINE([IOBROKER_USES_EPOLL])
else
echo "\"epoll\" is not available as an iobroker method."
echo "Please use one of the other options."
exit 1
fi
;;
poll*)
if test "x$ac_cv_header_sys_poll_h" = "xyes" -o "x$ac_cv_header_poll_h" = "xyes"; then
AC_DEFINE([IOBROKER_USES_POLL])
else
echo "\"poll\" is not available as an iobroker method."
echo "Please use one of the other options."
exit 1
fi
;;
select*)
if test "x$ac_cv_header_sys_select_h" = "xyes"; then
AC_DEFINE([IOBROKER_USES_SELECT])
else
echo "\"select\" is not available as an iobroker method."
echo "Please use one of the other options."
exit 1
fi
;;
none*)
if test "$GLIBC_NEWER_2_4" -eq 1 -a "x$ac_cv_header_sys_epoll_h" = "xyes"; then
AC_DEFINE([IOBROKER_USES_EPOLL])
IOBROKER_METHOD="epoll"
elif test "x$ac_cv_header_sys_poll_h" = "xyes" -o "x$ac_cv_header_poll_h" = "xyes"; then
AC_DEFINE([IOBROKER_USES_POLL])
IOBROKER_METHOD="poll"
elif test "x$ac_cv_header_sys_select_h" = "xyes"; then
AC_DEFINE([IOBROKER_USES_SELECT])
IOBROKER_METHOD="select"
else
echo "There are no available options for iobroker polling"
exit 1
fi
;;
*)
echo "\"$IOBROKER_METHOD\" is not a valid method for --with-iobroker"
exit 1
;;
esac
dnl Optional GD library and include paths
AC_ARG_WITH(gd-lib,
AC_HELP_STRING([--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,
AC_HELP_STRING([--with-gd-inc=DIR],[sets location of the gd include files]),
[CFLAGS="${CFLAGS} -I${withval}"]
)
TRYGD=yes
dnl 'NERD' is now disabled by default. enable it for functionality
NERD=no
NERD_O=""
AC_ARG_ENABLE(nerd,
AC_HELP_STRING([--enable-nerd],
[enables Nagios Event Radio Dispatch (NERD)]),
NERD=yes
)
if test "x$NERD" = "xyes"; then
AC_DEFINE_UNQUOTED(ENABLE_NERD,,[defined if user enabled NERD (radio dispatcher)])
NERD_O="nerd.o"
fi
AC_SUBST(NERD_O)
dnl 'corewindow' is now disabled. Allow it to be enabled if someone wants it
COREWINDOW=no
AC_ARG_ENABLE(corewindow,
AC_HELP_STRING([--enable-corewindow],
[enables the 'corewindow' URL argument]),
COREWINDOW=yes
)
AC_SUBST(COREWINDOW)
dnl statusmap CGI enabled by default, unless users chooses not to use it
TRYSTATUSMAP=yes
AC_ARG_ENABLE(statusmap,
AC_HELP_STRING([--disable-statusmap],
[disables compilation of statusmap CGI]),
TRYSTATUSMAP=nope
)
dnl statuswrl CGI enabled by default, unless users chooses not to use it
TRYSTATUSWRL=yes
AC_ARG_ENABLE(statuswrl,
AC_HELP_STRING([--disable-statuswrl],
[disables compilation of statuswrl (VRML) CGI]),
TRYSTATUSWRL=nope
)
if test "x$TRYSTATUSWRL" = "xyes"; 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" = "xyes"; 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=yes
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=yes
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=yes
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=yes
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
AC_MSG_CHECKING([for GD library])
AC_MSG_RESULT([yes])
if test "x$TRYSTATUSMAP" = "xyes"; 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,
AC_HELP_STRING([--with-cgiurl=<local-url>],
[sets URL for cgi programs (do not use a trailing slash)]),
cgiurl=$withval,
cgiurl=/nagios/cgi-bin
)
AC_ARG_WITH(htmurl,
AC_HELP_STRING([--with-htmurl=<local-url>],
[sets URL for public html]),
htmurl=$withval,
htmurl=/nagios
)
AC_SUBST(htmurl)
AC_SUBST(cgiurl)
USE_NANOSLEEP=yes
AC_ARG_ENABLE(nanosleep,
AC_HELP_STRING([--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,
AC_HELP_STRING([--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"
MOD_CFLAGS="-fPIC"
;;
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"
;;
*bsd*)
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)
dnl - flags for compiling workers
WORKER_CFLAGS="-I ../../include -I ../.."
WORKER_LDFLAGS="-L ../../lib -l nagios"
AC_SUBST(WORKER_CFLAGS)
AC_SUBST(WORKER_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
dnl Option for compiling under CYGWIN
nagios_name=nagios
nagiostats_name=nagiostats
cygwin=no
AC_ARG_ENABLE(cygwin,
AC_HELP_STRING([--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 Enable debugging?
ENABLE_DEBUGGING=no
AC_ARG_ENABLE(debugging,AC_HELP_STRING([--enable-debugging],[DEBUGGING ONLY - Enable some debugging for Nagios Core]),
[ENABLE_DEBUGGING=$enableval])
if test "x$ENABLE_DEBUGGING" = "xyes" -o "x$ENABLE_TESTING" = "xyes"; then
CFLAGS="${CFLAGS} -O0 -ggdb3 -g3"
fi
dnl Enable coverage?
ENABLE_COVERAGE=no
AC_ARG_ENABLE(coverage,AC_HELP_STRING([--enable-coverage],[DEBUGGING ONLY - Enable coverage reports (use with debugging)]),
[ENABLE_COVERAGE=$enableval])
if test "x$ENABLE_COVERAGE" = "xyes" -o "x$ENABLE_TESTING" = "xyes"; then
CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
fi
dnl Package directory for Solaris pkgmk (and other OSs, eventually)
dnl VERSION=`grep 1.0 include/common.h | cut -d ' ' -f 3 | sed 's/"//g'`
VERSION=$PKG_VERSION
PACKDIR=`pwd`/pkg
AC_SUBST(PACKDIR)
AC_SUBST(VERSION)
AC_MSG_CHECKING(for type va_list)
AC_TRY_COMPILE([#ifdef __STDC__
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#else
#include <sys/types.h>
#include <stdio.h>
#include <varargs.h>
#endif],
[va_list args;],
[AC_MSG_RESULT(yes)],
[AC_DEFINE(NEED_VA_LIST,,[defined if va_list fails to compile]) AC_MSG_RESULT(no)])
dnl Check if we should build local libtap
dnl From Nagios Plugins
dnl Have disabled autodetection of system library until later
AC_ARG_ENABLE(libtap,
AC_HELP_STRING([--enable-libtap],
[Enable built-in libtap for unit-testing (default: no).]),
[enable_libtap=$enableval],
[enable_libtap=no])
#Disabled for moment
#AM_CONDITIONAL([USE_LIBTAP_LOCAL],[test "$enable_libtap" = "yes"])
# Disabled for moment
# If not local, check if we can use the system one
#if test "$enable_libtap" != "yes"; then
# dnl Check for libtap, to run perl-like tests
# AC_CHECK_LIB(tap, plan_tests,
# enable_libtap="yes"
# )
#fi
# Finally, define tests if we use libtap
if test "x$enable_libtap" = "xyes" -o "x$ENABLE_TESTING" = "xyes"; 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(BASEEXTRALIBS)
AC_SUBST(USE_EVENTBROKER)
AC_PATH_PROG(PERL,perl)
if test -z "$PERL"; then
AC_MSG_ERROR([Cannot continue without perl!])
fi
AC_PATH_PROG(UNZIP,unzip)
if test -z "$UNZIP"; then
AC_MSG_ERROR([Cannot continue without unzip!])
fi
dnl Need this here because of removing it from autoconf-macros
eval sbindir=$sbindir
AC_OUTPUT([
Makefile
lib/Makefile
base/Makefile
common/Makefile
contrib/Makefile
cgi/Makefile
html/Makefile
module/Makefile
worker/Makefile
worker/ping/Makefile
xdata/Makefile
subst
pkginfo
startup/openrc-init
startup/default-init
startup/default-service
startup/upstart-init
t/Makefile
t-tap/Makefile
])
perl subst include/locations.h
perl subst html/config.inc.php
dnl perl subst daemon-service
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
incdir=`eval echo $includedir`
if test "x$incdir" = "x$prefix/include"; then
includedir=$prefix/include/nagios
fi
if test "x$USE_EVENTBROKER" != "xyes"; then
USE_EVENTBROKER=no
fi
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])
AC_MSG_RESULT([ Event Broker: $USE_EVENTBROKER])
AC_MSG_RESULT([ Install \${prefix}: $prefix])
AC_MSG_RESULT([ Install \${includedir}: $includedir])
AC_MSG_RESULT([ Lock file: $subsyslockfile])
AC_MSG_RESULT([ Check result directory: $CHECKRESULTDIR])
AC_MSG_RESULT([ Init directory: $initdir])
AC_MSG_RESULT([ Apache conf.d directory: $HTTPD_CONF])
AC_MSG_RESULT([ Mail program: $MAIL_PROG])
AC_MSG_RESULT([ Host OS: $host_os])
AC_MSG_RESULT([ IOBroker Method: $IOBROKER_METHOD])
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])
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 ""

4
contrib/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
Makefile
convertcfg
daemon-chk.cgi
nagios-worker

118
contrib/Makefile.in Normal file
View File

@ -0,0 +1,118 @@
###############################
# Makefile for contrib software
#
# Last Modified: 05-19-2008
###############################
CC=@CC@
CFLAGS=-I.. @CFLAGS@ @DEFS@
LDFLAGS=@LDFLAGS@ @LIBS@
# Source code directories
SRC_INCLUDE=../include
SRC_COMMON=../common
SRC_CGI=../cgi
SRC_LIB=../lib
# Generated automatically from configure script
SNPRINTF_O=@SNPRINTF_O@
INSTALL=@INSTALL@
INSTALL_OPTS=@INSTALL_OPTS@
prefix=@prefix@
exec_prefix=@exec_prefix@
CGIDIR=@cgibindir@
BINDIR=@bindir@
CGIS=traceroute.cgi daemonchk.cgi
UTILS=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 core *.o
rm -f */*/*~
rm -f */*~
rm -f *~
rm -rf rpmbuild *.rpm
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
$(SRC_LIB)/libnagios.a:
make -C $(SRC_LIB) libnagios.a
daemonchk.cgi: daemonchk.o $(CGI_O) $(CGI_H) $(COMMON_H) $(SRC_LIB)/libnagios.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(CGI_O) $(SRC_LIB)/libnagios.a
daemonchk.o: daemonchk.c
$(CC) $(CFLAGS) -c -o $@ $< -I$(SRC_INCLUDE)
nagios-worker: nagios-worker.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LIBS) $(SRC_LIB)/libnagios.a
##############################################################################
# dependencies
$(CGI_O): $(CGI_C)
cd $(SRC_CGI) && make $(CGI_O)
##############################################################################
# implicit rules
%.cgi : %.c
$(CC) $(CFLAGS) $(LDFLAGS) $< $(CGI_O) -o $@
##############################################################################
# rpm making automation for CentOS/RHEL.
ARCH ?= $(shell uname -m)
ifeq ($(ARCH),x86_64)
RPM_ARCH := x86_64
else
ifeq ($(ARCH),i686)
RPM_ARCH := i386
else
ifeq ($(ARCH),aarch64)
RPM_ARCH := aarch64
else
$(error Unknown arch "$(ARCH)".)
endif
endif
endif
rpm:
# create nagios tar ball.
@(cd ..;rm -f nagios-@VERSION@)
@(cd ..;ln -s . nagios-@VERSION@)
@(cd ..;tar zhcf nagios-@VERSION@.tar.gz --exclude nagios-@VERSION@/nagios-@VERSION@.tar.gz --exclude nagios-@VERSION@/nagios-@VERSION@ --exclude RCS --exclude CVS --exclude build-* --exclude *~ --exclude .git* nagios-@VERSION@/)
@(cd ..;rm -f nagios-@VERSION@)
# build the rpm using rpmbuild from ./rmbuild as topdir
@rm -rf rpmbuild && mkdir -p rpmbuild/SOURCES
@cp ../nagios-@VERSION@.tar.gz rpmbuild/SOURCES/nagios-@VERSION@.tar.gz
@rpmbuild -ba --define "_topdir ${PWD}/rpmbuild" ../nagios.spec
@mv rpmbuild/RPMS/$(RPM_ARCH)/*.rpm .
@ls -l *.rpm

43
contrib/README Normal file
View File

@ -0,0 +1,43 @@
#####################
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 executable
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.
- Automated rpm making.
1. ./configure # to generate contrib/Makefile
2. cd contrib ; make rpm
3. *.rpm will be generated in contrib directory.

745
contrib/convertcfg.c Normal file
View File

@ -0,0 +1,745 @@
/************************************************************************
*
* CONVERTCFG.C - Config File Converter
*
* Copyright (c) 2001-2005 Ethan Galstad (egalstad@nagios.org)
* Last Modified: 08-12-2005
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *my_strsep(char **, const char *);
int main(int argc, char **argv) {
FILE *fp;
char *temp_ptr;
char *temp_ptr2;
char input[8096];
int notify_recovery;
int notify_warning;
int notify_critical;
int notify_down;
int notify_unreachable;
int option;
int have_template = 0;
int x = 0, y = 0;
char *host_name;
char *service_description;
char *host_name2;
char *service_description2;
if(argc != 3) {
printf("Nagios Config File Converter\n");
printf("Written by Ethan Galstad (egalstad@nagios.org)\n");
printf("Last Modified: 08-12-2005\n");
printf("\n");
printf("Usage: %s <config file> <object type>\n", argv[0]);
printf("\n");
printf("Valid object types include:\n");
printf("\n");
printf("\ttimeperiods\n");
printf("\tcommands\n");
printf("\tcontacts\n");
printf("\tcontactgroups\n");
printf("\thosts\n");
printf("\thostgroups\n");
printf("\thostgroupescalations\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("\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; DON'T 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("\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; DON'T 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("# '%s' 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;
}

276
contrib/daemonchk.c Normal file
View File

@ -0,0 +1,276 @@
#include "config.h"
#include "common.h"
#include "locations.h"
#include "cgiutils.h"
#include "getcgi.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <stdarg.h>
#define CHARLEN 256
#define max(a,b) ((a)>(b))?(a):(b)
static void document_header(void);
//static void document_footer(void);
static int process_cgivars(void);
static char *strscpy(char *dest, const char *src);
static char *ssprintf(char *str, const char *fmt, ...);
static void terminate(int result, const char *fmt, ...);
static void get_expire_time_string(time_t *raw_time, char *buffer, int buffer_length);
int main(int argc, char **argv) {
FILE *fp;
char *status_file = NULL;
char *lock_file = NULL;
char *proc_file = NULL;
char input_buffer[CHARLEN];
int c, age, pid, testpid, found;
int wt = -1;
int ct = -1;
struct stat statbuf;
time_t current_time;
#ifdef DEFAULT_STATUS_FILE
status_file = strscpy(status_file, DEFAULT_STATUS_FILE);
#else
status_file = strscpy(status_file, "/var/log/nagios/status.log");
#endif
#ifdef DEFAULT_LOCK_FILE
lock_file = strscpy(lock_file, DEFAULT_LOCK_FILE);
#else
lock_file = strscpy(lock_file, "/tmp/nagios.lock");
#endif
if(getenv("REQUEST_METHOD")) {
process_cgivars();
document_header();
}
else { /* get arguments */
while((c = getopt(argc, argv, "+c:w:s:l:")) != EOF) {
switch(c) {
case 'c':
ct = atoi(optarg);
break;
case 'w':
wt = atoi(optarg);
break;
case 's':
status_file = optarg;
break;
case 'l':
lock_file = optarg;
break;
}
}
}
/* find status file, get lastmod time */
if(stat(status_file, &statbuf) == -1) {
printf("NAGIOS CRITICAL - could not find status log: %s\n", status_file);
exit(STATE_CRITICAL);
}
time(&current_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(&current_time);
get_expire_time_string(&current_time, date_time, (int)sizeof(date_time));
printf("Last-Modified: %s\n", date_time);
printf("Expires: %s\n", date_time);
printf("Content-type: text/html\n\n");
printf("<html>\n<head>\n<title>Nagios Daemon Status</title>\n</head>\n");
printf("<body onunload=\"if (window.wnd && wnd.close) wnd.close(); return true;\">\n");
return;
}
static int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
for(x = 0; variables[x] != NULL; x++) {
/* do some basic length checking on the variable identifier to prevent buffer overflows */
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
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", "Sep", "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);
}

View File

@ -0,0 +1,26 @@
#!/bin/sh
# Write a command to the Nagios command file to cause
# it to disable active service checks. This can be
# referred to as 'standby' mode in a redundant monitoring
# environment.
# Notes:
# 1) This script is not intended to be used as an
# event handler by itself. Instead, it is used by other
# event handler scripts (like the redundancy examples).
# 2) In order for Nagios to process any commands that
# are written to the command file, you must enable
# the check_external_commands option in the main
# configuration file.
printfcmd="/usr/bin/printf"
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
# get the current date/time in seconds since UNIX epoch
datetime=`date +%s`
# pipe the command to the command file
`$printfcmd "[%i] STOP_EXECUTING_SVC_CHECKS\n" $datetime >> $CommandFile`

View File

@ -0,0 +1,24 @@
#!/bin/sh
# Write a command to the Nagios command file to cause
# it to disable host and service notifications
# Notes:
# 1) This script is not intended to be used as an
# event handler by itself. Instead, it is used by other
# event handler scripts (like the redundancy examples).
# 2) In order for Nagios to process any commands that
# are written to the command file, you must enable
# the check_external_commands option in the main
# configuration file.
printfcmd="/usr/bin/printf"
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
# get the current date/time in seconds since UNIX epoch
datetime=`date +%s`
# pipe the command to the command file
`$printfcmd "[%i] DISABLE_NOTIFICATIONS;%i\n" $datetime $datetime >> $CommandFile`

View File

@ -0,0 +1,46 @@
#!/bin/sh
# OBSESSIVE_SVC_HANDLER
# Written by Ethan Galstad (nagios@nagios.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"

View File

@ -0,0 +1,39 @@
#!/bin/sh
# SUBMIT_CHECK_RESULT_VIA_NSCA
# Written by Ethan Galstad (egalstad@nagios.org)
# Last Modified: 10-15-2008
#
# This script will send passive check results to the
# nsca daemon that runs on the central Nagios server.
# If you simply want to submit passive checks from the
# same machine that Nagios is running on, look at the
# submit_check_result script.
#
# Arguments:
# $1 = host_name (Short name of host that the service is
# associated with)
# $2 = svc_description (Description of the service)
# $3 = return_code (An integer that determines the state
# of the service check, 0=OK, 1=WARNING, 2=CRITICAL,
# 3=UNKNOWN).
# $4 = plugin_output (A text string that should be used
# as the plugin output for the service check)s
#
#
# Note:
# Modify the NagiosHost parameter to match the name or
# IP address of the central server that has the nsca
# daemon running.
printfcmd="/usr/bin/printf"
NscaBin="/usr/local/nagios/libexec/send_nsca"
NscaCfg="/usr/local/nagios/etc/send_nsca.cfg"
NagiosHost="nagioshost"
# Fire the data off to the NSCA daemon using the send_nsca script
$printfcmd "%s\t%s\t%s\t%s\n" "$1" "$2" "$3" "$4" | $NscaBin -H $NagiosHost -c $NscaCfg
# EOF

View File

@ -0,0 +1,26 @@
#!/bin/sh
# Write a command to the Nagios command file to cause
# it to enable active service checks. This can be
# referred to as 'active' mode in a redundant monitoring
# environment.
# Notes:
# 1) This script is not intended to be used as an
# event handler by itself. Instead, it is used by other
# event handler scripts (like the redundancy examples).
# 2) In order for Nagios to process any commands that
# are written to the command file, you must enable
# the check_external_commands option in the main
# configuration file.
printfcmd="/usr/bin/printf"
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
# get the current date/time in seconds since UNIX epoch
datetime=`date +%s`
# pipe the command to the command file
`$printfcmd "[%i] START_EXECUTING_SVC_CHECKS\n" $datetime >> $CommandFile`

View File

@ -0,0 +1,27 @@
#!/bin/sh
# Write a command to the Nagios command file to cause
# it to enable host and service notifications
# Notes:
# 1) This script is not intended to be used as an
# event handler by itself. Instead, it is used by other
# event handler scripts (like the redundancy examples).
# 2) In order for Nagios to process any commands that
# are written to the command file, you must enable
# the check_external_commands option in the main
# configuration file.
printfcmd="/usr/bin/printf"
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
# get the current date/time in seconds since UNIX epoch
datetime=`date +%s`
# pipe the command to the command file
`$printfcmd "[%i] ENABLE_NOTIFICATIONS;%i\n" $datetime $datetime >> $CommandFile`

View File

@ -0,0 +1,68 @@
#!/bin/sh
# REDUNDANCY EVENT HANDLER SCRIPT
# Written By: Ethan Galstad (egalstad@nagios.org)
# Last Modified: 02-19-2004
#
# This is an example script for implementing redundancy.
# Read the HTML documentation on redundant monitoring for more
# information on what this does.
# Location of the echo and mail commands
echocmd="/bin/echo"
mailcmd="/bin/mail"
# Location of the event handlers
eventhandlerdir="/usr/local/nagios/libexec/eventhandlers"
# Only take action on hard host states...
case "$2" in
HARD)
case "$1" in
DOWN)
# The master host has gone down!
# We should now become the master host and take
# over the responsibilities of monitoring the
# network, so enable notifications...
`$eventhandlerdir/enable_notifications`
# Notify someone of what has happened with the original
# master server and our taking over the monitoring
# responsibilities. No one was notified of the master
# host going down, since the notification would have
# occurred while we were in standby mode, so this is a good idea...
#`$echocmd "Master Nagios host is down!" | /bin/mail -s "Master Nagios Host Is Down" root@localhost`
#`$echocmd "Slave Nagios host has entered ACTIVE mode and taken over network monitoring responsibilities!" | $mailcmd -s "Slave Nagios Host Has Entered ACTIVE Mode" root@localhost`
;;
UP)
# The master host has recovered!
# We should go back to being the slave host and
# let the master host do the monitoring, so
# disable notifications...
`$eventhandlerdir/disable_notifications`
# Notify someone of what has happened. Users were
# already notified of the master host recovery because we
# were in active mode at the time the recovery happened.
# However, we should let someone know that we're switching
# back to standby mode...
#`$echocmd "The master Nagios host has recovered, so the slave Nagios host has returned to standby mode..." | $mailcmd -s "Slave Nagios Host Has Returned To STANDBY Mode" root@localhost`
;;
esac
;;
esac
exit 0

Some files were not shown because too many files have changed in this diff Show More