diff options
190 files changed, 35322 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 00000000..96f4d1a6 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,10 @@ +configure +debian +Makefile +Makefile.in +config.* +test.pl +subst +command.cfg +Cache.pm +build-*
\ No newline at end of file diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..8e7bfeb6 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,12 @@ +Felipe Gustavo de Almeida +Ian Cass +Robert Dale +Karl DeBisschop +Ragnar Hojland Espinosa +Ethan Galstad +Bo Kersey +Pedro Leite +Richard Mayhew +Remi Paulmier +Didi Rieder +Tom Shields
\ No newline at end of file @@ -0,0 +1,38 @@ +The following guidelines are intended to aid programmers in creating +code that is consistent with the existing core plugins. + +The primary goals of these standards are internal consistency, and +readability in a wide range of environments. + +1. C Language Programming + +All code should comply with the requirements of the Free Software +Foundation Coding standards (which are currently available at +http://www.gnu.org/prep/standards_toc.html). We also follow most of +the FSF guidelines. Developers may suggest deviations from the FSF +style recommendations, which will be considered by open discussion on +the netsaintplug-devel mailing list. Any such deviations will apply to +the entire code base to ensure consistency. + +Currently, the exceptions to FSF recommendatios are roughly equivalent +to GNU indent with invoked as 'indent -ts 2 -br'. Specifically, the +exceptions are as follows: + +a) leading white space for a statement should be formatted as tabs, +with one tab for each code indentation level. + +b) in statement continuation lines, format whitespace up to the column +starting the statement as tabs, format the rest as spaces (this +results in code that is legible regardless of tab-width setting). + +c) with the exception of the above, tabs should generally be avoided + +d) when tab width is 2 spaces, line-length should not exceed 80 +characters + +e) The opening brace of an if or while block is on the same line as +the end of the conditional expression (the '-br' option). + +2. Perl Language Programming + +<To Be Written> diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d60c31a9 --- /dev/null +++ b/COPYING @@ -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) <year> <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) year 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. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..c08f73a9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,2533 @@ +2000-12-08 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + fix memory leaks + +2000-12-07 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_qmailq.pl: + checks mail in queue (needs much work still) + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_ftpget.pl: + tests fetching files from FTP server + +2000-12-02 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c: + password authentication patch, indent, standardize usage/help functions + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + don't quote PROGNAME + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + print pagesize on verbose flag + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + strncat causes segv in RH6.2 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + more tweaks for mysql + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: typo in usage2 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + additional tweaks needed for mysql + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + add usage2 macro + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + use strncat in strscat + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + fix recent bug in redirects + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + loof for libs in /usr/lib/mysql as well + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + test on nullhost may return warning or error + +2000-12-01 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c: + typo - fix dns left trim on bind 9 + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: details for 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/package.def: 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + remove AC_MSG_WARN for openSSL (redundant) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + use size constants in preference to sizeof() + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c: + typo - chopped one ltoo many lead characters + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + add argsument-array option to check_procs + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/version.h.in: + prepare for 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + move strip() to utils.c + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + add documentation for new argument-arry option + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + allow test against ARGS with -a switch + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t: + update for bind 9 + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_rrd_data.pl: + checks RRD data (for use with cricket) + +2000-12-01 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/package.def: 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + remove AC_MSG_WARN for openSSL (redundant) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + use size constants in preference to sizeof() + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c: + typo - chopped one ltoo many lead characters + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + add argsument-array option to check_procs + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/version.h.in: + prepare for 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + move strip() to utils.c + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + add documentation for new argument-arry option + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + allow test against ARGS with -a switch + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t: + update for bind 9 + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_rrd_data.pl: + checks RRD data (for use with cricket) + +2000-12-01 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + add argsument-array option to check_procs + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/version.h.in: + prepare for 1.2.9-beta3 + + * /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + move strip() to utils.c + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + add documentation for new argument-arry option + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + allow test against ARGS with -a switch + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t: + update for bind 9 + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_rrd_data.pl: + checks RRD data (for use with cricket) + +2000-11-30 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + fix typo, indent + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + don't trigger warning for Redhat 7 ping output on stderr (Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP) + +2000-11-28 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: indent + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + remove line continuations + +2000-11-18 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl: + add option for workgroups + +2000-11-17 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + run `indent -ts2 -sob check_disk.c` + + * /cvsroot/netsaintplug/netsaintplug/plugins/common.h.in: + typo in #ifndef HAVE_STROL + +2000-11-16 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: run indent + fix bugs on solaris + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + run indent over code + use strscat function instaed on messy internal loop + fix a couple of things that should have been ifdef'd for REGEX + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ping.t: + indent, use state_text() for output + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + explicitly initialize eval_method array + +2000-11-15 hgayosso <hgayosso@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + Added examples for: check_reply and check_radius. + +2000-11-08 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_joy.sh: + checks joystick port + +2000-11-07 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c: fix segfault + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + set label and units in validate() + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + automatically increase timeout if critical treshold is greater than crta + +2000-11-03 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + fis segfault looking for EOL on stripped line + +2000-10-25 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: automatic update + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: cleanup + move a slight bit closer to SSH protocal compliance + needs much more work + +2000-10-25 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: cleanup + move a slight bit closer to SSH protocal compliance + needs much more work + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + change type of counter 'i' to int + allow = in url query string + +2000-10-11 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c: + allow expiration to be optional + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/package.def: + prepare for beta 2 + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c: + use new process_tcp_request2 throughtout + + * /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c: + prototype for process_tcp_request2 + + * /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in: + new process_tcp_request2 + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c: + add function to get multiple lines of data from recv() loop + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c: + result was being improperly initialized + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c: + make consistent with check_mrtgtraf + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + cleanup arrays for '-u' and '-l' options + +2000-10-10 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + fix count of expect strings + +2000-10-06 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/contrib/checkciscotemp.pl: + missing comma + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + don't check output string content if there is no test string + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + add a few comments + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + fix some line breaks, OID typos + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + make sure cmd exists before runnin strstr + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c: + cpp conditionals must be in consistent order + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + additional fixes for munged multiple expect loop + +2000-10-02 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + fix bug in server expect code, due to bad logic in testing for + alternative expects for check_nntp + +2000-09-27 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + fix some extraneous linefeeds + fix missing leading dots in a few SNMP OIDs + +2000-09-25 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore: + make a separate distrib directory to run 'make dist' + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: + 1.2.9 beta 11.2.9 beta 11.2.9 beta 11.2.9 beta 11.2.9 beta 11.2.9 beta 11.2.9 beta 11.2.9 beta 11.2.9 beta 1 + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + set cmd to NULL when there are characters left, but they are all whitespace + +2000-09-24 karldebisschop <karldebisschop@miles.debisschop.net> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + something funky in check_time failure mode -- remove tests for now + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + fix possible buffer overflows revealed by libsafe + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + give CRITICAL|WARNING on connect failures only if connect-time checking used + +2000-09-24 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + something funky in check_time failure mode -- remove tests for now + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + fix possible buffer overflows revealed by libsafe + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + give CRITICAL|WARNING on connect failures only if connect-time checking used + +2000-09-21 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/aclocal.m4, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/common.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/getopt1.c, /cvsroot/netsaintplug/netsaintplug/plugins/getopt.c, /cvsroot/netsaintplug/netsaintplug/plugins/getopt.h, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am: + provide getopt_long for those OS's that do not have it + +2000-09-20 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + plugin now warns if server is not present + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + trap connect errors before invalid time difference is returned + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + strip line from server to remove EOL + use ssprintf to send proper length string to server + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c: + a few fixes for help screens + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c: + fix missed token in reverse-compatibility mode + help was completely worng + +2000-09-18 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c: + look for error codes oonly at beginning of string + add option to switch to MODE READER + +2000-09-14 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/INSTALL: + Use list as primry contact, not Ethan + + * /cvsroot/netsaintplug/netsaintplug/INSTALL: Add preamble for CVS tree + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + add 'mdev' to output forms to scan + +2000-09-13 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/test.pl.in: + get path a little closer to working on solaris with build dirs + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_procs.t: + print when test is unexpectedly successful + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/t/check_rpc.t: + print better info on errors + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + authentication for SSL + +2000-09-12 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_load.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_mysql.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_pop.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_procs.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_smtp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_swap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_users.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_vsz.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_imap.t: + better nessages when errors are found + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c: cleanup + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + tweaks for better operation on debian (still not right) + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t: typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_hpjd.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_disk.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + print better messages on failure + +2000-09-11 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: beta 1 + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/package.def: + 1.2.9-b11.2.9-b11.2.9-b11.2.9-b11.2.9-b11.2.9-b11.2.9-b11.2.9-b11.2.9-b1 + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + better output for error diagnosis + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dig.c: + trim newline on on DOS/MAC as well + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dig.c: + trim extra linefeed + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + also allow commas for critical (AKA, fix my stupid ommision) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + accept comma as arglist separator + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t: + don't check output when testing against nullhost or noserver + - there are just too many variants + +2000-09-11 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/package.def: + 1.2.9-b1 + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + better output for error diagnosis + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dig.c: + trim newline on on DOS/MAC as well + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dig.c: + trim extra linefeed + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + also allow commas for critical (AKA, fix my stupid ommision) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + accept comma as arglist separator + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t: + don't check output when testing against nullhost or noserver + - there are just too many variants + + * /cvsroot/netsaintplug/netsaintplug/configure.in: test for openssl + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t: + don't check output string when testing nullhost + +2000-09-10 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + bug killing 'ssl' twice cause segfault + +2000-09-07 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dig.c: + decalaration was moved into autoconf + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + solaris had problems with prototypes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + typo in variable name + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + add NNTP personality + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + put strpcat and strpcpy into utils + + * /cvsroot/netsaintplug/netsaintplug/acconfig.h, /cvsroot/netsaintplug/netsaintplug/configure.in: + add detection for getopt_long function call + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c: + cahnges needed fro Navis radius + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c: + by default only look for numeric codes, use server expect only when user specifies + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + show both long and short form for --help and --version + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + fix typo in warning note + show both long and short forn for --help and --version + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + PS_RAW_COMMAND needs to look at full path + +2000-09-06 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + use ssprintf function to formulate command + +2000-09-01 karldebisschop <karldebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c: + accidentally dropped ! + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c: + add verbose printf's and checnge NNRP to NNTP + +2000-09-01 karldebisschop <kdebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/subst.in: + escape = for nawk (AIX) + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl: + change chop to chomp + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl: + typo in usage warning + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + terminate copied string explicitly + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + ndle post operations + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t: + handle multiple line output + +2000-08-31 karldebisschop <kdebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Makefile.am: add acconfig.h + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: alpha 7 + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl: + add space in '$Revision$' to make emacs perl-maode work right + + * /cvsroot/netsaintplug/netsaintplug/package.def, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + alpha 7 + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am: + fix typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + was reallocing the wrong thing + +2000-08-31 karldebisschop <kdebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl: + add space in '$Revision$' to make emacs perl-maode work right + + * /cvsroot/netsaintplug/netsaintplug/package.def, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + alpha 7 + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am: + fix typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + was reallocing the wrong thing + + * /cvsroot/netsaintplug/netsaintplug/test.pl.in: + PWD environment variable is not always present + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c: + fix option handling for -v and fix testing of ups_name + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/t/check_rpc.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_hpjd.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_imap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_load.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_mysql.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_pop.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_procs.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_smtp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_swap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_users.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_vsz.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_disk.t: + always return 0 if called from Test::Harness + +2000-08-30 karldebisschop <kdebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am: + fix test environment + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + remove typo: AC_DEFINE_UNQUOTED + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + get check_disk to build on cygwin + +2000-08-28 karldebisschop <kdebisschop@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: autoupdate + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: use Helper + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_wave.pl: + add option processing + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + typo in ERROR hash, better host name checking + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl: + typo in ERROR hash + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: fix typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + fix args to strscpy + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c: + argc=2 IS valid (--help), optopt is char + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c: + fix incorrect PROGNAME + + * /cvsroot/netsaintplug/netsaintplug/opttest.pl: + test -h, -V, --help, --version, and check for correct PROGNAME + +2000-08-28 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: use Helper + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_wave.pl: + add option processing + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + typo in ERROR hash, better host name checking + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl: + typo in ERROR hash + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: fix typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + fix args to strscpy + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c: + argc=2 IS valid (--help), optopt is char + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c: + fix incorrect PROGNAME + + * /cvsroot/netsaintplug/netsaintplug/opttest.pl: + test -h, -V, --help, --version, and check for correct PROGNAME + +2000-08-28 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + use udp_hostname instead of localhost + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c: + fix typo in #if statements + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_imap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_pop.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_smtp.t: + not all OS types take long opts -- remove from test + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_hpjd.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_mysql.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t: + don't run test if plugin was not made + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + don't run tests if plugin wasn't made + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c: + arg processing typos + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am: + specify t as directory rather than wildcard - allows make dist in subdir + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am: + pecify t as directory rather than wildcard - allows make dist in subdir + + * /cvsroot/netsaintplug/netsaintplug/package.def, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec: + 1.2.9 alpha 6 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + PS_COMMAND checks for debian + +2000-08-25 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am: + chieck_by_ssh should also be in extras + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: update + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + remove extra printf from debigging + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am: + make check_netsaint an extra + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + small tweak to match latest check_fping mods + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + check to see if MSG_DONTWAIT is defined before using + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c: + check times, variable packet size + +2000-08-25 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: update + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + remove extra printf from debigging + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am: + make check_netsaint an extra + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + small tweak to match latest check_fping mods + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + check to see if MSG_DONTWAIT is defined before using + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c: + check times, variable packet size + +2000-08-23 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + 1.2.9 alpha 5 + + * /cvsroot/netsaintplug/netsaintplug/package.def: ID breaks autoconf + + * /cvsroot/netsaintplug/netsaintplug/package.def: 1.2.9 alpha 5 + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + update to reflect changes to check_fping for variable packet size handling + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: + more 1.2.9-a5 log entries + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog: + log some 1.2.9a5 changes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c: + provide option to control number of packets and packet size + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + add $ after HOSTADDRESS in check_http + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t: + Should now answer for any of check_(imap|pop|smtp|udp|tcp|reply) + +2000-08-22 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c: + HOUX reveals bug with PROC_LOADAVG logic + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore, /cvsroot/netsaintplug/netsaintplug/plugins/.cvsignore, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/.cvsignore: + housekeeping + + * /cvsroot/netsaintplug/netsaintplug/acconfig.h, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + bug fixes on 1.2.9-a4 + + * /cvsroot/netsaintplug/netsaintplug/plugins/config.h.in: + made by autoheader now + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am: + need to install utils.pm and utils.sh + +2000-08-18 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Makefile.am, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + last few things to get rpm working for 1.2.9-a4 + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Helper.pm, /cvsroot/netsaintplug/netsaintplug/Makefile.am, /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am, /cvsroot/netsaintplug/netsaintplug/test.pl.in: + get make test to work again + a couple of doc fixes for check_radius + + * /cvsroot/netsaintplug/netsaintplug/Makefile.am, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + update spec for 1.2.9a4 + add Helper.pm to dist + +2000-08-17 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/t/check_rpc.t: + output does not begin with ./ + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_log.sh, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle.sh, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/utils.sh.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_flexlm.pl: + add standard option syntax to shell plugins + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + standard option handling for shell scripts + +2000-08-16 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_imap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_pop.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_smtp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t: + tcp: don't scan unless --expect or --send + others: create a few new host types + + * /cvsroot/netsaintplug/netsaintplug/acconfig.h, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/package.def, /cvsroot/netsaintplug/netsaintplug/plugins/config.h.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/utils.pm.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + lost correct release tracking with change to automake - fixed + +2000-08-15 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_breeze.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/subst.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/utils.pm.in: + convert to getopt + +2000-08-12 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/utils.pm.in: + conversion to getopt and automake + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am: + change to getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c: + obsolete - functionanlity added to check_tcp + +2000-08-11 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/checkciscotemp.pl, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec: + conversion to standard options syntax + +2000-08-10 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c: + complete change to getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: + convert radius to getopt, cleanup on tcp + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c: + wrong PROGNAME + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c: + convert to getopt + +2000-08-08 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/.cvsignore, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/.cvsignore, /cvsroot/netsaintplug/netsaintplug/.cvsignore: + Makefile.in is built by automake + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t: + test for bin existence doesn't work right + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + use newer strscpy and ssprintf + fix typo (called wrong DEFINE) + + * /cvsroot/netsaintplug/netsaintplug/acconfig.h, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.am, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.am, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.am: + use automake + + * /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in: + switch to automake + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/t/check_rpc.t: + use automake + + * /cvsroot/netsaintplug/netsaintplug/plugins/config.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_disk.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_hpjd.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_imap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_load.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_mysql.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_pop.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_procs.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_smtp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_swap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_users.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_vsz.t: + convert to automake + +2000-08-04 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + needed for cygwin, other systems that don't meet SVr4 or BSD4.3 + +2000-08-03 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore, /cvsroot/netsaintplug/netsaintplug/plugins/.cvsignore: + prep for automake + + * /cvsroot/netsaintplug/netsaintplug/aclocal.m4, /cvsroot/netsaintplug/netsaintplug/AUTHORS, /cvsroot/netsaintplug/netsaintplug/missing, /cvsroot/netsaintplug/netsaintplug/mkinstalldirs, /cvsroot/netsaintplug/netsaintplug/NEWS: + GNU conformance, prep for automake + + * /cvsroot/netsaintplug/netsaintplug/ChangeLog, /cvsroot/netsaintplug/netsaintplug/Changelog: + rename to comply with GNU standards + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/.cvsignore: + needed now that there's a make process + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_dns.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_netdns.pl: + rename to avoid conflict when installing + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_dns.pl: + use Net::DNS to check name server + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dig.c: + use dig instead of nslookup. + + * /cvsroot/netsaintplug/netsaintplug/acconfig.h: use autoheader + +2000-08-02 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/common.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/config.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/version.h.in: + get rid of common/*.h + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: bugfix + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/urlize.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_game.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c: + move config.h and common.h out of ../common + ---------------------------------------------------------------------- + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c: + correct return status for --help and --version + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c: + convert to getopt + + * /cvsroot/netsaintplug/netsaintplug/opttest.pl: + test all plugins for -h --help -v --version options + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + reorganize LIBS to use as .IGNORED deps -- -L/usr/lib must be in LDFLAGS + +2000-07-30 hgayosso <hgayosso@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + Added examples for: check_nmap. + +2000-07-29 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore: add sparc64 + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/subst.in: + use shell/sed for subst script to meet GNU coding stamdards + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_imap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_pop.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_smtp.t: + new tests written with getopt conversion + + * /cvsroot/netsaintplug/netsaintplug/subst.sh: + shell wrapper handles diff'ing after sed substitution + (awk fails GNU coding stds) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_swap.t: + switch to getopt + eliminate overflow in t/check_swap.t (still need to fix check_swap.c) + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + better way of doing is_int + +2000-07-26 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore: + ignore arch-specific build directories + +2000-07-25 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c: + convert to getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + clean out a few sscanf calls + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_mysql.t: new test + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + help screen typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + delete extra printf + +2000-07-23 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + improve documentation of -i option and its use + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/subst.in: + add -_ to acceptable cahracters in commad name + +2000-07-21 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + we use explicit path with new subst script + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/subst.in, /cvsroot/netsaintplug/netsaintplug/subst.in: + convert perl utility scripts to awk + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + use -H where possible, change @libexec@ to @libexecdir@ + +2000-07-20 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + taint checking for -p option + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: order of libs + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/subst.in: + convert old perl script to awk + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + use package.def for tracking package release (works for scripts too) + allow df and ping syntax to be specified on command line + + * /cvsroot/netsaintplug/netsaintplug/package.def: + defines package release + +2000-07-19 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + remove debugging printf + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + another attempt to get this to work with all servers. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + get protocol version from buffer, but send reasonable client string + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + remove inconsistent comment info + change ':' as list separator to ',' (retain ':' for back-compatibility) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + fix goof in revision + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + send ident string (suppresses server error) + +2000-07-17 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + use utils.py + use ntpdc if available + clarify final logic (still needs mor work) + + * /cvsroot/netsaintplug/netsaintplug/configure.in: make perl utils.pm + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/utils.pm.in: + perl script essential functions + +2000-07-15 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/utils.py: + user contribution + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_nmap.py: tag as 1.20 + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_nmap.py: + closing in on consiostent options, etc + +2000-07-14 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_ircd.tar.gz: + This was in core + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl: + dd $Id$ + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl: + 1.3 was accidental reversion of 1.2 to 1.1 - flip to correct state + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_nmap.py: + contributor revisions + +2000-07-13 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + if xntpdc is present, check dispersion + set $state to be integer so compares can be done + +2000-07-12 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/rpm: typo in macro for srcrpmdir + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/rpm: + reverse compatibility for ':' + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + 1.2.9-a2 + + * /cvsroot/netsaintplug/netsaintplug/COPYING: + We refer to it but didn't distrubute it before + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_nmap.py: + add note that license is GPL + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t: + set timeout, add new text matches + + * /cvsroot/netsaintplug/netsaintplug/Changelog: 1.2.9-a2 + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + fix bug resulting from use of strncmp + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + define suffix rules so both gnumake and pmake will work + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + must not send more than 2 \r\n pairs to zope + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_nmap.py: + new contribution + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_udp.t: new test + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_disk.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_swap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t: + edit to go with change to getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + documentation typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c: use getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + documentation typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + use getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + use comma for pairs of options, reserve colon for ranges + +2000-07-12 hgayosso <hgayosso@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + Added command examples for: check_fping, check_game, check_imap, check_rpc. + Changed one `/bin/printf' for `/bin/echo -e'. (hgayosso) + +2000-07-11 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/REQUIREMENTS: add check_radius + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_sockets.pl: + new contribution + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + command termination on usage macro can be ambiguous in if block + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + convert to getopt + +2000-07-07 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t: + make output a little more standard + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + add function ssprintf to print to mallocable string + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + use new ssprintf function + don't sscanf for mount point + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_mem.pl: + check memory (written on BSD) + +2000-07-06 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c: typos in docs + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + add support message + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_time.t, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c: + creation + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + revert to 1.29 + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + this mod is wrong - it will go away + +2000-07-05 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Changelog, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_fping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_tcp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_users.t, /cvsroot/netsaintplug/netsaintplug/make-tarball, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + 1.2.9-a1 cleanup + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + fix usage statement + +2000-07-04 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c: + convert to getopt + +2000-07-03 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + minor bug fixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_disk.t: + match messages with new multidisk checks + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + CRITICAL if any unkown message are picked up on STDERR + + * /cvsroot/netsaintplug/netsaintplug/make-tarball: exclude sparc-64 + + * /cvsroot/netsaintplug/netsaintplug/Changelog: exclude sparc64 + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + add documentation + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + fix inaccurate comment + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: help screen + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + check multiple disks + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + 1.2.9-a1 + + * /cvsroot/netsaintplug/netsaintplug/make-tarball: + make bz2 files as well + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c: + use getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + functional multichecks, still need to tweak args + +2000-06-30 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + better error trapping for strscpy and strscat + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + further work on checking multiple partitions - some cleanup left, + plus documentation + +2000-06-29 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + snapshot working toward multidisk checks + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + next snapshot for passive multichecks + +2000-06-28 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + add new form of rta for FreeBSD + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in, /cvsroot/netsaintplug/netsaintplug/test.pl.in: + multiplatform build stuff + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + napshot - at least this one compiles + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + still trying to make complete + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + snapshot - updating for passive multichecks + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in, /cvsroot/netsaintplug/netsaintplug/test.pl, /cvsroot/netsaintplug/netsaintplug/test.pl.in: + multiplatform builds + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + now able to specify varlist to ps so various orders can be handled (AIX) + +2000-06-27 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Helper.pm, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in: + multiplatform builds + + * /cvsroot/netsaintplug/netsaintplug/plugins/Helper.pm: + modev for multiplatform builds + + * /cvsroot/netsaintplug/netsaintplug/Helper.pm: + moved here for multipltform build + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + multiplatform builds + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + strscat and strscpy functions + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + 1.2.8-4 plus switch to bzip2 + +2000-06-26 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + 1.2.8-41.2.8-41.2.8-41.2.8-4 + +2000-06-25 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + use standard POSIX getopt (only GNU supports '-' leadin for optarg + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + possible fix for check_ping + +2000-06-23 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + try to get -p 1 at end of line to work + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + misplaced paren on host strlen + +2000-06-22 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/make-tarball, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/rpm: + housekeeping for rpm builds + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore, /cvsroot/netsaintplug/netsaintplug/make-tarball: + housekeeping + + * /cvsroot/netsaintplug/netsaintplug/make-tarball: + automatically create md5sum + + * /cvsroot/netsaintplug/netsaintplug/Changelog: + 1.2.8-3 bugfix release1.2.8-3 bugfix release1.2.8-3 bugfix release + + * /cvsroot/netsaintplug/netsaintplug/Changelog: houskeeping + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + was not printing errors correctly + + * /cvsroot/netsaintplug/netsaintplug/plugins/.cvsignore, /cvsroot/netsaintplug/netsaintplug/rpm, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/README, /cvsroot/netsaintplug/netsaintplug/REQUIREMENTS: + housekeeping + + * /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/make-tarball, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + houskeeping + +2000-06-21 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Changelog: regular update + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + make more mandrake style + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + allocate extra byte for trailing null when using malloc + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh: + fix bug in version string cleanup + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + use new terminate, add':' to usage statement + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + terminate can now take format,arglist like printf + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: update docs + + * /cvsroot/netsaintplug/netsaintplug/Changelog: + new info, cleanup old info + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + another fix for reverse compatibility for -nohtml + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + another fix to revers compatibility for -nohtml + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + first step in making SRPM more mandrake compatible + +2000-06-19 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Changelog: update + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + restore -nohtml as do-nothing option for reverse compatibility + + * /cvsroot/netsaintplug/netsaintplug/Changelog: typo + +2000-06-18 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Changelog: + 1.2.8-2 -- really this time + +2000-06-17 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c: + assume 20-char max size for int + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + fix DUP checking, use malloc instead of fixed length strings + +2000-06-16 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + fix docs, use malloc, fix bug with warn on DUPs + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + forgat to double % in printf spec + + * /cvsroot/netsaintplug/netsaintplug/Changelog: + 1.2.8-2 changes (complete?) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + show header, status, content separately + do more rigorous parsing of where content starts + +2000-06-15 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/urlize.c: doc fix + + * /cvsroot/netsaintplug/netsaintplug/plugins/urlize.c: + and long opts to docs + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + dd a little header stuff, upgrade to 1.2.8-1 + + * /cvsroot/netsaintplug/netsaintplug/Changelog, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + fix docs, make nothml the default, and --link (-L) option + + * /cvsroot/netsaintplug/netsaintplug/Changelog: + update to release new current + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + make failed if there were no extras + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + fix docs, add separate option for vhost + +2000-06-14 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Changelog: dd todays changes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + change name of variable stat - it conflicts on AIX with <sys/stat.h> + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + make check_process obsolete + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c: + all new functionality now incorporated into check_procs.c + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c: + fix documentation + + * /cvsroot/netsaintplug/netsaintplug/subst.in: + -q option for mktemp breaks on HPUX + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh: + make version reporting GNU like + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + comments were inaccurate + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in: + add #defines for standard options - testing only right now + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + make print_version more compatible with GNU coding standards + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in: + add $(DESTDIR) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c: + use getopt, cleanup documentation, retabify + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + clean up documentation, retabify + +2000-06-13 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/Changelog: + tabify, update documentation + + * /cvsroot/netsaintplug/netsaintplug/Changelog, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + typo in print_help + + * /cvsroot/netsaintplug/netsaintplug/Changelog: + progress on 12 June 2000 + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh: + dd --verbose + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh: + add help and usage routines + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh: + test for non-zero exit, fix bug + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c: + dd netutils.h and timeout + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + dd netlibs to check_ldap + +2000-06-12 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + convert spaces to tab stops + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + bux fix in command loop + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in: + remove some GNUisms in Makefile, quote test strings + +2000-06-09 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + 1.2.8 release + + * /cvsroot/netsaintplug/netsaintplug/contrib/restrict.pl: + add comment that openssh will not work with this script + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + patch from William Pietri + +2000-06-08 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/Changelog: just getting up to date + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + mysql configure problems - will still want a bit more work + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + make -H option work right + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_ora_table_space.pl: + add a few comments + + * /cvsroot/netsaintplug/netsaintplug/contrib/restrict.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_ora_table_space.pl: + new contributions + +2000-06-07 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + no check_https anymore + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + check_https no longer exists + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + get HAVE_SSL def right + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: typo + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + consolidate ssl for check_http into one plugin + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http2.c: + seems debugged, so moved into check_http + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_https.c: + ssl functionality has been move into check_http + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http2.c: + fix problem with --onredirect + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http2.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_https.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + fix option processing, hopefully for the last time + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec: + prepare for pre7 RPMs + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-core.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-extra.spec: + now contained in one netsaint-plugins spec + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + upgrade to 1.2.8pre7, change install dir to plugins, add command.cfg to doc + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins-custom.spec: + undefined build list + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http2.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c: + streamline and debug reverse compatibility mode for option processing + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t: + use hostname to test http + +2000-06-06 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + clean up warn where user has no libcrypto + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-core.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-extra.spec: + minor changes + + * /cvsroot/netsaintplug/netsaintplug/configure.in: pgsql on solaris + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-core.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-extra.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + call directory plugins instead of plugin + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + comment debugging code + + * /cvsroot/netsaintplug/netsaintplug/make-tarball: + clean and autoconf first to prvent careless errors + +2000-06-05 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-core.spec, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + try to get sane build of extras + modify check_http to try and get AIX to compile + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + cleanup final test for OpenSSL + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in: + typo in configure, plus try to get AIX to make scripts + +2000-06-04 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + try to make postgres work on non-redhat + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-core.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-extra.spec: + ichnage to pre6 + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + yet another try for BSD + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + fix again for BSD - need to change order of packets option + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + cange order of options to support FreeBSD + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + change to match AIX man page + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c: + get rid of duplicate definitiopn of max + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + get rid of egrep -s (use >/dev/null for compatibility) + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-core.spec, /cvsroot/netsaintplug/netsaintplug/netsaint-plugin-extra.spec: + core should install on any system, extars may require nodeps + + * /cvsroot/netsaintplug/netsaintplug/Makefile.in: + quickcheck target is not defined anymore + +2000-06-03 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + update for 1.2.8pre5 + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + add rule for urlize (and check_http2, temporary) + + * /cvsroot/netsaintplug/netsaintplug/plugins/urlize.c: + add help/usage/version info, plus a few comments + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http2.c: comments + + * /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ping.t: + fix needed to match new output from plugin + +2000-06-02 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http2.c: + put up short term - will soon replace check_http and check_https + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + typo in email address + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + fix calls to realloc + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c: + typos in print_help + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + typoes in usage and in getopt + + * /cvsroot/netsaintplug/netsaintplug/configure.in: fix for solaris + + * /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c: + pedantic compilers complained these wre not tru prototypes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + fix bug (rta is not reported if pl = 100) + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + try different hadlning of lib to get OpenSSL to work on FreeBSD + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + typo (would not have effect under current code, but cleaner) + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + fix logic for check_https + +2000-06-01 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + delet build root + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + change to 1.2.8pre4 + + * /cvsroot/netsaintplug/netsaintplug/Requirements: + just a short list of where to get packages tha plugins depend on + + * /cvsroot/netsaintplug/netsaintplug/contrib/maser-oracle.pl: + expand from archive + + * /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + fix bad @LIBS@ in makefiles + update version + +2000-05-31 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + random changes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c: + check a bunch more OIDs + + * /cvsroot/netsaintplug/netsaintplug/contrib/readme.txt: + make notes about moving some stuff to core + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + DO NOT include @LIBS@ in LDFLAGS - configure messes it up + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_ipxping.c, /cvsroot/netsaintplug/netsaintplug/contrib/check_ipxping.tar.gz: + unpack source + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_ntp.tar.gz: + moved to core + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_nfs.tar.gz: + functionality moved to check_rpc in core + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_real.tar.gz: + moved to core + + * /cvsroot/netsaintplug/netsaintplug/contrib/readme.txt: + updated file from www.netsaint.org + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_bgpstate.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_dns_random.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_ifoperstatus.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_ifstatus.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_maxchannels.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_maxwanstate.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/contrib/check_mysql.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_pop3.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_radius.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_sap.sh, /cvsroot/netsaintplug/netsaintplug/contrib/check_uptime.c: + copied and unpacked from www.netsaint.org + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + minor typo in comment + + * /cvsroot/netsaintplug/netsaintplug/plugins/urlize.c: + wraps output of another plugin with a URL + +2000-05-30 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_netapp.pl: + new contribution + + * /cvsroot/netsaintplug/netsaintplug/contrib/checkciscotemp.pl, /cvsroot/netsaintplug/netsaintplug/contrib/check_nwstat.pl, /cvsroot/netsaintplug/netsaintplug/contrib/mrtgext.pl, /cvsroot/netsaintplug/netsaintplug/contrib/urlize.pl: + new contributions, pending review and inclusion in main source tree + +2000-05-25 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c: + general cleanup - keep test order consistent so possible bugs are + more likely to be caught + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + do not include @LIBS@ in LDFLAGS - it's getting munged by configure + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + get openssl and mysql to work on redhat 6.2 + +2000-05-24 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c: + some printers may be going offline with POWERSAVE mode + +2000-05-19 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + realloc crashes when calloc outside of memory page - code page size as + define (I really need a better solution here) + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.c: + fix possible sscanf overflow + +2000-05-18 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c: + get regex and string searched to work for HTML pages longer than 1024 chars + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: fix a few typos + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + spell author names correctly, fix help screen info + +2000-05-11 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ide-smart.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: + use text constants (no|required)_argument instead of numbers in getopt_long + options for clarity. Fix any mis-specified options + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + make regex scan work + fix errors in specification of getopt_long parameters + +2000-05-10 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + drop reference to old saintcheck script + +2000-05-05 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + fix typoes in OID definition + +2000-05-04 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/saintcheck: obsoleted by test.pl + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + update version number in -V option + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + add author, revision tracking + +2000-05-03 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/t/check_rpc.t: + try to get arg checking to work, add full rpc list + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + bug fixes + + * /cvsroot/netsaintplug/netsaintplug/.cvsignore: + use this file to block syncronizing configure script (developers should run + autoconf on their own) + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + fix includes for llber + + * /cvsroot/netsaintplug/netsaintplug/test.pl: + replaces saintcheck (new script is based on standard perl test harness) + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c: + use plugin standard -h for help + move -h(ost) option to -H + fix getopt to work on machines with no getopt_long + + * /cvsroot/netsaintplug/netsaintplug/Makefile.in: fix conflicts + + * /cvsroot/netsaintplug/netsaintplug/Changelog, /cvsroot/netsaintplug/netsaintplug/command.cfg.in, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/subst.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c: + bug fixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c: bug fix + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c: + use getopt + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c: use getopt + include enhancements from check_process + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: use getopt + scane multiple OIDs + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c: + add --version and --help + +2000-05-02 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors: + moved to check_sensor.sh + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors.sh: + add basic error checking + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle.sh: + for simpler make + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle: + replace with check_oracle.sh + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in: + fix 'clean' target + +2000-05-01 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + changes to get paths right for scripts + + * /cvsroot/netsaintplug/netsaintplug/plugins/Helper.pm, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_disk.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_dns.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ftp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_hpjd.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_http.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_load.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_ping.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_procs.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_snmp.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_swap.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_users.t, /cvsroot/netsaintplug/netsaintplug/plugins/t/check_vsz.t: + use perl test harness + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + bug fixes + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_log, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_log.sh: + replace check_log with check_log.sh + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle.sh: + to replace check_oracle + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_log.sh: + to replace check_log + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_rpc.pl: + replaces check_nfs and check_ypbind + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/t/check_rpc.t, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Helper.pm, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/subst.in: + use perl test harness + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_breeze.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_flexlm.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_wave.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in: + small mods to get paths reasonable for script files + + * /cvsroot/netsaintplug/netsaintplug/make-tarball: Makes a tar ball + +2000-02-17 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + changes for check_https + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_https.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ide-smart.c, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_sensors: + C contribs unmodified. + Script had to be retyed from scratch - maybe CR/LF problem? + +2000-02-15 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c: + add argv[0] to uasge + include common/config.h + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c: + encapsulate getopt_long stuff in ifdefs + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + fix solaris check_swap bug - change sscanf format from %*d,%*d to %*[0-9,-] + +2000-02-11 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + modify to check uid and ppid for architectures other than linux + +2000-02-09 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/configure.in: + step one to testing user (actually, userid) and ppid in check_procs + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + get DUP check to give warning + + * /cvsroot/netsaintplug/netsaintplug/configure: + should not be handed down - autoconf locally before making tarballs/RPMS + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c: + use foo[SIZE-1]=0 instead =f '\0' for better compatibility + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + change linux ping syntax to scan for DUPs + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c: + check for duplicates + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c: + fix DB_NAMELEN and string comparison tests + get rid of waron about discarding constant string + + * /cvsroot/netsaintplug/netsaintplug/configure.in: + use ps for HPUX that is close to working - still broken on check_vsz/rss + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c: + pass authentication info if either passwd or user is given + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c: + allow user without password for authentication + fix dbname check + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c: + Patch submitted by author to use strncpy + +2000-02-08 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in: + fix problem with test -e for solaris - kludge with 'cat filename' + + * /cvsroot/netsaintplug/netsaintplug/plugins/popen.h, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h: + superceded bu utils.h.in and popen.h.in + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/popen.c, /cvsroot/netsaintplug/netsaintplug/plugins/popen.h.in, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/subst.in: + use configure to check signal return type + use subst.in to fillin command.cfg + +2000-02-05 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in: + fix typo - triple slash in a few URLs + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c: + remove extra comma in terminate subroutine + +2000-02-04 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle: + submission by latigid010@yahoo.com + no scratch file + check db option + more normal switches (kdebisschop) + + * /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in: + compile only base plugins for RPM + fix little glitches in commands.cfg + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl: + better arg checking for perl taint + +2000-02-01 hgayosso <hgayosso@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/check_hprsc.tar.gz: + Perl script (check_hprsc) to check HP-UX resources via SNMP daemon (hgayosso) + + * /cvsroot/netsaintplug/netsaintplug/contrib/readme.txt: + check_hprsc.tar.gz added to the contrib plugins (hgayosso) + +2000-01-28 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_game.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in: + get date include correct + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c: + get date include right + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_game.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/netsaint.h, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + try to get version includes right + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + get revision listsing fixed + + * /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + udpate for release 1.2.8pre1 + + * /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + update spec for 1.2.8-pre1 + have makefile delete command.cfg on make distclean + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_game.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/popen.c, /cvsroot/netsaintplug/netsaintplug/plugins/popen.h, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h: + use print_revision function in utils + use included timeout_handlers throughout [(socket|popen)?alarm_handler] + clean up use of externs in popen.[hc] and utils.[hc] for above + handle percent or KB in check_disk + +2000-01-23 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + snmp: start trying to clarify hex mesages + ups: manually apply submitted patch + utils: bug fix in is_numeric + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle: + minor fixes posted to bugs list: + ircd - fix match string + ntp - return critical if server is down + oracle - make no temp files + +2000-01-22 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + streamline utils functions is_integer and is_numeric + tighten check_ping error prose so it nearly shows on a 80x24 display + +2000-01-21 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h: + fix bug in adapting configure to check_netsaint + fix omission in check_procs arg testing + fix utils sscanf syntax - linux uses EOF where FreeBSD uses 0 + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_process.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_radius.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/saintcheck: + add check_process and check_radius as extras + make check_pgsl understand old syntax as well + modify check_procs to look for specific comman names and test on ranges + modify configure.in tests so check_netsaint can maybe work with more OS's + +2000-01-20 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/saintcheck: + set default timeout to 10 seconds + make tests give fewer warnings + move check_httpstr to check_http + +2000-01-19 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c: + use -q option for who if available + use getopt for check_pgsql + make check_users work even if no users are logged in + clean up (developmental) utils.c + +2000-01-17 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in: + use the -n switch to prevent host lookups in check_ping + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c: + update for FreeBSD: + add new tests for FreeBSD ps syntax + add test for swapinfo command + modify check_users to work without -q option + modify check_vsz test to work without requiring 'init' listing in `ps` output + +2000-01-13 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in: + add HAVE_REGEX_H to configure + + * /cvsroot/netsaintplug/netsaintplug/command.cfg.in: + this should be included by reference in hosts.cfg + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c: + check redirects working + regex content search working + +2000-01-10 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c: + Incorporate netsaint_plugins-1.2.7p1 changes: + - Fixed RH 6.1 ICMP error "bug" in check_ping plugin + (patch by Luiz Felipe R E) + - Fixed uninitialized memory bug in netutils.c (patch by Frank Conrad) + +1999-12-28 holoway <holoway@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + I'm a schmuck. :) Would help if I deleted the line, doncha think? + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + Removed the requirement of netsaint in the rpm build; the plugins may + live on a machine without it. (nrpe or nrpep may use the plugins without + having netsaint proper present) + +1999-12-17 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/contrib/berger-ping.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/bowen-langley_plugins.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_bgp-1.0.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_breeze.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_flexlm.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_hltherm.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_ipxping.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_ircd.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_memory.tgz, /cvsroot/netsaintplug/netsaintplug/contrib/check_nfs.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_ntp.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_real.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/check_wave.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/hopcroft-plugins.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/radius.tar.gz, /cvsroot/netsaintplug/netsaintplug/contrib/readme.txt: + adds files from www.netsaint.org contrib area. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr: + add STATE_DEPENDENT to common/common.h + check_httpstr binary should never have been there in the first place + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c: + made actual http check into subroutine + cleaned up help screen + added option checking for --onredirect + added long-style syntax for all other current options + +1999-12-15 holoway <holoway@skillet.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + Modified the spec file to change the name of the tarball to + netsaint-plugins-version-release.tar.gz + + * /cvsroot/netsaintplug/netsaintplug/netsaint-plugins.spec: + Added the spec file for creating RPMs from the CVS source. + +1999-12-14 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c: + checkpoint - incorporate version info in header + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr: + use version.h for release date tracking + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c: + use sscanf to clean up HTTP error code checking + +1999-12-10 karldebisschop <kdebisschop@alert.infoplease.com> + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_nfs.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_wave.pl: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ircd.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_nfs.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_ntp.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_wave.pl: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_breeze.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_flexlm.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_log, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_breeze.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_disk_smb.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_flexlm.pl, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_log, /cvsroot/netsaintplug/netsaintplug/plugins-scripts/check_oracle: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_httpstr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_real.c, /cvsroot/netsaintplug/netsaintplug/plugins/Makefile.in, /cvsroot/netsaintplug/netsaintplug/plugins/utils.c, /cvsroot/netsaintplug/netsaintplug/plugins/utils.h: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_by_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_netsaint.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_game.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c, /cvsroot/netsaintplug/netsaintplug/plugins/netsaint.h, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/popen.c, /cvsroot/netsaintplug/netsaintplug/plugins/popen.h: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_fping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_game.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ldap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mysql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_reply.c, /cvsroot/netsaintplug/netsaintplug/plugins/netsaint.h, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.c, /cvsroot/netsaintplug/netsaintplug/plugins/netutils.h.in, /cvsroot/netsaintplug/netsaintplug/plugins/popen.c, /cvsroot/netsaintplug/netsaintplug/plugins/popen.h: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_overcr.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_snmp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ssh.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ups.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_swap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_tcp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_time.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_udp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_users.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_vsz.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_pgsql.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ping.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_pop.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_procs.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_smtp.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtgtraf.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nntp.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_nwstat.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_hpjd.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_http.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_imap.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_load.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_mrtg.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/plugins/check_disk.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dns.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_dummy.c, /cvsroot/netsaintplug/netsaintplug/plugins/check_ftp.c: + New file. + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/install-sh, /cvsroot/netsaintplug/netsaintplug/saintcheck: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/configure, /cvsroot/netsaintplug/netsaintplug/configure.in, /cvsroot/netsaintplug/netsaintplug/install-sh, /cvsroot/netsaintplug/netsaintplug/saintcheck: + New file. + + * /cvsroot/netsaintplug/netsaintplug/Changelog, /cvsroot/netsaintplug/netsaintplug/INSTALL, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/README, /cvsroot/netsaintplug/netsaintplug/REQUIREMENTS: + Initial checkin. + Release 1.2.7 plus bugfixes + + * /cvsroot/netsaintplug/netsaintplug/Changelog, /cvsroot/netsaintplug/netsaintplug/INSTALL, /cvsroot/netsaintplug/netsaintplug/Makefile.in, /cvsroot/netsaintplug/netsaintplug/README, /cvsroot/netsaintplug/netsaintplug/REQUIREMENTS: + New file. + +NetSaint Plugins Changelog +-------------------------- + +Current +------- +1.2.9-a6 - 25 August 2000 (alpha code) +-------------------------------------- +* check_disk + (process_arguments) remove stray debugging printf in -p option +* plugins/Makefile.am + (check_netsaint) move to EXTRAS + + +1.2.9-a5 - 23 August 2000 (alpha code) +-------------------------------------- +* check_fping + (main) check rta and packet loss, control packet size and count + (process_arguments) add options for number of packets and size +* check_tcp + (main) alter to run as any of check_(ftp|imaop|pop|smtp|tcp|ucp) +* check_rpc + (main) fix checking against initial error state (start UNKNOWN) +* plugins-scripts/Makefile.am + fix install.dist for utils.pm and utils.sh + +1.2.9-a2 - 12 July 2000 (alpha code) +------------------------------------ +* check_http + (check_http) remove "\r\n" pair causing problems for zope + (print_help) fix documentation +* check_disk + (global) malloc string pointers for most character variables + (print_help) fix documentation + (call_getopt) use comma for pairs of options, reserve colon for ranges + (main) use new ssprintf function to assemble 'command_line' + don't sscanf for mount point +* check_load + (global) malloc string pointers for most character variables + (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_procs + (main) was reporting too many matches due to strncmp +* check_swap + (global) malloc string pointers for most character variables + (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_time + (global) malloc string pointers for most character variables + (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_tcp + (print_help) fix documentation +* check_udp + (global) malloc string pointers for most character variables + (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_users + (global) malloc string pointers for most character variables + (main) use getopt + (process_arguments, print_help, print_usage) new functions +* utils + (strscpy) new -- safe string copy does its own malloc + (strscat) new -- safe string cat does its own malloc + (ssprintf) new -- safe string sprintf does its own malloc + +1.2.9-a1 - 3 July 2000 (alpha code) +----------------------------------- +* check_by_ssh.c (main) allow multiple services for passive checks + (call_getopt) add options needed for passive multichecks +* check_disk.c (main) check all mounted partitions if none specified +* check_fping.c (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_ftp.c (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_ping.c (check_ping) return critical if output comes on STDERR + add another sscanf for FreeBSD +* check_procs.c (print_usage) fix docs +* check_tcp.c (main) use getopt + (process_arguments, print_help, print_usage) new functions +* check_users.c (main) use getopt + (process_arguments, print_help, print_usage) new functions +* utils.h (macros) provide standard usage() macro +* rearrange directory for multiplatform builds +* test scripts added for check_fping and check_tcp + +1.2.8.4 +------- +* check_ping.c (process_arguments): don't malloc - just copy pointer + tweak to get non-POSIX order working + (call_getopt): don't malloc - just copy pointer + +1.2.8.3 - 22 June 2000 +---------------------- +* check_http.c (process_arguments): add -nothml to reverse-compat rewrites + (call_getopt): set display_html false for '-n' +* check_procs.c (print_help): update docs + (print_usage): update docs + (call_getopt): fix long option (was 'program', is 'command') + (main): allow inverted order of max/min for outside ranges + (validate_arguments): some valid, though strange, thresholds were rejected +* check_ssh.c (ssh_connect): fix display of host name for connect fails +* check_ping.c (process_arguments): add -nothml to reverse-compat rewrites + fix malloc error - need to malloc strlen+1 + (call_getopt): fix malloc error - need to malloc strlen+1 +* check_disk.c (main): use new terminate + (print_usage): typo in printout +* utils.h.in (terminate): update prototype for terminate +* utils.c (terminate): allow terminate to accept format,arglist as printf +* check_sensors.sh (print_revision): fix bug in Revision string cleanup +* netsaint-plugins.spec: make relocatable + use macros throughout +* netsaint-plugins-custom.spec: make relocatable + use macros throughout +* make-tarball: create md5sum + do some rpm setup + +1.2.8-2 - 16 June 2000 +---------------------- +* check_ping.c (run_ping): was not warning of DUPLICATES anymore, fixed + (all): switch most fixed length buffers to malloc + (print_usage): fix documentation + (print_help): fix documentation + (call_getopt): make nohtml the default, add -L (--link) option +* check_http.c (check_http): more rigorous header/content separation + alter verbose printout to show header, status, and content divisions + (process_arguments): distinguish server and vhost + (call_getopt): distinguish server and vhost + (print_usage): document new -I option for server IPaddress + (print_help): document new -I option for server IPaddress + (all): reindent, tabify +* plugins-scripts/Makfile.in (install): add $(DESTDIR) +* plugins/Makefile.in (install): add $(DESTDIR) + fix for case where there are no extras + (check_ldap): add NETLIBS and SOCKETLIBS + (check_process): remove (obolete) + (all): reorder $(CC) args so -o <src> comes earlier +* check_process.c (all): move to obsolete directory +* configure (check_process): remove (obolete) +* check_procs.c (all): change variable name for 'stat' to 'statopt' for AIX ?bug? + (print_help): fix typo +* check_dns.c (print_help,print_usage): fix documentation + (all): c-indent and retabify +* subst.in (/bin/mktemp): -q option breaks HPUX +* check_sensors.sh (print_help): new function + (print_usage): new function + (main): add --help, --version, --verbose options + (print_revision): make more GNU compatible +* utils.c (print_revision): print license to be more GNU standard +* utils.h.in: add #defines for STDOPTS +* check_rpc.pl (all): fix a few introductory comments +* check_vsz.c (main): move option processing to new process_arguments function + (all): retabify + use malloc and remove most fixed text string sizes +* check_snmp.c (print_help,print_usage): add items, fix typo +* check_by_ssh.c (parse_arguments): bugfix - increment 'c' in remote command parsing +* check_ldap.c (main): add timeout alarm + +1.2.8 - 9 June 2000 +------------------- +* check_by_ssh.c (parse_arguments): bugfix in remote command parsing + +1.2.8pre7 - 8 June 2000 +----------------------- +- make getopt() calls mostly backwards-compatible with all older + options specifications the do not directly conflict with present + standard. (pre-release 2 was only backwards compatible when compiled + against GNU getopt). +- integrate ssl code from Rene Klootwijk into check_http +- a variety of small bug fixes (mostly cases where I left development + printing code in plugin [KBD]). +- add -v (--verbose) option to check_http tp print out page(s) as they + are read and any redirects are followed (if specified in options). +- malloc variable for page contents in check_http so that entire page + can be scanned for strings or regular expressions. +- add urlize to wrap plugin output in HTML link tags, make no-html the + default for check_http. +- develop RPM specs netsaint-plugins.spec with a controlled list of + files in the package, and netsaint-plugins-custom.spec which will + rebuild differently based on the packages installed on the build + machine. + +1.2.8pre2 - 2 May 2000 +---------------------- +- Modify check_snmp to process multiple OIDs in a request (args not backward + compatible) +- Use getopt in check_by_ssh, check_disk, check_dns, check_ldap, check_pgsql, + check_ping, check_procs, check_snmp +- integrate enhancements from check_process [Rene Klootwijk] into check_procs + (including filter by user, parent PID and process name) +- add check_https plugin contributed by Rene Klootwijk +- add check_ide-smart contributed by Robert Dale +- add backward compatibility on check_ping args +- add Makefile for scripts, process trusted path for portability +- use perl test harness in place of saintcheck hack +- fix all plugins calling spopen to also open stderr +- add check_rpc script to replace check_nfs and check_ypbind +- replace check_oracle script with enhanced version by litigid010@yahoo.com +- modularize ping checking loop in check_ping to later allow adaptive loop + count within the plugin +- modify check_disk to accept either paths that are not partition mount points +- modify several plugins to print version number in response to --version opt +- begin distinction between --help (may be many screens) and --usage (1 to 10 + lines only) +- maintain commands.cfg file with syntactically correct command definitions + +1.2.7 - 11/09/1999 +------------------ +- Added check_ntp plugin script contributed by Bo Kersey +- Added check_real plugin contributed by Pedro Leite +- Added check_netsaint plugin +- Added delimiter option to check_snmp plugin +- Added STR and SUBSTR evaluation options to check_snmp plugin +- Fixed bug in check_hpjd where it would erroneously report timeout errors +- Added option to suppress HTML link in check_http and check_ping plugins +- Modified check_http plugin to send carriage returns in http request +- Modified configure script and check_ping plugin to work under FreeBSD +- Changed command line format for check_ping plugin!! + + +1.2.6 - 10/16/1999 +------------------ +- Several plugin bugfixes by Karl DeBisschop +- Added 'saintcheck' script contributed by Karl DeBisschop that can be used + to test various plugins before they are used +- Added check_nfs and check_flexlm plugin scripts contributed by + Ernst-Dieter Martin +- Added check_breeze and check_wave plugin scripts contributed by Jeffrey Blank +- Added check_ircd plugin script contributed by Richard Mayhew + + +1.2.5 - 09/19/1999 +------------------ +- Fixed bug with expect argument (-e) in check_http plugin +- Added additional ping command format to configure script (<srvr> -n <pkts>) +- Switched several plugins to safer version of popen() contributed by Karl + DeBisschop +- Added basic authentication ability to check_http plugin as contributed by + Perry Clarke +- Changed check_imap expect string to "* OK" (repoted by Matt Shibla) and + default port to 143 (reported by Darin Fisher) +- Added check_reply plugin contributed by Jacob Jundqvist + + +1.2.4 - 08/26/1999 +------------------ +- Added check_ldap and check_mysql plugins contributed by Dietmar Rieder +- Added check_game plugin contributed by Ian Cass +- Modified configure script to work with ping command under OpenBSD + + +1.2.3 - 08/18/1999 +------------------ +- Modified most plugins to use common network utilities and include files +- Plugins no longer create temp files (expect the check_log plugin script) + + +1.2.2 - 08/15/1999 +------------------ +- Modified plugins to create temp files in var/ subdirectory of installation +- Added Michael Anton's check_disk_smb.pl plugin + + +1.2.1 - 08/01/1999 +------------------ +- Added $(SOCKETLIBS) to Makefile for Over-CR plugin +- Added quotes around query in check_log plugin to allow for multiple word + queries +- Added a check for no supported options in the check_ups plugin + + +1.2.0 - 07/30/1999 +------------------ +- Added new check_log plugin script +- Added timeout alarm to the check_ssh plugin +- Added "not equal" evaluation method to check_snmp plugin +- Added new check_ups plugin (only tested on APC SmartUPS 2200) + + +1.1.0 - 07/23/1999 +------------------ +- Added new check_ssh plugin contributed by Remi Paulmier +- Added new check_overcr and check_snmp plugins +- Fixed the help screen on the check_nwstat plugin to correctly reflect the + meanings of the warn_value and crit_value variables. +- Fixed some problems with the check_load plugin to make it compile under + NetBSD +- Minor tweaks to various plugins + + +1.0.0 - 07/13/1999 +------------------ +- Initial release of plugins as a separate distribution + + + + @@ -0,0 +1,81 @@ +Frequently Asked Questions +************************** + +1. Q: Where can I find documentation for <insert name> plugin? + + A: All plugins that comply with minimal development guideline for + this project include internal documentation. The documentation + can be read executing plugin with the '-h' option ('--help' if + long options are enabled). If the '-h' option does not work, that + is a bug. + +2. Q: What version of <insert name> plugin am I running? + + A: All plugins that comply with minimal development guideline for + this project include detailed version information. When executed + with the '-V' option, a version string will be printed: + + check_radius (nagios-plugins 1.3.0-alpha1) 1.11 + + Note that this string include both the assigned package release + name and the CVS-generated revision for the individual plugin. + Authors hould strictly adhere to this format. All bug reports + and help requests should reference this information. + +3. Q: What information do I need to include when asking for help or + submitting a bug report? + + A: At a minimum, the output from 'uname -a' and the version string + from '<plugin_name> -V' and, of course, a description of the + problem and any solution/patch. + +4. Q: I'm using Redhat Linux (or some other RPM-based distribution). + Which packages should I install? + + A: The package nagios-plugins-<version>.<arch>.rpm contains only + those plugins that should work on any POSIX compliant system. In + other words, you should be able to install this package on your + system, no matter what else is or in not installed. + + However, most of us have more complex systems than barebones + POSIX. We tried creating a variety of separate packages so + each dependency could be installed cleanly, but many people + found that this resulted in too many packages. So in the end, + all the non-POSIX plugins were folded into one RPM + (nagios-plugins-<version>.<arch>.rpm). Most people will need to + use RPM's '--nodeps' option to install this package. + +5. Q: My sysem uses the .deb package format. What pacakges should I + install? + + A: We strive for cooperation between all packagers and developers. + The answers for .deb are the same as for RPM, afetr changing the + package name suffixes accordingly. + +6. Q: I prefer to build my own RPMs. Do I need to install all of the + various dependencies? + + A: Beginning with the 1.2.9-1 release, you may run + + rpm --define 'custom 1' -ta nagios-plugins-<release>.tar.gz + + In prior releases, you must unpack the tarball and build the + RPM using nagios-custom.spec with 'rpm -ba'. + +7. Q: I get an error like + + Warning: Return code of 127 for check of service 'PING' on host 'anyhost' was out of bounds. + + when I run Nagios. (Often check_ping runs just fine on the + command line). + + A: Commonly, system adminitartors will make security as tight as + possible on the monitoring system. Sometimes this includes OS + options or hardening scripts that prevent unpriveleged users from + running the ping command. Nagios runs with no more priveleges + than 'nobody' -- check to be sure that the nagios user can + actually run check ping. (This can also happen with other binaries + executed by nagios, but ping seems to be far and away the biggest + offender.) + + diff --git a/Helper.pm b/Helper.pm new file mode 100644 index 00000000..198a6480 --- /dev/null +++ b/Helper.pm @@ -0,0 +1,44 @@ +package Helper; +use strict; + +use Exporter(); +use vars qw($VERSION @ISA @EXPORT); +$VERSION = 0.01; +@ISA=qw(Exporter); +@EXPORT=qw(&get_option); + +sub get_option ($$) { + my $file = 'Cache'; + my $response; + my $var = shift; + + require "$file.pm"; + if(defined($Cache::{$var})){ + $response=$Cache::{$var}; + return $$response; + } + + my $request = shift; + my $filename; + my $path; + foreach $path (@INC) { + $filename="$path/$file.pm"; + last if (-e $filename); + } + print STDERR "Enter $request\n"; + $response=<STDIN>; + chop($response); + open(CACHE,"<$filename") or die "Cannot open cache for reading"; + undef $/; + my $cache = <CACHE>; + $/="\n"; + close CACHE; + $cache =~ s/^(\@EXPORT\s*=\s*qw\(\s*[^\)]*)\)\s*;/$1 $var\)\;/msg; + $cache =~ s/^1;[\n\s]*\Z/\$$var=\"$response\"\;\n1\;\n/msg; + open(CACHE,">$filename") or die "Cannot open cache for writing"; + print CACHE $cache; + close CACHE; + return $response; +} + +1; diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..c918a128 --- /dev/null +++ b/INSTALL @@ -0,0 +1,49 @@ +Nagios Plugins Quick-and-Dirty Installation Instructions +-------------------------------------------------------- + +0) If using the CVS tree, you need m4, automake, and autoconf. To + start out, run: + + # autoconf + # autoheader + # automake + + +1) Run the configure script to initialize variables and create a Makefile, etc. + + ./configure --prefix=BASEDIRECTORY --with-nagios-user=SOMEUSER --with-nagios-group=SOMEGROUP --with-cgiurl=SOMEURL + + a) Replace BASEDIRECTORY with the path of the directory under which Nagios + is installed (default is '/usr/local/nagios') + b) Replace SOMEUSER with the name of a user on your system that will be + assigned permissions to the installed plugins (default is 'nagios') + c) Replace SOMEGRP with the name of a group on your system that will be + assigned permissions to the installed plugins (default is 'nagios') + d) Replace CGIURL with the path used to access the Nagios CGIs with + a web browser (default is '/cgi-bin/nagios') + + +2) Compile the plugins with the following command: + + make all + + +3) Install the compiled plugins and plugin scripts with the following command: + + make install + + NOTE: + The installation procedure will attempt to place the plugins in a + 'libexec/' subdirectory in the base directory you specified with + the --prefix argument to the configure script. + + +4) Verify that your host configuration file (hosts.cfg) for Nagios contains + the correct paths to the new plugins. + + + +That's it. If you have any problems or questions, feel free send mail +to nagios-users@lists.sourceforge.net + + @@ -0,0 +1,10 @@ + +All source code, binaries, documentation, and information 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 of Ethan Galstad. All +other trademarks, servicemarks, registered trademarks, and +registered servicemarks are the property of their respective owner(s). + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..d1c7a683 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,9 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = plugins plugins-scripts + +EXTRA_DIST = REQUIREMENTS acconfig.h package.def subst.in subst.sh Helper.pm nagios-plugins.spec contrib + +test: + cd plugins; $(MAKE) test + cd plugins-scripts; $(MAKE) test @@ -0,0 +1,2 @@ +New in 1.2.9: +* Added support for multiplatform builds @@ -0,0 +1,42 @@ +Nagios Plugins README +--------------------- + +* For instructions on installing these plugins for use with Nagios, read + the INSTALL file. + +* For information on what chages have been made or plugin have been added, + read the Changelog file. + +* Some plugins require that you have additional programs and/or + libraries installed on your system before they can be used. Plugins + that are dependent on other programs/libraries that are missing are + usually not compiled. Read the REQUIREMENTS file for more information. + +* Individual plugins are self documenting. All plugins that comply with + the basic guidleines for development will provide detailed help when + invoked with the '-h' option ('--help' also, if long options are enabled). + +* The file command.cfg contains xample configurations for many of the + plugins + +You can check for the latest plugins at: + ftp://download.sourceforge.net/pub/sourceforge/nagiosplug + http://sourceforge.net/projects/nagiosplug/ + +Send mail to nagiosplug-help@lists.sourceforge.net for assistance. Please +include the OS type and version that you are using. Also, run the plugin with +the '-v' option and provide the resulting version information. Of course, +there may be additional diagnostic information required as well. Use good +judgement. + +Send mail to nagiosplug-devel@lists.sourceforge.net for developer discussions. + +For patch submissions and bug reports, please use the appropriate resources at +http://sourceforge.net/projects/nagiosplug/ (navigate to the bug tool and/or +patch tool from the summary page). Patches should be relative to the current +CVS head (development), or to the head of the current stable branch. Also, +please include version information for your OS and the plugin(s) your are +patching/reporting. + +-- +Karl DeBisschop (kdebisschop@users.sourceforge.net) diff --git a/REQUIREMENTS b/REQUIREMENTS new file mode 100644 index 00000000..fe3403ec --- /dev/null +++ b/REQUIREMENTS @@ -0,0 +1,52 @@ +Nagios Plugin Requirements +-------------------------- + +Some plugins require that you have additional programs and/or +libraries installed on your system before they can be used. Plugins +that are dependent on other programs/libraries that are missing are +usually not compiled. Requirements for various plugins are listed +below... + +check_fping: + - Requires the fping utility distributed with SATAN. Either + download and install SATAN or grab the fping program from + http://www.stanford.edu/~schemers/docs/fping/fping.html + ftp://ftp.redhat.com/pub/contrib/libc6/SRPMS/fping-2.2b1-1.src.rpm + ftp://ftp.redhat.com/pub/contrib/libc6/RPMS/fping-2.2b1-1.i386.rpm + Note that the fping command must be setuid root to function. + +check_game: + - Requires the qstat utility available from + http://www.activesw.com/people/steve/qstat.html + Last tested on qstat 2.3d BETA + +check_hpjd: + - Requires the UCD-SNMP package available from + http://ucd-snmp.ucdavis.edu + The snmpget binary is all that is required. + +check_ldap: + - Requires the LDAP libraries available from + http://www.openldap.org + Lib: libldap, liblber + Redhat Source: openldap-1.2.9-6.i386.rpm, openldap-devel-1.2.9-6.i386.rpm + +check_mysql: + - Requires the MySQL libraries available from + http://www.mysql.org + Lib: libmysql, libmysqlclient + Redhat Powertools Source: mysql-3.20.32a-3.i386.rpm, mysql-devel-3.20.32a-3.i386.rpm (these seem to be broken, however) + RPMS from www.mysql.org work better + +check_pqsql: + - Requires the PostgreSQL libraries available from + http://www.postgresql.org + +check_radius: + - Requires the radiusclient library available from + http://www.cityline.net/~lf/radius/ + RPM (rpmfind): radiusclient-0.3.1-1, radiusclient-devel-0.3.1-1 + +check_snmp: + - Requires the UCD-SNMP package available from + http://ucd-snmp.ucdavis.edu diff --git a/ROADMAP b/ROADMAP new file mode 100644 index 00000000..10fcd12c --- /dev/null +++ b/ROADMAP @@ -0,0 +1,117 @@ + +Releases in the 1.3 series will be for development. Version 1.4.0 will +be the next full production release. I am not planning on dates right now, +but you can expect maintennence releases for 1.2.9 as well. + +With that done, it's time to figure out what we are doing for release +1.3 development. I have a few ideas. Maybe others do as well. + +DOCUMENTATION: + We pretty much have decieded that we will doing something along + the lines of a literate programming model. So far, we have site + documentation in DocBook. I have some ideas here, which I will + discuss in a separate thread. + + + +OPTION PROCESSING: + I believe we can remove reverse compatibility for non-Getopt + option specifications. For example, 'check_ping 1 2 3 4 -p 2' + would not be supported anymore. Support for this is a hack, + and making it portable is bug-prone. We should also review + standardization of our options -- the current list is a little + ad hoc, it should be nailed down. Details in a separate thread. + +Also, + + check_http -p 443 --ssl www.infoplease.com + +should be fine, but if the getopt in use does not natively support it, +things like + + check_http www.infoplease.com -p 443 --ssl + +should be trapped and result in a call to one of the usage macros +(which print a message and then exit STATE_UNKNOWN). + +This means that the call_getopt() function can go away. It's an +inconsistent mess and I'd love to ditch it. I only created it to +satisfy people that wanted reverse compatibility and did not have +GNU getopt. + +Bu I would like to urge that all standard plugins contain +validate_arguments(). I think this will help convey the idea that +validations hould be done, even if we don't insist on the specific +extent that each plugin must do that validation. + +This is the set of standard options I envision: + +Reserved: + +-h, --help (REQUIRED!!!!!) +-V, --version (REQUIRED!!!!!) +-v, --verbose +-q, --quiet +-t, --timeout = INTEGER (senonds) +-c, --critical = (INT|FLOAT|RANGE|LIST) +-w, --warning = (INT|FLOAT|RANGE|LIST) +-H, --hostname = STRING +-F, --file = STRING (usually input) +-O, --output = STRING (output file) + +Recommended, but not reserverd: + +-I, --ipaddress = STRING +-C, --community = STRING +-a, --auth(info) = STRING (authentication or password) +-l, --logname = STRING +-p, --password = STRING +-P, --port = INT +-u, --url = STRING (also --username if --url is not needed) + +I am suggesting that port alway be '-P' (uppercase) -- we are +currently inconsistent in that regard. + +I am also adding '-q' for silent running. This is totally self +centered--I am planning to use a plugin in a cron script, and I +don't want nightly emails. + +As has been the case, ranges are specified with colons, like 'i:j' +and list are specified with commas like 'i,k' and may contain ranges +if it makes sense to do so. Perhaps it would be good to build a +standard list/range processing function for this task. + + +Programming: + I would like to follow the GNU guidelines and remove all fixed + length character assignments, at least to the extent possible, + from the C-based plugins. To that end, I have made strscpy and + friends in utils.c -- I'd like to deploy them. I have comments + that there is alot of duplicated code, and techniques used that + should be cleaned up. Details in a separate thread. + +Remote checks: + I have a proposal in hand to incorporate ssh check into spopen() + so that remote machine checks can be seemless. A nice idea, but + complex enough to require discussion. Another thread. + +I also have a wish list, and I'm sure I've forgot some items. I'll +list mine, please respond with other items that can be put into the +sourceforge task manager: + + Indent all code in a GNU-compatible manner (indent -ts 2 -br) + Add RAND_seed to check_http for --ssl on systems without /dev/random + Add regex filtering to check_procs --args option + Add working procs syntax for AIX check_procs + Allow check_disk to exclude non-local disks + Add md5 checksumming to check_http + Complete unification of check_tcp and friends + Add SSL in a general way to check_tcp and friends + Patches to check_log from Joonas + Add calculator engine and snmpwalk to check_snmp + Is there a bug in check_oracle + Are there outstanding bugs in check_snmp + Change check_http --onredirect to default as STATE_UNKNOWN + Create plugin to check tftp servers + Create plugin wrapper to invert error status + diff --git a/Requirements b/Requirements new file mode 100644 index 00000000..79e9990b --- /dev/null +++ b/Requirements @@ -0,0 +1,11 @@ +This file is NOT authoritative. It is simply a guide to users who need to locate a given dependency + + + +check_ldap + Lib: libldap, liblber + Redhat Source: openldap-1.2.9-6.i386.rpm, openldap-devel-1.2.9-6.i386.rpm + +check_mysql + Lib: libmysql, libmysqlclient + Redhat Powertools Source: mysql-3.20.32a-3.i386.rpm, mysql-devel-3.20.32a-3.i386.rpm diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 00000000..c9786c19 --- /dev/null +++ b/acconfig.h @@ -0,0 +1,37 @@ +#undef CGIURL +#undef DF_COMMAND +#undef HAVE_GETOPT_H +#undef HAVE_GETOPT_LONG +#undef HAVE_PROC_LOADAVG +#undef HAVE_PROC_MEMINFO +#undef HAVE_SSL +#undef HAVE_SWAP +#undef NSLOOKUP_COMMAND +#undef PACKAGE_VERSION +#undef PATH_TO_DIG +#undef PATH_TO_FPING +#undef PATH_TO_QSTAT +#undef PATH_TO_SNMPGET +#undef PATH_TO_SNMPGETNEXT +#undef PATH_TO_UPTIME +#undef PING_COMMAND +#undef PING_PACKETS_FIRST +#undef POSIX_STATE_DEFS +#undef PROC_LOADAVG +#undef PROC_MEMINFO +#undef PS_COMMAND +#undef PS_FORMAT +#undef PS_RAW_COMMAND +#undef PS_VARLIST +#undef RSS_COMMAND +#undef RSS_FORMAT +#undef SOCKET_SIZE_TYPE +#undef SSH_COMMAND +#undef SWAP_COMMAND +#undef SWAP_FORMAT +#undef USE_PS_VARS +#undef VSZ_COMMAND +#undef VSZ_FORMAT +#undef WHO_COMMAND +#undef PACKAGE +#undef VERSION diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 00000000..b75859d5 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,35 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<<am_indx=1 +for am_file in <<$1>>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + diff --git a/command.cfg.in b/command.cfg.in new file mode 100644 index 00000000..4ccb26c7 --- /dev/null +++ b/command.cfg.in @@ -0,0 +1,184 @@ +############################################################################### +# COMMAND CONFIGURATION +# +# $Id$ +# +# SYNTAX: +# command[<command_name>]=<command_line> +# +# <command_name> = A short name used to identify the command +# <command_line> = The actual command line. The command line doesn't have to +# be surrounded in quotes, but may contain quotes as needed within +# the command line. Take care to use single quotes at the +# outer edges of commands or you will have command line +# expansion problems when the command is executed by the shell. +# Any valid shell command can be used. Multiple commands can +# be separated with semicolons, piping is allowed. The +# command line can contain macros, but not are macros are valid +# at all time (notifications, service checks, etc). See the +# HTML documentaion for more informationon on using macros in +# commands. +# +# Note: Service check, service notification, host check, host notification, +# service event handler, and host event handler functions are all defined +# here. +############################################################################### + +# Service notification command - send email with problem summary + +command[notify-by-email]=/bin/printf "$OUTPUT$" | /bin/mail -s '$SERVICESTATE$ alert for $HOSTALIAS$/$SERVICEDESC$' $CONTACTEMAIL$ + +# Service notification command - send email to alphanumeric pager +# gateway The notify-by-epager command assumes that each contact has a +# pager email gateway, and that the address has been entered into the +# appropriate contact field instead of an actual pager number. +# (i.e. 'pagejoe@nowhere.com' routes mail to Joe's alphanumeric pager) + +command[notify-by-epager]=/bin/echo "$OUTPUT$" | /bin/mail -s '$HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$' $CONTACTPAGER$ + +# Host notification commands (one for email, one for alphanumeric +# pager with email gateway) + +command[host-notify-by-email]=/bin/echo -e "***** Nagios *****\n\nHost "$HOSTALIAS$" is $HOSTSTATE$!\n\nDate/Time: $DATETIME$\n" | /bin/mail -s 'Host $HOSTNAME$ is $HOSTSTATE$!' $CONTACTEMAIL$ + +command[host-notify-by-epager]=/bin/echo '$HOSTALIAS$ is $HOSTSTATE$!' | /bin/mail -s 'Host $HOSTNAME$ is $HOSTSTATE$!' $CONTACTPAGER$ + +# These are some example service check commands. See the HTML +# documentation on the plugins for examples of how to configure +# command definitions. + +command[check_tcp]=@libexecdir@/check_tcp -H $HOSTADDRESS$ -p $ARG1$ +command[check_udp]=@libexecdir@/check_udp -H $HOSTADDRESS$ -p $ARG1$ +command[check_ftp]=@libexecdir@/check_ftp -H $HOSTADDRESS$ +command[check_pop]=@libexecdir@/check_pop $HOSTADDRESS$ +command[check_smtp]=@libexecdir@/check_smtp $HOSTADDRESS$ +command[check_nntp]=@libexecdir@/check_nntp $HOSTADDRESS$ +command[check_telnet]=@libexecdir@/check_tcp -H $HOSTADDRESS$ -p 23 +command[check_users]=@libexecdir@/check_users $ARG1$ $ARG2$ +command[check_hpjd]=@libexecdir@/check_hpjd $HOSTADDRESS$ public +command[check_mrtg]=@libexecdir@/check_mrtg $ARG1$ 10 AVG $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ +command[traffic_average]=@libexecdir@/check_mrtgtraf $ARG1$ 10 AVG $ARG2$ $ARG3$ $ARG4$ $ARG5$ +command[check_load]=@libexecdir@/check_load $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ + +command[check_disk]=@libexecdir@/check_disk -w 85% -c 95% -p $ARG1$ +command[check_dns]=@libexecdir@/check_dns -H www.yahoo.com -s $HOSTADDRESS$ +command[check_http]=@libexecdir@/check_http -H $HOSTADDRESS$ -I $HOSTADDRESS$ +command[check_http2]=@libexecdir@/check_http -H $ARG1$ -I $HOSTADDRESS$ -w $ARG2$ -c $ARG3$ +command[check_pgsql]=@libexecdir@/check_pgsql -H $HOSTADDRESS$ +command[check_ping]=@libexecdir@/check_ping -H $HOSTADDRESS$ -w 10:20% -c 60:100% +command[check_procs]=@libexecdir@/check_procs -w $ARG1$ -c $ARG2$ +command[check_procs_zombie]=@libexecdir@/check_procs -w $ARG1$ -c $ARG2$ -s Z +command[check_procs_httpd]=@libexecdir@/check_procs -w 5:$ARG1$ -c 1:$ARG2$ -C httpd +command[check_vsz]=@libexecdir@/check_vsz -w 8096 -c 16182 -C httpd + +# An example of using check_by_ssh as an active service check +command[ssh_disk]=@libexecdir@/check_by_ssh -H $HOSTADDRESS$ -C '@libexecdir@/check_disk -w 85% -c 95% -p $ARG1$' + +# +# UCD_SNMP equivalents for some of the commands above +# + +command[snmp_load]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.2021.10.1.5.1,.1.3.6.1.4.1.2021.10.1.5.2,.1.3.6.1.4.1.2021.10.1.5.3 -w :$ARG2$,:$ARG3$,:$ARG4$ -w :$ARG5$,:$ARG6$,:$ARG7$ -l load + +command[snmp_cpustats]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.2021.11.9.0,.1.3.6.1.4.1.2021.11.10.0,.1.3.6.1.4.1.2021.11.11.0 -l 'CPU usage (user system idle)' -u '%' + +command[snmp_procname]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o 1.3.6.1.4.1.2021.2.1.5.$ARG2$ -w $ARG3$:$ARG4$ -c $ARG5$:$ARG6$ + +command[snmp_disk]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o 1.3.6.1.4.1.2021.9.1.7.$ARG1$,1.3.6.1.4.1.2021.9.1.9.$ARG1$ -w $ARG2$:,:$ARG3$ -c $ARG4$:,:$ARG5$ -u 'kB free (','% used)' -l 'disk space' + +command[snmp_mem]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.2021.4.6.0,.1.3.6.1.4.1.2021.4.5.0 -w $ARG2$: -c $ARG3$: + +command[snmp_swap]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o .1.3.6.1.4.1.2021.4.4.0,.1.3.6.1.4.1.2021.4.3.0 -w $ARG2$: -c $ARG3$: + +# +# Slightly more generic SNMP OIDs +# + +command[snmp_procs]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrSystem.hrSystemProcesses -w :$ARG2$ -c :$ARG3$ -l processes + +command[snmp_users]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrSystem.hrSystemNumUsers -w :$ARG2$ -c :$ARG3$ -l users + +command[snmp_mem2]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageUsed.101,host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageSize.101 -w $ARG2$ -c $ARG3$ + +command[snmp_swap2]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageUsed.102,host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageSize.102 -w $ARG2$ -c $ARG3$ + +command[snmp_mem]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageUsed.101,host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageSize.101 -w $ARG2$ -c $ARG3$ + +command[snmp_swap]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageUsed.102,host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageSize.102 -w $ARG2$ -c $ARG3$ + +command[snmp_disk2]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o host.hrStorage.hrStorageTable.hrStorageEntry.hrStorageUsed.$ARG2$ -w $ARG3$ -c $ARG4$ + +command[snmp_tcpopen]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o tcp.tcpCurrEstab.0 -w $ARG2$ -c $ARG3$ + +command[snmp_tcpstats]=@libexecdir@/check_snmp -H $HOSTADDRESS$ -C $ARG1$ -o tcp.tcpActiveOpens.0,tcp.tcpPassiveOpens.0,tcp.tcpInSegs.0,tcp.tcpOutSegs.0,tcp.tcpRetransSegs.0 -l 'TCP stats' + +# This command checks to see if a host is "alive" by pinging it. The +# check must result in a 100% packet loss or 5 second (5000ms) round +# trip average to produce an error. + +# This command checks to see if a host is "alive" by pinging it. +command[check-host-alive]=@libexecdir@/check_ping -H $HOSTADDRESS$ -w 5000,100% -c 5000,100% -p 1 + +# This command checks to see if a printer is "alive" by pinging it. +command[check-printer-alive]=@libexecdir@/check_ping -H $HOSTADDRESS$ -w 5000,100% -c 5000,100% -p 1 + +# This command checks to see if a switch is "alive" by pinging it. +command[check-switch-alive]=@libexecdir@/check_ping $HOSTADDRESS$ -w 5000,100% -c 5000,100% -p 1 + +# This command checks to see if a router is "alive" by pinging it. +command[check-router-alive]=@libexecdir@/check_ping -H $HOSTADDRESS$ -w 5000,100% -c 5000,100% -p 1 + +# Check if a host is alive by doing a fast ping instead of a regular ping +command[check-fast-alive]=@libexecdir@/check_fping -H $HOSTADDRESS$ + +# Check if the IMAP service is alive (default port=143) +command[check-imap]=@libexecdir@/check_imap $HOSTADDRESS$ + +# Check RPC services +command[check-rpc]=@libexecdir@/check_rpc -H $HOSTADDRESS$ $ARG1$ + +# Check if the NFS server is running +command[check-nfs]=@libexecdir@/check_rpc -H $HOSTADDRESS$ nfs + +# Check game servers +command[check_quake]=@libexecdir@/check_game qs $HOSTADDRESS$ +command[check_unreal]=@libexecdir@/check_game uns $HOSTADDRESS$ -p $ARG1$ -pf 8 + +# Check a port that should be open +command[check_nmap]=@libexecdir@/check_nmap -H $HOSTADDRESS$ -t 30 -p $ARG1$ + +# Check a port that should be open and another that *could* be open, +# but no warning is given if optional port is closed. + +command[check_nmap_optional]=@libexecdir@/check_nmap -H $HOSTADDRESS$ -t 60 -p $ARG1$ -o $ARG2$ + +# Specify range to nmap +command[check_nmap_range]=@libexecdir@/check_nmap -H $HOSTADDRESS$ -t 60 -p $ARG1$ -r $ARG2$ + +# Specify both optional and range +command[check_nmap_opt_range]=@libexecdir@/check_nmap -H $HOSTADDRESS$ -t 60 -p $ARG1$ -o $ARG2$ -r$ARG3$ + +# Check Radius +command[check_radius]=@libexecdir@/check_radius $ARG1$ $ARG2$ $HOSTADDRESS$ 1812 $ARG3$ + + +# Check Reply +# This is a command for checking squid proxy servers which uses check +# reply to ensure an HTTP 200 comes back ..... i.e. squid actually +# serves the page and not an error message. + +command[check_squid]=@libexecdir@/check_reply $HOSTADDRESS$ -p $ARG1$ -s 'GET $ARG2$ HTTP/1.0\n\n' -e 'HTTP/1.0 200 OK' + + +## Check RealAudio url +command[check_real_url]=@libexecdir@/check_real $HOSTADDRESS$ -p $ARG1$ -wt $ARG2$ -ct $ARG3$ -to 5 -u $ARG4$ + +## Check RealAudio server response +command[check_real]=@libexecdir@/check_real $HOSTADDRESS$ -p $ARG1$ -wt $ARG2$ -ct $ARG3$ -to 5 + + +# Still have to write sample entries for the following: +# +# check_ldap +# check_nwstat +# check_overcr diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..b2df7830 --- /dev/null +++ b/configure.in @@ -0,0 +1,748 @@ +dnl Process this file with autoconf to produce a configure script. +include(`aclocal.m4') +AC_REVISION ($Revision$) +AC_INIT(package.def) +VERSION=`cat $srcdir/package.def|sed -e 's/PACKAGE_RELEASE= *"//;s/"//'` +PACKAGE=nagios-plugins +dnl AM_INIT_AUTOMAKE(nagios-plugins,$VERSION) +AM_CONFIG_HEADER(plugins/config.h plugins/common.h plugins/version.h plugins/netutils.h plugins/utils.h plugins/popen.h) + +AC_PREFIX_DEFAULT(/usr/local/nagios) + +dnl Figure out how to invoke "install" and what install options to use. + +AC_PROG_INSTALL +AC_SUBST(INSTALL) + +AC_PROG_RANLIB + +AC_PATH_PROG(ACLOCAL,aclocal) +AC_PATH_PROG(AUTOMAKE,automake) +AC_PATH_PROG(AUTOCONF,autoconf) +AC_PATH_PROG(AUTOHEADER,autoheader) + +PLUGIN_TEST=`echo $srcdir/plugins/t/*.t|sed -e 's,\.*/plugins/,,g'` +AC_SUBST(PLUGIN_TEST)dnl + +SCRIPT_TEST=`echo $srcdir/plugins-scripts/t/*.t|sed -e 's,\.*/plugins-scripts/,,g'` +AC_SUBST(SCRIPT_TEST)dnl + +WARRANTY="The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\ncopies of the plugins under the terms of the GNU General Public License.\nFor more information about these matters, see the file named COPYING.\n" +AC_SUBST(WARRANTY) + +SUPPORT="Send email to nagios-users@lists.sourceforge.net if you have questions\nregarding use of this software. To submit patches or suggest improvements,\nsend email to nagiosplug-devel@lists.sourceforge.net\n" +AC_SUBST(SUPPORT) + +AC_ARG_PROGRAM + +dnl AC_ARG_WITH(nonposix_state_defs,--with-nonposix-state-defs uses POSIXLY incorrect states for netsaint < 0.0.7b2,,AC_DEFINE(POSIX_STATE_DEFS)) + +AC_ARG_WITH(cgiurl,--with-cgiurl=<dir> sets URL for cgi programs,cgiurl=$withval,cgiurl=/cgi-bin/nagios) +CGIURL="$cgiurl" +AC_DEFINE_UNQUOTED(CGIURL,"$CGIURL") + +AC_ARG_WITH(nagios_user,--with-nagios-user=<user> sets user name to run nagios,nagios_usr=$withval,nagios_usr=nagios) +AC_ARG_WITH(nagios_group,--with-nagios-group=<group> sets group name to run nagios,nagios_grp=$withval,nagios_grp=nagios) +AC_SUBST(nagios_usr) +AC_SUBST(nagios_grp) +INSTALL_OPTS="-o $nagios_usr -g $nagios_grp" +AC_SUBST(INSTALL_OPTS) + +AC_ARG_WITH(trusted_path,--with-trusted-path=/bin:/sbin:/usr/bin:/usr/sbin sets trusted path for executables called by scripts,trusted_path=$withval,trusted_path=/bin:/sbin:/usr/bin:/usr/sbin) +AC_SUBST(trusted_path) + +EXTRAS= +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/etc:/usr/local/bin:/usr/local/sbin:$PATH + +LDFLAGS="$LDFLAGS -L." + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PROG_AWK + +AC_PATH_PROG(PYTHON,python) +AC_PATH_PROG(PERL,perl) +AC_PATH_PROG(SH,sh) + +AC_PATH_PROG(HOSTNAME,hostname) +AC_PATH_PROG(BASENAME,basename) + + +dnl +dnl Checks for libraries. +dnl + +AC_FUNC_GETLOADAVG + +AC_CHECK_LIB(dce,main,SOCKETLIBS="$SOCKETLIBS -ldce") +AC_CHECK_LIB(nsl,main,SOCKETLIBS="$SOCKETLIBS -lnsl") +AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket") +AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv") +AC_SUBST(SOCKETLIBS) + +dnl Check for PostgreSQL libraries +_SAVEDLIBS="$LIBS" +_SAVEDCPPFLAGS="$CPPFLAGS" +AC_ARG_WITH(pgsql,--with-pgsql=<dir> sets path to pgsql installation,[PGSQL=$withval]) +AC_CHECK_LIB(crypt,main) +if test "$ac_cv_lib_crypt_main" = "yes"; then + if test -n "$PGSQL"; then + LIBS="$LIBS -L$PGSQL/lib" + CPPFLAGS="$CPPFLAGS -I$PGSQL/include" + fi + AC_CHECK_LIB(pq,PQsetdbLogin,,,-lcrypt) + if test "$ac_cv_lib_pq_PQsetdbLogin" = "yes"; then + AC_CHECK_HEADERS(pgsql/libpq-fe.h) + AC_CHECK_HEADERS(postgresql/libpq-fe.h) + AC_CHECK_HEADERS(libpq-fe.h) + if test "$ac_cv_header_pgsql_libpq_fe_h" = "yes"; then + PGLIBS="-lpq -lcrypt" + PGINCLUDE="-I/usr/include/pgsql" + elif test "$ac_cv_header_postgresql_libpq_fe_h" = "yes"; then + PGLIBS="-L$PGSQL/lib -lpq -lcrypt" + PGINCLUDE="-I/usr/include/postgresql" + elif test "$ac_cv_header_libpq_fe_h" = "yes"; then + PGLIBS="-L$PGSQL/lib -lpq -lcrypt" + PGINCLUDE="-I$PGSQL/include" + fi + if test -z "$PGINCLUDE"; then + AC_MSG_WARN([Skipping PostgreSQL plugin (check_pgsql)]) + AC_MSG_WARN([install PostgreSQL headers to compile this plugin (see Requirements).]) + else + AC_SUBST(PGLIBS) + AC_SUBST(PGINCLUDE) + EXTRAS="$EXTRAS check_pgsql" + fi + else + AC_MSG_WARN([Skipping PostgreSQL plugin (check_pgsql)]) + AC_MSG_WARN([LIBS="$LIBS" CPPFLAGS="$CPPFLAGS"]) + AC_MSG_WARN([install PostgreSQL libs to compile this plugin (see Requirements).]) + fi +else + AC_MSG_WARN([Skipping PostgreSQL plugin (check_pgsql)]) + AC_MSG_WARN([install lib crypt and PostgreSQL libs to compile this plugin (see Requirements).]) +fi +LIBS="$_SAVEDLIBS" +CPPFLAGS="$_SAVEDCPPFLAGS" + +dnl Check for radius libraries +_SAVEDLIBS="$LIBS" +AC_CHECK_LIB(radiusclient,rc_read_config) +if test "$ac_cv_lib_radiusclient_rc_read_config" = "yes"; then + EXTRAS="$EXTRAS check_radius" + RADIUSLIBS="-lradiusclient" + AC_SUBST(RADIUSLIBS) +else + AC_MSG_WARN([Skipping radius plugin]) + AC_MSG_WARN([install radius libs to compile this plugin (see Requirements).]) +fi +LIBS="$_SAVEDLIBS" + +dnl Check for LDAP libraries +_SAVEDLIBS="$LIBS" +AC_CHECK_LIB(ldap,main,,,-llber) +if test "$ac_cv_lib_ldap_main" = "yes"; then + LDAPLIBS="-lldap -llber"\ + LDAPINCLUDE="-I/usr/include/ldap" + AC_SUBST(LDAPLIBS) + AC_SUBST(LDAPINCLUDE) + EXTRAS="$EXTRAS check_ldap" +else + AC_MSG_WARN([Skipping LDAP plugin]) + AC_MSG_WARN([install LDAP libs to compile this plugin (see Requirements).]) +fi +LIBS="$_SAVEDLIBS" + +dnl Check for mysql libraries +_SAVEDLIBS="$LIBS" +_SAVEDCPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I/usr/include" +AC_ARG_WITH(mysqllibdir,--with-mysqllibdir=<dir> sets path to mysql libraries,[MYSQLLIBDIR=$withval]) +if test -n "$MYSQLLIBS"; then + AC_CHECK_LIB(mysqlclient,mysql_init,MYSQLLIBS="-lmysqlclient -lz" check_mysql_LDFLAGS="-L$MYSQLLIBDIR",,-L$MYSQLLIBDIR -lz) +elif test -f /usr/lib/libmysqlclient.so; then + AC_CHECK_LIB(mysqlclient,mysql_init,MYSQLLIBS="-lmysqlclient -lz",,-lz) + AC_CHECK_LIB(mysqlclient,mysql_close,MYSQLLIBS="-lmysqlclient") +elif test -f /usr/lib/libmysqlclient.a; then + AC_CHECK_LIB(mysqlclient,mysql_init,MYSQLLIBS="-lmysqlclient -lz",,-lz) + AC_CHECK_LIB(mysqlclient,mysql_close,MYSQLLIBS="-lmysqlclient") +elif test -f /usr/lib/mysql/libmysqlclient.so; then + AC_CHECK_LIB(mysqlclient,mysql_init,MYSQLLIBS="-lmysqlclient -lz" check_mysql_LDFLAGS="-L/usr/lib/mysql",,-L/usr/lib/mysql -lz) + AC_CHECK_LIB(mysqlclient,mysql_close,MYSQLLIBS="-lmysqlclient" check_mysql_LDFLAGS="-L/usr/lib/mysql",,-L/usr/lib/mysql) +elif test -f /usr/lib/mysql/libmysqlclient.a; then + AC_CHECK_LIB(mysqlclient,mysql_init,MYSQLLIBS="-lmysqlclient -lz" check_mysql_LDFLAGS="-L/usr/lib/mysql",,-L/usr/lib/mysql -lz) + AC_CHECK_LIB(mysqlclient,mysql_close,MYSQLLIBS="-lmysqlclient" check_mysql_LDFLAGS="-L/usr/lib/mysql",,-L/usr/lib/mysql) +fi +if test "$ac_cv_lib_mysqlclient_mysql_init" = "yes" -o "$ac_cv_lib_mysqlclient_mysql_close" = "yes"; then + AC_CHECK_HEADERS(mysql/mysql.h mysql/errmsg.h) + if test "$ac_cv_header_mysql_mysql_h" = "yes" -a "$ac_cv_header_mysql_errmsg_h" = "yes"; then + EXTRAS="$EXTRAS check_mysql" + AC_SUBST(MYSQLLIBS) + AC_SUBST(check_mysql_LDFLAGS) + else + AC_MSG_WARN([Skipping mysql plugin]) + AC_MSG_WARN([install mysql client headers to compile this plugin (see Requirements).]) + fi +else + AC_MSG_WARN([Skipping mysql plugin]) + AC_MSG_WARN([install mysql client libs to compile this plugin (see Requirements).]) +fi +LIBS="$_SAVEDLIBS" +CPPFLAGS="$_SAVEDCPPFLAGS" + +dnl Check for OpenSSL location +AC_PATH_PROG(OPENSSL,openssl) +if test "$OPENSSL" = "/usr/bin/openssl"; then + OPENSSL=/usr +elif test "$OPENSSL" = "/usr/sbin/openssl"; then + OPENSSL=/usr +elif test "$OPENSSL" = "/opt/bin/openssl"; then + OPENSSL=/opt +elif test "$OPENSSL" = "/opt/openssl/bin/openssl"; then + OPENSSL=/opt/openssl +elif test "$OPENSSL" = "/usr/slocal/bin/openssl"; then + OPENSSL=/usr/slocal +elif test "$OPENSSL" = "/usr/local/bin/openssl"; then + OPENSSL=/usr/local +elif test "$OPENSSL" = "/usr/local/ssl/bin/openssl"; then + OPENSSL=/usr/local/ssl +fi +AC_ARG_WITH(openssl,--with-openssl=<dir> sets path to openssl installation,[OPENSSL=$withval]) + +dnl Check for OpenSSL header files +_SAVEDCPPFLAGS="$CPPFLAGS" +FOUNDINCLUDE=yes +CPPFLAGS="-I$OPENSSL/include" +AC_CHECK_HEADERS(openssl/x509.h openssl/ssl.h openssl/rsa.h openssl/pem.h openssl/crypto.h openssl/err.h,SSLINCLUDE="-I$OPENSSL/include",FOUNDINCLUDE=no) +if test "$FOUNDINCLUDE" = "no"; then + FOUNDINCLUDE=yes + AC_CHECK_HEADERS(x509.h ssl.h rsa.h pem.h crypto.h err.h,SSLINCLUDE="-I$OPENSSL/include",FOUNDINCLUDE=no) +fi +AC_SUBST(SSLINCLUDE) +CPPFLAGS="$_SAVEDCPPFLAGS $SSLINCLUDE" + +dnl Check for crypto lib +_SAVEDLIBS="$LIBS" +AC_CHECK_LIB(crypto,CRYPTO_lock,,,-L$OPENSSL/lib) +if test "$ac_cv_lib_crypto_CRYPTO_lock" = "yes"; then + dnl Check for SSL lib + AC_CHECK_LIB(ssl,main,LDFLAGS="$LDFLAGS -L$OPENSSL/lib" SSLLIBS="-lssl -lcrypto",AC_CHECK_LIB(ssl,main,LDFLAGS="$LDFLAGS -L$OPENSSL/lib" SSLLIBS="-lssl -lcrypto"),-L$OPENSSL/lib -lcrypto) +fi +LIBS="$_SAVEDLIBS" + +dnl test headers and libs to decide whether check_http should use SSL +if test "$ac_cv_lib_crypto_CRYPTO_lock" = "yes"; then + if test "$ac_cv_lib_ssl_main" = "yes"; then + if test "$FOUNDINCLUDE" = "yes"; then + AC_SUBST(SSLLIBS) + AC_DEFINE(HAVE_SSL) + fi + fi +fi +CPPFLAGS="$_SAVEDCPPFLAGS" + +dnl +dnl Checks for header files. +dnl + +AC_HEADER_STDC +AC_HEADER_TIME +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(signal.h strings.h string.h syslog.h unistd.h uio.h errno.h regex.h sys/types.h sys/time.h sys/socket.h sys/loadavg.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_STRUCT_TM +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SIGNAL + +dnl EXTRA_LIBRARIES="libgetopt.a libsnprintf.a" +dnl noinst_LIBRARIES="libgetopt.a libsnprintf.a" +dnl libgetopt_a_SOURCES="getopt.c getopt1.c" +dnl libgetopt_a_DEPENDENCIES=getopt.h +dnl libsnprintf_a_SOURCES=snprintf.c +dnl AC_SUBST(noinst_LIBRARIES) +dnl AC_SUBST(libgetopt_a_SOURCES) +dnl AC_SUBST(libgetopt_a_DEPENDENCIES) +dnl AC_SUBST(libsnprintf_a_SOURCES) + +AC_MSG_CHECKING(for getopt_long) +AC_TRY_COMPILE([#include <getopt.h> +#include <stdlib.h>], +[int option_index=0; +static struct option *long_options; +getopt_long(0,NULL,"+h",long_options,&option_index);], +[AC_DEFINE(HAVE_GETOPT_H) AC_DEFINE(HAVE_GETOPT_LONG) AC_MSG_RESULT(yes)], +[AC_DEFINE(HAVE_GETOPT_H) AC_DEFINE(HAVE_GETOPT_LONG) AC_MSG_RESULT(no) import_sources=getopt]) + +AC_CHECK_FUNCS(getopt_long_only,,LIBS="$LIBS -lgetopt" DEPLIBS="$DEPLIBS libgetopt.a") + +AC_CHECK_FUNC(vsnprintf,,LIBS="$LIBS -lsnprintf" DEPLIBS="$DEPLIBS libsnprintf.a") + +dnl Checks for library functions. +AC_CHECK_FUNCS(select socket strdup strstr strtod strtol strtoul) + +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 *) buffer, (size_t *) 0, (int *) 0);], +[AC_DEFINE(SOCKET_SIZE_TYPE, size_t) AC_MSG_RESULT(size_t)], +[AC_DEFINE(SOCKET_SIZE_TYPE, int) AC_MSG_RESULT(int)]) + +if test -f "/proc/loadavg" +then + AC_DEFINE(HAVE_PROC_LOADAVG) + AC_DEFINE_UNQUOTED(PROC_LOADAVG,"/proc/loadavg") +fi + +AC_PATH_PROG(PATH_TO_PS,ps) +dnl OpenBSD (needs to come early because -exo appears to work, but does not give all procs) +dnl STAT UCOMM VSZ RSS USER UID PPID COMMAND +if [ps -axo 'stat comm vsz rss user uid ppid args' 2>/dev/null | egrep -i "^ *S[TAUES]* +[UCOMDNA]+ +[VSIZE]+ +R[S]+ +U[SER]+ +U[ID]+ +P[PID]+ +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS -axo 'stat user ppid args'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -axo 'stat uid ppid comm args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -axo 'vsz comm'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -axo 'rss comm'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -eo 'stat comm vsz rss user ppid args'" +elif [ps -eo 's comm vsz rss user uid ppid args' 2>/dev/null | egrep -i "^S[TAUES]* +C[OMDNA]+ +[VSIZE]+ +U[SER]+ +U[ID]+ +P[PID]+ +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS -eo 's user ppid args'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -eo 's uid ppid comm args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -eo 'vsz comm'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -eo 'rss comm'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -eo 's comm vsz rss user ppid args'" +elif [ps -Ao 's comm vsz rss uid user ppid args' 2>/dev/null | egrep -i "^S[TAUES]* +C[OMDNA]+ +V[SIZE]+ +RSS +UID +USER +PPID +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS -Ao 's user ppid args'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -Ao 's uid ppid comm args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -Ao 'vsz comm'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -Ao 'rss comm'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -Ao 's comm vsz rss'" +elif [ps -Ao 'status comm vsz rss uid user ppid args' 2>/dev/null | egrep -i "^S[TAUES]* +C[OMDNA]+ +V[SIZE]+ +RSS +UID +USER +PPID +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS -Ao 'status user ppid args'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -Ao 'status uid ppid comm args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -Ao 'vsz comm'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -Ao 'rss comm'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -Ao 'status comm vsz rss'" +elif [ps -Ao 'state comm vsz rss uid user ppid args' 2>/dev/null | egrep -i "^S[TAUES]* +C[OMDNA]+ +V[SIZE]+ +RSS +UID +USER +PPID +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS -Ao 'state user ppid args'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -Ao 'state uid ppid comm args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -Ao 'vsz comm'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -Ao 'rss comm'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -Ao 'state comm vsz rss'" +elif [ps -ao 'state command vsz rss user ppid args' 2>/dev/null | egrep -i "^S[TAUES]* +C[OMDNA]+ +V[SIZE]+ +RSS +UID +USER +PPID +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS -ao 'state user ppid args'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -ao 'state uid ppid command args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -ao 'vsz command'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -ao 'rss command'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -ao 'state command vsz rss'" +dnl FreeBSD +elif [ps waxco 'state command vsz rss uid user ppid' 2>/dev/null | egrep -i "^STAT +COMMAND +VSZ +RSS +UID +USER +PPID" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS waxo 'state uid ppid command'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS waxco 'state uid ppid command command'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS waxco 'vsz command'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS waxco 'rss command'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -Ao 'state command vsz rss'" +dnl BSD-like mode in RH 6.1 +elif [ps waxno 'state comm vsz rss uid user ppid args' 2>/dev/null | egrep -i "^S +COMMAND +VSZ +RSS +UID +USER +PPID +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,procprog,&pos]) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS waxno 'state user ppid comm'") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS waxno 'state uid ppid comm args'") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %d %s %n") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS waxno 'vsz comm'") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%d %s") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS waxno 'rss comm'") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%d %s") + echo " ps syntax... $PATH_TO_PS -waxco 'state comm vsz rss'" +dnl IRIX 53 +elif [ps -el 2>/dev/null | egrep -i "^ *F +S +UID +PID +PPID +C +PRI +NI +P +SZ +RSS +WCHAN +TTY +TIME +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,&pos,procprog]) + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%*s %s %d %*s %d %*s %*s %*s %*s %*s %*s %*s %*s %*s %n%s") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %d") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d") + echo " ps syntax... $PATH_TO_PS -el" +dnl IRIX 63 +elif [ps -el 2>/dev/null | egrep -i "^ *F +S +UID +PID +PPID +C +PRI +NI +P +ADDR +SZ +RSS +WCHAN +TTY +TIME +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,&pos,procprog]) + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%*s %s %d %*s %d %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %n%s") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %d") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d") + echo " ps syntax... $PATH_TO_PS -el" +dnl SunOS 4.1.3: +dnl F UID PID PPID CP PRI NI SZ RSS WCHAN STAT TT TIME COMMAND +dnl +elif [ps -laxnwww 2>/dev/null | egrep -i "^ *F(LAGS)? +UID +PID +PPID +CP +PRI +NI +(SZ)|(VSZ)|(SIZE) +RSS +WCHAN +STAT? +TTY? +TIME +COMMAND" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS laxnwww") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_VARLIST,[&procuid,&procppid,procstat,&pos,procprog]) + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -laxnwww") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%*s %d %*s %d %*s %*s %*s %*s %*s %*s %s %*s %*s %n%s") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS laxnwww") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %d") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS laxnwww") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %*s %d") + echo " ps syntax... $PATH_TO_PS laxnwww" +dnl Debian Linux / procps v1.2.9: +dnl FLAGS UID PID PPID PRI NI SIZE RSS WCHAN STA TTY TIME COMMAND +dnl 100 0 1 0 0 0 776 76 c0131c8c S ffff 0:11 init [2] +dnl +elif [ps laxnwww 2>/dev/null | egrep -i "^ *F(LAGS)? +UID +PID +PPID +PRI +NI +(VSZ)|(SIZE) +RSS +WCHAN +STAT? TTY +TIME +COMMAND" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_RAW_COMMAND,"$PATH_TO_PS laxnwww") + EXTRAS="$EXTRAS check_nagios" + AC_DEFINE_UNQUOTED(PS_VARLIST,[&procuid,&procppid,procstat,&pos,procprog]) + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS laxnwww") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%*s %d %*s %d %*s %*s %*s %*s %*s %s %*s %*s %n%s") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS laxnwww") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %*s %*s %d") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS laxnwww") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %d") + echo " ps syntax... $PATH_TO_PS laxnwww" +dnl +dnl AIX 4.1: +dnl F S UID PID PPID C PRI NI ADDR SZ RSS WCHAN TTY TIME CMD +dnl 303 A 0 0 0 120 16 -- 1c07 20 24 - 0:45 swapper +elif [ps -el 2>/dev/null | egrep -i "^ *F +S +UID +PID +PPID +C +PRI +NI +ADDR +SZ +WCHAN +TTY +TIME +[RGSCOMDNA]+" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[procstat,&procuid,&procppid,&pos,procprog]) + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%*s %s %d %*s %d %*s %*s %*s %*s %*s %*s %*s %*s %n%s") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %*s %*s %d") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS -el") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %*s %*s %d") + echo " ps syntax... $PATH_TO_PS -el" +dnl AIX? +elif [ps glaxen 2>/dev/null | egrep -i "^ *F +UID +PID +PPID +PRI +NI +VSZ +RSS +WCHAN +STAT +TTY +TIME +COMMAND" >/dev/null] +then + AC_DEFINE(USE_PS_VARS) + AC_DEFINE_UNQUOTED(PS_VARLIST,[&procuid,&procppid,procstat,&pos,procprog]) + AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS glaxen") + AC_DEFINE_UNQUOTED(PS_FORMAT,"%*s %d %*s %d %*s %*s %*s %*s %*s %s %*s %*s %n%s") + AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS glaxen") + AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %*s %*s %d") + AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS glaxen") + AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %*s %*s %d") + echo " ps syntax... $PATH_TO_PS glaxen" +dnl ucb style? +dnl elif [ps axun 2>/dev/null | egrep -i "^USER +PID +%CPU +%MEM +SIZE +RSS +TTY +STAT +START +TIME +COMMAND *$" >/dev/null] +dnl then +dnl AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS axun") +dnl AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %*s %*s %*s %*s %*s %s %*s %*s %s") +dnl AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS axun") +dnl AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %d") +dnl AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS axun") +dnl AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %d") +dnl echo " ps syntax... $PATH_TO_PS axun" +dnl ucb style? +dnl elif [ps axun 2>/dev/null | egrep -i "^USER +PID +%CPU +%MEM +SIZE +RSS +TTY +STAT +START +TIME +COMMAND" >/dev/null] +dnl then +dnl AC_DEFINE_UNQUOTED(PS_COMMAND,"$PATH_TO_PS axun") +dnl AC_DEFINE_UNQUOTED(PS_FORMAT,"%s %d %*s %*s %*s %*s %*s %s %*s %*s %s") +dnl AC_DEFINE_UNQUOTED(VSZ_COMMAND,"$PATH_TO_PS axun") +dnl AC_DEFINE_UNQUOTED(VSZ_FORMAT,"%*s %*s %*s %*s %d") +dnl AC_DEFINE_UNQUOTED(RSS_COMMAND,"$PATH_TO_PS axun") +dnl AC_DEFINE_UNQUOTED(RSS_FORMAT,"%*s %*s %*s %*s %*s %d") +dnl echo " ps syntax... $PATH_TO_PS axun" +else + echo "** Unable to find usable ps syntax" +fi + +AC_ARG_WITH(df_command,--with-df-command=<syntax> sets syntax for df,DF_COMMAND=$withval) +if test -n "$DF_COMMAND" +then + AC_DEFINE_UNQUOTED(DF_COMMAND,"$DF_COMMAND") +elif [df -Pk 2>/dev/null | egrep -i "^(/dev/|[a-zA-Z]:)[a-z0-9/\\]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+% +/[a-z0-9/\\]*" >/dev/null] +then + AC_PATH_PROG(PATH_TO_DF,df) + AC_MSG_RESULT(" df syntax... $PATH_TO_DF -Pk") + AC_DEFINE_UNQUOTED(DF_COMMAND,"$PATH_TO_DF -Pk") +elif [df -k 2>/dev/null | egrep -i "^/dev/[a-z0-9/]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+% +/[a-z0-9/]*" >/dev/null] +then + AC_PATH_PROG(PATH_TO_DF,df) + AC_MSG_RESULT(" df syntax... $PATH_TO_DF -k") + AC_DEFINE_UNQUOTED(DF_COMMAND,"$PATH_TO_DF -k") +elif [df 2>/dev/null | egrep -i "^/dev/[a-z0-9/]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+% +/[a-z0-9/]*" >/dev/null] +then + AC_PATH_PROG(PATH_TO_DF,df) + AC_MSG_RESULT(" df syntax... $PATH_TO_DF") + AC_DEFINE_UNQUOTED(DF_COMMAND,"$PATH_TO_DF") +elif [bdf 2>/dev/null | egrep -i "^/dev/[a-z0-9/]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+% +/[a-z0-9/]*" >/dev/null] +then + AC_PATH_PROG(PATH_TO_DF,bdf) + AC_MSG_RESULT(" df syntax... $PATH_TO_DF") + AC_DEFINE_UNQUOTED(DF_COMMAND,"$PATH_TO_DF") +else + AC_MSG_WARN("unable to find usable df syntax") +fi + +AC_PATH_PROG(PATH_TO_PING,ping) + +AC_ARG_WITH(ping_command,--with-ping-command=<syntax> sets syntax for ping,PING_COMMAND=$withval) +if test -n "$PING_COMMAND" +then + echo " ping syntax... (command-line) $PING_COMMAND" + if test -n "$PING_PACKETS_FIRST" + then + AC_DEFINE_UNQUOTED(PING_PACKETS_FIRST,"$PING_COMMAND") + fi +elif [ping -n -U -c 1 127.0.0.1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n -U -c %d %s" + AC_DEFINE_UNQUOTED(PING_PACKETS_FIRST,"$PING_COMMAND") + echo " ping syntax... $PATH_TO_PING -n -U -c <count> <host>" +elif [ping -n -c 1 127.0.0.1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n -c %d %s" + AC_DEFINE_UNQUOTED(PING_PACKETS_FIRST,"$PING_COMMAND") + echo " ping syntax... $PATH_TO_PING -n -c <count> <host>" +elif [ping -n 127.0.0.1 -c 1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n %s -c %d" + echo " ping syntax... $PATH_TO_PING -n <host> -c <count>" +elif [ping 127.0.0.1 -n 1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING %s -n %d" + echo " ping syntax... $PATH_TO_PING <host> -n <count>" +elif [ping -n -s 127.0.0.1 56 1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n -s %s 56 %d" + echo " ping syntax... $PATH_TO_PING -n -s <host> 56 <count>" +elif [ping -n -h 127.0.0.1 -s 56 -c 1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n -h %s -s 56 -c %d" + echo " ping syntax... $PATH_TO_PING -n -h <host> -s 56 -c <count>" +elif [ping -n -s 56 -c 1 127.0.0.1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n -s 56 -c %d %s" + AC_DEFINE_UNQUOTED(PING_PACKETS_FIRST,"$PING_COMMAND") + echo " ping syntax... $PATH_TO_PING -n -s 56 -c <count> <host>" +elif [ping -n -c 1 127.0.0.1 2>/dev/null | egrep -i "^round-trip" >/dev/null] +then + PING_COMMAND="$PATH_TO_PING -n -c %d %s" + AC_DEFINE_UNQUOTED(PING_PACKETS_FIRST,"$PING_COMMAND") + echo " ping syntax... $PATH_TO_PING -n -c <count> <host>" +else + AC_MSG_WARN("unable to find usable ping syntax") +fi +AC_DEFINE_UNQUOTED(PING_COMMAND,"$PING_COMMAND") + +AC_PATH_PROG(PATH_TO_NSLOOKUP,nslookup) +if test -n "$ac_cv_path_PATH_TO_NSLOOKUP" +then + AC_MSG_CHECKING("nslookup syntax") + if [nslookup -sil 127.0.0.1 2>&1 | grep "*** Invalid option: sil" >/dev/null] + then + AC_MSG_RESULT("$PATH_TO_NSLOOKUP") + AC_DEFINE_UNQUOTED(NSLOOKUP_COMMAND,"$PATH_TO_NSLOOKUP") + else + AC_MSG_RESULT("$PATH_TO_NSLOOKUP -sil") + AC_DEFINE_UNQUOTED(NSLOOKUP_COMMAND,"$PATH_TO_NSLOOKUP -sil") + fi + EXTRAS="$EXTRAS check_dns" +else + AC_MSG_WARN("nslookup command not found") +fi + +AC_PATH_PROG(PATH_TO_UPTIME,uptime) +AC_DEFINE_UNQUOTED(PATH_TO_UPTIME,"$PATH_TO_UPTIME") + +AC_PATH_PROG(PATH_TO_WHO,who) +if [who -q 2>/dev/null | egrep -i "^# users=[0-9]+$" >/dev/null] +then + AC_DEFINE_UNQUOTED(WHO_COMMAND,"$PATH_TO_WHO -q") +else + AC_DEFINE_UNQUOTED(WHO_COMMAND,"$PATH_TO_WHO") +fi + +AC_PATH_PROG(PATH_TO_SNMPGET,snmpget) +if test -f "$PATH_TO_SNMPGET" +then + AC_DEFINE_UNQUOTED(PATH_TO_SNMPGET,"$PATH_TO_SNMPGET") + EXTRAS="$EXTRAS check_hpjd check_snmp" +else + echo "** Get snmpget from http://ucd-snmp.ucdavis.edu to make check_hpjd and check_snmp plugins" +fi + +AC_PATH_PROG(PATH_TO_SNMPGETNEXT,snmpgetnext) +if test -f "$PATH_TO_SNMPGETNEXT" +then + AC_DEFINE_UNQUOTED(PATH_TO_SNMPGETNEXT,"$PATH_TO_SNMPGETNEXT") +fi + +AC_PATH_PROG(PATH_TO_QUAKESTAT,quakestat) +AC_PATH_PROG(PATH_TO_QSTAT,qstat) +if test -n "$PATH_TO_QUAKESTAT" +then + AC_DEFINE_UNQUOTED(PATH_TO_QSTAT,"$PATH_TO_QUAKESTAT") + EXTRAS="$EXTRAS check_game" +elif test -n "$PATH_TO_QSTAT" +then + AC_DEFINE_UNQUOTED(PATH_TO_QSTAT,"$PATH_TO_QSTAT") + EXTRAS="$EXTRAS check_game" +else + echo "** Get qstat from http://www.activesw.com/people/steve/qstat.html in order to make check_game plugin" +fi + +AC_PATH_PROG(PATH_TO_FPING,fping) +if test -n "$PATH_TO_FPING" +then + AC_DEFINE_UNQUOTED(PATH_TO_FPING,"$PATH_TO_FPING") + EXTRAS="$EXTRAS check_fping" +else + echo "** Get fping from http://www.stanford.edu/~schemers/docs/fping/fping.html in order to make check_fping plugin" +fi + +AC_PATH_PROG(PATH_TO_SSH,ssh) +if test -f "$PATH_TO_SSH" +then + AC_DEFINE_UNQUOTED(SSH_COMMAND,"$PATH_TO_SSH") + EXTRAS="$EXTRAS check_by_ssh" +else + echo "** Get ssh in order to make check_by_ssh plugin" +fi + +dnl dunno why this does not work below - use hack (kbd) +dnl fine on linux, broken on solaris +dnl if /bin/test -e "/proc/meminfo" + +if [cat /proc/meminfo > /dev/null 2>&1] +then + echo "found /proc/meminfo" + AC_DEFINE(HAVE_PROC_MEMINFO) + AC_DEFINE_UNQUOTED(PROC_MEMINFO,"/proc/meminfo") + EXTRAS="$EXTRAS check_swap" +elif [swap -l 2>&1 | egrep -i "swapfile" >/dev/null] +then + echo "found swap command" + AC_DEFINE(HAVE_SWAP) + AC_PATH_PROG(PATH_TO_SWAP,swap) + AC_DEFINE_UNQUOTED(SWAP_COMMAND,"$PATH_TO_SWAP -l") + if [swap -l 2>/dev/null | egrep -i "^lswap +path +pri +swaplo +blocks +free +maxswap" >/dev/null] + then + AC_DEFINE_UNQUOTED(SWAP_FORMAT,[" %*d %*s %*d,%*d %*d %*d %d %d"]) + echo " using IRIX format" + elif [swap -l 2>/dev/null | egrep -i "^swapfile +dev +swaplo +blocks +free" >/dev/null] + then + AC_DEFINE_UNQUOTED(SWAP_FORMAT,["%*s %*[[0-9,-]] %*d %d %d"]) + echo " using Solaris format" + fi + EXTRAS="$EXTRAS check_swap" +elif [swapinfo -k 2>&1 | egrep -i "Device" >/dev/null] +then + echo "found swapinfo command" + AC_DEFINE(HAVE_SWAP) + AC_PATH_PROG(PATH_TO_SWAP,swapinfo) + AC_DEFINE_UNQUOTED(SWAP_COMMAND,"$PATH_TO_SWAP -k") + if [swapinfo -k 2>/dev/null | egrep -i "^Device +1K-blocks +Used +Avail" >/dev/null] + then + AC_DEFINE_UNQUOTED(SWAP_FORMAT,["%*s %d %*d %d"]) + echo " using FreeBSD format" + fi + EXTRAS="$EXTRAS check_swap" +fi + +AC_PATH_PROG(PATH_TO_DIG,dig) +AC_DEFINE_UNQUOTED(PATH_TO_DIG,"$PATH_TO_DIG") +if test -n "$PATH_TO_DIG"; then + EXTRAS="$EXTRAS check_dig" +fi + +if test -f plugins/check_nt.c ; then + EXTRAS="$EXTRAS check_nt" +elif test -f ../plugins/check_nt.c ; then + EXTRAS="$EXTRAS check_nt" +fi + +dnl AC_EGREP_HEADER (PATTERN, HEADER-FILE, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +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)], +[NEED_VA_LIST=-DNEED_VA_LIST AC_SUBST(NEED_VA_LIST) AC_MSG_RESULT(no)]) + +AC_SUBST(EXTRAS) +AC_SUBST(DEPLIBS) + +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) +AC_DEFINE_UNQUOTED(PACKAGE,"${PACKAGE}") +AC_DEFINE_UNQUOTED(VERSION,"${VERSION}") +AC_DEFINE_UNQUOTED(PACKAGE_VERSION,"${VERSION}") + +AC_OUTPUT(Makefile subst plugins/Makefile plugins-scripts/Makefile plugins-scripts/subst plugins-scripts/utils.pm plugins-scripts/utils.sh command.cfg test.pl,echo timestamp > plugins/stamp-h1;echo timestamp > plugins/stamp-h2;echo timestamp > plugins/stamp-h3;echo timestamp > plugins/stamp-h4;echo timestamp > plugins/stamp-h5;echo timestamp > plugins/stamp-h6;PATH=.:..:$PATH subst.sh command.cfg) diff --git a/contrib/aix/check_crit_dsk b/contrib/aix/check_crit_dsk new file mode 100644 index 00000000..566e07c1 --- /dev/null +++ b/contrib/aix/check_crit_dsk @@ -0,0 +1,66 @@ +#!/bin/sh + +#========================================================================= +# Critical Disk Checker utility +# +# This is the same as the disk checker utility but we use it as +# a seperate service in Nagios to report on partitions that +# have reached 100% capacity. +# +# We have excluded /dev/cd0 because the cdrom drive will always +# report 100% capacity if a CD is in the drive. +# +# Authors: TheRocker +# SpEnTBoY +# +# Email: therocker@pawprints.2y.net +# lonny@abyss.za.org +# +#======================================================================= + +NUMBER=`rsh $1 -l root df -kP | grep -vE ":|/dev/cd0" | grep -E "100%" | tr -s ' '| cut -d' ' -f5 | cut -c1-3 | line` +TMPFILE=/tmp/tmpcrit.hndl +TMPTOO=/tmp/twocrit.hndl + +if [ "$NUMBER" -eq 100 ] +then + + `rsh $1 -l root df -kP |grep -vE ":|/dev/cd0" | grep -E "100%" | tr -s ' '| cut -d' ' -f6,5 >> $TMPFILE` + + LINES=`wc -l /tmp/tmpcrit.hndl | cut -c8` + LINESCTL=`wc -l /tmp/tmpcrit.hndl | cut -c8 ` + echo "Filesystems over 99% --> \c" + +#=============================================================== +# Just a little bit to check for multiple occurances of the +# condition. +#=============================================================== + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/tmpcrit.hndl` + echo "( $DATA ) \c" + + + done + echo "\n" + +#=============================================================== +# File clean up. Always pick up after yourself. Disk space +# doesn't grow on trees you know. +#=============================================================== + + rm -f $TMPFILE + rm -f $TMPTOO + exit 2 + +else + + echo "No Filesystems over 99%... OK" + exit 0 +fi diff --git a/contrib/aix/check_dsk b/contrib/aix/check_dsk new file mode 100644 index 00000000..c8ddb3f8 --- /dev/null +++ b/contrib/aix/check_dsk @@ -0,0 +1,62 @@ +#! /bin/sh + +#====================================================================== +# Disk Checker utility +# +# Simple little script that checks the status of all partitions +# on a node's hard disks. It will produce a warning alert and list +# the offending filesystems in nagios. +# +# Authors: SpEnTBoY +# TheRocker +# +# Email: lonny@abyss.za.org +# therocker@pawprints.2y.net +#===================================================================== + +NUMBER=`rsh $1 -l root df -kP | grep -v ":" | grep -E "9[0-9]%" | tr -s ' '| cut -d' ' -f5 | cut -c1-2 | line` +TMPFILE=/tmp/tmp.hndl +TMPTOO=/tmp/two.hndl + +if [ "$NUMBER" -gt 90 ] +then + + `rsh $1 -l root df -kP |grep -v ":" | grep -E "9[0-9]%" | tr -s ' '| cut -d' ' -f6,5 >> $TMPFILE` + + LINES=`wc -l /tmp/tmp.hndl | cut -c8` + LINESCTL=`wc -l /tmp/tmp.hndl | cut -c8 ` + echo "Filesystems over 90% --> \c" + +#====================================================================== +# You'll see this one in a few our shell scripts. Just chcecking for +# multiple occurances of the warnign condition. We gotta list 'em all +#====================================================================== + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/tmp.hndl` + echo "( $DATA ) \c" + + + done + echo "\n" + +#=============================================================== +# Clean up all those nasty tmp files that suck up valuable +# disk realestate. +#=============================================================== + + rm -f $TMPFILE + rm -f $TMPTOO + exit 1 + +else + + echo "No Filesystems over 90%... OK" + exit 0 +fi diff --git a/contrib/aix/check_failed b/contrib/aix/check_failed new file mode 100644 index 00000000..50cdf7e1 --- /dev/null +++ b/contrib/aix/check_failed @@ -0,0 +1,48 @@ +#!/usr/bin/perl +#====================== +# Created May 25, 2000 +#====================== + +# This scripts is for checking for failed root login attempts on +# any machine running AIX which has a failedlogin file in /etc/security +# The purpose is to thwart (good word) any unauthorised people from +# even trying to log in as root. This plugin has been developed for Nagios +# running on AIX. +# Lonny Selinger SpEnTBoY lonny@abyss.za.org +# May + + +my $server = $ARGV[0]; + +if (!$ARGV[0]) { + print "You must specify a server to check\n"; + print "usage: ./check_failed <Server Name>\n"; + exit (-1); + } else { + open (DATE, "/bin/date '+%b %d' |"); + while (<DATE>) { + $dline = $_; + @dresults = $dline; + chop $dresults[0]; + } + open (SULOG, "rsh $server -l root who /etc/security/failedlogin | grep root |"); + while (<SULOG>) { + $line = $_; + @results = split (/\s+/,$line); + if ($line =~ /^root/) { + if (join(' ', @results[2,3]) eq $dresults[0]) { + print "FAILED root login on $dresults[0], node: $ARGV[0] from $results[5]\n"; + exit(2); + } + } + } +} +if (join(' ', @results[2,3]) ne $dresults[0]) { + print "No Failed Root Logins on This Node\n"; + exit(0); +} +exit(0); +close(SULOG); +close(DATE); + + diff --git a/contrib/aix/check_io b/contrib/aix/check_io new file mode 100644 index 00000000..58b25f6d --- /dev/null +++ b/contrib/aix/check_io @@ -0,0 +1,69 @@ +#! /bin/sh + +#================================================================= +# +# I/O Checker (KBPS) +# This Script uses iostat to monitor disk io +# Useful for notifications of disk thrashing. +# +# Authors: TheRocker +# SpEnTBoY +# +# Email: therocker@pawprints.2y.net +# lonny@abyss.za.org +# +#================================================================ + +NUMBER1=`rsh $1 -l root iostat -d | grep -e "hdisk" | tr -s ' ' | cut -d' ' -f2 | sort -2 -r | cut -c1 | line` +NUMBER2=`rsh $1 -l root iostat -d | grep -e "hdisk" | tr -s ' ' | cut -d' ' -f2 | sort -2 -r | cut -c2 | line` +TMPFILE=/tmp/iotest.hndl +TMPTOO=/tmp/iotwo.hndl + +#=========================================================== +# +# We do an evaluation on $NUMBER1 and $NUMBER2 to see if +# disk io is exceeding 40%. +# +#=========================================================== + +if [ "$NUMBER1" -gt 4 ] && [ "$NUMBER2" -gt 0 ] +then + + `rsh $1 -l root iostat -d | grep -v cd0 | tr -s ' '| cut -d' ' -f1,2 | grep -e "4[0-9]." >> $TMPFILE` + +#==================================================================== +# +# Of course, there may be more than one hard disk on the node +# so we use this bit of code to report on more than one instance +# of excessive disk IO. +# +#==================================================================== + + LINES=`wc -l /tmp/iotest.hndl | cut -c8` + LINESCTL=`wc -l /tmp/iotest.hndl | cut -c8 ` + echo "WARNING!!! Disk I/O Exceeding 40% on --> \c" + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/iotest.hndl` + echo "( $DATA ) " + + + done + echo "\n" + + rm -f $TMPFILE + rm -f $TMPTOO + exit 1 + +else + + print "No Disk I/O Exceeding 40%...OK" + exit 0 + +fi diff --git a/contrib/aix/check_kerberos b/contrib/aix/check_kerberos new file mode 100644 index 00000000..443ab109 --- /dev/null +++ b/contrib/aix/check_kerberos @@ -0,0 +1,49 @@ +#! /bin/sh + +#========================================================================= +# Kerberos Ticket Checker +# +# This script is handy if you allow kerberos tickets to expire +# on your nodes. The script will simply warn you when a node has +# kerberos tickets expiring on the current date. This will allow to +# re-initialize the tickets if you wish to do so. +# +# Nothing fancy here, all Nagios will show is the number of tickets +# that are going to (or already have) expired. +# +# An item of note: +# +# We made no provisions for the weekend. If tickets expire on the +# weekend and nobody is around, you won't see a warning on the +# Nagios console because we look for expired on the current day +# only. It's a good idea to have this warning emailed to the +# appropriate admin and if there is something critical that relies +# on Kerberos, you might want to send a page. +# +# Authors: TheRocker +# SpEnTBoY +# +# Email: therocker@pawprints.2y.net +# lonny@abyss.za.org +#========================================================================= + +TMPFILE=/tmp/kerbtmp.hndl +DATE=`date +%b' '%d` + +rsh $1 -l root /usr/lpp/ssp/kerberos/bin/klist | tr -s ' ' | cut -d' ' -f4,5,6 | grep -e "$DATE" > $TMPFILE + + +if [ -s $TMPFILE ] +then + + LINES=`wc -l /tmp/kerbtmp.hndl | cut -c7-8` + echo "Kerberos Tickets set to expire --> \c" + echo "$LINES \c" + echo "\n" + + rm -f $TMPFILE + exit 1 + +fi + echo "Kerberos Tickets are valid" + exit 0 diff --git a/contrib/aix/check_ping b/contrib/aix/check_ping new file mode 100644 index 00000000..aaa8c84e --- /dev/null +++ b/contrib/aix/check_ping @@ -0,0 +1,117 @@ +#!/usr/bin/perl -w + +#================================================================ +# +# This perl script will accept an argument and simply pass it +# to ping. It works by sending 2 ping to the specified host +# and evaluating on the average delta time of those 2 pings. +# +# Author: SpEnTBoY +# Email: lonny@abyss.za.org +# April 5,2000 +# +#================================================================ + +#============================ +# State predefined stuff and +# requirements +#============================ + +require 5.004; +use POSIX; +use strict; + +sub usage; + +my $ipaddr = $ARGV[0]; + +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my $remote = shift || &usage(%ERRORS); +my $warning = shift || 750; +my $critical = shift || 1000; + +my $state = "OK"; +my $answer = undef; +my $offset = undef; +my $line = undef; + +#============================================================ +# If theres no response we can exit the bloody thing cleanly +# last thing I want to do is hang an AIX system ;-) +#============================================================ + +$SIG{'ALRM'} = sub { + print ("ERROR: No response from PING! (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + +#================================================ +# Pass stddn from $ARGV to the command and parse +# the info we need (namely the value for "max" +#================================================ + + + +open(PING,"/usr/sbin/ping -c 2 '$ipaddr' >&1|"); +while (<PING>) { + $line = $_; + if (/round-trip min\/avg\/max = (.+)\/(.+)\/(.+) ms/) { + $offset = $3; + last; + } +} + +#================================================== +# Do some error checking on the output of the file +# and implement values for <crit> and <warn> +# deffinitions if they were specified by the user +# or sub in the predefined ones +#================================================== + +if (defined $offset) { + if (abs($offset) > $warning) { + if (abs($offset) > $critical) { + $state = "CRITICAL"; + $answer = ": Ping Time $offset MS greater than +/- $critical MS\n"; + } else { + $state = "WARNING"; + $answer = ": Ping Time $offset MS greater than +/- $warning MS\n"; + } + } else { + $state = "OK"; + $answer = ": Ping Time $offset MS\n"; + } +} else { + $state = "UNKNOWN"; + $answer = ": $line\n"; +} +print ("$state$answer"); +exit $ERRORS{$state}; + +sub usage { + print "\n"; + print "#=========================================\n"; + print "Check_Ping 0.02 script by Lonny Selinger\n"; + print "Made with AIX in mind ;-)\n"; + print "#=========================================\n"; + print "\n"; + print "#================================================\n"; + print " I'm going to need a few more arguments from you\n"; + print "#================================================\n"; + print "\n"; + print "#================================================\n"; + print "Usage: check_ping <host> [<warn> [<crit>]\n"; + print "#================================================\n"; + print "\n"; + print "<warn> = Ping in MS at which a warning message will be generated.\n Defaults to 750.\n"; + print "<crit> = Ping in MS at which a critical message will be generated.\n Defaults to 1000.\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + diff --git a/contrib/aix/check_queue b/contrib/aix/check_queue new file mode 100644 index 00000000..9f709c54 --- /dev/null +++ b/contrib/aix/check_queue @@ -0,0 +1,67 @@ +#! /bin/sh + +#=============================================================== +# Print Queue Checker +# +# The print queue checker simply looks for an occurance of a +# DOWN queue. A note of warning, if you use remote queues in +# AIX to redirect print jobs from the AIX queue to an NT print +# server that print through DLC rather than IP, it will be very +# s - l - o - w. But it will work. +# +# Author: TheRocker +# Email: therocker@pawprints.2y.net +#=============================================================== + +TMPFILE=/tmp/qtmp.hndl +TMPTOO=/tmp/qtwo.hndl + +#======================================================================= +# +# This script will also work on AIX 4.2.1 BUT you have to change +# the following line. AIX 4.2.1 does not support the -W option +# with lpstat. For AIX 4.2.1 just remove the -W option and it should +# work just fine. +# +#======================================================================= + +`rsh $1 -l root lpstat -W | grep -e "DOWN" | tr -s ' ' | cut -d' ' -f1,3 > /tmp/qtmp.hndl 2> /tmp/q_err` + +if [ -s $TMPFILE ] +then + +#======================================================= +# +# If you've seen the other AIX scripts I wrote you may +# notice that I use this bit of code a lot. Well it +# works and appears to be all purpose. +# +#======================================================= + + LINES=`wc -l /tmp/qtmp.hndl | cut -c8` + LINESCTL=`wc -l /tmp/qtmp.hndl | cut -c8` + + echo "Print Queue DOWN --> \c" + + while [ $LINESCTL != 0 ] + do + + cat $TMPFILE | tail -$LINESCTL > $TMPTOO + cat $TMPTOO > $TMPFILE + LINESCTL=$(( $LINESCTL -1 )) + LINES=$(( $LINES -1 )) + DATA=`head -1 /tmp/qtmp.hndl` + echo "( $DATA ) \c" + + + done + + echo "\n" + + rm -f $TMPFILE + rm -f $TMPTOO + exit 2 + +fi + echo "Print Queues Running... OK" + exit 0 diff --git a/contrib/aix/pg_stat b/contrib/aix/pg_stat new file mode 100644 index 00000000..e0603ec4 --- /dev/null +++ b/contrib/aix/pg_stat @@ -0,0 +1,45 @@ +#!/bin/ksh + +#============================================================================== +# Script was originally created to collect stats and dump then to a log file +# every five minutes. But we like this better (the log file thing is still +# good if you want to track availability). +# +# Authors: SpEnTBoY +# TheRocker +# +# Email: lonny@abyss.za.org +# therocker@pawprints.2y.net +#============================================================================== + +#========================================================================================= +# +# The best way to do this is to use Kerberos but we use rsh here because our monitoring +# workstation doesn't have Kerberos installed. In order for this to work, the remote +# host ($1) must have a .rhosts file that contains a line like: +# +# monitorhost nagiosuser +# +#========================================================================================= + +PAGING2=`rsh $1 -l root lsps -a -s | grep -v Paging | tr -s ' '| cut -d' ' -f3 | cut -d'%' -f1` + + +if [ "$PAGING2" -gt "35" ] && [ "$PAGING2" -lt "50" ] +then + echo "Paging Space is over 35% ("$PAGING2")%" +exit 1 +fi + +if [ "$PAGING2" -gt "49" ] +then + echo "WARNING! Paging Space is over 50% ("$PAGING2")%" +exit 2 +fi + +if [ "$PAGING2" -lt "34" ] +then + echo "Paging Space is less than 34% ("$PAGING2")%" +exit 0 +fi + diff --git a/contrib/check_apache.pl b/contrib/check_apache.pl new file mode 100644 index 00000000..b9e69a0c --- /dev/null +++ b/contrib/check_apache.pl @@ -0,0 +1,283 @@ +#!/usr/bin/perl +# +# (c)2001 Sebastian Hetze, Linux Information Systems AG +# send bug reports to <S.Hetze@Linux-AG.com> +# +# 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 (or with Nagios); if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA +# +# +# Check apache status information provided by mod_status to find +# out about the load (number of servers working) and the +# performance (average response time for recent requests). +# +# Usage: +# check_apache -H <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>] +# +# check_apache <host> <warn> <crit> <url> (if you cannot avoid it) +# + +use LWP::UserAgent; +use URI::URL; +use Getopt::Long; +Getopt::Long::Configure('bundling'); + +$version=0.01; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + + +# +# some default values +# +$perf_w=500; +$perf_c=1000; +$load_w=20; +$load_c=30; +$TIMEOUT=15; + +# +# get command line options the regular way +# +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "l" => \$opt_l, "load" => \$opt_l, + "v" => \$verbose, "verbose" => \$verbose, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "H=s" => \$opt_H, "hostname=s" => \$opt_H, + "u=s" => \$opt_u, "url=s" => \$opt_u); + +# +# handle the verbose stuff first +# +if ($opt_V) { + print "\n"; + print "check_apache nagios plugin version $version\n"; + print "\n"; + print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"; + print "copies of the plugins under the terms of the GNU General Public License.\n"; + print "For more information about these matters, see the file named COPYING.\n"; + print "\n"; + print "Copyright (c) 2001 Sebastian Hetze Linux Information Systems AG\n"; + print "\n"; + print "\n"; + exit $ERRORS{'UNKNOWN'}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{'UNKNOWN'}; +} + +# +# now get options the weired way and set the defaults +# if nothing else is provided +# +$opt_H = shift unless ($opt_H); +print_usage() unless ($opt_H); + +if($opt_l) { + $autostring="?auto"; + ($opt_w) || ($opt_w = shift) || ($opt_w = $load_w); + $warn = $1 if ($opt_w =~ /([0-9]+)/); + ($opt_c) || ($opt_c = shift) || ($opt_c = $load_c); + $alert = $1 if ($opt_c =~ /([0-9]+)/); +} else { + $autostring=""; + ($opt_w) || ($opt_w = shift) || ($opt_w = $perf_w); + $warn = $1 if ($opt_w =~ /([0-9]+)/); + ($opt_c) || ($opt_c = shift) || ($opt_c = $perf_c); + $alert = $1 if ($opt_c =~ /([0-9]+)/); +} + +($opt_u) || ($opt_u = shift) || ($opt_u = "/server-status"); + + +# +# dont let us wait forever... +# +$SIG{'ALRM'} = sub { + print ("ERROR: No response from HTTP server (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +# +# now we set things up for the real work +# and fire up the request +# +$ua = new LWP::UserAgent; +$ua->agent("Nagios/0.1 " . $ua->agent); + + +$urlstring = "http://" . $opt_H . $opt_u . $autostring; +$url = url($urlstring); + +my $req = new HTTP::Request 'GET', $url; +my $res = $ua->request($req); + +# +# hopefully we´ve got something usefull +# +if ($res->is_success) { + if($opt_l) { + foreach $_ (split /^/m, $res->content) { + next if /^\s*$/; +# +# this is the load checking section +# we parse the whole content, just in case someone +# wants to use this some day in the future +# + if (/^Total Accesses:\s+([0-9.]+)/) { $accesses = $1; next; } + if (/^Total kBytes:\s+([0-9.]+)/) { $kbytes = $1; next; } + if (/^CPULoad:\s+([0-9.]+)\s+/) { $load = $1; next; } + if (/^Uptime:\s+([0-9.]+)\s+/) { $uptime = $1; next; } + if (/^ReqPerSec:\s+([0-9.]+)\s+/) { $rps = $1; next; } + if (/^BytesPerSec:\s+([0-9.]+)\s+/) { $bps = $1; next; } + if (/^BytesPerReq:\s+([0-9.]+)\s+/) { $bpr = $1; next; } + if (/^BusyServers:\s+([0-9.]+)\s+/) { $busy = $1; next; } + if (/^IdleServers:\s+([0-9.]+)\s+/) { $idle = $1; next; } + if (/^Scoreboard:\s+([SRWKDLG_.]+)\s+/) { $score = $1; next; } + print "Unknown Status\n"; + exit $ERRORS{"UNKNOWN"}; + } +# +# now we even parse the whole scoreboard, just for fun +# + foreach $scorepoint (split //m, $score) { + if($scorepoint eq '.') { $scores{'.'}+=1; next; } # Unused + if($scorepoint eq '_') { $scores{'_'}+=1; next; } # Waiting + if($scorepoint eq 'S') { $scores{'S'}+=1; next; } # Starting + if($scorepoint eq 'R') { $scores{'R'}+=1; next; } # Reading + if($scorepoint eq 'W') { $scores{'W'}+=1; next; } # Writing + if($scorepoint eq 'K') { $scores{'K'}+=1; next; } # Keepalive + if($scorepoint eq 'D') { $scores{'D'}+=1; next; } # DNS Lookup + if($scorepoint eq 'L') { $scores{'L'}+=1; next; } # Logging + if($scorepoint eq 'G') { $scores{'G'}+=1; next; } # Going + } + + if($busy>$alert) { + printf "HTTPD CRITICAL: %.0f servers running\n", $busy; + exit $ERRORS{"CRITICAL"}; + } + if($busy>$warn) { + printf "HTTPD WARNING: %.0f servers running\n", $busy; + exit $ERRORS{"WARNING"}; + } + printf "HTTPD ok: %.0f servers running, %d idle\n", $busy, $idle; + exit $ERRORS{"OK"}; + + } else { +# +# this is the performance check section +# We are a bit lazy here, no parsing of the initial data +# block and the scoreboard. +# However, you have the whole set of per server +# information to play with ;-) +# The actual performance is measured by adding up the +# milliseconds required to process the most recent +# requests of all instances and then taking the average. +# + foreach $tablerow (split /<tr>/m, $res->content) { + ($empty,$Srv,$PID,$Acc,$M,$CPU,$SS,$Req,$Conn,$Child,$Slot,$Client,$VHost,$Request) + = split /<td>/, $tablerow; + if($Req) { + $lines+=1; + $req_sum+=$Req; + } + undef $Req; + } + $average=$req_sum/$lines; + if($average>$alert) { + printf "HTTPD CRITICAL: average response time %.0f + milliseconds\n", $average; + exit $ERRORS{"CRITICAL"}; + } + if($average>$warn) { + printf "HTTPD WARNING: average response time %.0f + milliseconds\n", $average; + exit $ERRORS{"WARNING"}; + } + if($average>0) { + printf "HTTPD ok: average response time %.0f milliseconds\n", + $average; + exit $ERRORS{"OK"}; + } + print "Unknown Status\n"; + exit $ERRORS{"UNKNOWN"}; + } +} else { + print "HTTP request failed\n"; + exit $ERRORS{"CRITICAL"}; +} + + +# +# ok, now we are almost through +# These last subroutines do the things for those that do not +# read source code. +# +sub print_usage () { + print "Usage: $0 -H <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>]\n"; } + +sub print_help () { + print "\n"; + print "\n"; + print "check_apache nagios plugin version $version\n"; + print "\n"; + print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n"; + print "copies of the plugins under the terms of the GNU General Public License.\n"; + print "For more information about these matters, see the file named COPYING.\n"; + print "\n"; + print "Copyright (c) 2001 Sebastian Hetze Linux Information Systems AG\n"; + print "\n"; + print "\n"; + print "This plugin checks the apache HTTP service on the specified host.\n"; + print "It uses the mod_status facilities provided by the apache server.\n"; + print "The monitoring server must be authorized in httpd.conf.\n"; + print "\n"; + print "\n"; + print_usage(); + print "\n"; + print "Options:\n"; + print " -H, --hostname=ADDRESS\n"; + print " host name argument for server.\n"; + print " -l, --load\n"; + print " check load instead of performance.\n"; + print " -h, --help\n"; + print " print detailed help screen.\n"; + print " -V, --version\n"; + print " print version information.\n"; + print " -w, --warning=INTEGER\n"; + print " load / performance level at which a warning message will be gererated.\n"; + print " -c, --critical=INTEGER\n"; + print " load / performance level at which a critical message will be gererated.\n"; + print " -u, --url=PATH\n"; + print " location to call mod_status.\n"; + print "\n"; + print " Defaults for performance checking are $perf_w/$perf_c msec.\n"; + print " Defaults for load checking are $load_w/$load_c servers running.\n"; + print "\n"; + print "\n"; +} +# +# the end +# diff --git a/contrib/check_apc_ups.pl b/contrib/check_apc_ups.pl new file mode 100644 index 00000000..dd979f52 --- /dev/null +++ b/contrib/check_apc_ups.pl @@ -0,0 +1,314 @@ +#! /usr/bin/perl -wT +# +# Check_apc_ups - Check APC UPS status via SNMP +# Shamelessly copied from check_breeze.pl +# +# To do: +# - Send SNMP queries directly, instead of forking `snmpget`. +# - Make the status less verbose. Maybe we can send an "onLine, time +# remaining: hh:mm:ss" if all is well, and a list of specific problems +# if something is broken. + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_H $opt_T $opt_t $opt_R $opt_r + $opt_L $opt_l $PROGNAME); +use lib $main::runtimedir; +use utils qw(%ERRORS &print_revision &support &usage); + +sub print_help (); +sub print_usage (); +sub get_snmp_int_val ($); +sub escalate_exitval ($); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "T=s" => \$opt_T, "temp-critical" => \$opt_T, + "t=s" => \$opt_t, "temp-warning" => \$opt_t, + "R=s" => \$opt_R, "runtime-critical" => \$opt_R, + "r=s" => \$opt_r, "runtime-warning" => \$opt_r, + "L=s" => \$opt_L, "load-critical" => \$opt_L, + "l=s" => \$opt_l, "load-warning" => \$opt_l, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); + exit $ERRORS{'OK'}; +} + +if ($opt_h) {print_help(); exit $ERRORS{'OK'};} + +($opt_H) || ($opt_H = shift) || usage("Host name/address not specified\n"); +my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); +($host) || usage("Invalid host: $opt_H\n"); + +# Defaults + +$opt_R *= 60 * 100 if (defined $opt_R); # Convert minutes to secs/100 +$opt_r *= 60 * 100 if (defined $opt_R); + +my $tempcrit = $opt_T || 60; +my $tempwarn = $opt_t || 40; +my $runtimecrit = $opt_R || 30 * 60 * 100; # Secs / 100 +my $runtimewarn = $opt_r || 60 * 60 * 100; +my $loadcrit = $opt_L || 85; +my $loadwarn = $opt_l || 50; + +if ($tempcrit !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); } +if ($tempwarn !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); } + +if ($runtimecrit !~ /\d+/) { + usage ("Invalid critical run time threshold.\n"); +} +if ($runtimewarn !~ /\d+/) { + usage ("Invalid warning run time threshold.\n"); +} + +if ($loadcrit !~ /\d+/ || $loadcrit < 0 || $loadcrit > 100) { + usage ("Invalid critical load threshold.\n"); +} +if ($loadwarn !~ /\d+/ || $loadwarn < 0 || $loadwarn > 100) { + usage ("Invalid warning load threshold.\n"); +} + + +# APC UPS OIDs +# APC MIBs are available at ftp://ftp.apcftp.com/software/pnetmib/mib +my $upsBasicOutputStatus = ".1.3.6.1.4.1.318.1.1.1.4.1.1.0"; +my $upsBasicBatteryStatus = ".1.3.6.1.4.1.318.1.1.1.2.1.1.0"; +my $upsAdvInputLineFailCause = ".1.3.6.1.4.1.318.1.1.1.3.2.5.0"; +my $upsAdvBatteryTemperature = ".1.3.6.1.4.1.318.1.1.1.2.2.2.0"; +my $upsAdvBatteryRunTimeRemaining = ".1.3.6.1.4.1.318.1.1.1.2.2.3.0"; +my $upsAdvBatteryReplaceIndicator = ".1.3.6.1.4.1.318.1.1.1.2.2.4.0"; +my $upsAdvOutputLoad = ".1.3.6.1.4.1.318.1.1.1.4.2.3.0"; +my $upsAdvTestDiagnosticsResults = ".1.3.6.1.4.1.318.1.1.1.7.2.3.0"; + +my @outputStatVals = ( + [ undef, undef ], # pad 0 + [ undef, undef ], # pad 1 + [ "onLine", $ERRORS{'OK'} ], # 2 + [ "onBattery", $ERRORS{'WARNING'} ], # 3 + [ "onSmartBoost", $ERRORS{'WARNING'} ], # 4 + [ "timedSleeping", $ERRORS{'WARNING'} ], # 5 + [ "softwareBypass", $ERRORS{'WARNING'} ], # 6 + [ "off", $ERRORS{'CRITICAL'} ], # 7 + [ "rebooting", $ERRORS{'WARNING'} ], # 8 + [ "switchedBypass", $ERRORS{'WARNING'} ], # 9 + [ "hardwareFailureBypass", $ERRORS{'CRITICAL'} ], # 10 + [ "sleepingUntilPowerReturn", $ERRORS{'CRITICAL'} ], # 11 + [ "onSmartTrim", $ERRORS{'WARNING'} ], # 12 +); + +my @failCauseVals = ( + undef, + "noTransfer", + "highLineVoltage", + "brownout", + "blackout", + "smallMomentarySag", + "deepMomentarySag", + "smallMomentarySpike", + "largeMomentarySpike", + "selfTest", + "rateOfVoltageChnage", +); + +my @battStatVals = ( + [ undef, undef ], # pad 0 + [ undef, undef ], # pad 1 + [ "batteryNormal", $ERRORS{'OK'} ], # 2 + [ "batteryLow", $ERRORS{'CRITICAL'} ], # 3 +); + +my @battReplVals = ( + [ undef, undef ], # pad 0 + [ "noBatteryNeedsReplacing", $ERRORS{'OK'} ], # 1 + [ "batteryNeedsReplacing", $ERRORS{'CRITICAL'} ], # 2 +); + +my @diagnosticsResultsVals = ( + [ undef, undef ], # pad 0 + [ "OK", $ERRORS{'OK'} ], # 1 + [ "failed", $ERRORS{'CRITICAL'} ], # 2 + [ "invalidTest", $ERRORS{'CRITICAL'} ], # 3 + [ "testInProgress", $ERRORS{'OK'} ], # 4 +); + +my $exitval = $ERRORS{'UNKNOWN'}; +my $data; +my $onbattery = 3; + +$data = get_snmp_int_val( $upsBasicOutputStatus ); + +print "Output status: "; +if (defined ($data) && defined ($outputStatVals[$data][0])) { + print "$outputStatVals[$data][0] | "; + escalate_exitval($outputStatVals[$data][1]); +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvBatteryRunTimeRemaining ); + +print "Rem time: "; +if (defined ($data)) { + my $hrs = int($data / (60 * 60 * 100)); # Data is hundredths of a second + my $mins = int($data / (60 * 100)) % 60; + my $secs = ($data % 100) / 100; + printf "%d:%02d:%05.2f | ", $hrs, $mins, $secs; + if ($data <= $runtimecrit) { + escalate_exitval($ERRORS{'CRITICAL'}); + } elsif ($data <= $runtimewarn) { + escalate_exitval($ERRORS{'WARNING'}); + } else { + escalate_exitval($ERRORS{'OK'}); + } +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsBasicBatteryStatus ); + +print "Battery status: "; +if (defined ($data) && defined ($battStatVals[$data][0])) { + my $failcause = "unknown"; + my $fc = get_snmp_int_val( $upsAdvInputLineFailCause ); + if ($data == $onbattery) { + if (defined ($failCauseVals[$fc])) { $failcause = $failCauseVals[$fc]; } + print "$battStatVals[$data][0] ($failcause) | "; + } else { + print "$battStatVals[$data][0] | "; + } + escalate_exitval($battStatVals[$data][1]); +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvBatteryTemperature ); + +print "Battery temp(C): "; +if (defined ($data)) { + print "$data | "; + if ($data >= $tempcrit) { + escalate_exitval($ERRORS{'CRITICAL'}); + } elsif ($data >= $tempwarn) { + escalate_exitval($ERRORS{'WARNING'}); + } else { + escalate_exitval($ERRORS{'OK'}); + } +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvBatteryReplaceIndicator ); + +print "Battery repl: "; +if (defined ($data) && defined ($battReplVals[$data][0])) { + print "$battReplVals[$data][0] | "; + escalate_exitval($battReplVals[$data][1]); +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvOutputLoad ); + +print "Output load (%): "; +if (defined ($data)) { + print "$data | "; + if ($data >= $loadcrit) { + escalate_exitval($ERRORS{'CRITICAL'}); + } elsif ($data >= $loadwarn) { + escalate_exitval($ERRORS{'WARNING'}); + } else { + escalate_exitval($ERRORS{'OK'}); + } +} else { + print "unknown | "; +} + +$data = get_snmp_int_val( $upsAdvTestDiagnosticsResults ); + +print "Diag result: "; +if (defined ($data) && defined ($diagnosticsResultsVals[$data][0])) { + print "$diagnosticsResultsVals[$data][0]\n"; + escalate_exitval($diagnosticsResultsVals[$data][1]); +} else { + print "unknown\n"; +} + + +exit $exitval; + + +sub print_usage () { + print "Usage: $PROGNAME -H <host> -T temp -t temp -R minutes -r minutes\n"; + print " -L percent -l percent\n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2001 Gerald Combs/Jeffrey Blank/Karl DeBisschop + +This plugin reports the status of an APC UPS equipped with an SNMP management +module. + +"; + print_usage(); + print " +-H, --hostname=HOST + Name or IP address of host to check +-T --temp-critical + Battery degrees C above which a CRITICAL status will result (default: 60) +-t --temp-warning + Battery degrees C above which a WARNING status will result (default: 40) +-R --runtime-critical + Minutes remaining below which a CRITICAL status will result (default: 30) +-r --runtime-warning + Minutes remaining below which a WARNING status will result (default: 60) +-L --load-critical + Output load pct above which a CRITICAL status will result (default: 85 +-l --load-warning + Output load pct above which a WARNING status will result (default: 50 + +"; + support(); +} + +sub get_snmp_int_val ($) { + my $val=0; + my $oid = shift(@_); + + $val = `/usr/bin/snmpget $host public $oid 2> /dev/null`; + my @test = split(/ /,$val,3); + + return undef unless (defined ($test[2])); + + if ($test[2] =~ /\(\d+\)/) { # Later versions of UCD SNMP + ($val) = ($test[2] =~ /\((\d+)\)/); + } elsif ($test[2] =~ /: \d+/) { + ($val) = ($test[2] =~ /: (\d+)/); + } else { + $val = $test[2]; + } + + return $val; +} + +sub escalate_exitval ($) { + my $newval = shift(@_); + + if ($newval > $exitval) { $exitval = $newval; } +} diff --git a/contrib/check_bgpstate.pl b/contrib/check_bgpstate.pl new file mode 100644 index 00000000..6658a0b8 --- /dev/null +++ b/contrib/check_bgpstate.pl @@ -0,0 +1,215 @@ +#!/usr/bin/perl -w +# +# check_bgpstate.pl - nagios plugin +# +# Copyright (C) 2000 Christoph Kron +# +# 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. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + + + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +# whois programm for RIPE database queries +my $whois = '/usr/bin/whois'; +my $status; +my $TIMEOUT = 30; + +# critical bgp sessions +my %uplinks = ( 1273, 'Uplink ECRC', + 1755, 'Uplink EBONE', + 3300, 'Uplink AUCS' + ); + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + + +my %bgpPeerState = ( + '1',"idle", + '2',"connect", + '3',"active", + '4',"opensent", + '5',"openconfirm", + '6',"established" + ); +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey; +my $snmpoid; +my $key; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpbgpPeerState = '1.3.6.1.2.1.15.3.1.2'; +my $snmpbgpPeerLocalAddr = '1.3.6.1.2.1.15.3.1.5'; +my $snmpbgpPeerRemoteAddr = '1.3.6.1.2.1.15.3.1.7'; +my $snmpbgpPeerRemoteAs = '1.3.6.1.2.1.15.3.1.9'; +my $hostname; +my $session; +my $error; +my $response; +my %bgpStatus; +my $bgpestablished =0 ; +my $bgpcritical =0; +my $bgpdown =0; +my $bgpidle =0; +my $bgpmessage; +my $asname; +my $remoteas; +my @output; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl bgpstate plugin for Nagios\n"; + printf "monitors all BGP sessions\n"; + printf "usage: \n"; + printf "check_bgpstate.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n"; + printf "Copyright (C) 2000 Christoph Kron\n"; + printf "check_bgpstate.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + +push(@snmpoids, $snmpbgpPeerState); +push(@snmpoids, $snmpbgpPeerLocalAddr); +push(@snmpoids, $snmpbgpPeerRemoteAddr); +push(@snmpoids, $snmpbgpPeerRemoteAs); + +foreach $snmpoid (@snmpoids) { + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + if (!defined($response = $session->get_table($snmpoid))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + foreach $snmpkey (keys %{$response}) { + $snmpkey =~ m/.*\.(\d+\.\d+\.\d+\.\d+$)/; + $key = $1; +# printf "debug: $snmpkey: $key -> $response->{$snmpkey}\n"; + $bgpStatus{$key}{$snmpoid} = $response->{$snmpkey}; + } + $session->close; +} + +foreach $key (keys %bgpStatus) { + if ($bgpStatus{$key}{$snmpbgpPeerState} == 6 ) { + $bgpestablished++; + } + elsif ($bgpStatus{$key}{$snmpbgpPeerState} == 1 ) { + $bgpidle++; + } + else { + $bgpdown++ ; + if (exists($uplinks{$bgpStatus{$key}{$snmpbgpPeerRemoteAs}}) ) { + $bgpcritical++; + } + @output = `$whois -T aut-num AS$bgpStatus{$key}{$snmpbgpPeerRemoteAs}`; + + $asname = ""; + foreach (@output) { + if (m/as-name/) { + $asname = $_; + $asname =~ s/as-name://; + last; + } + if ( $asname =~ "" && m/descr/ ) { + $asname = $_; + $asname =~ s/descr://; + } + } + $asname =~ s/^\s*//; + $asname =~ s/\s*$//; + $bgpmessage .= sprintf("Peering with AS%s not established -> %s<BR>", + $bgpStatus{$key}{$snmpbgpPeerRemoteAs}, + $asname); + } +} + + + if ($bgpdown > 0) { + if ($bgpcritical > 0) { + $state = 'CRITICAL'; + } + else { + $state = 'WARNING'; + } + $answer = sprintf("host '%s', sessions up: %d, down: %d, shutdown: %d<BR>", + $hostname, + $bgpestablished, + $bgpdown, $bgpidle); + $answer = $answer . $bgpmessage . "\n"; + } + else { + $state = 'OK'; + $answer = sprintf("host '%s', sessions up: %d, down: %d, shutdown: %d\n", + $hostname, + $bgpestablished, + $bgpdown,$bgpidle); + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_dhcp.c b/contrib/check_dhcp.c new file mode 100644 index 00000000..8168b947 --- /dev/null +++ b/contrib/check_dhcp.c @@ -0,0 +1,992 @@ +/****************************************************************************** +* +* CHECK_DHCP.C +* +* Program: DHCP plugin for Nagios +* License: GPL +* Copyright (c) 2001 Ethan Galstad (nagios@nagios.org) +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <features.h> +#include <linux/if_ether.h> +#include <getopt.h> +#include <net/if.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +#define PROGNAME "check_dhcp" + +/*#define DEBUG*/ +#define HAVE_GETOPT_H + + +/**** Common definitions ****/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN -1 + +#define OK 0 +#define ERROR -1 + +#define FALSE 0 +#define TRUE 1 + + +/**** DHCP definitions ****/ + +#define MAX_DHCP_CHADDR_LENGTH 16 +#define MAX_DHCP_SNAME_LENGTH 64 +#define MAX_DHCP_FILE_LENGTH 128 +#define MAX_DHCP_OPTIONS_LENGTH 312 + + +typedef struct dhcp_packet_struct{ + u_int8_t op; /* packet type */ + u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ + u_int8_t hlen; /* length of hardware address (of this machine) */ + u_int8_t hops; /* hops */ + u_int32_t xid; /* random transaction id number - chosen by this machine */ + u_int16_t secs; /* seconds used in timing */ + u_int16_t flags; /* flags */ + struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ + struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ + struct in_addr siaddr; /* IP address of DHCP server */ + struct in_addr giaddr; /* IP address of DHCP relay */ + unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ + char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ + char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ + char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ + }dhcp_packet; + + +typedef struct dhcp_offer_struct{ + struct in_addr server_address; /* address of DHCP server that sent this offer */ + struct in_addr offered_address; /* the IP address that was offered to us */ + u_int32_t lease_time; /* lease time in seconds */ + u_int32_t renewal_time; /* renewal time in seconds */ + u_int32_t rebinding_time; /* rebinding time in seconds */ + struct dhcp_offer_struct *next; + }dhcp_offer; + + +typedef struct requested_server_struct{ + struct in_addr server_address; + struct requested_server_struct *next; + }requested_server; + + +#define BOOTREQUEST 1 +#define BOOTREPLY 2 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNACK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_MESSAGE_TYPE 53 +#define DHCP_OPTION_HOST_NAME 12 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQUESTED_ADDRESS 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_RENEWAL_TIME 58 +#define DHCP_OPTION_REBINDING_TIME 59 + +#define DHCP_INFINITE_TIME 0xFFFFFFFF + +#define DHCP_BROADCAST_FLAG 32768 + +#define DHCP_SERVER_PORT 67 +#define DHCP_CLIENT_PORT 68 + +#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ +#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ + +unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; + +char network_interface_name[8]="eth0"; + +u_int32_t packet_xid=0; + +u_int32_t dhcp_lease_time=0; +u_int32_t dhcp_renewal_time=0; +u_int32_t dhcp_rebinding_time=0; + +int dhcpoffer_timeout=2; + +dhcp_offer *dhcp_offer_list=NULL; +requested_server *requested_server_list=NULL; + +int valid_responses=0; /* number of valid DHCPOFFERs we received */ +int requested_servers=0; +int requested_responses=0; + +int request_specific_address=FALSE; +int received_requested_address=FALSE; +struct in_addr requested_address; + + +int process_arguments(int, char **); +int call_getopt(int, char **); +int validate_arguments(void); +void print_usage(void); +void print_help(void); + +int get_hardware_address(int,char *); + +int send_dhcp_discover(int); +int get_dhcp_offer(int); + +int get_results(void); + +int add_dhcp_offer(struct in_addr,dhcp_packet *); +int free_dhcp_offer_list(void); +int free_requested_server_list(void); + +int create_dhcp_socket(void); +int close_dhcp_socket(int); +int send_dhcp_packet(void *,int,int,struct sockaddr_in *); +int receive_dhcp_packet(void *,int,int,int,struct sockaddr_in *); + + + +int main(int argc, char **argv){ + int dhcp_socket; + int result; + + if(process_arguments(argc,argv)!=OK){ + /*usage("Invalid command arguments supplied\n");*/ + printf("Invalid command arguments supplied\n"); + exit(STATE_UNKNOWN); + } + + + /* create socket for DHCP communications */ + dhcp_socket=create_dhcp_socket(); + + /* get hardware address of client machine */ + get_hardware_address(dhcp_socket,network_interface_name); + + /* send DHCPDISCOVER packet */ + send_dhcp_discover(dhcp_socket); + + /* wait for a DHCPOFFER packet */ + get_dhcp_offer(dhcp_socket); + + /* close socket we created */ + close_dhcp_socket(dhcp_socket); + + /* determine state/plugin output to return */ + result=get_results(); + + /* free allocated memory */ + free_dhcp_offer_list(); + free_requested_server_list(); + + return result; + } + + + +/* determines hardware address on client machine */ +int get_hardware_address(int sock,char *interface_name){ + struct ifreq ifr; + + strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)); + + /* try and grab hardware address of requested interface */ + if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ + printf("Error: Could not get hardware address of interface '%s'\n",interface_name); + exit(STATE_UNKNOWN); + } + + memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); + +#ifdef DEBUG + printf("Hardware address: %02x:%02x:%02x:",client_hardware_address[0],client_hardware_address[1],client_hardware_address[2]); + printf("%02x:",client_hardware_address[3]); + printf("%02x:%02x\n",client_hardware_address[4],client_hardware_address[5]); + printf("\n"); +#endif + + return OK; + } + + +/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ +int send_dhcp_discover(int sock){ + dhcp_packet discover_packet; + struct sockaddr_in sockaddr_broadcast; + + + /* clear the packet data structure */ + bzero(&discover_packet,sizeof(discover_packet)); + + + /* boot request flag (backward compatible with BOOTP servers) */ + discover_packet.op=BOOTREQUEST; + + /* hardware address type */ + discover_packet.htype=ETHERNET_HARDWARE_ADDRESS; + + /* length of our hardware address */ + discover_packet.hlen=ETHERNET_HARDWARE_ADDRESS_LENGTH; + + discover_packet.hops=0; + + /* transaction id is supposed to be random */ + srand(time(NULL)); + packet_xid=random(); + discover_packet.xid=htonl(packet_xid); + + /**** WHAT THE HECK IS UP WITH THIS?!? IF I DON'T MAKE THIS CALL, ONLY ONE SERVER RESPONSE IS PROCESSED!!!! ****/ + /* downright bizzarre... */ + ntohl(discover_packet.xid); + + /*discover_packet.secs=htons(65535);*/ + discover_packet.secs=0xFF; + + /* tell server it should broadcast its response */ + discover_packet.flags=htons(DHCP_BROADCAST_FLAG); + + /* our hardware address */ + memcpy(discover_packet.chaddr,client_hardware_address,ETHERNET_HARDWARE_ADDRESS_LENGTH); + + /* first four bytes of options field is magic cookie (as per RFC 2132) */ + discover_packet.options[0]='\x63'; + discover_packet.options[1]='\x82'; + discover_packet.options[2]='\x53'; + discover_packet.options[3]='\x63'; + + /* DHCP message type is embedded in options field */ + discover_packet.options[4]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ + discover_packet.options[5]='\x01'; /* DHCP message option length in bytes */ + discover_packet.options[6]=DHCPDISCOVER; + + /* the IP address we're requesting */ + if(request_specific_address==TRUE){ + discover_packet.options[7]=DHCP_OPTION_REQUESTED_ADDRESS; + discover_packet.options[8]='\x04'; + memcpy(&discover_packet.options[9],&requested_address,sizeof(requested_address)); + } + + /* send the DHCPDISCOVER packet to broadcast address */ + sockaddr_broadcast.sin_family=AF_INET; + sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); + sockaddr_broadcast.sin_addr.s_addr=INADDR_BROADCAST; + bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); + + +#ifdef DEBUG + printf("DHCPDISCOVER to %s port %d\n",inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); + printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); + printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); + printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); + printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); + printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); +#endif + + /* send the DHCPDISCOVER packet out */ + send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); + +#ifdef DEBUG + printf("\n\n"); +#endif + + return OK; + } + + + + +/* waits for a DHCPOFFER message from one or more DHCP servers */ +int get_dhcp_offer(int sock){ + dhcp_packet offer_packet; + struct sockaddr_in source; + int result=OK; + int timeout=1; + int responses=0; + int x; + time_t start_time; + time_t current_time; + + time(&start_time); + + /* receive as many responses as we can */ + for(responses=0,valid_responses=0;;){ + + time(¤t_time); + if((current_time-start_time)>=dhcpoffer_timeout) + break; + +#ifdef DEBUG + printf("\n\n"); +#endif + + bzero(&source,sizeof(source)); + bzero(&offer_packet,sizeof(offer_packet)); + + result=OK; + result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); + + if(result!=OK){ +#ifdef DEBUG + printf("Result=ERROR\n"); +#endif + continue; + } + else{ +#ifdef DEBUG + printf("Result=OK\n"); +#endif + responses++; + } + +#ifdef DEBUG + printf("DHCPOFFER from IP address %s\n",inet_ntoa(source.sin_addr)); + printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); +#endif + + /* check packet xid to see if its the same as the one we used in the discover packet */ + if(ntohl(offer_packet.xid)!=packet_xid){ +#ifdef DEBUG + printf("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n",ntohl(offer_packet.xid),packet_xid); +#endif + continue; + } + + /* check hardware address */ + result=OK; +#ifdef DEBUG + printf("DHCPOFFER chaddr: "); +#endif + for(x=0;x<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){ +#ifdef DEBUG + printf("%02X",(unsigned char)offer_packet.chaddr[x]); +#endif + if(offer_packet.chaddr[x]!=client_hardware_address[x]){ + result=ERROR; + } + } +#ifdef DEBUG + printf("\n"); +#endif + if(result==ERROR){ +#ifdef DEBUG + printf("DHCPOFFER hardware address did not match our own - ignoring packet\n"); +#endif + continue; + } + +#ifdef DEBUG + printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); + printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); + printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); + printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); +#endif + + add_dhcp_offer(source.sin_addr,&offer_packet); + + valid_responses++; + } + +#ifdef DEBUG + printf("Total responses seen on the wire: %d\n",responses); + printf("Valid responses for this machine: %d\n",valid_responses); +#endif + + return OK; + } + + + +/* sends a DHCP packet */ +int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest){ + struct sockaddr_in myname; + int result; + + result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr_in *)dest,sizeof(*dest)); + +#ifdef DEBUG + printf("send_dhcp_packet result: %d\n",result); +#endif + + if(result<0) + return ERROR; + + return OK; + } + + + +/* receives a DHCP packet */ +int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){ + struct timeval tv; + fd_set readfds; + int recv_result; + socklen_t address_size; + struct sockaddr_in source_address; + + + /* wait for data to arrive (up time timeout) */ + tv.tv_sec=timeout; + tv.tv_usec=0; + FD_ZERO(&readfds); + FD_SET(sock,&readfds); + select(sock+1,&readfds,NULL,NULL,&tv); + + /* make sure some data has arrived */ + if(!FD_ISSET(sock,&readfds)){ +#ifdef DEBUG + printf("No (more) data recieved\n"); +#endif + return ERROR; + } + + else{ + + /* why do we need to peek first? i don't know, its a hack. without it, the source address of the first packet received was + not being interpreted correctly. sigh... */ + bzero(&source_address,sizeof(source_address)); + recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr_in *)&source_address,&address_size); +#ifdef DEBUG + printf("recv_result_1: %d\n",recv_result); +#endif + recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr_in *)&source_address,&address_size); +#ifdef DEBUG + printf("recv_result_2: %d\n",recv_result); +#endif + + if(recv_result==-1){ +#ifdef DEBUG + printf("recvfrom() failed, "); + printf("errno: (%d) -> %s\n",errno,strerror(errno)); +#endif + return ERROR; + } + else{ +#ifdef DEBUG + printf("receive_dhcp_packet() result: %d\n",recv_result); + printf("receive_dhcp_packet() source: %s\n",inet_ntoa(source_address.sin_addr)); +#endif + + memcpy(address,&source_address,sizeof(source_address)); + return OK; + } + } + + return OK; + } + + + +/* creates a socket for DHCP communication */ +int create_dhcp_socket(void){ + struct sockaddr_in myname; + int sock; + int flag=1; + + /* Set up the address we're going to bind to. */ + bzero(&myname,sizeof(myname)); + myname.sin_family=AF_INET; + myname.sin_port=htons(DHCP_CLIENT_PORT); + myname.sin_addr.s_addr=INADDR_ANY; /* listen on any address */ + bzero(&myname.sin_zero,sizeof(myname.sin_zero)); + + /* create a socket for DHCP communications */ + sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); + if(sock<0){ + printf("Error: Could not create socket!\n"); + exit(STATE_UNKNOWN); + } + +#ifdef DEBUG + printf("DHCP socket: %d\n",sock); +#endif + + /* set the reuse address flag so we don't get errors when restarting */ + flag=1; + if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ + printf("Error: Could not set reuse address option on DHCP socket!\n"); + exit(STATE_UNKNOWN); + } + + /* set the broadcast option - we need this to listen to DHCP broadcast messages */ + if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){ + printf("Error: Could not set broadcast option on DHCP socket!\n"); + exit(STATE_UNKNOWN); + } + + /* bind the socket */ + if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ + printf("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n",DHCP_CLIENT_PORT); + exit(STATE_UNKNOWN); + } + + return sock; + } + + + + + +/* closes DHCP socket */ +int close_dhcp_socket(int sock){ + + close(sock); + + return OK; + } + + + + +/* adds a requested server address to list in memory */ +int add_requested_server(struct in_addr server_address){ + requested_server *new_server; + + new_server=(requested_server *)malloc(sizeof(requested_server)); + if(new_server==NULL) + return ERROR; + + new_server->server_address=server_address; + + new_server->next=requested_server_list; + requested_server_list=new_server; + + requested_servers++; + +#ifdef DEBUG + printf("Requested server address: %s\n",inet_ntoa(new_server->server_address)); +#endif + + return OK; + } + + + + +/* adds a DHCP OFFER to list in memory */ +int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ + dhcp_offer *new_offer; + int x; + int y; + unsigned option_type; + unsigned option_length; + + if(offer_packet==NULL) + return ERROR; + + /* process all DHCP options present in the packet */ + for(x=4;x<MAX_DHCP_OPTIONS_LENGTH;){ + + /* end of options (0 is really just a pad, but bail out anyway) */ + if((int)offer_packet->options[x]==-1 || (int)offer_packet->options[x]==0) + break; + + /* get option type */ + option_type=offer_packet->options[x++]; + + /* get option length */ + option_length=offer_packet->options[x++]; + +#ifdef DEBUG + printf("Option: %d (0x%02X)\n",option_type,option_length); +#endif + + /* get option data */ + if(option_type==DHCP_OPTION_LEASE_TIME) + dhcp_lease_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); + if(option_type==DHCP_OPTION_RENEWAL_TIME) + dhcp_renewal_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); + if(option_type==DHCP_OPTION_REBINDING_TIME) + dhcp_rebinding_time=ntohl(*((u_int32_t *)&offer_packet->options[x])); + + /* skip option data we're ignoring */ + else + for(y=0;y<option_length;y++,x++); + } + +#ifdef DEBUG + if(dhcp_lease_time==DHCP_INFINITE_TIME) + printf("Lease Time: Infinite\n"); + else + printf("Lease Time: %lu seconds\n",(unsigned long)dhcp_lease_time); + if(dhcp_renewal_time==DHCP_INFINITE_TIME) + printf("Renewal Time: Infinite\n"); + else + printf("Renewal Time: %lu seconds\n",(unsigned long)dhcp_renewal_time); + if(dhcp_rebinding_time==DHCP_INFINITE_TIME) + printf("Rebinding Time: Infinite\n"); + printf("Rebinding Time: %lu seconds\n",(unsigned long)dhcp_rebinding_time); +#endif + + new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); + + if(new_offer==NULL) + return ERROR; + + + new_offer->server_address=source; + new_offer->offered_address=offer_packet->yiaddr; + new_offer->lease_time=dhcp_lease_time; + new_offer->renewal_time=dhcp_renewal_time; + new_offer->rebinding_time=dhcp_rebinding_time; + + +#ifdef DEBUG + printf("Added offer from server @ %s",inet_ntoa(new_offer->server_address)); + printf(" of IP address %s\n",inet_ntoa(new_offer->offered_address)); +#endif + + /* add new offer to head of list */ + new_offer->next=dhcp_offer_list; + dhcp_offer_list=new_offer; + + return OK; + } + + + + +/* frees memory allocated to DHCP OFFER list */ +int free_dhcp_offer_list(void){ + dhcp_offer *this_offer; + dhcp_offer *next_offer; + + for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ + next_offer=this_offer->next; + free(this_offer); + } + + return OK; + } + + + + +/* frees memory allocated to requested server list */ +int free_requested_server_list(void){ + requested_server *this_server; + requested_server *next_server; + + for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ + next_server=this_server->next; + free(this_server); + } + + return OK; + } + + +/* gets state and plugin output to return */ +int get_results(void){ + dhcp_offer *temp_offer; + requested_server *temp_server; + int result; + u_int32_t max_lease_time=0; + + received_requested_address=FALSE; + + /* checks responses from requested servers */ + requested_responses=0; + if(requested_servers>0){ + + for(temp_server=requested_server_list;temp_server!=NULL;temp_server=temp_server->next){ + + for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ + + /* get max lease time we were offered */ + if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) + max_lease_time=temp_offer->lease_time; + + /* see if we got the address we requested */ + if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) + received_requested_address=TRUE; + + /* see if the servers we wanted a response from talked to us or not */ + if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ +#ifdef DEBUG + printf("DHCP Server Match: Offerer=%s",inet_ntoa(temp_offer->server_address)); + printf(" Requested=%s\n",inet_ntoa(temp_server->server_address)); +#endif + requested_responses++; + } + } + } + + } + + /* else check and see if we got our requested address from any server */ + else{ + + for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ + + /* get max lease time we were offered */ + if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) + max_lease_time=temp_offer->lease_time; + + /* see if we got the address we requested */ + if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) + received_requested_address=TRUE; + } + } + + result=STATE_OK; + if(valid_responses==0) + result=STATE_CRITICAL; + else if(requested_servers>0 && requested_responses==0) + result=STATE_CRITICAL; + else if(requested_responses<requested_servers) + result=STATE_WARNING; + else if(request_specific_address==TRUE && received_requested_address==FALSE) + result=STATE_WARNING; + + + printf("DHCP %s: ",(result==STATE_OK)?"ok":"problem"); + + /* we didn't receive any DHCPOFFERs */ + if(dhcp_offer_list==NULL){ + printf("No DHCPOFFERs were received.\n"); + return result; + } + + printf("Received %d DHCPOFFER(s)",valid_responses); + + if(requested_servers>0) + printf(", %s%d of %d requested servers responded",((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); + + if(request_specific_address==TRUE) + printf(", requested address (%s) was %soffered",inet_ntoa(requested_address),(received_requested_address==TRUE)?"":"not "); + + printf(", max lease time = "); + if(max_lease_time==DHCP_INFINITE_TIME) + printf("Infinity"); + else + printf("%lu sec",(unsigned long)max_lease_time); + + printf(".\n"); + + return result; + } + + + + + + +/* print usage help */ +void print_help(void){ + + /*print_revision(PROGNAME,"$Revision$");*/ + + printf("Copyright (c) 2001 Ethan Galstad (nagios@nagios.org)\n\n"); + printf("This plugin tests the availability of DHCP servers on a network.\n\n"); + + print_usage(); + + printf + ("\nOptions:\n" + " -s, --serverip=IPADDRESS\n" + " IP address of DHCP server that we must hear from\n" + " -r, --requestedip=IPADDRESS\n" + " IP address that should be offered by at least one DHCP server\n" + " -t, --timeout=INTEGER\n" + " Seconds to wait for DHCPOFFER before timeout occurs\n" + " -i, --interface=STRING\n" + " Interface to to use for listening (i.e. eth0)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n" + ); + + /*support();*/ + + return; + } + + +/* prints usage information */ +void print_usage(void){ + + printf("Usage: %s [-s serverip] [-r requestedip] [-t timeout] [-i interface]\n",PROGNAME); + printf(" %s --help\n",PROGNAME); + printf(" %s --version\n",PROGNAME); + + return; + } + + + + +/* process command-line arguments */ +int process_arguments(int argc, char **argv){ + int c; + + if(argc<1) + return ERROR; + + c=0; + while((c+=(call_getopt(argc-c,&argv[c])))<argc){ + + /* + if(is_option(argv[c])) + continue; + */ + } + + return validate_arguments(); + } + + + +int call_getopt(int argc, char **argv){ + int c=0; + int i=0; + struct in_addr ipaddress; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = + { + {"serverip", required_argument,0,'s'}, + {"requestedip", required_argument,0,'r'}, + {"timeout", required_argument,0,'t'}, + {"interface", required_argument,0,'i'}, + {"verbose", no_argument, 0,'v'}, + {"version", no_argument, 0,'V'}, + {"help", no_argument, 0,'h'}, + {0,0,0,0} + }; +#endif + + while(1){ +#ifdef HAVE_GETOPT_H + c=getopt_long(argc,argv,"+hVvt:s:r:t:i:",long_options,&option_index); +#else + c=getopt(argc,argv,"+?hVvt:s:r:t:i:"); +#endif + + i++; + + if(c==-1||c==EOF||c==1) + break; + + switch(c){ + case 'w': + case 'r': + case 't': + case 'i': + i++; + break; + default: + break; + } + + switch(c){ + + case 's': /* DHCP server address */ + if(inet_aton(optarg,&ipaddress)) + add_requested_server(ipaddress); + /* + else + usage("Invalid server IP address\n"); + */ + break; + + case 'r': /* address we are requested from DHCP servers */ + if(inet_aton(optarg,&ipaddress)){ + requested_address=ipaddress; + request_specific_address=TRUE; + } + /* + else + usage("Invalid requested IP address\n"); + */ + break; + + case 't': /* timeout */ + + /* + if(is_intnonneg(optarg)) + */ + if(atoi(optarg)>0) + dhcpoffer_timeout=atoi(optarg); + /* + else + usage("Time interval must be a nonnegative integer\n"); + */ + break; + + case 'i': /* interface name */ + + strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); + network_interface_name[sizeof(network_interface_name)-1]='\x0'; + + break; + + case 'V': /* version */ + + /*print_revision(PROGNAME,"$Revision$");*/ + exit(STATE_OK); + + case 'h': /* help */ + + print_help(); + exit(STATE_OK); + + case '?': /* help */ + + /*usage("Invalid argument\n");*/ + break; + + default: + break; + } + } + + return i; + } + + + +int validate_arguments(void){ + + return OK; + } + diff --git a/contrib/check_dlswcircuit.pl b/contrib/check_dlswcircuit.pl new file mode 100755 index 00000000..f6ef9311 --- /dev/null +++ b/contrib/check_dlswcircuit.pl @@ -0,0 +1,221 @@ +#!/usr/bin/perl -w +# +# check_dlswcircuit.pl - nagios plugin +# +# Checks if a Cisco Dlsw circuit is connected. +# +# +# Copyright (C) 2000 Carsten Foss & Christoph Kron +# +# Basically this is an adapted version of Christoph Kron's (ck@zet.net) check_ifoperstatus.pl plugin. +# most of the thanks should go to him. +# +# 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. +# +# Arguments : -s <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME or IP-Addr> +# - +# Source & Dest Mac/Sap arguments must be given in Hex as this example : 40.00.01.37.45.01.ss (Where ss is the sap) +# +# Sample command line : check_dlswcircuit.pl -s 40.00.01.37.45.01.04 -d 40.00.02.37.45.02.04 -c secret 1.2.3.4 +# +# Sample host.cfg entry : +#service[Dlsw-xx]=NCP1-NCP2;0;24x7;3;5;1;router-admins;240;24x7;1;1;0;;check_dlswcircuit!-s 40.00.01.37.45.01.04!-d 40.00..01.37.45.02.04!-c secret!1.2.3.4 +# remember to add the service to commands.cfg , something like this: +# command[check_dlswcircuit]=$USER1$/check_dlswcircuit.pl $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ +# +# Report bugs to: cfo@dmdata.dk +# +# 11.03.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %dlswCircuitStatus = ( + '1','disconnected', + '2','circuitStart', + '3','resolvePending', + '4','circuitPending', + '5','circuitEstablished', + '6','connectPending', + '7','contactPending', + '8','connected', + '9','disconnectPending', + '10','haltPending', + '11','haltPendingNoack', + '13','circuitRestart', + '14','restartPending'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $smac = ""; +my $dmac = ""; +my $community = "public"; +my $port = 161; +#Dlsw Circuit Oid enterprises.9.10.9.1.5.2.1.17.6.0.96.148.47.230.166.4.6.64.0.1.55.69.2.4 = 8 +my $enterpriseOid = "1.3.6.1.4.1"; +my $ciscoDlswCircuitOid = ".9.10.9.1.5.2.1.17."; +my $unknownOid = "6."; +my $smacOid = ""; +my $dmacOid = ""; +my $tmpOid = ""; +my @tmparg; +my $snmpoid; +my @snmpoids; +my $hostname; +my $session; +my $error; +my $response; +my $p = ""; +my $q = ""; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check Cisco Dlsw Circuit State plugin for Nagios\n"; + printf "checks operational status of specified DLSW Circuit\n"; + printf "usage: \n"; + printf "check_dlswcircuit.pl -s <SourceMac> -d <DestMac> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>"; + printf "\nCopyright (C) 2000 Carsten Foss\n"; + printf "check_dlswcircuit.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("sourcemac=s",\$smac,"destmac=s",\$dmac, + "community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + +# +#Convert Source Mac & Sap +# + @tmparg = split(/\./,$smac); + #print "-$smac-\n"; + #print "@tmparg\n"; + #print "$#tmparg\n"; + if($#tmparg != 6) + { + print "SourceMac/Sap format $smac not valid\n"; + &usage; + } + while($p = shift @tmparg) + { + $q = hex($p); + $smacOid = $smacOid.$q; + $smacOid = $smacOid.'.'; + } + + #print "@tmparg1\n"; + #print "$smacOid\n"; + +# +#Convert Dest Mac & Sap +# + @tmparg = split(/\./,$dmac); + #print "-$dmac-\n"; + #print "@tmparg\n"; + #print "$#tmparg\n"; + if($#tmparg != 6) + { + print "DestMac/Sap format $dmac not valid\n"; + &usage; + } + + while($p = shift @tmparg) + { + $q = hex($p); + $dmacOid = $dmacOid.$q; + $dmacOid = $dmacOid.'.'; + } +# Remove Trailing Dot + $dmacOid = substr($dmacOid,0,length($dmacOid)-1); + + + #print "@tmparg1\n"; + #print "$dmacOid\n"; +#Build the Dlsw Oic to use + $snmpoid = $enterpriseOid.$ciscoDlswCircuitOid.$unknownOid.$smacOid.$unknownOid.$dmacOid ; + #print "$snmpoid\n"; + + #shift; + $hostname = shift || &usage; + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + push(@snmpoids,$snmpoid); + #push(@snmpoids,$snmpLocIfDescr); + + if (!defined($response = $session->get_request(@snmpoids))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$smac - $dmac"); + exit $ERRORS{$state}; + } + + $answer = sprintf("dlsw circuit %s - %s at host '%s',is %s\n", + $smac, + $dmac, + $hostname, + $dlswCircuitStatus{$response->{$snmpoid}} + ); + + $session->close; + + if ( $response->{$snmpoid} == 8 ) { + $state = 'OK'; + } + else { + $state = 'CRITICAL'; + } + +print ("$state: $answer"); +exit $ERRORS{$state}; diff --git a/contrib/check_dns_random.pl b/contrib/check_dns_random.pl new file mode 100644 index 00000000..787d4644 --- /dev/null +++ b/contrib/check_dns_random.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl +# ------------------------------------------------------------------------------ +# File Name: check_dns_random.pl +# Author: Richard Mayhew - South Africa +# Date: 2000/01/26 +# Version: 1.0 +# Description: This script will check to see if dns resolves hosts +# randomly from a list using the check_dns plugin. +# Email: netsaint@splash.co.za +# ------------------------------------------------------------------------------ +# Copyright 1999 (c) Richard Mayhew +# Credits go to Ethan Galstad for coding Nagios +# If any changes are made to this script, please mail me a copy of the +# changes :) +# License GPL +# ------------------------------------------------------------------------------ +# Date Author Reason +# ---- ------ ------ +# 1999/09/26 RM Creation +# ------------------------------------------------------------------------------ + +# -----------------------------------------------------------------[ Require ]-- +require 5.004; + +# --------------------------------------------------------------------[ Uses ]-- +use Socket; +use strict; + +# --------------------------------------------------------------[ Enviroment ]-- +$ENV{PATH} = "/bin"; +$ENV{BASH_ENV} = ""; +$|=1; + +my $host = shift || &usage; + +my $domainfile = "/usr/local/nagios/etc/domains.list"; +my $wc = `/usr/bin/wc -l $domainfile`; +my $check = "/usr/local/nagios/libexec/check_dns"; +my $x = 0; +my $srv_file = ""; +my $z = ""; +my $y = ""; + +open(DOMAIN,"<$domainfile") or die "Error Opening $domainfile File!\n"; + while (<DOMAIN>) { + $srv_file .= $_; +} + close(DOMAIN); + my @data = split(/\n/,$srv_file); + +chomp $wc; +$wc =~ s/ //g; +$wc =~ s/domains//g; + +$x = rand $wc; +($z,$y) = split(/\./,$x); + +print `$check $data[$z] $host`; + + + +sub usage +{ + print "Minimum arguments not supplied!\n"; + print "\n"; + print "Perl Check Random DNS plugin for Nagios\n"; + print "Copyright (c) 2000 Richard Mayhew\n"; + print "\n"; + print "Usage: check_dns_random.pl <host>\n"; + print "\n"; + print "<host> = DNS server you would like to query.\n"; + exit -1; + +} + diff --git a/contrib/check_email_loop.pl b/contrib/check_email_loop.pl new file mode 100644 index 00000000..733406da --- /dev/null +++ b/contrib/check_email_loop.pl @@ -0,0 +1,268 @@ +#!/usr/bin/perl +# +# (c)2000 Benjamin Schmid, blueshift@gmx.net (emergency use only ;-) +# Copyleft by GNU GPL +# +# +# check_email_loop Nagios Plugin +# +# This script sends a mail with a specific id in the subject via +# an given smtp-server to a given email-adress. When the script +# is run again, it checks for this Email (with its unique id) on +# a given pop3 account and send another mail. +# +# +# Example: check_email_loop.pl -poph=mypop -popu=user -pa=password +# -smtph=mailer -from=returnadress@yoursite.com +# -to=remaileradress@friend.com -pendc=2 -lostc=0 +# +# This example will send eacht time this check is executed a new +# mail to remaileradress@friend.com using the SMTP-Host mailer. +# Then it looks for any back-forwarded mails in the POP3 host +# mypop. In this Configuration CRITICAL state will be reached if +# more than 2 Mails are pending (meaning that they did not came +# back till now) or if a mails got lost (meaning a mail, that was +# send later came back prior to another mail). +# + +use Net::POP3; +use Net::SMTP; +use strict; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + +# ---------------------------------------- + +my $TIMEOUT = 120; +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my $state = "UNKNOWN"; +my ($sender,$receiver, $pophost, $popuser, $poppasswd, $smtphost); +my ($poptimeout,$smtptimeout,$pinginterval)=(60,60,5); +my ($lostwarn, $lostcrit,$pendwarn, $pendcrit); + +# Internal Vars +my ($pop,$msgcount,@msglines,$statinfo,@messageids,$newestid); +my ($matchcount,$statfile) = (0,"check_email_loop.stat"); + +# Subs declaration +sub usage; +sub messagematchs; +sub nsexit; + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: $0 Time-Out $TIMEOUT s \n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +# Evaluate Command Line Parameters +my $status = GetOptions( + "from=s",\$sender, + "to=s",\$receiver, + "pophost=s",\$pophost, + "popuser=s",\$popuser, + "passwd=s",\$poppasswd, + "poptimeout=i",\$poptimeout, + "smtphost=s",\$smtphost, + "smtptimeout=i",\$smtptimeout, + "statfile=s",\$statfile, + "interval=i",\$pinginterval, + "lostwarr=i",\$lostwarn, + "lostcrit=i",\$lostcrit, + "pendwarn=i",\$pendwarn, + "pendcrit=i",\$pendcrit, + ); +usage() if ($status == 0 || ! ($pophost && $popuser && $poppasswd && + $smtphost && $receiver && $sender )); + +# Try to read the ids of the last send emails out of statfile +if (open STATF, "$statfile") { + @messageids = <STATF>; + chomp @messageids; + close STATF; +} + +# Try to open statfile for writing +if (!open STATF, ">$statfile") { + nsexit("Failed to open mail-ID database $statfile for writing",'CRITICAL'); +} + +# Ok - check if it's time to release another mail + +# ... + +# creating new serial id +my $serial = time(); +$serial = "ID#" . $serial . "#$$"; + +# sending new ping email +my $smtp = Net::SMTP->new($smtphost,Timeout=>$smtptimeout) + || nsexit("SMTP connect timeout ($smtptimeout s)",'CRITICAL'); +($smtp->mail($sender) && + $smtp->to($receiver) && + $smtp->data() && + $smtp->datasend("To: $receiver\nSubject: E-Mail Ping [$serial]\n\n". + "This is a automatically sended E-Mail.\n". + "It ist not intended for human reader.\n\n". + "Serial No: $serial\n") && + $smtp->dataend() && + $smtp->quit + ) || nsexit("Error delivering message",'CRITICAL'); + +# no the interessting part: let's if they are receiving ;-) + +$pop = Net::POP3->new( $pophost, + Timeout=>$poptimeout) + || nsexit("POP3 connect timeout (>$poptimeout s, host: $pophost)",'CRITICAL'); + +$msgcount=$pop->login($popuser,$poppasswd); + +$statinfo="$msgcount mails on POP3"; + +nsexit("POP3 login failed (user:$popuser)",'CRITICAL') if (!defined($msgcount)); + +# Count messages, that we are looking 4: +while ($msgcount > 0) { + @msglines = @{$pop->get($msgcount)}; + + for (my $i=0; $i < scalar @messageids; $i++) { + if (messagematchsid(\@msglines,$messageids[$i])) { + $matchcount++; + # newest received mail than the others, ok remeber id. + $newestid = $messageids[$i] if ($messageids[$i] > $newestid || !defined $newestid); + $pop->delete($msgcount); # remove E-Mail from POP3 server + splice @messageids, $i, 1;# remove id from List + last; # stop looking in list + } + } + + $msgcount--; +} + +$pop->quit(); # necessary for pop3 deletion! + +# traverse through the message list and mark the lost mails +# that mean mails that are older than the last received mail. +if (defined $newestid) { + $newestid =~ /\#(\d+)\#/; + $newestid = $1; + for (my $i=0; $i < scalar @messageids; $i++) { + $messageids[$i] =~ /\#(\d+)\#/; + my $akid = $1; + if ($akid < $newestid) { + $messageids[$i] =~ s/^ID/LI/; # mark lost + } + } +} + +# Write list to id-Database +foreach my $id (@messageids) { + print STATF "$id\n"; +} +print STATF "$serial\n"; # remember send mail of this session +close STATF; + +# ok - count lost and pending mails; +my @tmp = grep /^ID/, @messageids; +my $pendingm = scalar @tmp; +@tmp = grep /^LI/, @messageids; +my $lostm = scalar @tmp; + +# Evaluate the Warnin/Crit-Levels +if (defined $pendwarn && $pendingm > $pendwarn) { $state = 'WARNING'; } +if (defined $lostwarn && $lostm > $lostwarn) { $state = 'WARNING'; } +if (defined $pendcrit && $pendingm > $pendcrit) { $state = 'CRITICAL'; } +if (defined $lostcrit && $lostm > $lostcrit) { $state = 'CRITICAL'; } + +if ((defined $pendwarn || defined $pendcrit || defined $lostwarn + || defined $lostcrit) && ($state eq 'UNKNOWN')) {$state='OK';} + + +# Append Status info +$statinfo = $statinfo . ", $matchcount mail(s) came back,". + " $pendingm pending, $lostm lost."; + +# Exit in a Nagios-compliant way +nsexit($statinfo); + +# ---------------------------------------------------------------------- + +sub usage { + print "check_email_loop 1.0 Nagios Plugin - Real check of a E-Mail system\n"; + print "=" x 75,"\nERROR: Missing or wrong arguments!\n","=" x 75,"\n"; + print "This script sends a mail with a specific id in the subject via an given\n"; + print "smtp-server to a given email-adress. When the script is run again, it checks\n"; + print "for this Email (with its unique id) on a given pop3 account and sends \n"; + print "another mail.\n"; + print "\nThe following options are available:\n"; + print " -from=text email adress of send (for mail returnr on errors)\n"; + print " -to=text email adress to which the mails should send to\n"; + print " -pophost=text IP or name of the POP3-host to be checked\n"; + print " -popuser=text Username of the POP3-account\n"; + print " -passwd=text Password for the POP3-user\n"; + print " -poptimeout=num Timeout in seconds for the POP3-server\n"; + print " -smtphost=text IP oder name of the SMTP host\n"; + print " -smtptimeout=num Timeout in seconds for the SMTP-server\n"; + print " -statfile=text File to save ids of messages ($statfile)\n"; +# print " -interval=num Time (in minutes) that must pass by before sending\n" +# print " another Ping-mail (gibe a new try);\n"; + print " -lostwarn=num WARNING-state if more than num lost emails\n"; + print " -lostcrit=num CRITICAL \n"; + print " -pendwarn=num WARNING-state if more than num pending emails\n"; + print " -pendcrit=num CRITICAL \n"; + print " Options may abbreviated!\n"; + print " LOST mails are mails, being sent before the last mail arrived back.\n"; + print " PENDING mails are those, which are not. (supposed to be on the way)\n"; + print "\nExample: \n"; + print " $0 -poph=host -pa=pw -popu=popts -smtph=host -from=root\@me.com\n "; + print " -to=remailer\@testxy.com -lostc=0 -pendc=2\n"; + print "\nCopyleft 19.10.2000, Benjamin Schmid\n"; + print "This script comes with ABSOLUTELY NO WARRANTY\n"; + print "This programm is licensed under the terms of the "; + print "GNU General Public License\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# --------------------------------------------------------------------- + +sub nsexit { + my ($msg,$code) = @_; + $code=$state if (!defined $code); + print "$code: $msg\n" if (defined $msg); + exit $ERRORS{$code}; +} + +# --------------------------------------------------------------------- + +sub messagematchsid { + my ($mailref,$id) = (@_); + my (@tmp); + my $match = 0; + + # ID + $id =~ s/^LI/ID/; # evtl. remove lost mail mark + @tmp = grep /Subject: E-Mail Ping \[/, @$mailref; + chomp @tmp; + if (($tmp[0] =~ /$id/)) + { $match = 1; } + + # Sender: +# @tmp = grep /^From:\s+/, @$mailref; +# if (@tmp && $sender ne "") +# { $match = $match && ($tmp[0]=~/$sender/); } + + # Receiver: +# @tmp = grep /^To: /, @$mailref; +# if (@tmp && $receiver ne "") +# { $match = $match && ($tmp[0]=~/$receiver/); } + + return $match; +} + +# --------------------------------------------------------------------- diff --git a/contrib/check_fping_in.c b/contrib/check_fping_in.c new file mode 100644 index 00000000..50fd5eea --- /dev/null +++ b/contrib/check_fping_in.c @@ -0,0 +1,430 @@ +/****************************************************************************** +* +* CHECK_INET_FPING.C +* +* Program: Fping plugin for Nagios +* License: GPL +* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* $Id$ +* +* Modifications: +* +* 08-24-1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* Intial Coding +* 09-11-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* Change to spopen +* Fix so that state unknown is returned by default +* (formerly would give state ok if no fping specified) +* Add server_name to output +* Reformat to 80-character standard screen +* 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* set STATE_WARNING of stderr written or nonzero status returned +* 09-29-2000 Matthew Grant (matthewg@plain.co.nz) +* changes for monitoring multiple hosts for checking Internet +* reachibility +* +* Description: +* +* This plugin will use the /bin/fping command (from nagios) to ping +* the specified host for a fast check if the host is alive. Note that +* it is necessary to set the suid flag on fping. +******************************************************************************/ + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_fping" +#define PACKET_COUNT 15 +#define PACKET_SIZE 56 +#define CRITICAL_COUNT 2 +#define WARNING_COUNT 1 +#define UNKNOWN_PACKET_LOSS 200 /* 200% */ +#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ + +#define STRSZ 100 + +int textscan(char *buf); +int process_arguments(int, char **); +int get_threshold (char *arg, char *rv[2]); +void print_usage(void); +void print_help(void); + +char *server_names=NULL; +char *name="INTERNET"; +int cthresh=CRITICAL_COUNT; +int wthresh=WARNING_COUNT; +int nnames=0; +int tpl=UNKNOWN_PACKET_LOSS; +double trta=UNKNOWN_TRIP_TIME; +int packet_size=PACKET_SIZE; +int packet_count=PACKET_COUNT; +int verbose=FALSE; +int fail = 0; +int not_found = 0; +int rta_fail = 0; +int pl_fail = 0; +int unreachable = 0; + +int main(int argc, char **argv){ + int result; + int status=STATE_UNKNOWN; + char *servers=NULL; + char *command_line=NULL; + char *input_buffer=NULL; + char *pl_buffer=NULL; + char *rta_buffer=NULL; + input_buffer=malloc(MAX_INPUT_BUFFER); + rta_buffer = malloc(80); + pl_buffer = malloc(80); + memset(rta_buffer, 0, 80); + memset(pl_buffer, 0, 80); + + if(process_arguments(argc,argv)==ERROR) + usage("Could not parse arguments\n"); + + servers=strscpy(servers,server_names); + + /* compose the command */ + command_line=ssprintf + (command_line,"%s -b %d -c %d %s", + PATH_TO_FPING, + packet_size, + packet_count, + servers); + + if (verbose) printf("%s\n",command_line); + + /* run the command */ + child_process=spopen(command_line); + if(child_process==NULL){ + printf("Unable to open pipe: %s\n",command_line); + return STATE_UNKNOWN; + } + + child_stderr=fdopen(child_stderr_array[fileno(child_process)],"r"); + if(child_stderr==NULL){ + printf("Could not open stderr for %s\n",command_line); + } + + while (fgets(input_buffer,MAX_INPUT_BUFFER-1,child_process)) { + if (verbose) printf("%s",input_buffer); + result = textscan(input_buffer); + status = max(status,result); + } + + while(fgets(input_buffer,MAX_INPUT_BUFFER-1,child_stderr)) { + if (verbose) printf("%s",input_buffer); + result = textscan(input_buffer); + status = max(status,result); + } + + (void)fclose(child_stderr); + + /* close the pipe */ + if(spclose(child_process)) + status=max(status,STATE_WARNING); + + /* Analyse fail count and produce results */ + if (fail >= wthresh) { + status = max(status, STATE_WARNING); + } + + if (fail >= cthresh) { + status = max(status, STATE_CRITICAL); + } + + if( tpl != UNKNOWN_PACKET_LOSS ) { + snprintf(pl_buffer, 80, ", %d PL", pl_fail); + } + + if( trta != UNKNOWN_TRIP_TIME ) { + snprintf(rta_buffer, 80, ", %d RTA", rta_fail); + + } + + printf("FPING %s - %s, %d of %d fail, %d NF, %d UR%s%s\n", + state_text(status), + (name != NULL ? name : server_names), + fail, + nnames, + not_found, + unreachable, + pl_buffer, + rta_buffer); + + return status; +} + + + +/* analyse fping output - each event resulting in an increment of fail + * must be mutually exclusive. packet loss and round trip time analysed + * together, both at once just results in one increment of fail + */ +int textscan(char *buf) +{ + char *rtastr=NULL; + char *losstr=NULL; + double loss; + double rta; + int status=STATE_OK; + + if (strstr(buf,"not found")) { + fail++; + not_found++; + } else if(strstr(buf,"xmt/rcv/%loss") + && strstr(buf,"min/avg/max")) { + losstr = strstr(buf,"="); + losstr = 1+strstr(losstr,"/"); + losstr = 1+strstr(losstr,"/"); + rtastr = strstr(buf,"min/avg/max"); + rtastr = strstr(rtastr,"="); + rtastr = 1+index(rtastr,'/'); + loss = strtod(losstr,NULL); + rta = strtod(rtastr,NULL); + /* Increment fail counter + */ + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) { + fail++; + } + else if (trta!=UNKNOWN_TRIP_TIME && rta>trta) { + fail++; + } + else if (loss >= 100) { + fail++; + } + /* Increment other counters + */ + if (trta!=UNKNOWN_TRIP_TIME && rta>trta) + rta_fail++; + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) + pl_fail++; + if (loss >= 100) + unreachable++; + } else if(strstr(buf,"xmt/rcv/%loss") ) { + losstr = strstr(buf,"="); + losstr = 1+strstr(losstr,"/"); + losstr = 1+strstr(losstr,"/"); + loss = strtod(losstr,NULL); + /* Increment fail counter + */ + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) { + fail++; + } + else if (loss >= 100) { + fail++; + } + /* Increment other counters + */ + if (tpl!=UNKNOWN_PACKET_LOSS && loss>tpl) + pl_fail++; + if (loss >= 100) + unreachable++; + } + + return status; +} + + + + +/* process command-line arguments */ +int process_arguments(int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = + { + {"hostname" ,required_argument,0,'H'}, + {"critical" ,required_argument,0,'c'}, + {"warning" ,required_argument,0,'w'}, + {"bytes" ,required_argument,0,'b'}, + {"number" ,required_argument,0,'n'}, + {"pl-threshold" ,required_argument,0,'p'}, + {"rta-threshold" ,required_argument,0,'r'}, + {"name" ,required_argument,0,'N'}, + {"verbose" ,no_argument, 0,'v'}, + {"version" ,no_argument, 0,'V'}, + {"help" ,no_argument, 0,'h'}, + {0,0,0,0} + }; +#else + + if(argc<2) return ERROR; + + if (!is_option(argv[1])){ + server_names=argv[1]; + argv[1]=argv[0]; + argv=&argv[1]; + argc--; + } +#endif + + while (1){ +#ifdef HAVE_GETOPT_H + c = getopt_long(argc,argv,"+hVvH:c:w:b:n:N:p:r:",long_options,&option_index); +#else + c = getopt(argc,argv,"+hVvH:c:w:b:n:N:p:r:"); +#endif + + if (c==-1||c==EOF||c==1) + break; + + switch (c) + { + case '?': /* print short usage statement if args not parsable */ + printf("%s: Unknown argument: %s\n\n",my_basename(argv[0]),optarg); + print_usage(); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_OK); + case 'V': /* version */ + print_revision(my_basename(argv[0]),"$Revision$"); + exit(STATE_OK); + case 'v': /* verbose mode */ + verbose=TRUE; + break; + case 'H': /* hostname */ + if(is_host(optarg)==FALSE){ + printf("Invalid host name/address\n\n"); + print_usage(); + exit(STATE_UNKNOWN); + } + if (server_names != NULL) + server_names=strscat(server_names," "); + server_names=strscat(server_names,optarg); + nnames++; + break; + case 'c': + if (is_intpos(optarg)) + cthresh = atoi(optarg); + else + usage("Critical threshold must be a positive integer"); + break; + case 'w': + if (is_intpos(optarg)) + wthresh = atoi(optarg); + else + usage("Warning threshold must be a postive integer"); + break; + case 'r': + if (is_intpos(optarg)) { + trta=strtod(optarg,NULL); + } + else { + usage("RTA threshold must be a positive integer"); + } + break; + case 'p': + if (is_intpos(optarg)) { + tpl=strtod(optarg,NULL); + } + else { + usage("RTA threshold must be a positive integer"); + } + break; + case 'b': /* bytes per packet */ + if (is_intpos(optarg)) + packet_size=atoi(optarg); + else + usage("Packet size must be a positive integer"); + break; + case 'N': /* Name of service */ + name = optarg; + break; + case 'n': /* number of packets */ + if (is_intpos(optarg)) + packet_count=atoi(optarg); + else + usage("Packet count must be a positive integer"); + break; + } + } + + while (optind < argc) { + if(is_host(argv[optind])==FALSE) { + printf("Invalid host name/address\n\n"); + print_usage(); + exit(STATE_UNKNOWN); + } + if (server_names != NULL) + server_names=strscat(server_names," "); + server_names=strscat(server_names,argv[optind]); + nnames++; + optind++; + } + + if (server_names==NULL || nnames < 2) + usage("At least 2 hostnames must be supplied\n\n"); + + if (cthresh < 2) + usage("Critical threshold must be at least 2"); + if (cthresh > nnames) + usage("Critical threshold cannot be greater than number of hosts tested"); + if (wthresh < 1) + usage("Warning threshold must be at least 1"); + if (wthresh > nnames) + usage("Warning threshold cannot be greater than number of hosts tested"); + if(wthresh >= cthresh) + usage("Warning threshold must be less than the critical threshold"); + + return OK; +} + + +void print_usage(void) +{ + printf("Usage: %s <host_address> <host_address> [<host_address>] ...\n",PROGNAME); +} + + + + + +void print_help(void) +{ + + print_revision(PROGNAME,"$Revision$"); + + printf + ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n" + " (c) 2000 Matthew Grant (matthewg@plain.co.nz)\n" + "This plugin will use the /bin/fping command (from saint) to ping the\n" + "specified hosts for a fast check to see if the Internet is still \n" + "reachable, and the results of the testing aggregated. Note that it\n" + "is necessary to set the suid flag on fping.\n\n"); + + print_usage(); + + printf + ("\nOptions:\n" + "-b, --bytes=INTEGER\n" + " Size of ICMP packet (default: %d)\n" + "-c, --critical=INTEGER (default: %d)\n" + " critical threshold failure count\n" + "-n, --number=INTEGER\n" + " Number of ICMP packets to send (default: %d)\n" + "-H, --hostname=HOST\n" + " Name or IP Address of host to ping (IP Address bypasses name lookup,\n" + " reducing system load)\n" + "-h, --help\n" + " Print this help screen\n" + "-N, --name\n" + " Service name to print in results, defaults to INTERNET\n" + "-p, --pl-threshold\n" + " Packet loss threshold - specify to turn on packet loss testing\n" + "-r, --rta-threshold\n" + " Round trip average threshold - specify to turn on RTA testing\n" + "-V, --version\n" + " Print version information\n" + "-v, --verbose\n" + " Show details for command-line debugging (do not use with nagios server)\n" + "-w, --warning=INTEGER (default: %d)\n" + " warning threshold failure count\n", + PACKET_SIZE, CRITICAL_COUNT, PACKET_COUNT, WARNING_COUNT); +} diff --git a/contrib/check_ftpget.pl b/contrib/check_ftpget.pl new file mode 100755 index 00000000..de7e8242 --- /dev/null +++ b/contrib/check_ftpget.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl -w +## Written 12/5/00 Jeremy Hanmer +# $Id$ + +use strict; +use Net::FTP; +use Getopt::Std; + +use vars qw($opt_H $opt_u $opt_p $opt_f); +getopts("H:u:p:f:"); + +my $host = $opt_H || + die "usage: check_ftp.pl -h host [<-u user> <-p pass> <-f file>]\n"; + +my $username = $opt_u || 'anonymous'; +my $pass = $opt_p || "$ENV{'LOGNAME'}\@$ENV{'HOSTNAME'}" ; + +my $file = $opt_f; + +my $status = 0; +my $problem; +my $output = "ftp ok"; + +my $ftp = Net::FTP->new("$host") || + &crit("connect"); + +$ftp->login("$username", "$pass") || + &crit("login"); + +$ftp->get($file) || + &crit("get") if $file; + +sub crit() +{ + $problem = $_[0]; + $status = 2; + if ( $problem eq 'connect' ) { + $output = "can't connect"; + } elsif ( $problem eq 'login' ) { + $output = "can't log in"; + } elsif ( $problem eq 'get' ) { + $output = "cant get $file"; + } +} + +print "$output\n"; +exit $status; + diff --git a/contrib/check_ifoperstatus.pl b/contrib/check_ifoperstatus.pl new file mode 100644 index 00000000..3f21cddd --- /dev/null +++ b/contrib/check_ifoperstatus.pl @@ -0,0 +1,145 @@ +#!/usr/bin/perl -w +# +# check_ifoperstatus.pl - nagios plugin +# +# +# +# +# Copyright (C) 2000 Christoph Kron +# +# 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. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %ifOperStatus = ('1','up', + '2','down', + '3','testing', + '4','unknown', + '5','dormant', + '6','notPresent'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey = 1; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpIfOperStatus; +my $snmpLocIfDescr; +my $hostname; +my $session; +my $error; +my $response; + + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check IfOperStatus plugin for Nagios\n"; + printf "checks operational status of specified interface\n"; + printf "usage: \n"; + printf "ifoperstatus.pl -k <IF_KEY> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>"; + printf "\nCopyright (C) 2000 Christoph Kron\n"; + printf "check_ifoperstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("key=i",\$snmpkey, + "community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8' . "." . $snmpkey; + $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28' . "." . $snmpkey; + + + push(@snmpoids,$snmpIfOperStatus); + push(@snmpoids,$snmpLocIfDescr); + + if (!defined($response = $session->get_request(@snmpoids))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + $answer = sprintf("host '%s',%s(%s) is %s\n", + $hostname, + $response->{$snmpLocIfDescr}, + $snmpkey, + $ifOperStatus{$response->{$snmpIfOperStatus}} + ); + + $session->close; + + if ( $response->{$snmpIfOperStatus} == 1 ) { + $state = 'OK'; + } + else { + $state = 'CRITICAL'; + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_ifstatus.pl b/contrib/check_ifstatus.pl new file mode 100644 index 00000000..a7ab39ec --- /dev/null +++ b/contrib/check_ifstatus.pl @@ -0,0 +1,178 @@ +#!/usr/bin/perl -w +# +# check_ifstatus.pl - nagios plugin +# +# +# Copyright (C) 2000 Christoph Kron +# +# 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. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 1500; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %ifOperStatus = ('1','up', + '2','down', + '3','testing', + '4','unknown', + '5','dormant', + '6','notPresent'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey; +my $snmpoid; +my $key; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; +my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; +my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; +my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; +my $hostname; +my $session; +my $error; +my $response; +my %ifStatus; +my $ifup =0 ; +my $ifdown =0; +my $ifdormant = 0; +my $ifmessage; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check IfStatus plugin for Nagios\n"; + printf "monitors operational status of each interface\n"; + printf "usage: \n"; + printf "check_ifstatus.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n"; + printf "Copyright (C) 2000 Christoph Kron\n"; + printf "check_ifstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + + + push(@snmpoids,$snmpIfOperStatus); + push(@snmpoids,$snmpLocIfDescr); + push(@snmpoids,$snmpIfAdminStatus); + push(@snmpoids,$snmpIfDescr); + +foreach $snmpoid (@snmpoids) { + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + if (!defined($response = $session->get_table($snmpoid))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + foreach $snmpkey (keys %{$response}) { + $snmpkey =~ /.*\.(\d+)$/; + $key = $1; + $ifStatus{$key}{$snmpoid} = $response->{$snmpkey}; + } + $session->close; +} + + foreach $key (keys %ifStatus) { + # check only if interface is administratively up + if ($ifStatus{$key}{$snmpIfAdminStatus} == 1 ) { + if ($ifStatus{$key}{$snmpIfOperStatus} == 1 ) { $ifup++ ;} + if ($ifStatus{$key}{$snmpIfOperStatus} == 2 ) { + $ifdown++ ; + $ifmessage .= sprintf("%s: down -> %s<BR>", + $ifStatus{$key}{$snmpIfDescr}, + $ifStatus{$key}{$snmpLocIfDescr}); + + } + if ($ifStatus{$key}{$snmpIfOperStatus} == 5 ) { $ifdormant++ ;} + } + } + + + if ($ifdown > 0) { + $state = 'CRITICAL'; + $answer = sprintf("host '%s', interfaces up: %d, down: %d, dormant: %d<BR>", + $hostname, + $ifup, + $ifdown, + $ifdormant); + $answer = $answer . $ifmessage . "\n"; + } + else { + $state = 'OK'; + $answer = sprintf("host '%s', interfaces up: %d, down: %d, dormant: %d\n", + $hostname, + $ifup, + $ifdown, + $ifdormant); + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_ipxping.c b/contrib/check_ipxping.c new file mode 100644 index 00000000..1ba10fe6 --- /dev/null +++ b/contrib/check_ipxping.c @@ -0,0 +1,200 @@ +/****************************************************************************************** + * + * CHECK_IPXPING.C + * + * Program: IPX ping plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: 09-24-1999 + * + * Command line: CHECK_IPXPING <dest_network> <dest_address> <wrtt> <crtt> + * + * Description: + * + * This plugin will use the /usr/bin/ipxping command to ping the specified host using the + * IPX protocol. Note: Linux users must have IPX support compiled into the kernerl and + * must have IPX configured correctly in order for this plugin to work. + * If the round trip time value is above the <wrtt> level, a STATE_WARNING is + * returned. If it exceeds the <crtt> level, a STATE_CRITICAL is returned. + * + * + * + * IMPORTANT!! + * + * This plugin will only work with the ipxping command that has been ported to Linux. + * The version for Sun takes different command line arguments and differs in its output. + * + *****************************************************************************************/ + +#include "../common/config.h" +#include "../common/common.h" +#include "netutils.h" + +/* this should be moved out to the configure script! */ +#define IPXPING_COMMAND "/tmp/ipxping/ipxping" + +/* these should be moved to the common header file */ +#define MAX_IPXNET_ADDRESS_LENGTH 12 +#define MAX_IPXHOST_ADDRESS_LENGTH 18 + +int socket_timeout=DEFAULT_SOCKET_TIMEOUT; +char dest_network[MAX_IPXNET_ADDRESS_LENGTH]; +char dest_address[MAX_IPXHOST_ADDRESS_LENGTH]; +int wrtt; +int crtt; + +int process_arguments(int,char **); + +FILE * spopen(const char *); +int spclose(FILE *); + +int main(int argc, char **argv){ + char command_line[MAX_INPUT_BUFFER]; + int rtt; + int bytes_returned; + int result=STATE_OK; + FILE *fp; + char input_buffer[MAX_INPUT_BUFFER]; + char *substr; + int current_line; + + if(process_arguments(argc,argv)!=OK){ + printf("Incorrect arguments supplied\n"); + printf("\n"); + printf("IPX ping plugin for Nagios\n"); + printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); + printf("Last Modified: 09-24-1999\n"); + printf("License: GPL\n"); + printf("\n"); + printf("Usage: %s <dest_network> <dest_address> <wrtt> <crtt> [-to to_sec]\n",argv[0]); + printf("\n"); + printf("Options:\n"); + printf(" <dest_network> = IPX network that the remote host lies on. (Hex Format - 00:00:00:00)\n"); + printf(" <dest_address> = MAC address of the remote host. (Hex Format - 00:00:00:00:00:00)\n"); + printf(" <wrtt> = Round trip time in milliseconds necessary to result in a WARNING state\n"); + printf(" <crtt> = Round trip time in milliseconds necessary to result in a CRITICAL state\n"); + printf(" [to_sec] = Seconds before we should timeout waiting for ping result. Default = %d sec\n",DEFAULT_SOCKET_TIMEOUT); + printf("\n"); + printf("Notes:\n"); + printf("This plugin will use the /usr/bin/ipxping command to ping the specified host using\n"); + printf("the IPX protocol. IPX support must be compiled into the kernel and your host must\n"); + printf("be correctly configured to use IPX before this plugin will work! An RPM package of\n"); + printf("the ipxping binary can be found at...\n"); + printf("http://www.rpmfind.net/linux/RPM/contrib/libc5/i386/ipxping-0.0-2.i386.shtml\n"); + printf("\n"); + return STATE_UNKNOWN; + } + + /* create the command line to use... */ + sprintf(command_line,"%s %s %s",IPXPING_COMMAND,dest_network,dest_address); + + /* initialize alarm signal handling */ + signal(SIGALRM,socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm(socket_timeout); + + /* run the command */ + fp = spopen(command_line); + if(fp==NULL){ + printf("Unable to open pipe: %s",command_line); + return STATE_UNKNOWN; + } + + current_line=0; + while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ + + current_line++; + + /* skip the first line of the output */ + if(current_line==1) + continue; + + /* we didn't get the "is alive" */ + if(current_line==2 && !strstr(input_buffer,"is alive")) + result=STATE_CRITICAL; + + /* get the round trip time */ + if(current_line==3){ + substr=strtok(input_buffer,":"); + substr=strtok(NULL,"\n"); + rtt=atoi(substr); + } + + /* get the number of bytes returned */ + if(current_line==4 && strstr(input_buffer,"bytes returned")){ + bytes_returned=atoi(input_buffer); + } + } + + /* close the pipe */ + spclose(fp); + + /* reset the alarm */ + alarm(0); + + if(current_line==1 || result==STATE_CRITICAL) + printf("IPX Ping problem - No response from host\n"); + else{ + + if(rtt>crtt) + result=STATE_CRITICAL; + else if(rtt>wrtt) + result=STATE_WARNING; + + printf("IPX Ping %s - RTT = %d ms, %d bytes returned from %s %s\n",(result==STATE_OK)?"ok":"problem",rtt,bytes_returned,dest_network,dest_address); + } + + + return result; + } + + + +/* process all arguments passed on the command line */ +int process_arguments(int argc, char **argv){ + int x; + + /* no options were supplied */ + if(argc<5) + return ERROR; + + /* get the destination network address */ + strncpy(dest_network,argv[1],sizeof(dest_network)-1); + dest_network[sizeof(dest_network)-1]='\x0'; + + /* get the destination host address */ + strncpy(dest_address,argv[2],sizeof(dest_address)-1); + dest_address[sizeof(dest_address)-1]='\x0'; + + /* get the round trip time variables */ + wrtt=atoi(argv[3]); + crtt=atoi(argv[4]); + + /* process remaining arguments */ + for(x=6;x<=argc;x++){ + + /* we got the timeout to use */ + if(!strcmp(argv[x-1],"-to")){ + if(x<argc){ + socket_timeout=atoi(argv[x]); + if(socket_timeout<=0) + return ERROR; + x++; + } + else + return ERROR; + } + + /* else we got something else... */ + else + return ERROR; + } + + return OK; + } + + + + diff --git a/contrib/check_joy.sh b/contrib/check_joy.sh new file mode 100755 index 00000000..cd076db9 --- /dev/null +++ b/contrib/check_joy.sh @@ -0,0 +1,69 @@ +#! /bin/sh + +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +PROGNAME=`basename $0` +PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'` +REVISION=`echo '$Revision$' | sed -e 's/[^0-9.]//g'` +STATUS="" + +. $PROGPATH/utils.sh + + +print_usage() { + echo "Usage: $PROGNAME /dev/js<#> <button #>" +} + +print_help() { + print_revision $PROGNAME $REVISION + echo "" + print_usage + echo "" + echo "This plugin checks a joystick button status using the " + echo "joyreadbutton utility from the joyd package." + echo "" + support + exit 0 +} + +if [ $# -ne 2 ]; then + print_usage + exit 0 +fi + +case "$1" in + --help) + print_help + exit 0 + ;; + -h) + print_help + exit 0 + ;; + --version) + print_revision $PROGNAME $REVISION + exit 0 + ;; + -V) + print_revision $PROGNAME $REVISION + exit 0 + ;; + /dev/js*) + joyreadbutton $1 $2 1>&1 1>/dev/null + STATUS=$? + if [ "$STATUS" -eq 0 ]; then + echo OK + exit 0 + elif [ "$STATUS" -eq 1 ];then + echo CRITICAL + exit 2 + else + echo UNKNOWN + exit -1 + fi + ;; + *) + print_usage + exit 0 + ;; +esac diff --git a/contrib/check_maxchannels.pl b/contrib/check_maxchannels.pl new file mode 100644 index 00000000..a3ce525b --- /dev/null +++ b/contrib/check_maxchannels.pl @@ -0,0 +1,231 @@ +#!/usr/bin/perl -w +# +# check_maxchannels.pl - nagios plugin +# +# +# Copyright (C) 2000 Christoph Kron +# +# 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. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + + +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey; +my $snmpoid; +my $key; +my $community = "public"; +my $port = 161; +my @snmpoids; +# free channels +my $snmpWanAvailableChannels = '1.3.6.1.4.1.529.4.23.0'; +# maximum channels +my $snmpWanSwitchedChannels = '1.3.6.1.4.1.529.4.24.0'; +my $snmpWanDisabledChannels = '1.3.6.1.4.1.529.4.25.0'; +my $snmpWanActiveChannels = '1.3.6.1.4.1.529.4.26.0'; +my $snmpWanNailedChannels = '1.3.6.1.4.1.529.4.27.0'; +my $snmpWanOutOfServiceChannels = '1.3.6.1.4.1.529.4.28.0'; +my $snmpEventCurrentActiveSessions = '1.3.6.1.4.1.529.10.6.0'; +# since startup +my $snmpEventTotalNoModems = '1.3.6.1.4.1.529.10.15.0'; +# lan modem +my $snmpDeadLanModem = '1.3.6.1.4.1.529.15.7.0'; +my $snmpDisabledLanModem = '1.3.6.1.4.1.529.15.5.0'; +my $snmpSuspectLanModem = '1.3.6.1.4.1.529.15.3.0'; +my $snmpAvailLanModem = '1.3.6.1.4.1.529.15.1.0'; +my $snmpBusyLanModem = '1.3.6.1.4.1.529.15.9.0'; +# max modems +my $snmpMdmNumber = '1.3.6.1.2.1.38.1.1.0'; +my $hostname; +my $session; +my $error; +my $response; +my %wanStatus; + + +my $WanAvailableChannels; +my $WanSwitchedChannels; +my $WanDisabledChannels; +my $WanActiveChannels; +my $WanNailedChannels; +my $WanOutOfServiceChannels; +my $EventCurrentActiveSessions; +my $EventTotalNoModems; +my $DeadLanModem; +my $DisabledLanModem; +my $SuspectLanModem; +my $AvailLanModem; +my $BusyLanModem; +my $MdmNumber; + + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check maxchannels plugin for Nagios\n"; + printf "monitors ISDN lines and modems on Ascend MAX 2000/4000/6000/TNT\n"; + printf "usage: \n"; + printf "check_maxchannel.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n"; + printf "Copyright (C) 2000 Christoph Kron\n"; + printf "check_maxchannels.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + + +push(@snmpoids,$snmpWanAvailableChannels); +push(@snmpoids,$snmpWanSwitchedChannels); +push(@snmpoids,$snmpWanDisabledChannels); +push(@snmpoids,$snmpWanActiveChannels); +push(@snmpoids,$snmpWanNailedChannels); +push(@snmpoids,$snmpWanOutOfServiceChannels); + +push(@snmpoids,$snmpEventCurrentActiveSessions); + +push(@snmpoids,$snmpEventTotalNoModems); +push(@snmpoids,$snmpDeadLanModem); +push(@snmpoids,$snmpDisabledLanModem); +push(@snmpoids,$snmpSuspectLanModem); +push(@snmpoids,$snmpAvailLanModem); +push(@snmpoids,$snmpBusyLanModem); +push(@snmpoids,$snmpMdmNumber); + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + if (!defined($response = $session->get_request(@snmpoids))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community"); + exit $ERRORS{$state}; + } + + +$WanAvailableChannels = $response->{$snmpWanAvailableChannels}; +$WanSwitchedChannels = $response->{$snmpWanSwitchedChannels}; +$WanDisabledChannels = $response->{$snmpWanDisabledChannels}; +$WanActiveChannels = $response->{$snmpWanActiveChannels}; +$WanNailedChannels = $response->{$snmpWanNailedChannels}; +$WanOutOfServiceChannels = $response->{$snmpWanOutOfServiceChannels}; +$EventCurrentActiveSessions = $response->{$snmpEventCurrentActiveSessions}; +$EventTotalNoModems = $response->{$snmpEventTotalNoModems}; +$DeadLanModem = $response->{$snmpDeadLanModem}; +$DisabledLanModem = $response->{$snmpDisabledLanModem}; +$SuspectLanModem = $response->{$snmpSuspectLanModem}; +$AvailLanModem = $response->{$snmpAvailLanModem}; +$BusyLanModem = $response->{$snmpBusyLanModem}; +$MdmNumber = $response->{$snmpMdmNumber}; + +# less than 50% -> WARNING +if ( 0 < $WanOutOfServiceChannels + && $WanOutOfServiceChannels < ($snmpWanSwitchedChannels * 0.5) ) { + $state = 'WARNING'; +} +elsif ($WanOutOfServiceChannels > 0) { + $state = 'CRITICAL'; +} +elsif ($DeadLanModem > 0) { + $state = 'CRITICAL'; +} +elsif ($SuspectLanModem > 0) { + $state = 'WARNING'; +} +elsif ($AvailLanModem == 0) { + $state = 'WARNING'; +} +else { + $state = 'OK'; +} + + +$answer = sprintf("active sessions: %d (%d), active modems: %d (%d)<BR>", + $EventCurrentActiveSessions, + $WanSwitchedChannels, + $BusyLanModem, + $MdmNumber); + +$answer .= sprintf("channels available: %d, disabled: %d", + $WanAvailableChannels, + $WanDisabledChannels); + +$answer .= sprintf(", out of service: %d, nailed: %d<BR>", + $WanOutOfServiceChannels, + $WanNailedChannels); + +$answer .= sprintf("modems avail.: %d, disabled: %d, suspect: %d, dead: %d<BR>", + $AvailLanModem, + $DisabledLanModem, + $SuspectLanModem, + $DeadLanModem); + +$answer .= sprintf("unserviced modem calls: %d (since startup)\n", + $EventTotalNoModems); + +$session->close; + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_maxwanstate.pl b/contrib/check_maxwanstate.pl new file mode 100644 index 00000000..4fbb9da2 --- /dev/null +++ b/contrib/check_maxwanstate.pl @@ -0,0 +1,201 @@ +#!/usr/bin/perl -w +# +# check_maxwanstate.pl - nagios plugin +# +# +# Copyright (C) 2000 Christoph Kron +# +# 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. +# +# +# Report bugs to: ck@zet.net +# +# 11.01.2000 Version 1.0 + +use strict; + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + + +my $status; +my $TIMEOUT = 1500; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my %wanLineState = ( + 1,'ls-unknown', + 2,'ls-does-not-exist', + 3,'ls-disabled', + 4,'ls-no-physical', + 5,'ls-no-logical', + 6,'ls-point-to-point', + 7,'ls-multipoint-1', + 8,'ls-multipoint-2', + 9,'ls-loss-of-sync', + 10,'ls-yellow-alarm', + 11,'ls-ais-receive', + 12,'ls-no-d-channel', + 13,'ls-active', + 14,'ls-maintenance'); + +my %wanLineType = ( + '1.3.6.1.4.1.529.4.1','Any', + '1.3.6.1.4.1.529.4.2','T1', + '1.3.6.1.4.1.529.4.3','E1', + '1.3.6.1.4.1.529.4.4','Dpnss', + '1.3.6.1.4.1.529.4.5','Bri', + '1.3.6.1.4.1.529.4.6','S562', + '1.3.6.1.4.1.529.4.7','S564', + '1.3.6.1.4.1.529.4.8','Sdsl', + '1.3.6.1.4.1.529.4.9','AdslCap'); + +my $state = "UNKNOWN"; +my $answer = ""; +my $snmpkey; +my $snmpoid; +my $key; +my $community = "public"; +my $port = 161; +my @snmpoids; +my $snmpWanLineName = '1.3.6.1.4.1.529.4.21.1.2'; +my $snmpWanLineType = '1.3.6.1.4.1.529.4.21.1.3'; +my $snmpWanLineState = '1.3.6.1.4.1.529.4.21.1.5'; +my $snmpWanLineUsage = '1.3.6.1.4.1.529.4.21.1.8'; + +my $hostname; +my $session; +my $error; +my $response; +my %wanStatus; +my $ifup =0 ; +my $ifdown =0; +my $ifdormant = 0; +my $ifmessage; + +sub usage { + printf "\nMissing arguments!\n"; + printf "\n"; + printf "Perl Check maxwanstate plugin for Nagios\n"; + printf "monitors E1/T1 interface status\n"; + printf "usage: \n"; + printf "check_maxwanstate.pl -c <READCOMMUNITY> -p <PORT> <HOSTNAME>"; + printf "Copyright (C) 2000 Christoph Kron\n"; + printf "check_maxwanstate.pl comes with ABSOLUTELY NO WARRANTY\n"; + printf "This programm is licensed under the terms of the "; + printf "GNU General Public License\n(check source code for details)\n"; + printf "\n\n"; + exit $ERRORS{"UNKNOWN"}; +} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No snmp response from $hostname (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +$status = GetOptions("community=s",\$community, + "port=i",\$port); +if ($status == 0) +{ + &usage; +} + + #shift; + $hostname = shift || &usage; + + + +push(@snmpoids,$snmpWanLineUsage); +push(@snmpoids,$snmpWanLineState); +push(@snmpoids,$snmpWanLineName); +push(@snmpoids,$snmpWanLineType); + +foreach $snmpoid (@snmpoids) { + + ($session, $error) = Net::SNMP->session( + -hostname => $hostname, + -community => $community, + -port => $port + ); + + if (!defined($session)) { + $state='UNKNOWN'; + $answer=$error; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + if (!defined($response = $session->get_table($snmpoid))) { + $answer=$session->error; + $session->close; + $state = 'CRITICAL'; + print ("$state: $answer,$community,$snmpkey"); + exit $ERRORS{$state}; + } + + foreach $snmpkey (keys %{$response}) { + $snmpkey =~ /.*\.(\d+)$/; + $key = $1; + $wanStatus{$key}{$snmpoid} = $response->{$snmpkey}; + } + $session->close; +} + + foreach $key (keys %wanStatus) { + # look only at active Interfaces lu-trunk(5) + if ($wanStatus{$key}{$snmpWanLineUsage} == 5 ) { + + # 13 -> active + if ($wanStatus{$key}{$snmpWanLineState} == 13 ) { + $ifup++; + } + else { + $ifdown++ ; + $ifmessage .= sprintf("%s interface status : %s (%s)<BR>", + $wanLineType{$wanStatus{$key}{$snmpWanLineType}}, + $wanLineState{$wanStatus{$key}{$snmpWanLineState}}, + $wanStatus{$key}{$snmpWanLineName}); + + } + } + } + + + if ($ifdown > 0) { + $state = 'CRITICAL'; + $answer = sprintf("host '%s', interfaces up: %d, down: %d<BR>", + $hostname, + $ifup, + $ifdown); + $answer = $answer . $ifmessage . "\n"; + } + else { + $state = 'OK'; + $answer = sprintf("host '%s', interfaces up: %d, down: %d\n", + $hostname, + $ifup, + $ifdown); + } + +print ("$state: $answer"); +exit $ERRORS{$state}; + diff --git a/contrib/check_mem.pl b/contrib/check_mem.pl new file mode 100644 index 00000000..f0c82129 --- /dev/null +++ b/contrib/check_mem.pl @@ -0,0 +1,146 @@ +#!/usr/bin/perl -w +# $Id$ + +# check_mem.pl Copyright (C) 2000 Dan Larsson <dl@tyfon.net> +# +# 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 (or with Nagios); if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA + +# Tell Perl what we need to use +use strict; +use Getopt::Std; + +use vars qw($opt_c $opt_f $opt_u $opt_w + $free_memory $used_memory $total_memory + $crit_level $warn_level + %exit_codes @memlist + $percent $fmt_pct + $verb_err $command_line); + +# Predefined exit codes for Nagios +%exit_codes = ('UNKNOWN' ,-1, + 'OK' , 0, + 'WARNING' , 1, + 'CRITICAL', 2,); + +# Turn this to 1 to see reason for parameter errors (if any) +$verb_err = 0; + +# This the unix command string that brings Perl the data +$command_line = `vmstat | tail -1 | awk '{print \$4,\$5}'`; + +chomp $command_line; +@memlist = split(/ /, $command_line); + +# Define the calculating scalars +$used_memory = $memlist[0]; +$free_memory = $memlist[1]; +$total_memory = $used_memory + $free_memory; + +# Get the options +if ($#ARGV le 0) +{ + &usage; +} +else +{ + getopts('c:fuw:'); +} + +# Shortcircuit the switches +if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0) +{ + print "*** You must define WARN and CRITICAL levels!" if ($verb_err); + &usage; +} +elsif (!$opt_f and !$opt_u) +{ + print "*** You must select to monitor either USED or FREE memory!" if ($verb_err); + &usage; +} + +# Check if levels are sane +if ($opt_w <= $opt_c and $opt_f) +{ + print "*** WARN level must not be less than CRITICAL when checking FREE memory!" if ($verb_err); + &usage; +} +elsif ($opt_w >= $opt_c and $opt_u) +{ + print "*** WARN level must not be greater than CRITICAL when checking USED memory!" if ($verb_err); + &usage; +} + +$warn_level = $opt_w; +$crit_level = $opt_c; + +if ($opt_f) +{ + $percent = $free_memory / $total_memory * 100; + $fmt_pct = sprintf "%.1f", $percent; + if ($percent <= $crit_level) + { + print "Memory CRITICAL - $fmt_pct% ($free_memory kB) free\n"; + exit $exit_codes{'CRITICAL'}; + } + elsif ($percent <= $warn_level) + { + print "Memory WARNING - $fmt_pct% ($free_memory kB) free\n"; + exit $exit_codes{'WARNING'}; + } + else + { + print "Memory OK - $fmt_pct% ($free_memory kB) free\n"; + exit $exit_codes{'OK'}; + } +} +elsif ($opt_u) +{ + $percent = $used_memory / $total_memory * 100; + $fmt_pct = sprintf "%.1f", $percent; + if ($percent >= $crit_level) + { + print "Memory CRITICAL - $fmt_pct% ($used_memory kB) used\n"; + exit $exit_codes{'CRITICAL'}; + } + elsif ($percent >= $warn_level) + { + print "Memory WARNING - $fmt_pct% ($used_memory kB) used\n"; + exit $exit_codes{'WARNING'}; + } + else + { + print "Memory OK - $fmt_pct% ($used_memory kB) used\n"; + exit $exit_codes{'OK'}; + } +} + +# Show usage +sub usage() +{ + print "\ncheck_mem.pl v1.0 - Nagios Plugin\n\n"; + print "usage:\n"; + print " check_mem.pl -<f|u> -w <warnlevel> -c <critlevel>\n\n"; + print "options:\n"; + print " -f Check FREE memory\n"; + print " -u Check USED memory\n"; + print " -w PERCENT Percent free/used when to warn\n"; + print " -c PERCENT Percent free/used when critical\n"; + print "\nCopyright (C) 2000 Dan Larsson <dl\@tyfon.net>\n"; + print "check_mem.pl comes with absolutely NO WARRANTY either implied or explicit\n"; + print "This program is licensed under the terms of the\n"; + print "GNU General Public License (check source code for details)\n"; + exit $exit_codes{'UNKNOWN'}; +} diff --git a/contrib/check_memory.tgz b/contrib/check_memory.tgz Binary files differnew file mode 100644 index 00000000..b0f80160 --- /dev/null +++ b/contrib/check_memory.tgz diff --git a/contrib/check_mysql.c b/contrib/check_mysql.c new file mode 100644 index 00000000..9abacf87 --- /dev/null +++ b/contrib/check_mysql.c @@ -0,0 +1,75 @@ +/***************************************************************** + * + * Program: check_mysql.c + * License: GPL + * + * Written by Tim Weippert + * (based on plugins by Ethan Galstad and MySQL example code) + * + * Command line: check_mysql <host> [user] [passwd] + * <host> can be the FQDN or the IP-Adress + * [user] and [passwd] are optional + * + * Description: + * + * This plugin attempts to connect to an MySQL Server + * with the optional specified parameters user and passwd. + * Normaly the host and a user HAVE to assigned. + * + * The plugin returns + * STATE_OK and the Version Number of the Server when all is fine + * STATE_CRITICAL if the Connection can't be esablished + * STATE_WARNING if the connection was established but the + * program can't get the Versoin Number + * STATE_UNKNOWN if to many parameters are given + * + * Copyright (c) 1999 by Tim Weippert + * + * Changes: + * 16.12.1999: Changed the return codes from numbers to statements + * + *******************************************************************/ + +#include "../common/config.h" +#include "../common/common.h" +#include "mysql.h" + +MYSQL mysql; + +int main(int argc, char **argv) +{ + uint i = 0; + char *host; + char *user; + char *passwd; + + char *status; + char *version; + + if ( argc > 4 ) { + printf("Too many Arguments supplied - %i .\n", argc); + printf("Usage: %s <host> [user] [passwd]\n", argv[0]); + return STATE_UNKNOWN; + } + + (host = argv[1]) || (host = NULL); + (user = argv[2]) || (user = NULL); + (passwd = argv[3]) || (passwd = NULL); + + if (!(mysql_connect(&mysql,host,user,passwd))) { + printf("Can't connect to Mysql on Host: %s\n", host); + return STATE_CRITICAL; + } + + if ( !(version = mysql_get_server_info(&mysql)) ) { + printf("Connect OK, but can't get Serverinfo ... something wrong !\n"); + return STATE_WARNING; + } + + printf("Mysql ok - Running Version: %s\n", version); + + mysql_close(&mysql); + return STATE_OK; +} + + diff --git a/contrib/check_mysql.pl b/contrib/check_mysql.pl new file mode 100644 index 00000000..143d5a5a --- /dev/null +++ b/contrib/check_mysql.pl @@ -0,0 +1,73 @@ +#!/nyet/bin/perl +# +# (c)1999 Mitch Wright, NetLine Corporation +# Read the GNU copyright stuff for all the legalese +# +# Check to see that our MySQL server(s) are up and running. +# This plugin requires that mysqladmin(1) is installed on the system. +# Since it is part of the MySQL distribution, that should be a problem. +# +# If no parameters are giving, a usage statement is output. +# +# Exit 0 on success, providing some informational output +# Exit 2 on failure, provide what we can... +# + +require 5.004; + +sub usage; + +my $TIMEOUT = 15; +my $MYSQLADMIN = "/usr/local/bin/mysqladmin"; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my $host = shift || &usage(%ERRORS); +my $user = shift || &usage(%ERRORS); +my $pass = shift || ""; +my $warn = shift || 60; +my $crit = shift || 100; + +my $state = "OK"; + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No response from MySQL server (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + +open (OUTPUT, + "$MYSQLADMIN -h $host -u $user --password=\"$pass\" version 2>&1 + |"); + +while (<OUTPUT>) { + if (/failed/) { $state="CRITICAL"; s/.*://; $status=$_; last; } + next if /^\s*$/; + if (/^Server version\s+(\d+.*)/) { $version = $1; next; } + if (/^Uptime:\s+(\d.*)/) { $uptime = $1; next; } + if (/^Threads:\s+(\d+)\s+/) { $threads = $1; next; } +} + +$status = "Version $version -- $threads Threads <br>Uptime $uptime" if +$state ne "CRITICAL"; + +if ($threads >= $warn) { $state = "WARNING"; } +if ($threads >= $crit) { $state = "CRITICAL"; } + +print $status; +exit $ERRORS{$state}; + +sub usage { + print "Required arguments not given!\n\n"; + print "MySQL status checker plugin for Nagios, V1.01\n"; + print "Copyright (c) 1999-2000 Mitch Wright \n\n"; + print "Usage: check_mysql.pl <host> <user> [<pass> [<warn> + [<crit>]]]\n\n"; print " <pass> = password to use for <user> at + <host>\n"; print " <warn> = number of threads to warn us + about\n"; print " <crit> = number of threads to scream at us + about\n"; exit $ERRORS{"UNKNOWN"}; +} diff --git a/contrib/check_nagios.pl b/contrib/check_nagios.pl new file mode 100644 index 00000000..7d15d4db --- /dev/null +++ b/contrib/check_nagios.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl +# denao - denao@uol.com.br - Systems Engineering +# Universo Online - http://www.uol.com.br +use DBI; +use Time::Local; + +my $t_lambuja = 5; # (expire_minutes) +my $databasename = ""; # The name of nagios database (i.e.: nagios) +my $table = "programstatus"; +my $where = "localhost"; # The machine where the database +my $port = "3306"; +my $base = "DBI:mysql:$databasename:$where:$port"; +my $user = ""; # the user to connect to the database + # (needs permission to "select at programstatus table only" +my $password = ""; # the password (if any) +my %results; +my @fields = qw( last_update ); +my $dbh = DBI->connect($base,$user,$password); +my $fields = join(', ', @fields); +my $query = "SELECT $fields FROM $table"; + +my $sth = $dbh->prepare($query); +$sth->execute(); + +@results{@fields} = (); +$sth->bind_columns(map { \$results{$_} } @fields); + +$sth->fetch(); +$sth->finish(); +$dbh->disconnect(); + +check_update(); + +sub check_update { +($yea,$mon,$day,$hou,$min,$sec)=($results{last_update}=~/(\d+)\-(\d+)\-(\d+)\s(\d+)\:(\d+)\:(\d+)/); +($sec_now, $min_now, $hou_now, $day_now, $mon_now, $yea_now) = (localtime(time))[0,1,2,3,4,5]; +$mon_now+=1; $yea_now+=1900; +$unixdate=timelocal($sec,$min,$hou,$day,$mon,$yea); +$unixdate_now=timelocal($sec_now,$min_now,$hou_now,$day_now,$mon_now,$yea_now); + if (scalar($unixdate_now - $unixdate) > scalar($t_lambuja * 60)) { + print "Nagios problem: nagios is down, for at least " . scalar($t_lambuja) . " minutes.\n"; + exit(1); + } else { + print "Nagios ok: status data updated " . scalar($unixdate_now - $unixdate) . " seconds ago\n"; + exit(0); + } +} + diff --git a/contrib/check_netapp.pl b/contrib/check_netapp.pl new file mode 100755 index 00000000..d556e9da --- /dev/null +++ b/contrib/check_netapp.pl @@ -0,0 +1,178 @@ +#!/usr/bin/perl -wT +# check_netapp +# +# Copyright (C) 2000 Leland E. Vandervort <leland@mmania.com> +# +# 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 (or with Nagios); if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA +#################################### +# checks for overtemperature, fans, psu, and nfs operations/second on +# Network Appliance Filers. +# Returns: +# OK if temp, fans, psu OK and Ops/Sec below warning and critical +# Thresholds (default is warning=3500, critical=5000) +# ** Note: See the specifications for your Filer model for +# the thresholds ! +# Returns Warning if NFS Ops/Sec is above warning threshold +# (default 3500, or specified by -o command line option) +# Returns Critical if NFS Ops/Sec is above critical threshold +# ( -m option, or default 5000), or if overtem, psufault, or +# fanfault detected. +# +#################################### +# Notes on operational limits for NetApp Filers: +# Platform Maximum Ops/Second (recommended) +# ------------------------------------------------------------- +# F230 1000 +# F740 5500 +# F760 9000 +#################################### + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + +my $status; +my $response = ""; +my $TIMEOUT = 10; +my $community = "public"; +my $port = 161; +my $opsthresh = "3500"; +my $critical = "5000"; + +my $status_string = ""; + +my %OIDLIST = ( + overtemp => '1.3.6.1.4.1.789.1.2.4.1.0', + failedfan => '1.3.6.1.4.1.789.1.2.4.2.0', + failedpsu => '1.3.6.1.4.1.789.1.2.4.4.0', + nfsops => '1.3.6.1.4.1.789.1.2.2.1.0' + ); + + + +my %STATUSCODE = ( 'UNKNOWN' => '-1', + 'OK' => '0', + 'WARNING' => '1', + 'CRITICAL' => '2'); + +my $state = "UNKNOWN"; + + +$SIG{'ALRM'} = sub { + print "ERROR: No snmp response from $hostname (sigALRM)\n"; + exit($STATUSCODE{"UNKNOWN"}); +}; + +alarm($TIMEOUT); + +sub get_nfsops { + my $nfsops_start = &SNMPGET($OIDLIST{nfsops}); + sleep(1); + my $nfsops_end = &SNMPGET($OIDLIST{nfsops}); + my $nfsopspersec = $nfsops_end - $nfsops_start; + return($nfsopspersec); +} + + +sub show_help { + printf("\nPerl NetApp filer plugin for Nagios\n"); + printf("Usage:\n"); + printf(" + check_netapp [options] <hostname> + Options: + -c snmp-community + -p snmp-port + -o Operations per second warning threshold + -m Operations per second critical threshold + +"); + printf("Copyright (C)2000 Leland E. Vandervort\n"); + printf("check_netapp comes with absolutely NO WARRANTY either implied or explicit\n"); + printf("This program is licensed under the terms of the\n"); + printf("GNU General Public License\n(check source code for details)\n\n\n"); + exit($STATUSCODE{"UNKNOWN"}); +} + + +$status = GetOptions( "community=s", \$community, + "port=i", \$port, + "opsthresh=i", \$opsthresh, + "maxops=i", \$critical ); + +if($status == 0) { + &show_help; +} + +sub SNMPGET { + $OID = shift; + ($session,$error) = Net::SNMP->session( + Hostname => $hostname, + Community => $community, + Port => $port + ); + if(!defined($session)) { + printf("$state %s\n", $error); + exit($STATUSCODE{$state}); + } + if(!defined($response = $session->get_request($OID))) { + printf("$state %s\n", $session->error()); + $session->close(); + exit($STATUSCODE{$state}); + } + $session->close(); + return($response->{$OID}); +} + +$hostname = shift || &show_help; + +my $tempcheck = &SNMPGET($OIDLIST{overtemp}); +if($tempcheck == 1) { + $state = "OK"; + $status_string .= "Temp OK "; +} +else { + $state = "CRITICAL"; + $status_string .= "Temp CRIT"; +} + +foreach $element ('failedfan','failedpsu') { + my $my_return = &SNMPGET($OIDLIST{$element}); + if(($my_return =~ /no/) || ($my_return == 0)) { + $status_string .= "$element = $my_return "; + $state = "OK"; + } + else { + $status_string .= "$element = $my_return "; + $state = "CRITICAL"; + } +} + +my $tmp_opssec = &get_nfsops(); + +if ($tmp_opssec >= $critical) { + $state = "CRITICAL"; +} +elsif ($tmp_opssec >= $opsthresh) { + $state = "WARNING"; +} +else { + $state = "OK"; +} + +$status_string .= "Ops\/Sec = $tmp_opssec "; + +print "$state $status_string\n"; +exit($STATUSCODE{$state}); diff --git a/contrib/check_nmap.py b/contrib/check_nmap.py new file mode 100644 index 00000000..4f53406d --- /dev/null +++ b/contrib/check_nmap.py @@ -0,0 +1,440 @@ +#!/usr/bin/python +# Change the above line if python is somewhere else + +# +# check_nmap +# +# Program: nmap plugin for Nagios +# License: GPL +# Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com) +# +_version_ = '1.20' +# +# +# Description: +# +# Does a nmap scan, compares open ports to those given on command-line +# Reports warning for closed that should be open and error for +# open that should be closed. +# If optional ports are given, no warning is given if they are closed +# and they are included in the list of valid ports. +# +# Requirements: +# python +# nmap +# +# History +# ------- +# 1.20 2000-07-15 jaclu Updated params to correctly comply to plugin-standard +# moved support classes to utils.py +# 1.16 2000-07-14 jaclu made options and return codes more compatible with +# the plugin developer-guidelines +# 1.15 2000-07-14 jaclu added random string to temp-file name +# 1.14 2000-07-14 jaclu added check for error from subproc +# 1.10 2000-07-14 jaclu converted main part to class +# 1.08 2000-07-13 jaclu better param parsing +# 1.07 2000-07-13 jaclu changed nmap param to -P0 +# 1.06 2000-07-13 jaclu make sure tmp file is deleted on errors +# 1.05 2000-07-12 jaclu in debug mode, show exit code +# 1.03 2000-07-12 jaclu error handling on nmap output +# 1.01 2000-07-12 jaclu added license +# 1.00 2000-07-12 jaclu implemented timeout handling +# 0.20 2000-07-10 jaclu Initial release + + +import sys, os, string, whrandom + +import tempfile +from getopt import getopt + +# +# import generic Nagios-plugin stuff +# +import utils + +# Where temp files should be placed +tempfile.tempdir='/usr/local/nagios/var' + +# Base name for tempfile +tempfile.template='check_nmap_tmp.' + +# location and possibly params for nmap +nmap_cmd='/usr/bin/nmap -P0' + + + + + + +# +# the class that does all the real work in this plugin... +# +# +class CheckNmap: + + # Retcodes, so we are compatible with nagios + #ERROR= -1 + UNKNOWN= -1 + OK= 0 + WARNING= 1 + CRITICAL= 2 + + + def __init__(self,cmd_line=[]): + """Constructor. + arguments: + cmd_line: normaly sys.argv[1:] if called as standalone program + """ + self.tmp_file='' + self.host='' # host to check + self.timeout=10 + self.debug=0 # 1= show debug info + self.ports=[] # list of mandatory ports + self.opt_ports=[] # list of optional ports + self.ranges='' # port ranges for nmap + self.exit_code=0 # numerical exit-code + self.exit_msg='' # message to caller + + self.ParseCmdLine(cmd_line) + + def Run(self): + """Actually run the process. + This method should be called exactly once. + """ + + # + # Only call check_host if cmd line was accepted earlier + # + if self.exit_code==0: + self.CheckHost() + + self.CleanUp() + return self.exit_code,self.exit_msg + + def Version(self): + return 'check_nmap %s' % _version_ + + #----------------------------------------- + # + # class internal stuff below... + # + #----------------------------------------- + + # + # Param checks + # + def param2int_list(self,s): + lst=string.split(string.replace(s,',',' ')) + try: + for i in range(len(lst)): + lst[i]=int(lst[i]) + except: + lst=[] + return lst + + def ParseCmdLine(self,cmd_line): + try: + opt_list=getopt(cmd_line,'vH:ho:p:r:t:V',['debug','host=','help', + 'optional=','port=','range=','timeout','version']) + for opt in opt_list[0]: + if opt[0]=='-v' or opt[0]=='--debug': + self.debug=1 + elif opt[0]=='-H' or opt[0]=='--host': + self.host=opt[1] + elif opt[0]=='-h' or opt[0]=='--help': + doc_help() + self.exit_code=1 # request termination + break + elif opt[0]=='-o' or opt[0]=='--optional': + self.opt_ports=self.param2int_list(opt[1]) + elif opt[0]=='-p' or opt[0]=='--port': + self.ports=self.param2int_list(opt[1]) + elif opt[0]=='-r' or opt[0]=='--range': + r=string.replace(opt[1],':','-') + self.ranges=r + elif opt[0]=='-t' or opt[0]=='--timeout': + self.timeout=opt[1] + elif opt[0]=='-V' or opt[0]=='--version': + print self.Version() + self.exit_code=1 # request termination + break + else: + self.host='' + break + + except: + # unknown param + self.host='' + + if self.debug: + print 'Params:' + print '-------' + print 'host = %s' % self.host + print 'timeout = %s' % self.timeout + print 'ports = %s' % self.ports + print 'optional ports = %s' % self.opt_ports + print 'ranges = %s' % self.ranges + print + + # + # a option that wishes us to terminate now has been given... + # + # This way, you can test params in debug mode and see what this + # program recognised by suplying a version param at the end of + # the cmd-line + # + if self.exit_code<>0: + sys.exit(self.UNKNOWN) + + if self.host=='': + doc_syntax() + self.exit_code=self.UNKNOWN + self.exit_msg='UNKNOWN: bad params, try running without any params for syntax' + + + def CheckHost(self): + 'Check one host using nmap.' + # + # Create a tmp file for storing nmap output + # + # The tempfile module from python 1.5.2 is stupid + # two processes runing at aprox the same time gets + # the same tempfile... + # For this reason I use a random suffix for the tmp-file + # Still not 100% safe, but reduces the risk significally + # I also inserted checks at various places, so that + # _if_ two processes in deed get the same tmp-file + # the only result is a normal error message to nagios + # + r=whrandom.whrandom() + self.tmp_file=tempfile.mktemp('.%s')%r.randint(0,100000) + if self.debug: + print 'Tmpfile is: %s'%self.tmp_file + # + # If a range is given, only run nmap on this range + # + if self.ranges<>'': + global nmap_cmd # needed, to avoid error on next line + # since we assigns to nmap_cmd :) + nmap_cmd='%s -p %s' %(nmap_cmd,self.ranges) + # + # Prepare a task + # + t=utils.Task('%s %s' %(nmap_cmd,self.host)) + # + # Configure a time-out handler + # + th=utils.TimeoutHandler(t.Kill, time_to_live=self.timeout, + debug=self.debug) + # + # Fork of nmap cmd + # + t.Run(detach=0, stdout=self.tmp_file,stderr='/dev/null') + # + # Wait for completition, error or timeout + # + nmap_exit_code=t.Wait(idlefunc=th.Check, interval=1) + # + # Check for timeout + # + if th.WasTimeOut(): + self.exit_code=self.CRITICAL + self.exit_msg='CRITICAL - Plugin timed out after %s seconds' % self.timeout + return + # + # Check for exit status of subprocess + # Must do this after check for timeout, since the subprocess + # also returns error if aborted. + # + if nmap_exit_code <> 0: + self.exit_code=self.UNKNOWN + self.exit_msg='nmap program failed with code %s' % nmap_exit_code + return + # + # Read output + # + try: + f = open(self.tmp_file, 'r') + output=f.readlines() + f.close() + except: + self.exit_code=self.UNKNOWN + self.exit_msg='Unable to get output from nmap' + return + + # + # Store open ports in list + # scans for lines where first word contains '/' + # and stores part before '/' + # + self.active_ports=[] + try: + for l in output: + if len(l)<2: + continue + s=string.split(l)[0] + if string.find(s,'/')<1: + continue + p=string.split(s,'/')[0] + self.active_ports.append(int(p)) + except: + # failure due to strange output... + pass + + if self.debug: + print 'Ports found by nmap: ',self.active_ports + # + # Filter out optional ports, we don't check status for them... + # + try: + for p in self.opt_ports: + self.active_ports.remove(p) + + if self.debug and len(self.opt_ports)>0: + print 'optional ports removed:',self.active_ports + except: + # under extreame loads the remove(p) above failed for me + # a few times, this exception hanlder handles + # this bug-alike situation... + pass + + opened=self.CheckOpen() + closed=self.CheckClosed() + + if opened <>'': + self.exit_code=self.CRITICAL + self.exit_msg='PORTS CRITICAL - Open:%s Closed:%s'%(opened,closed) + elif closed <>'': + self.exit_code=self.WARNING + self.exit_msg='PORTS WARNING - Closed:%s'%closed + else: + self.exit_code=self.OK + self.exit_msg='PORTS ok - Only defined ports open' + + + # + # Compares requested ports on with actually open ports + # returns all open that should be closed + # + def CheckOpen(self): + opened='' + for p in self.active_ports: + if p not in self.ports: + opened='%s %s' %(opened,p) + return opened + + # + # Compares requested ports with actually open ports + # returns all ports that are should be open + # + def CheckClosed(self): + closed='' + for p in self.ports: + if p not in self.active_ports: + closed='%s %s' % (closed,p) + return closed + + + def CleanUp(self): + # + # If temp file exists, get rid of it + # + if self.tmp_file<>'' and os.path.isfile(self.tmp_file): + try: + os.remove(self.tmp_file) + except: + # temp-file colition, some other process already + # removed the same file... + pass + + # + # Show numerical exits as string in debug mode + # + if self.debug: + print 'Exitcode:',self.exit_code, + if self.exit_code==self.UNKNOWN: + print 'UNKNOWN' + elif self.exit_code==self.OK: + print 'OK' + elif self.exit_code==self.WARNING: + print 'WARNING' + elif self.exit_code==self.CRITICAL: + print 'CRITICAL' + else: + print 'undefined' + # + # Check if invalid exit code + # + if self.exit_code<-1 or self.exit_code>2: + self.exit_msg=self.exit_msg+' - undefined exit code (%s)' % self.exit_code + self.exit_code=self.UNKNOWN + + + + + +# +# Help texts +# +def doc_head(): + print """ +check_nmap plugin for Nagios +Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com) +License: GPL +Version: %s""" % _version_ + + +def doc_syntax(): + print """ +Usage: check_ports [-v|--debug] [-H|--host host] [-V|--version] [-h|--help] + [-o|--optional port1,port2,port3 ...] [-r|--range range] + [-p|--port port1,port2,port3 ...] [-t|--timeout timeout]""" + + +def doc_help(): + 'Help is displayed if run without params.' + doc_head() + doc_syntax() + print """ +Options: + -h = help (this screen ;-) + -v = debug mode, show some extra output + -H host = host to check (name or IP#) + -o ports = optional ports that can be open (one or more), + no warning is given if optional port is closed + -p ports = ports that should be open (one or more) + -r range = port range to feed to nmap. Example: :1024,2049,3000:7000 + -t timeout = timeout in seconds, default 10 + -V = Version info + +This plugin attempts to verify open ports on the specified host. + +If all specified ports are open, OK is returned. +If any of them are closed, WARNING is returned (except for optional ports) +If other ports are open, CRITICAL is returned + +If possible, supply an IP address for the host address, +as this will bypass the DNS lookup. +""" + + +# +# Main +# +if __name__ == '__main__': + + if len (sys.argv) < 2: + # + # No params given, show syntax and exit + # + doc_syntax() + sys.exit(-1) + + nmap=CheckNmap(sys.argv[1:]) + exit_code,exit_msg=nmap.Run() + + # + # Give Nagios a msg and a code + # + print exit_msg + sys.exit(exit_code) diff --git a/contrib/check_nwstat.pl b/contrib/check_nwstat.pl new file mode 100644 index 00000000..2194640e --- /dev/null +++ b/contrib/check_nwstat.pl @@ -0,0 +1,188 @@ +#!/usr/bin/perl +# +# check_nwstat.pl: Nagios plugin that uses Jim Drews' nwstat.pl for +# MRTG instead of emulating it. For use particularly with Cliff +# Woolley's mrtgext.pl Unix companion to Drews' MRTGEXT.NLM, where +# mrtgext.pl can contain custom commands that check_nwstat won't recognize, +# though this also does its best to perfectly emulate the C version +# of check_nwstat. +# + + +###################################################################### +# Configuration +###################################################################### + +$nwstatcmd = "/apps/mrtg/helpers/nwstat.pl"; + +use Getopt::Long; + +$::host = shift || &usage(%ERROR); +$::opt_v = undef; +$::opt_wv = undef; +$::opt_cv = undef; +$::opt_to = 10; +$::opt_url = undef; + +GetOptions (qw(v=s wv=i cv=i to=i url=s)) || &usage(%ERROR); + +my $cmd1 = ""; +my $cmd2 = "ZERO"; +my $backward = 0; +my $desc = ""; +my $okstr = "OK"; +my $probstr = "Problem"; +my $result = ""; +my @CMD; +my %ERROR = ("UNKNOWN" => -1, + "OK" => 0, + "WARNING" => 1, + "CRITICAL" => 2); +my $status = $ERROR{"OK"}; + + +###################################################################### +# Main program +###################################################################### + +$SIG{'ALRM'} = sub { + print "Connection timed out\n"; + exit $ERROR{"CRITICAL"}; +}; + +# translate table for compatability with +# check_nwstat (C version) +SWITCH: for ($::opt_v) { + /^LOAD(1|5|15)$/ + && do { $desc = "Load <status> - Up <cmd2>, ". + "$1-min load average = <cmd0>%"; + $cmd1 = "UTIL$1"; last; }; + /^CONNS$/ && do { $desc = "Conns <status>: ". + "<cmd0> current connections"; + $cmd1 = "CONNECT"; last; }; + /^CDBUFF$/ && do { $desc = "Dirty cache buffers = <cmd0>"; + $cmd1 = "S3"; last; }; + /^LTCH$/ && do { $desc = "Long term cache hits = <cmd0>%"; + $cmd1 = "S1"; + $backward = 1; last; }; + /^CBUFF$/ && do { $desc = "Total cache buffers = <cmd0>"; + $cmd1 = "S2"; + $backward = 1; last; }; + /^LRUM$/ && do { $desc = "LRU sitting time = <cmd0> minutes"; + $cmd1 = "S5"; + $backward = 1; last; }; + /^VPF(.*)$/ && do { $desc = "<status><int(cmd0/1024)> MB ". + "(<result>%) free on volume $1"; + $okstr = ""; $probstr = "Only "; + $cmd1 = "VKF$1"; + $cmd2 = "VKS$1"; + $backward = 1; last; }; + /^VKF/ && do { $desc = "<status><cmd0> KB free on volume $1"; + $okstr = ""; $probstr = "Only "; + $cmd1 = "$::opt_v"; + $backward = 1; last; }; + /^$/ && die "Nothing to check!"; + $desc = "<status>: <cmd0>"; + $cmd1 = "$::opt_v"; + } + + +# begin timeout period, run the check +alarm($::opt_to); +open ( CMD, "$nwstatcmd $host $cmd1 $cmd2|" ) || die "Couldn't execute nwstat"; +@CMD = <CMD>; +close ( CMD ); +alarm(0); + +for (@CMD) { chomp; } + +# for any variables that manipulate the results instead of +# just using <cmd0> directly, do that manipulation here into <result> +SWITCH: for ($::opt_v) { + /^VPF/ && do { $result=int(("$CMD[0]"/"$CMD[1]")*100); last; }; + $result = "$CMD[0]"; + } + +if ("$result" == -1) { + $status = $ERROR{"UNKNOWN"}; + $desc = "Server returned \"variable unknown\""; +} elsif ("$result" == -2) { + $status = $ERROR{"CRITICAL"}; + $desc = "Connection failed"; +} + +if (defined($::opt_cv) && $status == $ERROR{"OK"}) { + if ($backward) { + ("$result" <= "$::opt_cv") && ( $status = $ERROR{"CRITICAL"} ); + } else { + ("$result" >= "$::opt_cv") && ( $status = $ERROR{"CRITICAL"} ); + } +} +if (defined($::opt_wv) && $status == $ERROR{"OK"}) { + if ($backward) { + ("$result" <= "$::opt_wv") && ( $status = $ERROR{"WARNING"} ); + } else { + ("$result" >= "$::opt_wv") && ( $status = $ERROR{"WARNING"} ); + } +} + +$desc =~ s/<status>/($status == $ERROR{"OK"})?"$okstr":"$probstr"/eg; +$desc =~ s/<([^>]*)cmd([0-3])([^>]*)>/eval("$1\"$CMD[$2]\"$3")/eg; +$desc =~ s/<result>/"$result"/eg; + +if (defined($::opt_url)) { + print "<A HREF=\"$::opt_url\">$desc</A>\n"; +} else { + print "$desc\n"; +} +exit $status; + + +###################################################################### +# Subroutines +###################################################################### + +sub usage { + + %ERROR = shift; + + print <<EOF +check_nwstat.pl plugin for Nagios +by Cliff Woolley, (c) 2000 + +Usage: ./check_nwstat.pl <host_address> [-v variable] [-wv warn_value] [-cv crit_value] [-to to_sec] [-url url_value] + +Options: + [variable] = Variable to check. Valid variables include: + LOAD1 = 1 minute average CPU load + LOAD5 = 5 minute average CPU load + LOAD15 = 15 minute average CPU load + CONNS = number of currently licensed connections + VPF<vol> = percent free space on volume <vol> + VKF<vol> = KB of free space on volume <vol> + LTCH = percent long term cache hits + CBUFF = current number of cache buffers + CDBUFF = current number of dirty cache buffers + LRUM = LRU sitting time in minutes + [warn_value] = Threshold for value necessary to result in a warning status + [crit_value] = Threshold for value necessary to result in a critical status + [to_sec] = Number of secs before connection times out - default is 10 sec + [url_value] = URL to use in output as a hyperlink. Useful to link to a page + with more details or history for this variable (ie an MRTG page) + +This plugin attempts to contact the MRTGEXT NLM running on a Novell server +to gather the requested system information. + +Notes: + - This plugin requres that the MRTGEXT.NLM file distributed with + James Drews' MRTG extension for NetWare (available from + http://www.engr.wisc.edu/~drews/mrtg/) be loaded on the Novell + servers you wish to check. + - Critical thresholds should be lower than warning thresholds when + the following variables are checked: VPF, VKF, LTCH, CBUFF, and LRUM. +EOF +; + + exit $ERROR{"UNKNOWN"}; +} + diff --git a/contrib/check_ora_table_space.pl b/contrib/check_ora_table_space.pl new file mode 100644 index 00000000..24497b24 --- /dev/null +++ b/contrib/check_ora_table_space.pl @@ -0,0 +1,82 @@ +#!/usr/bin/perl +# +# Program check_ora_table_space +# Written by: Erwan Arzur (erwan@netvalue.com) +# License: GPL +# +# Last Modified: $Date$ +# Revisiin: $Revision$ +# +# "check_ora_table_space.pl" plugin to check the state of Oracle +# table spaces. Scarce documentation. +# +# you need DBD-Oracle-1.03.tar.gz and DBI-1.13.tar.gz from CPAN.org as +# well as some Oracle client stuff to use it. +# +# The SQL request comes from www.dbasupport.com +# + +use DBI; +$ENV{"ORACLE_HOME"}="/intranet/apps/oracle"; + +my $host = shift || &usage ("no host specified"); +my $sid = shift || &usage ("no sid specified"); +my $port = shift || &usage ("no port specified"); +my $dbuser = shift || &usage ("no user specified"); +my $dbpass = shift || &usage ("no password specified"); +my $tablespace = shift || &usage ("no table space specified"); + +my $alertpct = int(shift) || &usage ("no warning state percentage specified"); +my $critpct = int(shift) || &usage ("no critical state percentage specified"); + +my $dbh = DBI->connect( "dbi:Oracle:host=$host;port=$port;sid=$sid", $dbuser, $dbpass, { PrintError => 0, AutoCommit => 1, RaiseError => 0 } ) + || &error ("cannot connect to $dbname: $DBI::errstr\n"); + +#$sth = $dbh->prepare(q{SELECT tablespace_name, SUM(BYTES)/1024/1024 FreeSpace FROM dba_free_space group by tablespace_name}) +my $exit_code = -1; +$sth = $dbh->prepare(<<EOF +select a.TABLESPACE_NAME, a.total,nvl(b.used,0) USED, +nvl((b.used/a.total)*100,0) PCT_USED +from (select TABLESPACE_NAME, sum(bytes)/(1024*1024) total +from sys.dba_data_files group by TABLESPACE_NAME) a, +(select TABLESPACE_NAME,bytes/(1024*1024) used from sys.SM\$TS_USED) b +where a.TABLESPACE_NAME='$tablespace' and + a.TABLESPACE_NAME=b.TABLESPACE_NAME(+) +EOF +) + || &error("Cannot prepare request : $DBI::errstr\n"); +$sth->execute + || &error("Cannot execute request : $DBI::errstr\n"); + +while (($tbname, $total, $used, $pct_used) = $sth->fetchrow) +{ + $pct_used=int($pct_used); + print STDOUT "size: " . $total . " MB Used:" . int($used) . " MB (" . int($pct_used) . "%)\n"; + #print "table space $answer\n"; + if ($pct_used > $alertpct) { + if ($pct_used > $critpct) { + $exit_code = 2 + } else { + $exit_code = 1; + } + } else { + $exit_code = 0; + } +} + +$rc = $dbh->disconnect + || &error ("Cannot disconnect from database : $dbh->errstr\n"); + +exit ($exit_code); + +sub usage { + print "@_\n" if @_; + print "usage : check_ora_table_space.pl <host> <sid> <port> <user> <passwd> <tablespace> <pctwarn> <pctcrit>\n"; + exit (-1); +} + +sub error { + print "@_\n" if @_; + exit (2); +} + diff --git a/contrib/check_pop3.pl b/contrib/check_pop3.pl new file mode 100644 index 00000000..c0c2712c --- /dev/null +++ b/contrib/check_pop3.pl @@ -0,0 +1,144 @@ +#!/usr/bin/perl +# ------------------------------------------------------------------------------ +# File Name: check_pop3.pl +# Author: Richard Mayhew - South Africa +# Date: 2000/01/21 +# Version: 1.0 +# Description: This script will check to see if an POP3 is running +# and whether authentication can take place. +# Email: netsaint@splash.co.za +# ------------------------------------------------------------------------------ +# Copyright 1999 (c) Richard Mayhew +# Credits go to Ethan Galstad for coding Nagios +# If any changes are made to this script, please mail me a copy of the +# changes :) +# License GPL +# ------------------------------------------------------------------------------ +# Date Author Reason +# ---- ------ ------ +# 1999/09/20 RM Creation +# 1999/09/20 TP Changed script to use strict, more secure by +# specifying $ENV variables. The bind command is +# still insecure through. Did most of my work +# with perl -wT and 'use strict' +# 2000/01/20 RM Corrected POP3 Exit State. +# 2000/01/21 RM Fix Exit Codes Again!! +# ------------------------------------------------------------------------------ + +# -----------------------------------------------------------------[ Require ]-- +require 5.004; + +# --------------------------------------------------------------------[ Uses ]-- +use Socket; +use strict; + +# --------------------------------------------------------------[ Enviroment ]-- +$ENV{PATH} = "/bin"; +$ENV{BASH_ENV} = ""; +$|=1; +# ------------------------------------------------------------------[ Global ]-- +my $TIMEOUT = 60; + +# -------------------------------------------------------------------[ usage ]-- +sub usage +{ + print "Minimum arguments not supplied!\n"; + print "\n"; + print "Perl Check POP3 plugin for Nagios\n"; + print "Copyright (c) 2000 Richard Mayhew\n"; + print "\n"; + print "Usage: check_pop3.pl <host> <username> <password> [port]\n"; + print "\n"; + print "<port> = Port that the pop3 daemon is running on <host>. Defaults to 110.\n"; + exit -1; + +} + +# --------------------------------------------------------------[ bindRemote ]-- +sub bindRemote +{ + my ($in_remotehost, $in_remoteport, $in_hostname) = @_; + my $proto; + my $sockaddr; + my $this; + my $thisaddr; + my $that; + my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost); + + if (!socket(ClientSocket,AF_INET, SOCK_STREAM, $proto)) { die $!; } + $sockaddr = 'S n a4 x8'; + $this = pack($sockaddr, AF_INET, 0, $thisaddr); + $that = pack($sockaddr, AF_INET, $in_remoteport, $thataddr); + if (!bind(ClientSocket, $this)) { print "Connection Refused"; exit 2; } + if (!connect(ClientSocket, $that)) { print "Connection Refused"; exit 2; } + select(ClientSocket); $| = 1; select(STDOUT); + return \*ClientSocket; +} + +# ====================================================================[ MAIN ]== +MAIN: +{ + my $hostname; + my $remotehost = shift || &usage; + my $username = shift || &usage; + my $password = shift || &usage; + my $remoteport = shift || 110; + + # Just in case of problems, let's not hang Nagios + $SIG{'ALRM'} = sub { + print "Something is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n"; + exit -1; + }; + + alarm($TIMEOUT); + + chop($hostname = `hostname`); + my ($name, $alias, $proto) = getprotobyname('tcp'); + my $ClientSocket = &bindRemote($remotehost,$remoteport,$hostname); + + +print ClientSocket "user $username\n"; + +#Debug Server +#print "user $username\n"; + +#Sleep or 3 secs, incase server is slow. +sleep 3; + +print ClientSocket "pass $password\n"; + +#Debug Server +#print "pass $password\n"; + +while (<ClientSocket>) { + +print ClientSocket "pass $password\n"; + +#Debug Server +#print $_; + +err($_) if (m/\-ERR\s+(.*)\s+.*/); +message($_) if (m/\+OK Mailbox open,\s+(.*\d)\s+messages.*/); +} +} + +sub message +{ + my $answer = "UNKNOWN"; + $answer = "Pop3 OK - Total Messages On Server :- $1"; + alarm(0); + print ClientSocket "quit\n"; + print "$answer"; + exit 0; +} + +sub err +{ + my $answer = "UNKNOWN"; + $answer = "Pop3 Error :- $1"; + alarm(0); + print ClientSocket "quit\n"; + print "$answer"; + exit 2; +} + diff --git a/contrib/check_qmailq.pl b/contrib/check_qmailq.pl new file mode 100755 index 00000000..4c3f68ff --- /dev/null +++ b/contrib/check_qmailq.pl @@ -0,0 +1,121 @@ +#!/usr/bin/perl +# +# check_qmailq.pl - nagios plugin +# This plugin allows you to check the number of Mails in a qmail- +# queue. PLUGIN NEEDS CONFIGURATION ! (see below) +# +# Copyright 2000 Benjamin Schmid +# +# 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. +# +# +# Emergency E-Mail :) blueshift@gmx.net +# + +### CONFIGURATION SECTION #################### + +my $statcommand = "/var/qmail/bin/qmail-qstat"; +my $queuewarn = 5; # Warning, if more than x mail in Queue +my $queuecrit = 10; # Critical if "--" +my $prewarn = 1; # Warning, if more than x unhandled mails + # (not in Queue +my $precrit = 5; # Critical, if "--" + +### CONFIURATION SECTION END ################ + +use strict; +use Carp; + +#use Getopt::Long; +#&Getopt::Long::config('auto_abbrev'); + + + +my $TIMEOUT = 15; + +my %ERRORS = ('UNKNOWN' , '-1', + 'OK' , '0', + 'WARNING', '1', + 'CRITICAL', '2'); + +my $state = "UNKNOWN"; +my $answer = ""; + +#sub usage { +# printf "\nMissing arguments!\n"; +# printf "\n"; +# printf "Printer Server Queue Nagios Plugin\n"; +# printf "monitors jobs in lpr queues\n"; +# printf "usage: \n"; +# printf "check_lpq.pl \n"; +# printf "Copyright (C) 2000 Benjamin Schmid\n"; +# printf "check_lpq.pl comes with ABSOLUTELY NO WARRANTY\n"; +# printf "This programm is licensed under the terms of the "; +# printf "GNU General Public License\n(check source code for details)\n"; +# printf "\n\n"; +# exit $ERRORS{"UNKNOWN"}; +#} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: check_lpq.pl Time-Out $TIMEOUT s \n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +#$status = GetOptions("community=s",\$community, +# "port=i",\$port); +#if ($status == 0) +#{ +# &usage; +#} + +# $hostname = shift || &usage; + +if (! open STAT, "$statcommand|") { + print ("$state: $statcommand returns no result!"); + exit $ERRORS{$state}; +} +my @lines = <STAT>; +close STAT; + +# Mails in Queues +if ($lines[0]=~/^messages in queue: (\d+)/) { + my $anzq = $1; + $answer = $answer . "$anzq"; + $state='WARNING' if ($anzq >= $queuewarn); + $state='CRITICAL' if ($anzq >= $queuecrit); +} else { + $state='CRITICAL'; + $answer="Keine gueltigte Antwort (Zeile #1) von $statcommand\n"; +} + +# Unverarbeite Mails +if ($lines[1]=~/^messages in queue but not yet preprocessed: (\d+)/) { + my $anzp = $1; + $answer = $answer . " E-Mail(s) nicht ausgeliefert, $anzp unverarbeitet."; + $state='WARNING' if ($anzp >= $prewarn && $state eq 'UNKNOWN'); + $state='CRITICAL' if ($anzp >= $precrit); +} else { + $state='CRITICAL'; + $answer=$answer . "Keine gueltigte Antwort (Zeile #2) von $statcommand\n"; +} + +$state = 'OK' if ($state eq 'UNKNOWN'); + +print ("$state: $answer\n"); +exit $ERRORS{$state}; + diff --git a/contrib/check_rrd_data.pl b/contrib/check_rrd_data.pl new file mode 100644 index 00000000..0ff8750b --- /dev/null +++ b/contrib/check_rrd_data.pl @@ -0,0 +1,129 @@ +#!/usr/bin/perl -wT + +# check_rrd_data plugin for nagios +# +# usage: +# check_rrd machine_id perlexp_warn perlexp_crit perlexp_default [ds] +# +# Checks data from a RRD file. machine_id is normally an IP address, that has +# to be mapped to a RRD file, by means of the config file (by default +# /var/spool/nagios/rrd-files, a file with pairs of (machine_id,rrd_file), +# separated by whitespace). It can be a RRD file, too. +# +# The Perl expressions are expressions to be evaluated in the following cases: +# +# - perlexp_crit. The first one, to check if there is a critical situation. If +# it returns other than "", it will be a critical message. +# - perlexp_warn. The second one to be evaluated. If returns other than "", a +# warning will be issued to Nagios. +# - perlexp_default. If both of the above return "", it will be evaluated, and +# wathever returns this expression will be returned by the script. NOTE that +# this is different from the other two cases, to allow the user issue a +# warning or critical failure even if the other two don't return it. +# +# Use these hosts.cfg entries as examples +# +# command[check_ping]=$USER1$/check_rrd_data.pl $HOSTADDRESS$ \ +# 'return "CHECK_CRICKET_PING: Warning\n" if ($value > 10);' 'return \ +# "CHECK_CRICKET_PING: Critical\n" if ($value > 100);' 'printf \ +# "PING OK - RTA = %.2fms\n", $value; return 0;' 1 +# service[machine]=PING;0;24x7;3;5;1;router-admins;240;24x7;1;1;1;;check_ping +# +# initial version: 28 Nov 2000 by Esteban Manchado Velázquez +# current status: 0.1 +# +# Copyright Notice: GPL +# + +# Doesn't work! Why? +# BEGIN { + # my $runtimedir = substr($0,0,rindex($0,'/')); + # require "$runtimedir/utils.pm"; +# } + +require '/usr/libexec/nagios/plugins/utils.pm'; +use RRD::File; +# use strict; # RRD:File and utils.pm don't like this + +my $configfilepath = "/var/spool/nagios/rrd-files"; # Change if needed +my %hostfile; # For storing config +my $rrdfile; # RRD file to open + +$ENV{'PATH'} = "/bin:/usr/bin"; +$ENV{'ENV'} = ""; + +if (scalar @ARGV != 4 && scalar @ARGV != 5) { + print STDERR join "' '", @ARGV, "\n"; + my $foo = 'check_rrd_data'; + print STDERR $foo, " <file.rrd> <perl_exp_warn> <perl_exp_crit> <perl_exp_default> [<ds>]\n\n"; + print STDERR "<perl_exp_*> is an expression that gets evaluated with \$_ at the current\n"; + print STDERR "value of the data source. If it returns something other than \"\", there\n"; + print STDERR "will be a warning or a critical failure. Else, the expression\n"; + print STDERR "<perl_exp_default> will be evaluated\n"; + exit; +} + +# Check configuration file +open F, $configfilepath or do { + print "Can't open config file $configfilepath\n"; + return $ERRORS{'UNKNOWN'}; +}; +while (<F>) { + next unless /(.+)\s+(.+)/; + $hostfile{$1} = $2; +} +close F; + +# Default +my $ds = defined $ARGV[4]?$ARGV[4]:0; + # print "\$ds = " . $ds . ":"; + # print "\$ARGV[4] = " . $ARGV[4] . ":"; +$ds =~ s/\$//g; # Sometimes Nagios gives 1$ as the last parameter + +# Guess which RRD file have to be opened +$rrdfile = $ARGV[0] if (-r $ARGV[0]); # First the parameter +$rrdfile = $hostfile{$ARGV[0]} unless $rrdfile; # Second, the config file + # print "$ARGV[0]:"; + +if (! $rrdfile) { + print "Can't open data file for $ARGV[0]\n"; # Aaaargh! + return $ERRORS{'UNKNOWN'}; # Unknown +} + + # print "Opening file $rrdfile:"; +my $rrd = new RRD::File ( -file => $rrdfile ); +$rrd->open(); +if (! $rrd->loadHeader()) { + print "Couldn't read header from $rrdfile\n"; + exit $ERRORS{'UNKNOWN'}; # Unknown +} +my $value = $rrd->getDSCurrentValue($ds); +$rrd->close(); + +# Perl expressions to evaluate +my ($perl_exp_warn, $perl_exp_crit, $perl_exp_default) = + ($ARGV[1], $ARGV[2], $ARGV[3]); +my $result; # Result of the expressions (will be printed) +my @data; # Special data reserved for the expressions, to pass data + +# First check for critical errors +$perl_exp_crit =~ /(.*)/; +$perl_exp_crit = $1; +$result = eval $perl_exp_crit; +if ($result) { + print $result; + exit 2; # Critical +} + +# Check for warnings +$perl_exp_warn =~ /(.*)/; +$perl_exp_warn = $1; +$result = eval $perl_exp_warn; +if ($result) { + print $result; + exit 1; # Warning +} + +$perl_exp_default =~ /(.*)/; +$perl_exp_default = $1; +eval $perl_exp_default; # Normally returns 0 (OK) diff --git a/contrib/check_sap.sh b/contrib/check_sap.sh new file mode 100755 index 00000000..eadf977e --- /dev/null +++ b/contrib/check_sap.sh @@ -0,0 +1,70 @@ +#!/bin/sh +################################################################################ +# +# CHECK_SAP plugin for Nagios +# +# Written by Karel Salavec (karel.salavec@ct.cz) +# Last Modified: 20Apr2000 +# +# Command line: CHECK_SAP <typ_of_check> <param1> <param2> [<param3>] +# +# Description: +# This plugin will attempt to open an SAP connection with the message +# server or application server. +# It need the sapinfo program installed on your server (see Notes). +# +# Notes: +# - This plugin requires that the saprfc-devel-45A-1.i386.rpm (or higher) +# package be installed on your machine. Sapinfo program +# is a part of this package. +# - You can find this package at SAP ftp server in +# /general/misc/unsupported/linux +# +# +# Parameters: +# $1 - type of checking - valid values: "ms" = message server +# "as" = application server +# $2 - SAP server identification - can be IP address, DNS name or SAP +# connect string (for example: /H/saprouter/S/sapdp01/H/sapserv3) +# $3 - for $1="ms" - SAP system name (for example: DEV, TST, ... ) +# for $1="as" - SAP system number - note: central instance have sysnr=00 +# $4 - valid only for $1="ms" - logon group name - default: PUBLIC +# +# Example of command definitions for nagios: +# +# command[check_sap_ms]=/usr/local/nagios/libexec/check_sap ms $HOSTADDRESS$ $ARG1$ $ARG2$ +# command[check_sap_as]=/usr/local/nagios/libexec/check_sap as $HOSTADDRESS$ $ARG1$ +# command[check_sap_ex]=/usr/local/nagios/libexec/check_sap as $ARG1$ $ARG2$ +# (for ARG1 see SAP OOS1 transaction) +# +############################################################################## + +if [ $# -lt 3 ]; then +echo "Need min. 3 parameters" +exit 2 +fi + +case "$1" + in + ms) + if [ $4 ] + then + params="r3name=$3 mshost=$2 group=$4" + else + params="r3name=$3 mshost=$2" + fi + ;; + as) + params="ashost=$2 sysnr=$3" + ;; + *) + echo "The first parametr must be ms (message server) or as (application server)!" + exit 2 + ;; +esac + +if /usr/sap/rfcsdk/bin/sapinfo $params | grep -i ERROR ; then +exit 2 +else +exit 0 +fi diff --git a/contrib/check_sockets.pl b/contrib/check_sockets.pl new file mode 100644 index 00000000..b8ae24a2 --- /dev/null +++ b/contrib/check_sockets.pl @@ -0,0 +1,145 @@ +#! /usr/bin/perl +# ------------------------------------------------------------------------------ +# File Name: check_sockets.pl +# Author: Richard Mayhew - South Africa +# Date: 2000/07/11 +# Version: 1.0 +# Description: This script will check to see how may open sockets +# a server has and waron respectivly +# Email: netsaint@splash.co.za +# ------------------------------------------------------------------------------ +# Copyright 1999 (c) Richard Mayhew +# Credits go to Ethan Galstad for coding Nagios +# If any changes are made to this script, please mail me a copy of the +# changes :) +# Some code taken from Charlie Cook (check_disk.pl) +# License GPL +# +# ------------------------------------------------------------------------------ +# Date Author Reason +# ---- ------ ------ +# 1999/09/20 RM Creation +# 1999/09/20 TP Changed script to use strict, more secure by +# specifying $ENV variables. The bind command is +# still insecure through. Did most of my work +# with perl -wT and 'use strict' +# +# ------------------------------------------------------------------------------ + +# -----------------------------------------------------------------[ Require ]-- +require 5.004; +# --------------------------------------------------------------------[ Uses ]-- +use Socket; +use strict; +# --------------------------------------------------------------[ Enviroment ]-- +$ENV{'PATH'}='/bin:/sbin:/usr/bin:/usr/sbin'; +$ENV{BASH_ENV} = ""; +# ------------------------------------------------------------------[ Global ]-- +my $TIMEOUT = 20; +my %ERRORS = ( + 'UNKNOWN', '-1', + 'OK', '0', + 'WARNING', '1', + 'CRITICAL', '2'); +# --------------------------------------------------------------[ connection ]-- +sub connection +{ + my ($in_total,$in_warn,$in_crit,$in_high) = @_; + my $state; + my $answer; + + $in_total =~ s/\ //g; + if ($in_total >= 0) { + + if ($in_total > $in_crit) { + $state = "CRITICAL"; + $answer = "Critical Number Of Sockets Connected : $in_total (Limit = $in_crit)\n"; + + } elsif ($in_total > $in_warn) { + $state = "WARNING"; + $answer = "Warning Number Of Sockets Connected : $in_total (Limit = $in_warn)\n"; + + } else { + if ($in_high ne "") { + $answer = "Sockets OK - Current Sockets: $in_total : $in_high\n"; + } + if ($in_high eq "") { + $answer = "Sockets OK - Current Sockets: $in_total\n"; + } + $state = "OK"; + } + + } else { + $state = "UNKNOWN"; + $answer = "Something is Really WRONG! Sockets Is A Negative Figure!\n"; + } + + print $answer; + exit $ERRORS{$state}; +} + +# -------------------------------------------------------------------[ usage ]-- +sub usage +{ + print "Minimum arguments not supplied!\n"; + print "\n"; + print "Perl Check Sockets plugin for Nagios\n"; + print "Copyright (c) 2000 Richard Mayhew\n"; + print "\n"; + print "Usage: check_sockets.pl <type> <warn> <crit>\n"; + print "\n"; + print "<type> = TOTAL, TCP, UDP, RAW.\n"; + print "<warn> = Number of sockets connected at which a warning message will be generated.[Default = 256]\n"; + print "<crit> = Number of sockets connected at which a critical message will be generated.[Default = 512]\n"; + exit $ERRORS{"UNKNOWN"}; + +} + +# ====================================================================[ MAIN ]== +MAIN: +{ + my $type = shift || &usage; + my $warn = shift || 256; + my $crit = shift || 512; + my $data; + my @data; + my $line; + my $data1; + my $data2; + my $data3; + my $junk; + my $total1; + my $total2; + $type = uc $type; + if ($type eq "TOTAL") { + $type = "sockets"; + } + + # Just in case of problems, let's not hang Nagios + $SIG{'ALRM'} = sub { + print "Somthing is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n"; + exit $ERRORS{"UNKNOWN"}; + }; + + $data = `/bin/cat /proc/net/sockstat`; + @data = split("\n",$data); + alarm($TIMEOUT); + my $output = ""; + my $high; + + + foreach $line (@data) { + if ($line =~ /$type/) { + ($data1,$data2,$data3) = split(" ",$line,3); + + if ($data3 =~ /highest/){ + ($total1,$junk,$total2) = split(" ",$data3,3); + $output = $total1; + $high = $total2; + } + else {$output = $data3;} + alarm(0); + connection($output,$warn,$crit,$high); + } + } +} diff --git a/contrib/check_timeout.c b/contrib/check_timeout.c new file mode 100644 index 00000000..858bdfe9 --- /dev/null +++ b/contrib/check_timeout.c @@ -0,0 +1,55 @@ +/***************************************************************************** + * + * CHECK_TIMEOUT.C + * + * Program: Plugin timeout tester for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: 01-10-2000 + * + * Command line: CHECK_TIMEOUT <something..> + * + * Description: + * This 'plugin' - if you want to call it that - doesn't do anything. It + * just stays in a loop forever and never exits, and is therefore useful for + * testing service and host check timeouts in Nagios. You must supply at + * least one argument on the command line in order to activate the loop. + * + ****************************************************************************/ + +#include <stdio.h> +#include <unistd.h> + + +int main(int argc, char **argv){ + + if(argc==1){ + printf("Incorrect arguments supplied\n"); + printf("\n"); + printf("Plugin timeout tester for Nagios\n"); + printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); + printf("Last Modified: 01-10-2000\n"); + printf("License: GPL\n"); + printf("\n"); + printf("Usage: %s <something>\n",argv[0]); + printf("\n"); + printf("Options:\n"); + printf(" <something> = Anything at all...\n"); + printf("\n"); + printf("Notes:\n"); + printf("This 'plugin' doesn't do anything. It is designed to never exit and therefore\n"); + printf("provides an easy way of testing service and host check timeouts in Nagios.\n"); + printf("\n"); + return 0; + } + + /* let's never leave here, okay? */ + while(1) + sleep(1); + + return 0; + } + + + diff --git a/contrib/check_uptime.c b/contrib/check_uptime.c new file mode 100644 index 00000000..46a1b826 --- /dev/null +++ b/contrib/check_uptime.c @@ -0,0 +1,99 @@ +/****************************************************************************** + * + * CHECK_UPTIME.C + * + * Program: Uptime plugin for Nagios + * License: GPL + * Copyright (c) 2000 Teresa Ramanan (teresa@redowl.org) + * + * Based on CHECK_LOAD.C + * Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br> + * + * Last Modified: $Date$ + * + * Command line: CHECK_UPTIME <host_address> + * + * Description: + * + * This plugin parses the output from "uptime", tokenizing it with ',' as the + * delimiter. Returning only the number of days and/or the hours and minutes + * a machine has been up and running. + * + *****************************************************************************/ + +#include "common/config.h" +#include "common/common.h" +#include "common/utils.h" +#include "common/popen.h" + +int main(int argc, char **argv) +{ + + int result; + char input_buffer[MAX_INPUT_BUFFER]; + int ct; + int i; + char *tok1 = NULL; + char *daytok = NULL; + char *hrmintok = NULL; + char *runstr = NULL; + char tempp; + char ch; + char delim[] = ","; + + if(argc != 2){ + printf("Incorrect number of arguments supplied\n"); + printf("\n"); + print_revision(argv[0],"$Revision$"); + printf("Copyright (c) 2000 Teresa Ramanan (tlr@redowl.org)\n"); + printf("\n"); + printf("Usage: %s <host_address>\n",argv[0]); + printf("\n"); + return STATE_UNKNOWN; + } + + child_process = spopen(PATH_TO_UPTIME); + if(child_process==NULL){ + printf("Error opening %s\n",PATH_TO_UPTIME); + return STATE_UNKNOWN; + } + child_stderr=fdopen(child_stderr_array[fileno(child_process)],"r"); + if(child_stderr==NULL){ + printf("Could not open stderr for %s\n",PATH_TO_UPTIME); + } + fgets(input_buffer,MAX_INPUT_BUFFER-1,child_process); + i = 0; + ct = 0; + + /* Let's mark the end of this string for parsing purposes */ + input_buffer[strlen(input_buffer)-1]='\0'; + + tempp = input_buffer[0]; + while(ch != '\0'){ + ch = (&tempp)[i]; + if (ch == ',') { ct++; } + i++; + } + runstr = input_buffer; + tok1 = strsep(&runstr, delim); + if (ct > 4) { + hrmintok = strsep(&runstr, delim); + hrmintok++; + daytok = strstr(tok1,"up"); + } + else { + hrmintok = strstr(tok1, "up"); + } + + result = spclose(child_process); + if(result){ + printf("Error code %d returned in %s\n",result,PATH_TO_UPTIME); + return STATE_UNKNOWN; + } + if (hrmintok == NULL) { + printf("Problem - unexpected data returned\n"); + return STATE_UNKNOWN; + } + printf("%s%s%s\n",(daytok == NULL)?"":daytok,(daytok == NULL)?"":",",hrmintok); + return STATE_OK; +} diff --git a/contrib/checkciscotemp.pl b/contrib/checkciscotemp.pl new file mode 100644 index 00000000..a702a89e --- /dev/null +++ b/contrib/checkciscotemp.pl @@ -0,0 +1,163 @@ +#!/usr/bin/perl -wT +# check_ciscotemp.pl +# +# Copyright (C) 2000 Leland E. Vandervort <leland@mmania.com> +# +# 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 (or with Nagios); if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA +#################################### +# Nagios pluging to check inlet and outlet temperatures on +# Cisco router platforms which support environmental monitoring +# (7200, 7500, GSR12000...) +#################################### +# default temperature thresholds are 30C for inlet, 40C outlet. +# if input or output is less than thresholds, returns OK +# if equal to (the temps don't change that rapidly) returns WARNING +# if greater than threshold, returns CRITICAL +# if undetermined, or cannot access environmental, returns UNKNOWN +# (in accordance with the plugin coding guidelines) +#################################### + +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('auto_abbrev'); + +my $status; +my $response = ""; +my $timeout = 10; +my $community = "public"; +my $port = 161; +my $INTAKE_TEMP = "1.3.6.1.4.1.9.9.13.1.3.1.3.1"; +my $OUTLET_TEMP = "1.3.6.1.4.1.9.9.13.1.3.1.3.3"; +my $in_temp; +my $out_temp; +my $inlet_thresh = 30; +my $outlet_thresh = 40; + +my %STATUSCODE = ( 'UNKNOWN' => '-1', + 'OK' => '0', + 'WARNING' => '1', + 'CRITICAL' => '2'); + +my $state = "UNKNOWN"; + + +$SIG{'ALRM'} = sub { + print "ERROR: No snmp response from $hostname (sigALRM)\n"; + exit($STATUSCODE{"UNKNOWN"}); +}; + +Getopt::Long::Configure('bundling'); +$status = GetOptions + ("community=s", \$community, + "C=s", \$community, + "H=s", \$hostname, + "hostname=s", \$hostname, + "port=i", \$port, + "timeout=i", \$timeout, + "c=s", \$critical_vals, + "w=s", \$warning_vals, + "ithresh=i", \$inlet_thresh, + "othresh=i", \$outlet_thresh); + +if($status == 0) { + &show_help; +} + +unless (defined($hostname)) { + $hostname = shift || &show_help; +} + +if (defined($critical_vals)) { + die "Cannot Parse Critical Thresholds\n" + unless (split(/:/,$critical_vals)>=2); + ($inlet_thresh,$outlet_thresh) = @_ +} +die unless(defined($inlet_thresh) && defined($outlet_thresh)); + +if (defined($warning_vals)) { + die "Cannot Parse Critical Thresholds\n" + unless (split(/:/,$warning_vals)>=2); + ($inlet_warn,$outlet_warn) = @_; +}else{ + $inlet_warn=$inlet_thresh; + $outlet_warn=$outlet_thresh; +} + +alarm($timeout); + +$in_temp = &SNMPGET($INTAKE_TEMP); +$out_temp = &SNMPGET($OUTLET_TEMP); + +if (($in_temp < $inlet_thresh) && ($out_temp < $outlet_thresh)) { + $state = "OK"; +} +elsif (($in_temp == $inlet_thresh) || ($out_temp == $outlet_thresh)) { + if(($in_temp > $inlet_thresh) || ($out_temp > $outlet_thresh)) { + $state = "CRITICAL"; + } + else { + $state = "WARNING"; + } +} +elsif (($in_temp > $inlet_thresh) || ($out_temp > $outlet_thresh)) { + $state = "CRITICAL"; +} +else { + $state = "WARNING"; +} + +print "$state Inlet Temp: $in_temp Outlet Temp: $out_temp\n"; +exit($STATUSCODE{$state}); + +sub show_help { + printf("\nPerl envmon temperature plugin for Nagios\n"); + printf("Usage:\n"); + printf(" + check_ciscotemp [options] <hostname> + Options: + -C snmp-community + -p snmp-port + -i input temperature threshold + -o output temperature threshold + +"); + printf("Copyright (C)2000 Leland E. Vandervort\n"); + printf("check_ciscotemp comes with absolutely NO WARRANTY either implied or explicit\n"); + printf("This program is licensed under the terms of the\n"); + printf("GNU General Public License\n(check source code for details)\n\n\n"); + exit($STATUSCODE{"UNKNOWN"}); +} + +sub SNMPGET { + $OID = shift; + ($session,$error) = Net::SNMP->session( + Hostname => $hostname, + Community => $community, + Port => $port + ); + if(!defined($session)) { + printf("$state %s\n", $error); + exit($STATUSCODE{$state}); + } + if(!defined($response = $session->get_request($OID))) { + printf("$state %s\n", $session->error()); + $session->close(); + exit($STATUSCODE{$state}); + } + $session->close(); + return($response->{$OID}); +} + diff --git a/contrib/maser-oracle.pl b/contrib/maser-oracle.pl new file mode 100644 index 00000000..aa2741f1 --- /dev/null +++ b/contrib/maser-oracle.pl @@ -0,0 +1,13 @@ +#!/usr/bin/perl + +# Oracle plugin submitted by Christopher Maser (maser@onvista.de) +# 12/31/1999 + +my $host=$ARGV[0]; +my @test=`tnsping $host`; +my $arg=$test[6]; +chomp $arg; +if ($arg =~ /^OK (.*)/) +{print "$arg"; exit 0} +else {exit 2;} + diff --git a/contrib/mrtgext.pl b/contrib/mrtgext.pl new file mode 100644 index 00000000..b9e9f6b9 --- /dev/null +++ b/contrib/mrtgext.pl @@ -0,0 +1,291 @@ +#!/usr/bin/perl -w +# +# mrtgext.pl v0.3 +# (c)2000 Cliff Woolley, Washington and Lee University +# jwoolley@wlu.edu +# +# A UNIX counterpart to Jim Drews' MRTG Extension for netware servers +# Mimics output of mrtgext.nlm using output of various standard UNIX +# programs (df, uptime, and uname) +# +# Dependencies: I make some assumptions about the output format of +# your df and uptime commands. If you have nonstandard outputs for +# any of these, either pick a different command that gives more +# standard output or modify the script below. Example: use /usr/bin/bdf +# on HP-UX instead of /usr/bin/df, because bdf follows the output format +# I expect while df does not. This was written on Linux and tested on +# HP-UX 10.20 (with changes to the subroutines at the bottom of the +# program to reflect HP's command parameters); similar tweaking could +# well be required to port this to other platforms. If you get it +# working on your platform, please send me any changes you had to +# make so I can try to incorporate them. +# +# +# Following is what I expect the programs' outputs to look like: +# +# ======= df ======== +# Filesystem 1k-blocks Used Available Use% Mounted on +# /dev/sda1 1014696 352708 609612 37% / +# /dev/sda2 2262544 586712 1559048 27% /apps +# /dev/sda3 4062912 566544 3286604 15% /share +# /dev/sr0 651758 651758 0 100% /cdrom +# =================== +# +# ===== uptime ====== +# 3:17pm up 15 days, 4:40, 5 users, load average: 0.12, 0.26, 0.33 +# =================== +# + +############################################################### +# Configuration section +############################################################### + +$dfcmd = "/bin/df 2>/dev/null"; +$uptimecmd = "/usr/bin/uptime"; +%customcmds = ( "PROCS" => "numprocesses", + "ZOMBIES" => "numzombies", + "MEMFREE" => "memfree", + "SWAPUSED" => "swapused", + "TCPCONNS" => "tcpconns", + "CLIENTS" => "ipclients" ); + # These are functions that you can + # define and customize for your system. + # You probably need to change the provided + # subroutines to work on your system (if + # not Linux). + +$rootfsnickname = "root"; # this is necessary as a kludge to + # better match the netware behavior. + # if you already have a _filesystem_ + # mounted as /root, then you'll need + # to change this to something else +$DEBUG = 0; +$recvtimeout = 30; + + +############################################################### +# Program section +############################################################### + +require 5.004; + +use Sys::Hostname; + + +$DEBUG = $ARGV[0] unless ($DEBUG); +$SIG{'ALRM'} = sub { exit 1; }; + +# some things never change +$hostname = hostname; + + +if ( $DEBUG ) { + $| = 1; + print scalar localtime,": mrtgext.pl started\n"; +} + +# timeout period +alarm($recvtimeout); +my $items = <STDIN>; +alarm(0); + +$items =~ s/[\r\n]//g; +( $DEBUG ) && print scalar localtime,": request: \"$items\"\n"; +my @items = split (/\s+/,"$items"); +( $DEBUG ) && print scalar localtime,": ",scalar @items," item(s) to process\n"; + +my $uptime = `$uptimecmd`; +my @df = grep {/^\//} `$dfcmd`; + +my $processed = 1; + +foreach $_ (@items) { + ( $DEBUG ) && print scalar localtime,": processing item #$processed: \"$_\"\n"; + $_ = uc; #convert $_ to upper case + if ( /^UTIL1$/ ) { + $uptime =~ /load average: ([^,]+),/; + print $1 * 100,"\n"; + } + elsif ( /^UTIL5$/ ) { + $uptime =~ /load average: [^,]+, ([^,]+)/; + print $1 * 100,"\n"; + } + elsif ( /^UTIL15$/ ) { + $uptime =~ /load average: [^,]+, [^,]+, ([^,]+)/; + print $1 * 100,"\n"; + } + elsif ( /^CONNECT$/ ) { + $uptime =~ /(\d+) users?,/; + print "$1\n"; + } + elsif ( /^NAME$/ ) { + print "$hostname\n"; + } + elsif ( /^UPTIME$/ ) { + $uptime =~ /up (.*),\s+\d+\s+users?,/; + print "$1\n"; + } + elsif ( /^VOLUMES$/ ) { + foreach $dfline (@df) { + my $volname = (split(/\s+/, "$dfline"))[5]; + $volname =~ s/^\/$/$rootfsnickname/; + $volname =~ s/^\///; + $volname =~ s/\//_/g; + print "$volname\n"; + } + } + elsif ( /^VF(\w*)$/ ) { + my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; + foreach $dfline (@df) { + my @dfline = split(/\s+/, "$dfline"); + if ($dfline[5] =~ /^\/?$volname$/i ) { + print (($dfline[1]-$dfline[2]) * 1024,"\n"); + goto done; + } + } + ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; + print "-1\n"; + } + elsif ( /^VU(\w*)$/ ) { + my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; + foreach $dfline (@df) { + my @dfline = split(/\s+/, "$dfline"); + if ($dfline[5] =~ /^\/?$volname$/i ) { + print ($dfline[2] * 1024,"\n"); + goto done; + } + } + ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; + print "-1\n"; + } + elsif ( /^VS(\w*)$/ ) { + my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; + foreach $dfline (@df) { + my @dfline = split(/\s+/, "$dfline"); + if ($dfline[5] =~ /^\/?$volname$/i ) { + print ($dfline[1] * 1024,"\n"); + goto done; + } + } + ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; + print "-1\n"; + } + elsif ( /^VKF(\w*)$/ ) { + my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; + foreach $dfline (@df) { + my @dfline = split(/\s+/, "$dfline"); + if ($dfline[5] =~ /^\/?$volname$/i ) { + print (($dfline[1]-$dfline[2]),"\n"); + goto done; + } + } + ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; + print "-1\n"; + } + elsif ( /^VKU(\w*)$/ ) { + my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; + foreach $dfline (@df) { + my @dfline = split(/\s+/, "$dfline"); + if ($dfline[5] =~ /^\/?$volname$/i ) { + print ($dfline[2],"\n"); + goto done; + } + } + ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; + print "-1\n"; + } + elsif ( /^VKS(\w*)$/ ) { + my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1"; + foreach $dfline (@df) { + my @dfline = split(/\s+/, "$dfline"); + if ($dfline[5] =~ /^\/?$volname$/i ) { + print ($dfline[1],"\n"); + goto done; + } + } + ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n"; + print "-1\n"; + } + elsif ( /^ZERO$/ ) { + print "0\n"; + } + elsif (exists( $customcmds{"$_"} )) { + my $cmdsub = "$customcmds{$_}"; + print &$cmdsub."\n"; + } + else { + print "-1\n"; + } + done: $processed++; +} +( $DEBUG ) && print scalar localtime,": done.\n"; + + +############################################################### +# CUSTOMIZED PROCEDURES +############################################################### + +sub numprocesses { + + my $num = `/bin/ps -eaf | /usr/bin/tail -n +2 | /usr/bin/wc -l`; + chomp ($num); + $num =~ s/\s+//g; + + $num; +} + +sub numzombies { + + my $num = `/bin/ps -afx | /usr/bin/awk '{print \$3}' | /usr/bin/grep Z | /usr/bin/tail -n +2 | /usr/bin/wc -l`; + chomp ($num); + $num =~ s/\s+//g; + + $num; +} + +sub tcpconns { + + my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/wc -l`; + chomp ($num); + $num =~ s/\s+//g; + + $num; +} + +sub ipclients { + + my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/awk '{print \$5}' | /bin/cut -d : -f 1 | /usr/bin/sort -nu | /usr/bin/wc -l`; + chomp ($num); + $num =~ s/\s+//g; + + $num; +} + +sub memfree { + + open( FP, "/proc/meminfo" ); + my @meminfo = <FP>; + close(FP); + + # total: used: free: shared: buffers: cached: + # Mem: 994615296 592801792 401813504 91193344 423313408 93118464 + # Swap: 204791808 0 204791808 + my ($total,$free,$buffers,$cache) = (split(/ +/,$meminfo[1]))[1,3,5,6]; + + int(($free+$buffers+$cache)/$total*100); +} + +sub swapused { + + open( FP, "/proc/meminfo" ); + my @meminfo = <FP>; + close(FP); + + # total: used: free: shared: buffers: cached: + # Mem: 994615296 592424960 402190336 89821184 423313408 93077504 + # Swap: 204791808 0 204791808 + + my ($total,$used) = (split(/ +/,$meminfo[2]))[1,2]; + + int($used/$total*100); +} diff --git a/contrib/readme.txt b/contrib/readme.txt new file mode 100644 index 00000000..d9ae0250 --- /dev/null +++ b/contrib/readme.txt @@ -0,0 +1,147 @@ +Contrib Plugins README +---------------------- + +This directory contains plugins which have been contributed by various people, but that +have not yet been incorporated into the core plugins distribution. + +If you have questions regarding the use of these plugins, try contacting the author(s) +or post a message to the nagios-users mailing list (nagios-users@onelist.com) +requesting assistance. + + +Plugin Overview +--------------- + +berger-ping.tar.gz - Perl script version of the check_ping plugin and a corresponding + CGI (mtr.cgi) that uses mtr to traceroute a path to a host. + (Gary Berger) + +bowen-langley_plugins.tar.gz + - Several C plugins including check_inode, check_boot, etc. + (Adam Bown & Thomas Langley) + + +check_bgpstate.tar.gz - Perl script intended for monitoring BGP sessions on Cisco routers. + Only useful if you are using BGP4 as a routing protocol. For + critical alert the AS (autonomous system) number has to be in the + uplinks hash (see the source code). Requires SNMP read community. + (Christoph Kron) + +check_breeze.tar.gz - Perl script to test signal strength on Breezecom wireless + equipment (Jeffrey Blank) + +check_dns_random.tar.gz - Perl script to see if dns resolves hosts randomly from a list + using the check_dns plugin (Richard Mayhew) + +check_flexlm.tar.gz - Perl script to check a flexlm licensing manager using lmtest + (Ernst-Dieter Martin) + +check_hltherm.tar.gz - C program to check the temperature on a Hot Little Therm temperature + probe. The HLT device, along with temperature probes, can be obtained + from Spiderplant at http://www.spiderplant.com + (Ethan Galstad) + +check_ifoperstatus.tar.gz + - Perl script that checks the operational interface status (up/down) for + one interface on cisco/ascend routers. Especially useful for monitoring + leased lines. Requires SNMP read community and SNMP interface key. + (Christoph Kron) + +check_ifstatus.tar.gz - Perl script that checks operational interface status for every interface + on cisco routers. Requires SNMP read community. + (Christoph Kron) + +check_ipxping.tar.gz - C program that it similiar to the check_ping plugin, except that it + send IPX ping packets to Novell servers or other IPX devices. This + requires the ipxping binary for Linux systems. It does NOT by work + without modification with the ipxping binary for SunOS/Solaris. + (Ethan Galstad) + +check_maxchannels.tar.gz + - Perl script that can only be used for monitoring Ascend/Lucent Max/TNT + access server. Checks ISDN channels and modem cards. Also shows ISDN and + modem usage. Requires SNMP read community. + (Christoph Kron) + +check_maxwanstate.tar.gz + - Perl script that can only be used for monitoring Ascend/Lucent Max/TNT + access server. Checks if every enabled E1/T1 interface is operational + (link active). Requires SNMP read community. + (Christoph Kron) + +check_memory.tgz - C program to check available system memory - RAM, swap, buffers, + and cache (Joshua Jackson) + +check_nfs.tar.gz - Perl script to test and NFS server using rpcinfo + (Ernst-Dieter Martin) + <NOW PART OF check_rpc IN CORE> + +check_ntp.tar.gz - Perl script to check an NTP time source (Bo Kernsey) + <MOVED TO CORE> + +check_ora.tar.gz - Shell script that will check an Oracle database and the TNS listener. + Unlike the check_oracle plugin, this plugin detects when a database is + down and does not create temp files (Jason Hedden) + <MOVED TO CORE> + +check_pop3.tar.gz - Perl script that checks to see if POP3 is running and whether or not + authentication can take place (Richard Mayhew) + +check_radius.tar.gz - C program to check RADIUS authentication. This is a hacked version of + the Cistron Radiusd program radtest that acts as a plugin for Nagios. + The vast majority of the code was written by someone at Livingston + Enterprises and Cistron. NOTE: Due to the copyright restrictions in + this code, it cannot be distributed under the GPL license, and thus + will not appear in the core plugin distribution! + (Adam Jacob) + +check_real.tar.gz - C program to check the status of a REAL media server + (Pedro Leite) + <MOVED TO CORE> + +check_rpc.pl.gz - Perl script to check rpc services. Will check to see if the a specified + program is running on the specified server (Chris Kolquist) + +check_sap.tar.gz - Shell script to check an SAP message or application server. Requires + that you install the saprfc-devel-45A-1.i386.rpm (or higher) package + on your system. The package can be obtained from the SAP FTP site in + the /general/misc/unsupported/linux directory. (Kavel Salavec) + +check_uptime.tar.gz - C program to check system uptime. Must be compiled with the release + 1.2.8 or later of the plugins. (Teresa Ramanan) + +check_wave.tar.gz - Perl script to test signal strength on Speedlan wireless + equipment (Jeffrey Blank) + +hopcroft-plugins.tar.gz - Various example plugin scripts contributed by Stanley Hopcroft. + Includes a plugin to check Internet connectivity by checking various + popular search engines, a plugin to check the availability of login + to a TN/3270 mainframe database using Expect to search for "usual" + screens, and another plugin to test the availability of a database + search via the web. + (Stanley Hopcroft) + +maser-oracle.tar.gz - This is a modification to the check_oracle plugin script that returns + the response time in milliseconds. Requires the Oracle tnsping utility. + (Christoph Maser) + +radius.tar.gz - Code modifications necessary to make the radexample app + supplied with the radiusclient code work as a RADIUS plugin + for Nagios (Nick Shore) + +vincent-check_radius.tar.gz + - C program to check RADIUS authentication. Requires the radiusclient + library available from ftp://ftp.cityline.net/pub/radiusclient/ + (Robert August Vincent II) + <MOVED TO CORE> + +weipert-mysql.tar.gz - C program to check a connection to a MySQL database server, with an + optional username and password. Requires mysql.h and libmysqlclient + to compile (Time Weipert) + +wright-mysql.tar.gz - Perl script to check MySQL database servers. Requires that mysqladmin(1) + be installed on the system (included in the MySQL distribution). This + plugin can accept warning and critical thresholds for the number of threads + in use by the server (Mitch Wright) + + diff --git a/contrib/restrict.pl b/contrib/restrict.pl new file mode 100755 index 00000000..75ea5698 --- /dev/null +++ b/contrib/restrict.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' + if 0; + +# Set this to your local Nagios plugin path +my $pluginpath = "/usr/libexec/nagios/plugins/"; + +# Put all the legal commands (i.e. the commands that are +# not Nagios checks but are allowed to be executed anyway) +# in the following associative array. +my %legal_cmds = ("nc" => "/usr/sbin/nc"); + +# This will not work on OpenSSH +# It does work on ssh-1.2.27-1i +@arg = split ' ',$ENV{'SSH_ORIGINAL_COMMAND'}; + +$arg[0] =~ s/.*\///; # strip leading path +$arg[0] =~ tr/-_.a-zA-Z0-9/X/c; # change atypical chars to X + +if (!defined ($cmd = $legal_cmds{$arg[0]})) +{ + $cmd = $pluginpath . $arg[0]; +} + +exec { $cmd } @arg or die "Can't exec $cmd: $!"; diff --git a/contrib/tarballs/berger-ping.tar.gz b/contrib/tarballs/berger-ping.tar.gz Binary files differnew file mode 100644 index 00000000..cc58750d --- /dev/null +++ b/contrib/tarballs/berger-ping.tar.gz diff --git a/contrib/tarballs/bowen-langley_plugins.tar.gz b/contrib/tarballs/bowen-langley_plugins.tar.gz Binary files differnew file mode 100644 index 00000000..6195109f --- /dev/null +++ b/contrib/tarballs/bowen-langley_plugins.tar.gz diff --git a/contrib/tarballs/check_bgp-1.0.tar.gz b/contrib/tarballs/check_bgp-1.0.tar.gz Binary files differnew file mode 100644 index 00000000..9d45c195 --- /dev/null +++ b/contrib/tarballs/check_bgp-1.0.tar.gz diff --git a/contrib/tarballs/check_breeze.tar.gz b/contrib/tarballs/check_breeze.tar.gz Binary files differnew file mode 100644 index 00000000..fb5186ef --- /dev/null +++ b/contrib/tarballs/check_breeze.tar.gz diff --git a/contrib/tarballs/check_flexlm.tar.gz b/contrib/tarballs/check_flexlm.tar.gz Binary files differnew file mode 100644 index 00000000..4ab71441 --- /dev/null +++ b/contrib/tarballs/check_flexlm.tar.gz diff --git a/contrib/tarballs/check_hltherm.tar.gz b/contrib/tarballs/check_hltherm.tar.gz Binary files differnew file mode 100644 index 00000000..7c45cc87 --- /dev/null +++ b/contrib/tarballs/check_hltherm.tar.gz diff --git a/contrib/tarballs/check_hprsc.tar.gz b/contrib/tarballs/check_hprsc.tar.gz Binary files differnew file mode 100644 index 00000000..8998ff83 --- /dev/null +++ b/contrib/tarballs/check_hprsc.tar.gz diff --git a/contrib/tarballs/check_radius.tar.gz b/contrib/tarballs/check_radius.tar.gz Binary files differnew file mode 100644 index 00000000..70bb08a2 --- /dev/null +++ b/contrib/tarballs/check_radius.tar.gz diff --git a/contrib/tarballs/check_wave.tar.gz b/contrib/tarballs/check_wave.tar.gz Binary files differnew file mode 100644 index 00000000..755be5a9 --- /dev/null +++ b/contrib/tarballs/check_wave.tar.gz diff --git a/contrib/tarballs/hopcroft-plugins.tar.gz b/contrib/tarballs/hopcroft-plugins.tar.gz Binary files differnew file mode 100644 index 00000000..0406a743 --- /dev/null +++ b/contrib/tarballs/hopcroft-plugins.tar.gz diff --git a/contrib/tarballs/radius.tar.gz b/contrib/tarballs/radius.tar.gz Binary files differnew file mode 100644 index 00000000..022dc3be --- /dev/null +++ b/contrib/tarballs/radius.tar.gz diff --git a/contrib/urlize.pl b/contrib/urlize.pl new file mode 100644 index 00000000..8bb591f2 --- /dev/null +++ b/contrib/urlize.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl +# +# urlize.pl +# jcw, 5/12/00 +# +# A wrapper around Nagios plugins that provides a URL link in the output +# + +($#ARGV < 1) && die "Incorrect arguments"; +my $url = shift; + +chomp ($result = `@ARGV`); +print "<A HREF=\"$url\">$result</A>\n"; + +# exit with same exit value as the child produced +exit ($? >> 8); diff --git a/contrib/utils.py b/contrib/utils.py new file mode 100644 index 00000000..73d795c9 --- /dev/null +++ b/contrib/utils.py @@ -0,0 +1,310 @@ +# +# +# Util classes for Nagios plugins +# +# + + + +#========================================================================== +# +# Version: = '$Id$' +# +# (C) Rob W.W. Hooft, Nonius BV, 1998 +# +# Contact r.hooft@euromail.net for questions/suggestions. +# See: <http://starship.python.net/crew/hooft/> +# Distribute freely. +# +# jaclu@galdrion.com 2000-07-14 +# Some changes in error handling of Run() to avoid error garbage +# when used from Nagios plugins +# I also removed the following functions: AbortableWait() and _buttonkill() +# since they are only usable with Tkinter + +import sys,os,signal,time,string + +class error(Exception): + pass + +class _ready(Exception): + pass + +def which(filename): + """Find the file 'filename' in the execution path. If no executable + file is found, return None""" + for dir in string.split(os.environ['PATH'],os.pathsep): + fn=os.path.join(dir,filename) + if os.path.exists(fn): + if os.stat(fn)[0]&0111: + return fn + else: + return None + +class Task: + """Manage asynchronous subprocess tasks. + This differs from the 'subproc' package! + - 'subproc' connects to the subprocess via pipes + - 'task' lets the subprocess run autonomously. + After starting the task, we can just: + - ask whether it is finished yet + - wait until it is finished + - perform an 'idle' task (e.g. Tkinter's mainloop) while waiting for + subprocess termination + - kill the subprocess with a specific signal + - ask for the exit code. + Summarizing: + - 'subproc' is a sophisticated os.popen() + - 'task' is a sophisticated os.system() + Another difference of task with 'subproc': + - If the Task() object is deleted, before the subprocess status + was retrieved, the child process will stay. + It will never be waited for (i.e., the process will turn into + a zombie. Not a good idea in general). + + Public data: + None. + + Public methods: + __init__, __str__, Run, Wait, Kill, Done, Status. + """ + def __init__(self,command): + """Constructor. + arguments: + command: the command to run, in the form of a string, + or a tuple or list of words. + """ + if type(command)==type(''): + self.cmd=command + self.words=string.split(command) + elif type(command)==type([]) or type(command)==type(()): + # Surround each word by ' '. Limitation: words cannot contain ' chars + self.cmd="'"+string.join(command,"' '")+"'" + self.words=tuple(command) + else: + raise error("command must be tuple, list, or string") + self.pid=None + self.status=None + + def Run(self,usesh=0,detach=0,stdout=None,stdin=None,stderr=None): + """Actually run the process. + This method should be called exactly once. + optional arguments: + usesh=0: if 1, run 'sh -c command', if 0, split the + command into words, and run it by ourselves. + If usesh=1, the 'Kill' method might not do what + you want (it will kill the 'sh' process, not the + command). + detach=0: if 1, run 'sh -c 'command&' (regardless of + 'usesh'). Since the 'sh' process will immediately + terminate, the task created will be inherited by + 'init', so you can safely forget it. Remember that if + detach=1, Kill(), Done() and Status() will manipulate + the 'sh' process; there is no way to find out about the + detached process. + stdout=None: filename to use as stdout for the child process. + If None, the stdout of the parent will be used. + stdin= None: filename to use as stdin for the child process. + If None, the stdin of the parent will be used. + stderr=None: filename to use as stderr for the child process. + If None, the stderr of the parent will be used. + return value: + None + """ + if self.pid!=None: + raise error("Second run on task forbidden") + self.pid=os.fork() + if not self.pid: + for fn in range(3,256): # Close all non-standard files in a safe way + try: + os.close(fn) + except os.error: + pass + # + # jaclu@galdrion.com 2000-07-14 + # + # I changed this bit somewhat, since Nagios plugins + # should send only limited errors to the caller + # The original setup here corupted output when there was an error. + # Instead the caller should check result of Wait() and anything + # not zero should be reported as a failure. + # + try: + if stdout: # Replace stdout by file + os.close(1) + i=os.open(stdout,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666) + if i!=1: + sys.stderr.write("stdout not opened on 1!\n") + if stdin: # Replace stdin by file + os.close(0) + i=os.open(stdin,os.O_RDONLY) + if i!=0: + sys.stderr.write("stdin not opened on 0!\n") + if stderr: # Replace stderr by file + os.close(2) + i=os.open(stderr,os.O_CREAT|os.O_WRONLY|os.O_TRUNC,0666) + if i!=2: + sys.stdout.write("stderr not opened on 2!\n") + #try: + if detach: + os.execv('/bin/sh',('sh','-c',self.cmd+'&')) + elif usesh: + os.execv('/bin/sh',('sh','-c',self.cmd)) + else: + os.execvp(self.words[0],self.words) + except: + #print self.words + #sys.stderr.write("Subprocess '%s' execution failed!\n"%self.cmd) + sys.exit(1) + else: + # Mother process + if detach: + # Should complete "immediately" + self.Wait() + + def Wait(self,idlefunc=None,interval=0.1): + """Wait for the subprocess to terminate. + If the process has already terminated, this function will return + immediately without raising an error. + optional arguments: + idlefunc=None: a callable object (function, class, bound method) + that will be called every 0.1 second (or see + the 'interval' variable) while waiting for + the subprocess to terminate. This can be the + Tkinter 'update' procedure, such that the GUI + doesn't die during the run. If this is set to + 'None', the process will really wait. idlefunc + should ideally not take a very long time to + complete... + interval=0.1: The interval (in seconds) with which the 'idlefunc' + (if any) will be called. + return value: + the exit status of the subprocess (0 if successful). + """ + if self.status!=None: + # Already finished + return self.status + if callable(idlefunc): + while 1: + try: + pid,status=os.waitpid(self.pid,os.WNOHANG) + if pid==self.pid: + self.status=status + return status + else: + idlefunc() + time.sleep(interval) + except KeyboardInterrupt: + # Send the interrupt to the inferior process. + self.Kill(signal=signal.SIGINT) + elif idlefunc: + raise error("Non-callable idle function") + else: + while 1: + try: + pid,status=os.waitpid(self.pid,0) + self.status=status + return status + except KeyboardInterrupt: + # Send the interrupt to the inferior process. + self.Kill(signal=signal.SIGINT) + + def Kill(self,signal=signal.SIGTERM): + """Send a signal to the running subprocess. + optional arguments: + signal=SIGTERM: number of the signal to send. + (see os.kill) + return value: + see os.kill() + """ + if self.status==None: + # Only if it is not already finished + return os.kill(self.pid,signal) + + def Done(self): + """Ask whether the process has already finished. + return value: + 1: yes, the process has finished. + 0: no, the process has not finished yet. + """ + if self.status!=None: + return 1 + else: + pid,status=os.waitpid(self.pid,os.WNOHANG) + if pid==self.pid: + #print "OK:",pid,status + self.status=status + return 1 + else: + #print "NOK:",pid,status + return 0 + + def Status(self): + """Ask for the status of the task. + return value: + None: process has not finished yet (maybe not even started). + any integer: process exit status. + """ + self.Done() + return self.status + + def __str__(self): + if self.pid!=None: + if self.status!=None: + s2="done, exit status=%d"%self.status + else: + s2="running" + else: + s2="prepared" + return "<%s: '%s', %s>"%(self.__class__.__name__,self.cmd,s2) + + +#========================================================================== +# +# +# Class: TimeoutHandler +# License: GPL +# Copyright (c) 2000 Jacob Lundqvist (jaclu@galdrion.com) +# +# Version: 1.0 2000-07-14 +# +# Description: +# On init, suply a call-back kill_func that should be called on timeout +# +# Make sure that what ever you are doing is calling Check periodically +# +# To check if timeout was triggered call WasTimeOut returns (true/false) +# + +import time,sys + +class TimeoutHandler: + def __init__(self,kill_func,time_to_live=10,debug=0): + 'Generic time-out handler.' + self.kill_func=kill_func + self.start_time=time.time() + self.stop_time=+self.start_time+int(time_to_live) + self.debug=debug + self.aborted=0 + + def Check(self): + 'Call this periodically to check for time-out.' + if self.debug: + sys.stdout.write('.') + sys.stdout.flush() + if time.time()>=self.stop_time: + self.TimeOut() + + def TimeOut(self): + 'Trigger the time-out callback.' + self.aborted=1 + if self.debug: + print 'Timeout, aborting' + self.kill_func() + + def WasTimeOut(self): + 'Indicates if timeout was triggered 1=yes, 0=no.' + if self.debug: + print '' + print 'call duration: %.2f seconds' % (time.time()-self.start_time) + return self.aborted diff --git a/install-sh b/install-sh new file mode 100755 index 00000000..ebc66913 --- /dev/null +++ b/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/make-tarball b/make-tarball new file mode 100755 index 00000000..1695c8c2 --- /dev/null +++ b/make-tarball @@ -0,0 +1,26 @@ +#! /bin/sh +if [ "x$1" = "x" ] +then + echo "Usage: $0 <release number>" + exit 1 +fi + +autoconf +if test -e Makefile; then + make devclean +fi + +PWDSAVE=`pwd` +PACKAGE=`basename $PWDSAVE` +pushd .. +ln -s $PACKAGE $PACKAGE-$1 +tar zhcvf $PWDSAVE/SOURCES/$PACKAGE-$1.tar.gz --exclude RCS --exclude CVS --exclude SOURCES --exclude RPMS --exclude SRPMS --exclude redhat --exclude debian --exclude solaris --exclude sparc64 --exclude rpmrc --exclude rpmmacros --exclude *~ --exclude .#* $PACKAGE-$1 +rm $PACKAGE-$1 +popd + +gzip -cd SOURCES/$PACKAGE-$1.tar.gz | bzip2 -c9 > SOURCES/$PACKAGE-$1.tar.bz2 + +if md5sum --help >/dev/null; then + md5sum ./SOURCES/$PACKAGE-$1.tar.gz > ./SOURCES/$PACKAGE-$1.tar.gz.md5 + md5sum ./SOURCES/$PACKAGE-$1.tar.bz2 > ./SOURCES/$PACKAGE-$1.tar.bz2.md5 +fi diff --git a/missing b/missing new file mode 100755 index 00000000..7789652e --- /dev/null +++ b/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 00000000..6b3b5fc5 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman <friedman@prep.ai.mit.edu> +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/nagios-plugins.spec b/nagios-plugins.spec new file mode 100644 index 00000000..e5997f74 --- /dev/null +++ b/nagios-plugins.spec @@ -0,0 +1,199 @@ +%{!?custom:%global custom 0} + +%define archive nagios-plugins + +%if %custom +%define name %{archive}-custom +%else +%define name %{archive} +%endif + +%define version 1.3.0 +%define release alpha1 +%define source http://nagiosplug.sourceforge.net/src/%{archive}-%{version}-%{release}.tar.gz + +Name: %{name} +Version: %{version} +Release: %{release} +Copyright: GPL +Source: %{source} +BuildRoot: %{_tmppath}/%{name}-buildroot +Prefix: %{_prefix}/lib/nagios/plugins +Packager: Karl DeBisschop <kdebisschop@users.sourceforge.net> +Vendor: Nagios Plugin Development Group +%if %custom +Obsoletes: nagios-plugins nagios-plugins-extras +%else +Obsoletes: nagios-plugins-custom +%endif +AutoReqProv: no +Summary: Host/service/network monitoring program plugins for Nagios +Group: Applications/System + + +%description + +Nagios is a program that will monitor hosts and services on your +network, and to email or page you when a problem arises or is +resolved. Nagios runs on a unix server as a background or daemon +process, intermittently running checks on various services that you +specify. The actual service checks are performed by separate "plugin" +programs which return the status of the checks to Nagios. + +This package contains the basic plugins necessary for use with the +Nagios package. This package should install cleanly on almost any +RPM-based system. + + +%package extras +Summary: Plugins which depend on the presence of other packages +Group: Applications/System + +%description extras + +Nagios is a program that will monitor hosts and services on your +network, and to email or page you when a problem arises or is +resolved. Nagios runs on a unix server as a background or daemon +process, intermittently running checks on various services that you +specify. The actual service checks are performed by separate "plugin" +programs which return the status of the checks to Nagios. + +This package contains plugins which use additional libraries or system +calls that are not installed on all systems. As a result, most users +will need to install the '--nodeps' option when invoking `rpm` + + +%prep +%setup -q -n %{archive}-%{version}-%{release} + + +%build +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure \ +--prefix=%{_prefix}/lib/nagios/plugins \ +--libexecdir=%{_prefix}/lib/nagios/plugins \ +--with-cgiurl=/nagios/cgi-bin +make + + +%install +make AM_INSTALL_PROGRAM_FLAGS="" DESTDIR=${RPM_BUILD_ROOT} install +install -d ${RPM_BUILD_ROOT}/etc/nagios +install -m 664 command.cfg ${RPM_BUILD_ROOT}/etc/nagios + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root) +%config(missingok,noreplace) /etc/nagios/command.cfg +%doc INSTALL README REQUIREMENTS COPYING ChangeLog command.cfg +%defattr(775,root,root) +%dir %{_prefix}/lib/nagios/plugins +%if %custom +%{_prefix}/lib/nagios/plugins/* +%else +%{_prefix}/lib/nagios/plugins/check_by_ssh +%{_prefix}/lib/nagios/plugins/check_breeze +%{_prefix}/lib/nagios/plugins/check_disk +%{_prefix}/lib/nagios/plugins/check_disk_smb +%{_prefix}/lib/nagios/plugins/check_dns +%{_prefix}/lib/nagios/plugins/check_dummy +%{_prefix}/lib/nagios/plugins/check_flexlm +%{_prefix}/lib/nagios/plugins/check_ftp +%{_prefix}/lib/nagios/plugins/check_http +%{_prefix}/lib/nagios/plugins/check_imap +%{_prefix}/lib/nagios/plugins/check_ircd +%{_prefix}/lib/nagios/plugins/check_load +%{_prefix}/lib/nagios/plugins/check_log +%{_prefix}/lib/nagios/plugins/check_mrtg +%{_prefix}/lib/nagios/plugins/check_mrtgtraf +%{_prefix}/lib/nagios/plugins/check_nagios +%{_prefix}/lib/nagios/plugins/check_nntp +%{_prefix}/lib/nagios/plugins/check_ntp +%{_prefix}/lib/nagios/plugins/check_nwstat +%{_prefix}/lib/nagios/plugins/check_oracle +%{_prefix}/lib/nagios/plugins/check_overcr +%{_prefix}/lib/nagios/plugins/check_ping +%{_prefix}/lib/nagios/plugins/check_pop +%{_prefix}/lib/nagios/plugins/check_procs +%{_prefix}/lib/nagios/plugins/check_real +%{_prefix}/lib/nagios/plugins/check_rpc +%{_prefix}/lib/nagios/plugins/check_sensors +%{_prefix}/lib/nagios/plugins/check_smtp +%{_prefix}/lib/nagios/plugins/check_ssh +%{_prefix}/lib/nagios/plugins/check_swap +%{_prefix}/lib/nagios/plugins/check_tcp +%{_prefix}/lib/nagios/plugins/check_time +%{_prefix}/lib/nagios/plugins/check_udp +%{_prefix}/lib/nagios/plugins/check_ups +%{_prefix}/lib/nagios/plugins/check_users +%{_prefix}/lib/nagios/plugins/check_vsz +%{_prefix}/lib/nagios/plugins/check_wave +%{_prefix}/lib/nagios/plugins/utils.pm +%{_prefix}/lib/nagios/plugins/utils.sh +%{_prefix}/lib/nagios/plugins/urlize +%endif + +%if ! %custom +%files extras +%defattr(775,root,root) +%{_prefix}/lib/nagios/plugins/check_fping +%{_prefix}/lib/nagios/plugins/check_game +%{_prefix}/lib/nagios/plugins/check_ldap +%{_prefix}/lib/nagios/plugins/check_mysql +%{_prefix}/lib/nagios/plugins/check_pgsql +%{_prefix}/lib/nagios/plugins/check_radius +%{_prefix}/lib/nagios/plugins/check_snmp +%{_prefix}/lib/nagios/plugins/check_hpjd + +%endif + +%changelog +* Wed Jan 17 2001 Karl DeBisschop <karl@debisschop.net> (1.2.9-1) +- switch from /usr/libexec to /usr/lib because FHS has no libexec +- use 'custom' macro define to merge with nagios-plugins-custom spec +- add check_game to extras + +* Mon Jun 26 2000 Karl DeBisschop <karl@debisschop.net> +- Release 1.2.8-4 (check_ping bug fix) +- use bzip2 insted of gzip for mandrake compatibility + +* Thu Jun 22 2000 Karl DeBisschop <karl@debisschop.net> +- Release 1.2.8-3 (bug fixes) +- Add macros to spec where possible + +* Fri Jun 16 2000 Karl DeBisschop <karl@debisschop.net> +- Release 1.2.8-2 (bug fixes) + +* Fri Jun 09 2000 Karl DeBisschop <karl@debisschop.net> +- Release to 1.2.8 + +* Wed Jun 07 2000 Karl DeBisschop <karl@debisschop.net> +- Upgrade to 1.2.8pre7 + +* Sat Jun 03 2000 Karl DeBisschop <karl@debisschop.net> +- Upgraded to 1.2.8pre5 +- use RPM_OPT_FALGS to set compiler options +- cahneg group to Applications/System + +* Fri May 19 2000 Karl DeBisschop <karl@debisschop.net> +- Upgraded to 1.2.8pre3 (release-3) + +* Mon Mar 20 2000 Karl DeBisschop <karl@debisschop.net> +- Upgraded to 1.2.8b2 + +* Tue Dec 14 1999 Adam Jacob <adam@cybertrails.com> (1.2.7-1cvs) +- Upgraded package from 1.2.6 to 1.2.7 from the latest CVS code +- Modified SPEC file to contain the proper build_root stuff. :) + +* Tue Oct 19 1999 Mike McHenry <mmchen@minn.net> (1.2.6) +- Upgraded package from 1.2.4 to 1.2.6 +- Resolved dependancy issue with libpq.so +- Added support for check_fping + +* Fri Sep 03 1999 Mike McHenry <mmchen@minn.net> (1.2.4) +- Upgraded package from 1.2.2 to 1.2.4 + +* Mon Aug 16 1999 Mike McHenry <mmchen@minn.net> (1.2.2) +- First RPM build (1.2.2) diff --git a/opttest.pl b/opttest.pl new file mode 100755 index 00000000..85e3b494 --- /dev/null +++ b/opttest.pl @@ -0,0 +1,50 @@ +#!/usr/bin/perl -w +use strict; +use Test; + +use vars qw($dir $file $prog $idx $state $output %progs @dirs); + +my $tests = 0; + +@dirs = qw(plugins plugins-scripts); + +foreach $dir (@dirs) { + opendir(DIR, $dir) || die "can't opendir $dir: $!"; + while ($file = readdir(DIR)) { + if (-x "$dir/$file" && -f "$dir/$file") { + $tests++; + $progs{"$dir/$file"} = $file; + } + } + closedir DIR; +} + +plan tests => $tests; + +for $prog (keys %progs) { + $state = 0; + $file = `basename $prog`; + + $idx = 1; + $output = `$prog -h 2>&1`; + if($?) {$state++;print "$prog failed test $idx\n";} + unless ($output =~ m/$progs{$prog}/ms) { + $idx++; $state++;print "$output\n$prog failed test $idx\n"; + } + + $idx++; + `$prog --help 2>&1 > /dev/null`; + if($?) {$state++;print "$prog failed test $idx\n";} + + $idx++; + `$prog -V 2>&1 > /dev/null`; + if($?) {$state++;print "$prog failed test $idx\n";} + + $idx++; + `$prog --version 2>&1 > /dev/null`; + if($?) {$state++;print "$prog failed test $idx\n";} + + print "$prog ($idx tests) "; + ok $state,0; +} + diff --git a/package.def b/package.def new file mode 100644 index 00000000..37e147b8 --- /dev/null +++ b/package.def @@ -0,0 +1 @@ +PACKAGE_RELEASE="1.3.0-alpha1" diff --git a/plugins-scripts/.cvsignore b/plugins-scripts/.cvsignore new file mode 100644 index 00000000..95d79c72 --- /dev/null +++ b/plugins-scripts/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +subst +utils.pm +utils.sh
\ No newline at end of file diff --git a/plugins-scripts/Makefile.am b/plugins-scripts/Makefile.am new file mode 100644 index 00000000..4bdf7175 --- /dev/null +++ b/plugins-scripts/Makefile.am @@ -0,0 +1,30 @@ +## Process this file with automake to produce Makefile.in + +SUFFIXES = .pl .sh + +VPATH=$(top_srcdir) $(top_srcdir)/plugins-scripts $(top_srcdir)/plugins-scripts/t + +libexec_SCRIPTS = check_breeze check_disk_smb check_flexlm check_ircd \ + check_log check_ntp check_oracle check_rpc check_sensors check_wave \ + utils.sh utils.pm + +EXTRA_DIST=check_breeze.pl check_disk_smb.pl check_flexlm.pl check_ircd.pl \ + check_log.sh check_ntp.pl check_oracle.sh check_rpc.pl check_sensors.sh \ + check_wave.pl utils.sh.in utils.pm.in t + +TESTS_ENVIRONMENT=perl -I $(top_builddir) -I $(top_srcdir) + +TESTS = @SCRIPT_TEST@ + +test: + perl -I $(top_builddir) -I $(top_srcdir) ../test.pl + +CLEANFILES=$(libexec_SCRIPTS) + +.pl : + $(AWK) -f ./subst $< > $@ + chmod +x $@ + +.sh : + $(AWK) -f ./subst $< > $@ + chmod +x $@ diff --git a/plugins-scripts/check_breeze.pl b/plugins-scripts/check_breeze.pl new file mode 100755 index 00000000..79e36be7 --- /dev/null +++ b/plugins-scripts/check_breeze.pl @@ -0,0 +1,86 @@ +#! /usr/bin/perl -wT + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_H $opt_w $opt_c $PROGNAME); +use lib $main::runtimedir; +use utils qw(%ERRORS &print_revision &support &usage); + +sub print_help (); +sub print_usage (); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); + exit $ERRORS{'OK'}; +} + +if ($opt_h) {print_help(); exit $ERRORS{'OK'};} + +($opt_H) || ($opt_H = shift) || usage("Host name/address not specified\n"); +my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); +($host) || usage("Invalid host: $opt_H\n"); + +($opt_w) || ($opt_w = shift) || usage("Warning threshold not specified\n"); +my $warning = $1 if ($opt_w =~ /([0-9]{1,2}|100)+/); +($warning) || usage("Invalid warning threshold: $opt_w\n"); + +($opt_c) || ($opt_c = shift) || usage("Critical threshold not specified\n"); +my $critical = $1 if ($opt_c =~ /([0-9]{1,2}|100)/); +($critical) || usage("Invalid critical threshold: $opt_c\n"); + +my $sig=0; +$sig = `/usr/bin/snmpget $host public .1.3.6.1.4.1.710.3.2.3.1.3.0`; +my @test=split(/ /,$sig); +$sig=$test[2]; +$sig=int($sig); +if ($sig>100){$sig=100} + +print "Signal Strength at: $sig%\n"; + +exit $ERRORS{'CRITICAL'} if ($sig<$critical); +exit $ERRORS{'WARNING'} if ($sig<$warning); +exit $ERRORS{'OK'}; + + +sub print_usage () { + print "Usage: $PROGNAME -H <host> -w <warn> -c <crit>\n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2000 Jeffrey Blank/Karl DeBisschop + +This plugin reports the signal strength of a Breezecom wireless equipment + +"; + print_usage(); + print " +-H, --hostname=HOST + Name or IP address of host to check +-w, --warning=INTEGER + Percentage strength below which a WARNING status will result +-c, --critical=INTEGER + Percentage strength below which a CRITICAL status will result + +"; + support(); +} diff --git a/plugins-scripts/check_disk_smb.pl b/plugins-scripts/check_disk_smb.pl new file mode 100755 index 00000000..d1b0b3d6 --- /dev/null +++ b/plugins-scripts/check_disk_smb.pl @@ -0,0 +1,240 @@ +#! /usr/bin/perl -wT +# +# +# check_disk.pl <host> <share> <user> <pass> [warn] [critical] [port] +# +# Nagios host script to get the disk usage from a SMB share +# +# Changes and Modifications +# ========================= +# 7-Aug-1999 - Michael Anthon +# Created from check_disk.pl script provided with netsaint_statd (basically +# cause I was too lazy (or is that smart?) to write it from scratch) +# 8-Aug-1999 - Michael Anthon +# Modified [warn] and [critical] parameters to accept format of nnn[M|G] to +# allow setting of limits in MBytes or GBytes. Percentage settings for large +# drives is a pain in the butt + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +require 5.004; +use POSIX; +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $verbose); +use vars qw($PROGNAME); +use lib $main::runtimedir; +use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); + +sub print_help (); +sub print_usage (); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("v" => \$verbose, "verbose" => \$verbose, + "V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "p=s" => \$opt_p, "password=s" => \$opt_p, + "u=s" => \$opt_u, "username=s" => \$opt_u, + "s=s" => \$opt_s, "share=s" => \$opt_s, + "W=s" => \$opt_W, "workgroup=s" => \$opt_W, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); #' + exit $ERRORS{'OK'}; +} + +if ($opt_h) {print_help(); exit $ERRORS{'OK'};} + +my $smbclient="/usr/bin/smbclient"; +my $smbclientoptions=""; + +($opt_H) || ($opt_H = shift) || usage("Host name not specified\n"); +my $host = $1 if ($opt_H =~ /([-_.A-Za-z0-9]+)/); +($host) || usage("Invalid host: $opt_H\n"); + +($opt_s) || ($opt_s = shift) || usage("Share volume not specified\n"); +my $share = $1 if ($opt_s =~ /([-_.A-Za-z0-9]+)/); +($share) || usage("Invalid share: $opt_s\n"); + +($opt_u) || ($opt_u = shift) || ($opt_u = "guest"); +my $user = $1 if ($opt_u =~ /([-_.A-Za-z0-9]+)/); +($user) || usage("Invalid user: $opt_u\n"); + +($opt_p) || ($opt_p = shift) || ($opt_p = "guest"); +my $pass = $1 if ($opt_p =~ /(.*)/); + +($opt_w) || ($opt_w = shift) || ($opt_w = 85); +my $warn = $1 if ($opt_w =~ /([0-9]{1,2}\%?|100\%?|[0-9]+[kmKM])+/); +($warn) || usage("Invalid warning threshold: $opt_w\n"); + +($opt_c) || ($opt_c = shift) || ($opt_c = 95); +my $crit = $1 if ($opt_c =~ /([0-9]{1,2}\%?|100\%?|[0-9]+[kmKM])/); +($crit) || usage("Invalid critical threshold: $opt_c\n"); + +my $workgroup = $1 if (defined($opt_W) && $opt_W =~ /(.*)/); + +my $state = "OK"; +my $answer = undef; +my $res = undef; +my @lines = undef; + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print "No Answer from Client\n"; + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + +# Execute an "ls" on the share using smbclient program +# get the results into $res +if (defined($workgroup)) { + $res = qx/$smbclient \/\/$host\/$share $pass -W $workgroup -U $user $smbclientoptions -c ls/; +} else { + $res = qx/$smbclient \/\/$host\/$share $pass -U $user $smbclientoptions -c ls/; +} +#Turn off alarm +alarm(0); + +#Split $res into an array of lines +@lines = split /\n/, $res; + +#Get the last line into $_ +$_ = $lines[$#lines]; +#print "$_\n"; + +#Process the last line to get free space. +#If line does not match required regexp, return an UNKNOWN error +if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) { + + my ($avail) = ($3*$2)/1024; + my ($avail_bytes) = $avail; + my ($capper) = int(($3/$1)*100); + my ($mountpt) = "\\\\$host\\$share"; + + #Check $warn and $crit for type (%/M/G) and set up for tests + #P = Percent, K = KBytes + my $warn_type; + my $crit_type; + if ($warn =~ /^([0-9]+$)/) { + $warn_type = "P"; + } elsif ($warn =~ /^([0-9]+)k$/) { + my ($warn_type) = "K"; + $warn = $1; + } elsif ($warn =~ /^([0-9]+)M$/) { + $warn_type = "K"; + $warn = $1 * 1024; + } elsif ($warn =~ /^([0-9]+)G$/) { + $warn_type = "K"; + $warn = $1 * 1048576; + } + if ($crit =~ /^([0-9]+$)/) { + $crit_type = "P"; + } elsif ($crit =~ /^([0-9]+)k$/) { + $crit_type = "K"; + $crit = $1; + } elsif ($crit =~ /^([0-9]+)M$/) { + $crit_type = "K"; + $crit = $1 * 1024; + } elsif ($crit =~ /^([0-9]+)G$/) { + $crit_type = "K"; + $crit = $1 * 1048576; + } + + if (int($avail / 1024) > 0) { + $avail = int($avail / 1024); + if (int($avail /1024) > 0) { + $avail = (int(($avail / 1024)*100))/100; + $avail = $avail."G"; + } else { + $avail = $avail."M"; + } + } else { + $avail = $avail."K"; + } + +#print ":$warn:$warn_type:\n"; +#print ":$crit:$crit_type:\n"; +#print ":$avail:$avail_bytes:$capper:$mountpt:\n"; + if ((($warn_type eq "P") && (100 - $capper) < $warn) || (($warn_type eq "K") && ($avail_bytes > $warn))) { + $answer = "Disk ok - $avail ($capper%) free on $mountpt\n"; + } elsif ((($crit_type eq "P") && (100 - $capper) < $crit) || (($crit_type eq "K") && ($avail_bytes > $crit))) { + $state = "WARNING"; + $answer = "Only $avail ($capper%) free on $mountpt\n"; + } else { + $state = "CRITICAL"; + $answer = "Only $avail ($capper%) free on $mountpt\n"; + } +} else { + $answer = "Result from smbclient not suitable\n"; + $state = "UNKNOWN"; + foreach (@lines) { + if (/Access denied/) { + $answer = "Access Denied\n"; + $state = "CRITICAL"; + last; + } + if (/(Unknown host \w*)/) { + $answer = "$1\n"; + $state = "CRITICAL"; + last; + } + if (/(You specified an invalid share name)/) { + $answer = "Invalid share name \\\\$host\\$share\n"; + $state = "CRITICAL"; + last; + } + } +} + + +print $answer; +print "$state\n" if ($verbose); +exit $ERRORS{$state}; + +sub print_usage () { + print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> + -w <warn> -c <crit> [-W <workgroup>]\n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2000 Michael Anthon/Karl DeBisschop + +Perl Check SMB Disk plugin for Nagios + +"; + print_usage(); + print " +-H, --hostname=HOST + NetBIOS name of the server +-s, --share=STRING + Share name to be tested +-W, --workgroup=STRING + Workgroup or Domain used (Defaults to \"WORKGROUP\") +-u, --user=STRING + Username to log in to server. (Defaults to \"guest\") +-p, --password=STRING + Password to log in to server. (Defaults to \"guest\") +-w, --warning=INTEGER + Percent of used space at which a warning will be generated (Default: 85%) + +-c, --critical=INTEGER + Percent of used space at which a critical will be generated (Defaults: 95%) + + +"; + support(); +} diff --git a/plugins-scripts/check_flexlm.pl b/plugins-scripts/check_flexlm.pl new file mode 100755 index 00000000..1d26b7c8 --- /dev/null +++ b/plugins-scripts/check_flexlm.pl @@ -0,0 +1,149 @@ +#! /usr/bin/perl -wT +# +# usage: +# check_flexlm.pl license_file +# +# Check available flexlm license managers. +# Use lmstat to check the status of the license server +# described by the license file given as argument. +# Check and interpret the output of lmstat +# and create returncodes and output. +# +# Contrary to the nagios concept, this script takes +# a file, not a hostname as an argument and returns +# the status of hosts and services described in that +# file. Use these hosts.cfg entries as an example +# +#host[anchor]=any host will do;some.address.com;;check-host-alive;3;120;24x7;1;1;1; +#service[anchor]=yodel;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_flexlm!/opt/lic/licfiles/yodel_lic +#service[anchor]=yeehaw;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_flexlm!/opt/lic/licfiles/yeehaw_lic +#command[check_flexlm]=/some/path/libexec/check_flexlm.pl $ARG1$ +# +# Notes: +# - you need the lmstat utility which comes with flexlm. +# - set the correct path in the variable $lmstat. +# +# initial version: 9-10-99 Ernst-Dieter Martin edmt@infineon.com +# +# License: GPL +# + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_F $verbose $PROGNAME); +use lib $main::runtimedir; +use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); + +sub print_help (); +sub print_usage (); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "v" => \$verbose, "verbose" => \$verbose, + "F=s" => \$opt_F, "filename=s" => \$opt_F); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); + exit $ERRORS{'OK'}; +} + +if ($opt_h) {print_help(); exit $ERRORS{'OK'};} + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print "No Answer from Client\n"; + exit 2; +}; +alarm($TIMEOUT); + +my $lmstat = "/opt/lic/sw/cadadm/default/bin/lmstat"; + +($opt_F) || ($opt_F = shift) || usage("License file not specified\n"); +my $licfile = $1 if ($opt_F =~ /^(.*)$/); +($licfile) || usage("Invalid filename: $opt_F\n"); + +print "$licfile\n" if $verbose; + +open CMD,"$lmstat -c $licfile |"; + +my $serverup = 0; +my ($ls1,$ls2,$ls3,$lf1,$lf2,$lf3,$servers); + +while ( <CMD> ) { + if ( /^License server status: [0-9]*@([-0-9a-zA-Z_]*),[0-9]*@([-0-9a-zA-Z_]*),[0-9]*@([-0-9a-zA-Z_]*)/ ) { + $ls1 = $1; + $ls2 = $2; + $ls3 = $3; + $lf1 = $lf2 = $lf3 = 0; + $servers = 3; + } elsif ( /^License server status: [0-9]*@([-0-9a-zA-Z_]*)/ ) { + $ls1 = $1; + $ls2 = $ls3 = ""; + $lf1 = $lf2 = $lf3 = 0; + $servers = 1; + } elsif ( / *$ls1: license server UP/ ) { + print "$ls1 UP, "; + $lf1 = 1 + } elsif ( / *$ls2: license server UP/ ) { + print "$ls2 UP, "; + $lf2 = 1 + } elsif ( / *$ls3: license server UP/ ) { + print "$ls3 UP, "; + $lf3 = 1 + } elsif ( / *([^:]*: UP .*)/ ) { + print " license server for $1\n"; + $serverup = 1; + } +} +if ( $serverup == 0 ) { + print " license server not running\n"; + exit 2; +} + +exit $ERRORS{'OK'} if ( $servers == $lf1 + $lf2 + $lf3 ); +exit $ERRORS{'WARNING'} if ( $servers == 3 && $lf1 + $lf2 + $lf3 == 2 ); +exit $ERRORS{'CRITICAL'}; + + +sub print_usage () { + print "Usage: + $PROGNAME -F <filename> [--verbose] + $PROGNAME --help + $PROGNAME --version +"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2000 Ernst-Dieter Martin/Karl DeBisschop + +Check available flexlm license managers + +"; + print_usage(); + print " +-F, --filename=FILE + Name of license file +-v, --verbose + Print some extra debugging information (not advised for normal operation) +-V, --version + Show version and license information +-h, --help + Show this help screen + +"; + support(); +} diff --git a/plugins-scripts/check_ircd.pl b/plugins-scripts/check_ircd.pl new file mode 100755 index 00000000..e4c4bd02 --- /dev/null +++ b/plugins-scripts/check_ircd.pl @@ -0,0 +1,257 @@ +#!/usr/bin/perl -wT + +# ----------------------------------------------------------------------------- +# File Name: check_ircd.pl +# +# Author: Richard Mayhew - South Africa +# +# Date: 1999/09/20 +# +# $Id$ +# +# Description: This script will check to see if an IRCD is running +# about how many users it has +# +# Email: netsaint@splash.co.za +# +# ----------------------------------------------------------------------------- +# Copyright 1999 (c) Richard Mayhew +# +# Credits go to Ethan Galstad for coding Nagios +# +# If any changes are made to this script, please mail me a copy of the +# changes :) +# +# Some code taken from Charlie Cook (check_disk.pl) +# +# License GPL +# +# ----------------------------------------------------------------------------- +# Date Author Reason +# ---- ------ ------ +# +# 1999/09/20 RM Creation +# +# 1999/09/20 TP Changed script to use strict, more secure by +# specifying $ENV variables. The bind command is +# still insecure through. Did most of my work +# with perl -wT and 'use strict' +# +# test using check_ircd.pl (irc-2.mit.edu|irc.erols.com|irc.core.com) +# +# ------------------------------------------------------------------[ Begin ]-- + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +# ----------------------------------------------------------------[ Require ]-- + +require 5.004; + +# -------------------------------------------------------------------[ Uses ]-- + +use Socket; +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_t $opt_p $opt_H $opt_w $opt_c $verbose); +use vars qw($PROGNAME); +use lib $main::runtimedir; +use utils qw($TIMEOUT %ERRORS &print_revision &support &usage); + +# ----------------------------------------------------[ Function Prototypes ]-- + +sub print_help (); +sub print_usage (); +sub connection ($$$$); +sub bindRemote ($$$); + +# -------------------------------------------------------------[ Enviroment ]-- + +$ENV{PATH} = ""; +$ENV{ENV} = ""; +$ENV{BASH_ENV} = ""; + +# -----------------------------------------------------------------[ Global ]-- + +my $NICK="ircd$$"; +my $USER_INFO="monitor localhost localhost : "; + +# -------------------------------------------------------------[ connection ]-- +sub connection ($$$$) +{ + my ($in_remotehost,$in_users,$in_warn,$in_crit) = @_; + my $state; + my $answer; + + print "connection(debug): users = $in_users\n" if $verbose; + $in_users =~ s/\ //g; + + if ($in_users >= 0) { + + if ($in_users > $in_crit) { + $state = "CRITICAL"; + $answer = "Critical Number Of Clients Connected : $in_users (Limit = $in_crit)\n"; + + } elsif ($in_users > $in_warn) { + $state = "WARNING"; + $answer = "Warning Number Of Clients Connected : $in_users (Limit = $in_warn)\n"; + + } else { + $state = "OK"; + $answer = "IRCD ok - Current Local Users: $in_users\n"; + } + + } else { + $state = "UNKNOWN"; + $answer = "Server $in_remotehost has less than 0 users! Something is Really WRONG!\n"; + } + + print ClientSocket "quit\n"; + print $answer; + exit $ERRORS{$state}; +} + +# ------------------------------------------------------------[ print_usage ]-- + +sub print_usage () { + print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>] [-p <port>]\n"; +} + +# -------------------------------------------------------------[ print_help ]-- + +sub print_help () +{ + print_revision($PROGNAME,'$Revision$ '); + print "Copyright (c) 2000 Richard Mayhew/Karl DeBisschop + +Perl Check IRCD plugin for Nagios + +"; + print_usage(); + print " +-H, --hostname=HOST + Name or IP address of host to check +-w, --warning=INTEGER + Number of connected users which generates a warning state (Default: 50) +-c, --critical=INTEGER + Number of connected users which generates a critical state (Default: 100) +-p, --port=INTEGER + Port that the ircd daemon is running on <host> (Default: 6667) +-v, --verbose + Print extra debugging information +"; +} + +# -------------------------------------------------------------[ bindRemote ]-- + +sub bindRemote ($$$) +{ + my ($in_remotehost, $in_remoteport, $in_hostname) = @_; + my $proto = getprotobyname('tcp'); + my $sockaddr; + my $this; + my $thisaddr = gethostbyname($in_hostname); + my $that; + my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost); +# ($name,$aliases,$type,$len,$thisaddr) = gethostbyname($in_hostname); + + if (!socket(ClientSocket,AF_INET, SOCK_STREAM, $proto)) { + print "IRCD UNKNOWN: Could not start socket ($!)\n"; + exit $ERRORS{"UNKNOWN"}; + } + $sockaddr = 'S n a4 x8'; + $this = pack($sockaddr, AF_INET, 0, $thisaddr); + $that = pack($sockaddr, AF_INET, $in_remoteport, $thataddr); + if (!bind(ClientSocket, $this)) { + print "IRCD UNKNOWN: Could not bind socket ($!)\n"; + exit $ERRORS{"UNKNOWN"}; + } + if (!connect(ClientSocket, $that)) { + print "IRCD UNKNOWN: Could not connect socket ($!)\n"; + exit $ERRORS{"UNKNOWN"}; + } + select(ClientSocket); $| = 1; select(STDOUT); + return \*ClientSocket; +} + +# ===================================================================[ MAIN ]== + +MAIN: +{ + my $hostname; + + Getopt::Long::Configure('bundling'); + GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "v" => \$verbose,"verbose" => \$verbose, + "t=i" => \$opt_t, "timeout=i" => \$opt_t, + "w=i" => \$opt_w, "warning=i" => \$opt_w, + "c=i" => \$opt_c, "critical=i" => \$opt_c, + "p=i" => \$opt_p, "port=i" => \$opt_p, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + + if ($opt_V) { + print_revision($PROGNAME,'$Revision$ '); + exit $ERRORS{'OK'}; + } + + if ($opt_h) {print_help(); exit $ERRORS{'OK'};} + + ($opt_H) || ($opt_H = shift) || usage("Host name/address not specified\n"); + my $remotehost = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); + ($remotehost) || usage("Invalid host: $opt_H\n"); + + ($opt_w) || ($opt_w = shift) || ($opt_w = 50); + my $warn = $1 if ($opt_w =~ /^([0-9]+)$/); + ($warn) || usage("Invalid warning threshold: $opt_w\n"); + + ($opt_c) || ($opt_c = shift) || ($opt_c = 100); + my $crit = $1 if ($opt_c =~ /^([0-9]+)$/); + ($crit) || usage("Invalid critical threshold: $opt_c\n"); + + ($opt_p) || ($opt_p = shift) || ($opt_p = 6667); + my $remoteport = $1 if ($opt_p =~ /^([0-9]+)$/); + ($remoteport) || usage("Invalid port: $opt_p\n"); + + if ($opt_t && $opt_t =~ /^([0-9]+)$/) { $TIMEOUT = $1; } + + # Just in case of problems, let's not hang Nagios + $SIG{'ALRM'} = sub { + print "Somthing is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $TIMEOUT Seconds)\n"; + exit $ERRORS{"UNKNOWN"}; + }; + + alarm($TIMEOUT); + + chomp($hostname = `/bin/hostname`); + $hostname = $1 if ($hostname =~ /([-.a-zA-Z0-9]+)/); + my ($name, $alias, $proto) = getprotobyname('tcp'); + print "MAIN(debug): hostname = $hostname\n" if $verbose; + + print "MAIN(debug): binding to remote host: $remotehost -> $remoteport -> $hostname\n" if $verbose; + my $ClientSocket = &bindRemote($remotehost,$remoteport,$hostname); + + print ClientSocket "NICK $NICK\nUSER $USER_INFO\n"; + + while (<ClientSocket>) { + print "MAIN(debug): default var = $_\n" if $verbose; + + # DALnet,LagNet,UnderNet etc. Require this! + # Replies with a PONG when presented with a PING query. + # If a server doesn't require it, it will be ignored. + + if (m/^PING (.*)/) {print ClientSocket "PONG $1\n";} + + alarm(0); + + # Look for pattern in IRCD Output to gather Client Connections total. + connection($remotehost,$1,$warn,$crit) if (m/:I have\s+(\d+)/); + } + print "IRCD UNKNOWN: Unknown error - maybe could not authenticate\n"; + exit $ERRORS{"UNKNOWN"}; +} diff --git a/plugins-scripts/check_log.sh b/plugins-scripts/check_log.sh new file mode 100755 index 00000000..08e7fef6 --- /dev/null +++ b/plugins-scripts/check_log.sh @@ -0,0 +1,214 @@ +#! /bin/sh +# +# Log file pattern detector plugin for Nagios +# Written by Ethan Galstad (nagios@nagios.org) +# Last Modified: 07-31-1999 +# +# Usage: ./check_log <log_file> <old_log_file> <pattern> +# +# Description: +# +# This plugin will scan a log file (specified by the <log_file> option) +# for a specific pattern (specified by the <pattern> option). Successive +# calls to the plugin script will only report *new* pattern matches in the +# log file, since an copy of the log file from the previous run is saved +# to <old_log_file>. +# +# Output: +# +# On the first run of the plugin, it will return an OK state with a message +# of "Log check data initialized". On successive runs, it will return an OK +# state if *no* pattern matches have been found in the *difference* between the +# log file and the older copy of the log file. If the plugin detects any +# pattern matches in the log diff, it will return a CRITICAL state and print +# out a message is the following format: "(x) last_match", where "x" is the +# total number of pattern matches found in the file and "last_match" is the +# last entry in the log file which matches the pattern. +# +# Notes: +# +# If you use this plugin make sure to keep the following in mind: +# +# 1. The "max_attempts" value for the service should be 1, as this +# will prevent Nagios from retrying the service check (the +# next time the check is run it will not produce the same results). +# +# 2. The "notify_recovery" value for the service should be 0, so that +# Nagios does not notify you of "recoveries" for the check. Since +# pattern matches in the log file will only be reported once and not +# the next time, there will always be "recoveries" for the service, even +# though recoveries really don't apply to this type of check. +# +# 3. You *must* supply a different <old_file_log> for each service that +# you define to use this plugin script - even if the different services +# check the same <log_file> for pattern matches. This is necessary +# because of the way the script operates. +# +# Examples: +# +# Check for login failures in the syslog... +# +# check_log /var/log/messages ./check_log.badlogins.old "LOGIN FAILURE" +# +# Check for port scan alerts generated by Psionic's PortSentry software... +# +# check_log /var/log/message ./check_log.portscan.old "attackalert" +# + +# Paths to commands used in this script. These +# may have to be modified to match your system setup. + +PATH="" + +ECHO="/bin/echo" +GREP="/bin/grep" +DIFF="/bin/diff" +TAIL="/bin/tail" +CAT="/bin/cat" +RM="/bin/rm" + +PROGNAME=`/bin/basename $0` +PROGPATH=`echo $0 | /bin/sed -e 's,[\\/][^\\/][^\\/]*$,,'` +REVISION=`echo '$Revision$' | /bin/sed -e 's/[^0-9.]//g'` + +. $PROGPATH/utils.sh + +print_usage() { + echo "Usage: $PROGNAME -F logfile -O oldlog -q query" + echo "Usage: $PROGNAME --help" + echo "Usage: $PROGNAME --version" +} + +print_help() { + print_revision $PROGNAME $REVISION + echo "" + print_usage + echo "" + echo "Log file pattern detector plugin for Nagios" + echo "" + support +} + +# Make sure the correct number of command line +# arguments have been supplied + +if [ $# -lt 1 ]; then + print_usage + exit $STATE_UNKNOWN +fi + +# Grab the command line arguments + +#logfile=$1 +#oldlog=$2 +#query=$3 +exitstatus=$STATE_WARNING #default +while test -n "$1"; do + case "$1" in + --help) + print_help + exit $STATE_OK + ;; + -h) + print_help + exit $STATE_OK + ;; + --version) + print_revision $PROGNAME $VERSION + exit $STATE_OK + ;; + -V) + print_revision $PROGNAME $VERSION + exit $STATE_OK + ;; + --filename) + logfile=$2 + shift + ;; + -F) + logfile=$2 + shift + ;; + --oldlog) + oldlog=$2 + shift + ;; + -O) + oldlog=$2 + shift + ;; + --query) + query=$2 + shift + ;; + -q) + query=$2 + shift + ;; + -x) + exitstatus=$2 + shift + ;; + --exitstatus) + exitstatus=$2 + shift + ;; + *) + echo "Unknown argument: $1" + print_usage + exit $STATE_UNKNOWN + ;; + esac + shift +done + +# If the source log file doesn't exist, exit + +if [ ! -e $logfile ]; then + $ECHO "Log check error: Log file $logfile does not exist!\n" + exit 2 +fi + +# If the old log file doesn't exist, this must be the first time +# we're running this test, so copy the original log file over to +# the old diff file and exit + +if [ ! -e $oldlog ]; then + $CAT $logfile > $oldlog + $ECHO "Log check data initialized...\n" + exit 0 +fi + +# The old log file exists, so compare it to the original log now + +# The temporary file that the script should use while +# processing the log file. +if [-x /bin/mktemp]; then + tempdiff="/bin/mktemp /tmp/check_log.XXXXXXXXXX" +else + tempdiff="/tmp/check_log.`/bin/date '+%H%M%S'`" + /bin/touch $tempdiff + chmod 600 $tempdiff +fi + +$DIFF $logfile $oldlog > $tempdiff + +# Count the number of matching log entries we have +count=`$GREP -c "$query" $tempdiff` + +# Get the last matching entry in the diff file +lastentry=`$GREP "$query" $tempdiff | $TAIL --lines=1` + +$RM -f $tempdiff +$CAT $logfile > $oldlog + +if [ "$count" = "0" ]; then # no matches, exit with no error + $ECHO "Log check ok - 0 pattern matches found\n" + exitstatus=0 +else # Print total matche count and the last entry we found + $ECHO "($count) $lastentry" +fi + +exit exitstatus + + diff --git a/plugins-scripts/check_netdns.pl b/plugins-scripts/check_netdns.pl new file mode 100755 index 00000000..4bf7bd76 --- /dev/null +++ b/plugins-scripts/check_netdns.pl @@ -0,0 +1,129 @@ +#!/usr/bin/perl -w + +# Perl version of check_dns plugin which calls DNS directly instead of +# relying on nslookup (which has bugs) +# +# Copyright 2000, virCIO, LLP +# +# $Log$ +# Revision 1.1 2002/02/28 06:43:00 egalstad +# Initial revision +# +# Revision 1.1 2000/08/03 20:41:12 karldebisschop +# rename to avoid conflict when installing +# +# Revision 1.1 2000/08/03 19:27:08 karldebisschop +# use Net::DNS to check name server +# +# Revision 1.1 2000/07/20 19:09:13 cwg +# All the pieces needed to use my version of check_dns. +# + +use Getopt::Long; +use Net::DNS; + + Getopt::Long::Configure(`bundling`); +GetOptions("V" => $opt_V, "version" => $opt_V, + "h" => $opt_h, "help" => $opt_h, + "t=i" => $opt_t, "timeout=i" => $opt_t, + "s=s" => $opt_s, "server=s" => $opt_s, + "H=s" => $opt_H, "hostname=s" => $opt_H); + +# -h means display verbose help screen +if($opt_h){ print_help(); exit 0; } + +# -V means display version number +if ($opt_V) { print_version(); exit 0; } + +# -H means host name +$opt_H = shift unless ($opt_H); +unless ($opt_H) { print_usage(); exit -1; } +if ($opt_H && + $opt_H =~ m/^([0-9]+.[0-9]+.[0-9]+.[0-9]+|[a-zA-Z][-a-zA-Z0]+(.[a-zA-Z][-a-zA-Z0]+)*)$/) +{ + $host = $1; +} else { + print "$opt_H is not a valid host name"; + exit -1; +} + +# -s means server name +$opt_s = shift unless ($opt_s); +if ($opt_s) { + if ($opt_s =~ m/^([0-9]+.[0-9]+.[0-9]+.[0-9]+|[a-zA-Z][-a-zA-Z0]+(.[a-zA-Z][-a-zA-Z0]+)*)$/) + { + $server = $1; + } else { + print "$opt_s is not a valid host name"; + exit -1; + } +} + +# -t means timeout +my $timeout = 10 unless ($opt_t); + +my $res = new Net::DNS::Resolver; +#$res->debug(1); +if ($server) { + $res->nameservers($server); +} + +$res->tcp_timeout($timeout); +$SIG{ALRM} = &catch_alarm; +alarm($timeout); + +$query = $res->query($host); +if ($query) { + my @answer = $query->answer; + if (@answer) { + print join(`/`, map { + $_->type . ` ` . $_->rdatastr; + } @answer); + exit 0; + } else { + print "empty answer"; + exit 2; + } +} +else { + print "query failed: ", $res->errorstring, ""; + exit 2; +} + +sub catch_alarm { + print "query timed out"; + exit 2; +} + +sub print_version () { + my $arg0 = $0; + chomp $arg0; + print "$arg0 version 0.1"; +} +sub print_help() { + print_version(); + print ""; + print "Check if a nameserver can resolve a given hostname."; + print ""; + print_usage(); + print ""; + print "-H, --hostname=HOST"; + print " The name or address you want to query"; + print "-s, --server=HOST"; + print " Optional DNS server you want to use for the lookup"; + print "-t, --timeout=INTEGER"; + print " Seconds before connection times out (default: 10)"; + print "-h, --help"; + print " Print detailed help"; + print "-V, --version"; + print " Print version numbers and license information"; +} + +sub print_usage () { + my $arg0 = $0; + chomp $arg0; + print "$arg0 check_dns -H host [-s server] [-t timeout]"; + print "$arg0 [-h | --help]"; + print "$arg0 [-V | --version]"; +} + diff --git a/plugins-scripts/check_nfs.pl b/plugins-scripts/check_nfs.pl new file mode 100755 index 00000000..040466d3 --- /dev/null +++ b/plugins-scripts/check_nfs.pl @@ -0,0 +1,48 @@ +#!/usr/local/bin/perl +# +# check_nfs plugin for nagios +# +# usage: +# check_nfs.pl server +# +# Check if a nfs server is registered and running +# using rpcinfo -T udp <arg1> 100003. +# 100003 is the rpc programmnumber for nfs. +# <arg1> is the server queried. +# +# +# Use these hosts.cfg entries as examples +# +#service[fs0]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_nfs +#command[check_nfs]=/some/path/libexec/check_nfs.pl $HOSTADDRESS$ +# +# initial version: 9-13-99 Ernst-Dieter Martin edmt@infineon.com +# current status: looks like working +# +# +# Copyright Notice: Do as you please, credit me, but don't blame me +# + + +$server = shift; + + +open CMD,"/bin/rpcinfo -T udp $server 100003 |"; + +$response = "nfs version "; + +while ( <CMD> ) { + if ( /program 100003 version ([0-9]*) ready and waiting/ ) { + $response = $ response . "$1,"; + } +} + +if ( $response eq "nfs version " ) { + print "rpcinfo: RPC: Program not registered\n"; + exit 2; +} + +$response =~ s/,$//; +print "$response\n"; + +exit 0; diff --git a/plugins-scripts/check_ntp.pl b/plugins-scripts/check_ntp.pl new file mode 100755 index 00000000..f3f6f78b --- /dev/null +++ b/plugins-scripts/check_ntp.pl @@ -0,0 +1,236 @@ +#! /usr/bin/perl -wT + +# (c)1999 Ian Cass, Knowledge Matters Ltd. +# Read the GNU copyright stuff for all the legalese +# +# Check NTP time servers plugin. This plugin requires the ntpdate utility to +# be installed on the system, however since it's part of the ntp suite, you +# should already have it installed. +# +# Nothing clever done in this program - its a very simple bare basics hack to +# get the job done. +# +# Things to do... +# check @words[9] for time differences greater than +/- x secs & return a +# warning. +# +# (c) 1999 Mark Jewiss, Knowledge Matters Limited +# 22-9-1999, 12:45 +# +# Modified script to accept 2 parameters or set defaults. +# Now issues warning or critical alert is time difference is greater than the +# time passed. +# +# These changes have not been tested completely due to the unavailability of a +# server with the incorrect time. +# +# (c) 1999 Bo Kersey, VirCIO - Managed Server Solutions <bo@vircio.com> +# 22-10-99, 12:17 +# +# Modified the script to give useage if no parameters are input. +# +# Modified the script to check for negative as well as positive +# time differences. +# +# Modified the script to work with ntpdate 3-5.93e Wed Apr 14 20:23:03 EDT 1999 +# +# Modified the script to work with ntpdate's that return adjust or offset... +# +# +# Script modified 2000 June 01 by William Pietri <william@bianca.com> +# +# Modified script to handle weird cases: +# o NTP server doesn't respond (e.g., has died) +# o Server has correct time but isn't suitable synchronization +# source. This happens while starting up and if contact +# with master has been lost. +# +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +require 5.004; +use POSIX; +use strict; +use Getopt::Long; +use vars qw($opt_V $opt_h $opt_H $opt_w $opt_c $verbose $PROGNAME); +use lib $main::runtimedir; +use utils qw($TIMEOUT %ERRORS &print_revision &support); + +sub print_help (); +sub print_usage (); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "v" => \$verbose, "verbose" => \$verbose, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$ '); + exit $ERRORS{'OK'}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{'OK'}; +} + +$opt_H = shift unless ($opt_H); +my $host = $1 if ($opt_H && $opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0-9]+(\.[a-zA-Z][-a-zA-Z0-9]+)*)$/); +unless ($host) { + print_usage(); + exit $ERRORS{'UNKNOWN'}; +} + +($opt_w) || ($opt_w = shift) || ($opt_w = 60); +my $warning = $1 if ($opt_w =~ /([0-9]+)/); + +($opt_c) || ($opt_c = shift) || ($opt_c = 120); +my $critical = $1 if ($opt_c =~ /([0-9]+)/); + +my $answer = undef; +my $offset = undef; +my $msg; # first line of output to print if format is invalid + +my $state = $ERRORS{'UNKNOWN'}; +my $ntpdate_error = $ERRORS{'UNKNOWN'}; +my $dispersion_error = $ERRORS{'UNKNOWN'}; + +my $key = undef; + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("ERROR: No response from ntp server (alarm)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + + +### +### +### First, check ntpdate +### +### + +if (!open (NTPDATE, "/usr/local/sbin/ntpdate -q $host 2>&1 |")) { + print "Could not open ntpdate\n"; + exit $ERRORS{"UNKNOWN"}; +} + +while (<NTPDATE>) { + print if ($verbose); + $msg = $_ unless ($msg); + if (/(offset|adjust)\s+([-.\d]+)/i) { + $offset = $2; + last; + } +} + +# soak up remaining output; check for error +while (<NTPDATE>) { + if (/no server suitable for synchronization found/) { + $ntpdate_error = $ERRORS{"CRITICAL"}; + } +} + +close(NTPDATE); + +# only declare an error if we also get a non-zero return code from ntpdate +$ntpdate_error = ($? >> 8) || $ntpdate_error; + +### +### +### Then scan xntpdc if it exists +### +### + +if (#open(NTPDC,"/usr/sbin/ntpdc -c $host 2>&1 |") || + open(NTPDC,"/usr/sbin/xntpdc -c $host 2>&1 |") ) { + while (<NTPDC>) { + print if ($verbose); + if (/([^\s]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)/) { + if ($8>15) { + $dispersion_error = $ERRORS{'CRITICAL'}; + } elsif ($8>5 && $dispersion_error<$ERRORS{'CRITICAL'}) { + $dispersion_error = $ERRORS{'WARNING'}; + } + } + } + close NTPDC; +} + +# An offset of 0.000000 with an error is probably bogus. Actually, +# it's probably always bogus, but let's be paranoid here. +if ($ntpdate_error && $offset && ($offset == 0)) { undef $offset;} + +if ($ntpdate_error > $ERRORS{'OK'}) { + $state = $ntpdate_error; + $answer = "Server for ntp probably down\n"; + if (defined($offset) && abs($offset) > $critical) { + $state = $ERRORS{'CRITICAL'}; + $answer = "Server Error and time difference $offset seconds greater than +/- $critical sec\n"; + } elsif (defined($offset) && abs($offset) > $warning) { + $answer = "Server error and time difference $offset seconds greater than +/- $warning sec\n"; + } + +} elsif ($dispersion_error > $ERRORS{'OK'}) { + $state = $dispersion_error; + $answer = "Dispersion too high\n"; + if (defined($offset) && abs($offset) > $critical) { + $state = $ERRORS{'CRITICAL'}; + $answer = "Dispersion error and time difference $offset seconds greater than +/- $critical sec\n"; + } elsif (defined($offset) && abs($offset) > $warning) { + $answer = "Dispersion error and time difference $offset seconds greater than +/- $warning sec\n"; + } + +} else { # no errors from ntpdate or xntpdc + if (defined $offset) { + if (abs($offset) > $critical) { + $state = $ERRORS{'CRITICAL'}; + $answer = "Time difference $offset seconds greater than +/- $critical sec\n"; + } elsif (abs($offset) > $warning) { + $state = $ERRORS{'WARNING'}; + $answer = "Time difference $offset seconds greater than +/- $warning sec\n"; + } elsif (abs($offset) <= $warning) { + $state = $ERRORS{'OK'}; + $answer = "Time difference $offset seconds\n"; + } + } else { # no offset defined + $state = $ERRORS{'UNKNOWN'}; + $answer = "Invalid format returned from ntpdate ($msg)\n"; + } +} + +foreach $key (keys %ERRORS) { + if ($state==$ERRORS{$key}) { + print ("$key: $answer"); + last; + } +} +exit $state; + +sub print_usage () { + print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>]\n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2000 Bo Kersey/Karl DeBisschop\n"; + print "\n"; + print_usage(); + print "\n"; + print "<warn> = Clock offset in seconds at which a warning message will be generated.\n Defaults to 60.\n"; + print "<crit> = Clock offset in seconds at which a critical message will be generated.\n Defaults to 120.\n\n"; + support(); +} diff --git a/plugins-scripts/check_oracle.sh b/plugins-scripts/check_oracle.sh new file mode 100755 index 00000000..1a4d8ab6 --- /dev/null +++ b/plugins-scripts/check_oracle.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# latigid010@yahoo.com +# 01/06/2000 +# +# This Nagios plugin was created to check remote or local TNS +# status and check local Database status. +# +# Add the following lines to your object config file (i.e. commands.cfg) +# command[check-tns]=/usr/local/nagios/libexec/check_ora 1 $ARG$ +# command[check-oradb]=/usr/local/nagios/libexec/check_ora 2 $ARG$ +# +# +# Usage: +# To check TNS Status: ./check_ora 1 <Oracle Sid or Hostname/IP address> +# To Check local database: ./check_ora 2 <ORACLE_SID> +# +# I have the script checking for the Oracle PMON process and +# the sgadefORACLE_SID.dbf file. +# +# +# If you have any problems check that you have the $ORACLE_HOME +# enviroment variable set, have $ORACLE_HOME/bin in your PATH, and +# dont forget about your tnsnames.ora file. when checking Local +# Database status your ORACLE_SID is case sensitive. +# + +PROGNAME=`basename $0` +PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'` +REVISION=`echo '$Revision$' | sed -e 's/[^0-9.]//g'` + +. $PROGPATH/utils.sh + + +print_usage() { + echo "Usage:" + echo " $PROGNAME --tns <Oracle Sid or Hostname/IP address>" + echo " $PROGNAME --db <ORACLE_SID>" + echo " $PROGNAME --help" + echo " $PROGNAME --version" +} + +print_help() { + print_revision $PROGNAME $REVISION + echo "" + print_usage + echo "" + echo "Check remote or local TNS status and check local Database status" + echo "" + echo "--tns=SID/IP Address" + echo " Check remote TNS server" + echo "--db=SID" + echo " Check local database (search /bin/ps for PMON process and check" + echo " filesystem for sgadefORACLE_SID.dbf" + echo "--help" + echo " Print this help screen" + echo "--version" + echo " Print version and license information" + echo "" + echo "If the plugin doesn't work, check that the $ORACLE_HOME environment" + echo "variable is set, that $ORACLE_HOME/bin is in your PATH, and the" + echo "tnsnames.ora file is locatable and is properly configured." + echo "" + echo "When checking Local Database status your ORACLE_SID is case sensitive." + echo "" + support +} + +case "$1" in +1) + cmd='--tns' + ;; +2) + cmd='--db' + ;; +*) + cmd="$1" + ;; +esac + +case "$cmd" in +--tns) + export tnschk=` tnsping $2` + export tnschk2=` echo $tnschk | grep -c OK` + export tnschk3=` echo $tnschk | cut -d\( -f7 | sed y/\)/" "/` + if [ ${tnschk2} -eq 1 ] ; then + echo "OK - reply time ${tnschk3} from $2" + exit 0 + else + echo "No TNS Listener on $2" + exit $STATE_CRITICAL + fi + ;; +--db) + export pmonchk=`ps -ef | grep -v grep | grep ${2} | grep -c pmon` + if [ -e $ORACLE_HOME/dbs/sga*${2}* ] ; then + if [ ${pmonchk} -eq 1 ] ; then + export utime=`ls -la $ORACLE_HOME/dbs/sga*$2* | cut -c 43-55` + echo "${2} OK - running since ${utime}" + exit $STATE_OK + fi + else + echo "${2} Database is DOWN" + exit $STATE_CRITICAL + fi + ;; +--help) + print_help + exit $STATE_OK + ;; +-h) + print_help + exit $STATE_OK + ;; +--version) + print_revision $PLUGIN $REVISION + exit $STATE_OK + ;; +-V) + print_revision $PLUGIN $REVISION + exit $STATE_OK + ;; +*) + print_usage + exit $STATE_UNKNOWN +esac diff --git a/plugins-scripts/check_rpc.pl b/plugins-scripts/check_rpc.pl new file mode 100755 index 00000000..51901ac0 --- /dev/null +++ b/plugins-scripts/check_rpc.pl @@ -0,0 +1,274 @@ +#! /usr/bin/perl -wT +# +# check_rpc plugin for nagios +# +# usage: +# check_rpc host service +# +# Check if an rpc serice is registered and running +# using rpcinfo - $proto $host $prognum 2>&1 |"; +# +# Use these hosts.cfg entries as examples +# +# command[check_nfs]=/some/path/libexec/check_rpc $HOSTADDRESS$ nfs +# service[check_nfs]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_rpc +# +# initial version: 3 May 2000 by Truongchinh Nguyen and Karl DeBisschop +# current status: $Revision$ +# +# Copyright Notice: GPL +# +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +use strict; +use lib $main::runtimedir; +use utils qw($TIMEOUT %ERRORS &print_revision &support); +use vars qw($PROGNAME); +my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd); +my ($array_ref,$test,$element,@progkeys,$proto,$a,$b); +my ($opt_V,$opt_h,$opt_C,$opt_p,$opt_H); +$opt_V = $opt_h = $opt_C = $opt_p = $opt_H = ''; + +sub print_help (); +sub print_usage (); +sub in ($$); + +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; +$ENV{'PATH'}=''; + +#Initialise protocol for each progname number +# 'u' for UDP, 't' for TCP +$proto[10003]='u'; +$proto[10004]='u'; +$proto[10007]='u'; + +use Getopt::Long; +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "C=s" => \$opt_C, "command=s" => \$opt_C, + "p=i" => \$opt_p, "port=i" => \$opt_p, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +# -h means display verbose help screen +if ($opt_h) { print_help(); exit 0; } + +# -V means display version number +if ($opt_V) { print_revision($PROGNAME,'$Revision$ '); exit 0; } + +# -H means host name +$opt_H = shift unless ($opt_H); +unless ($opt_H) { print_usage(); exit -1; } +if($opt_H && $opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0-9]+(\.[a-zA-Z][-a-zA-Z0-9]+)*)$/) { + $host = $1; +} else { + print "$opt_H is not a valid host name\n"; + exit -1; +} + +while (<DATA>) { + ($a,$b) = split; + $prognum{$a} = $b; +} +close DATA; + +# -C means command name or number +$opt_C = shift unless ($opt_C); +unless ($opt_C) { print_usage(); exit -1; } +@progkeys = keys %prognum; +if ($opt_C =~ m/^([0-9]+)$/){ + $response = "RPC ok: program $opt_p (version "; + $prognum = $1; +} elsif ( in( \@progkeys, $opt_C)) { + $response = "RPC ok: $opt_C (version "; + $prognum = $prognum{$opt_C}; +} else { + print "Program $opt_C is not defined\n"; + exit -1; +} + +# -p means port number +if($opt_p =~ /^([0-9]+)$/){ + $port = "-n $1"; +} else { + $port = ""; +} + +$proto = 'u'; +$proto = $proto[$prognum] if ($proto[$prognum]); +$cmd = "/usr/sbin/rpcinfo $port -" . "$proto $host $prognum 2>&1 |"; +print "$cmd\n" if ($verbose); +open CMD, $cmd; + +while ( <CMD> ) { + chomp; + if ( /program $prognum version ([0-9]*) ready and waiting/ ) { + $response .= "$1) is running"; + print "$response\n"; + exit 0; + } +} + +print "RPC CRITICAL: Program $opt_C not registered\n"; +exit 2; + + + +sub print_help() { + print_revision($PROGNAME,'$Revision$ '); + print "Copyright (c) 2000 Karl DeBisschop/Truongchinh Nguyen\n"; + print "\n"; + print "Check if a rpc service is registered and running using\n"; + print " rpcinfo -<protocol> <host> <program number>\n"; + print "\n"; + print_usage(); + print "\n"; + print "<host> The server providing the rpc service\n"; + print "<program> The program name (or number).\n\n"; + support(); +} + +sub print_usage () { + print "$PROGNAME -H host -C rpc_command [-p port]\n"; + print "$PROGNAME [-h | --help]\n"; + print "$PROGNAME [-V | --version]\n"; +} + +sub in ($$) { + $array_ref = shift; + $test = shift; + + while ( $element = shift @{$array_ref} ) { + if ($test eq $element) { + return 1; + } + } + return 0; +} + +__DATA__ +portmapper 100000 +portmap 100000 +sunrpc 100000 +rpcbind 100000 +rstatd 100001 +rstat 100001 +rup 100001 +perfmeter 100001 +rstat_svc 100001 +rusersd 100002 +rusers 100002 +nfs 100003 +nfsprog 100003 +ypserv 100004 +ypprog 100004 +mountd 100005 +mount 100005 +showmount 100005 +ypbind 100007 +walld 100008 +rwall 100008 +shutdown 100008 +yppasswdd 100009 +yppasswd 100009 +etherstatd 100010 +etherstat 100010 +rquotad 100011 +rquotaprog 100011 +quota 100011 +rquota 100011 +sprayd 100012 +spray 100012 +3270_mapper 100013 +rje_mapper 100014 +selection_svc 100015 +selnsvc 100015 +database_svc 100016 +rexd 100017 +rex 100017 +alis 100018 +sched 100019 +llockmgr 100020 +nlockmgr 100021 +x25_inr 100022 +statmon 100023 +status 100024 +bootparam 100026 +ypupdated 100028 +ypupdate 100028 +keyserv 100029 +keyserver 100029 +sunlink_mapper 100033 +tfsd 100037 +nsed 100038 +nsemntd 100039 +showfhd 100043 +showfh 100043 +ioadmd 100055 +rpc.ioadmd 100055 +NETlicense 100062 +sunisamd 100065 +debug_svc 100066 +dbsrv 100066 +ypxfrd 100069 +rpc.ypxfrd 100069 +bugtraqd 100071 +kerbd 100078 +event 100101 +na.event 100101 +logger 100102 +na.logger 100102 +sync 100104 +na.sync 100104 +hostperf 100107 +na.hostperf 100107 +activity 100109 +na.activity 100109 +hostmem 100112 +na.hostmem 100112 +sample 100113 +na.sample 100113 +x25 100114 +na.x25 100114 +ping 100115 +na.ping 100115 +rpcnfs 100116 +na.rpcnfs 100116 +hostif 100117 +na.hostif 100117 +etherif 100118 +na.etherif 100118 +iproutes 100120 +na.iproutes 100120 +layers 100121 +na.layers 100121 +snmp 100122 +na.snmp 100122 +snmp-cmc 100122 +snmp-synoptics 100122 +snmp-unisys 100122 +snmp-utk 100122 +traffic 100123 +na.traffic 100123 +nfs_acl 100227 +sadmind 100232 +nisd 100300 +rpc.nisd 100300 +nispasswd 100303 +rpc.nispasswdd 100303 +ufsd 100233 +ufsd 100233 +pcnfsd 150001 +pcnfs 150001 +amd 300019 +amq 300019 +bwnfsd 545580417 +fypxfrd 600100069 +freebsd-ypxfrd 600100069 diff --git a/plugins-scripts/check_sensors.sh b/plugins-scripts/check_sensors.sh new file mode 100755 index 00000000..011aa709 --- /dev/null +++ b/plugins-scripts/check_sensors.sh @@ -0,0 +1,65 @@ +#! /bin/sh + +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin + +PROGNAME=`basename $0` +PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'` +REVISION=`echo '$Revision$' | sed -e 's/[^0-9.]//g'` + +. $PROGPATH/utils.sh + + +print_usage() { + echo "Usage: $PROGNAME" +} + +print_help() { + print_revision $PROGNAME $REVISION + echo "" + print_usage + echo "" + echo "This plugin checks hardware status using the lm_sensors package." + echo "" + support + exit 0 +} + +case "$1" in + --help) + print_help + exit 0 + ;; + -h) + print_help + exit 0 + ;; + --version) + print_revision $PROGNAME $REVISION + exit 0 + ;; + -V) + print_revision $PROGNAME $REVISION + exit 0 + ;; + *) + sensordata=`sensors 2>&1` + status=$? + if test "$1" = "-v" -o "$1" = "--verbose"; then + echo ${sensordata} + fi + if test ${status} -eq 127; then + echo "SENSORS UNKNOWN - command not found (did you install lmsensors?)" + exit -1 + elif test ${status} -ne 0 ; then + echo "WARNING - sensors returned state $status" + exit 1 + fi + if echo ${sensordata} | egrep ALARM > /dev/null; then + echo SENSOR CRITICAL - Sensor alarm detected! + exit 2 + else + echo sensor ok + exit 0 + fi + ;; +esac diff --git a/plugins-scripts/check_wave.pl b/plugins-scripts/check_wave.pl new file mode 100755 index 00000000..c6e6c662 --- /dev/null +++ b/plugins-scripts/check_wave.pl @@ -0,0 +1,129 @@ +#! /usr/bin/perl -wT +# +# $Id$ + + +BEGIN { + if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) { + $runtimedir = $1; + $PROGNAME = $2; + } +} + +use strict; +use lib $main::runtimedir; +use utils qw($TIMEOUT %ERRORS &print_revision &support); +use vars qw($PROGNAME); +use Getopt::Long; +use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H); +my (@test, $low1, $med1, $high1, $snr, $low2, $med2, $high2); +my ($low, $med, $high, $lowavg, $medavg, $highavg, $tot, $ss); + +sub print_help (); +sub print_usage (); + +$ENV{'PATH'}=''; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$opt_V, "version" => \$opt_V, + "h" => \$opt_h, "help" => \$opt_h, + "v" => \$verbose, "verbose" => \$verbose, + "w=s" => \$opt_w, "warning=s" => \$opt_w, + "c=s" => \$opt_c, "critical=s" => \$opt_c, + "H=s" => \$opt_H, "hostname=s" => \$opt_H); + +if ($opt_V) { + print_revision($PROGNAME,'$Revision$'); #' + exit $ERRORS{'OK'}; +} + +if ($opt_h) { + print_help(); + exit $ERRORS{'OK'}; +} + +$opt_H = shift unless ($opt_H); +print_usage() unless ($opt_H); +my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/); +print_usage() unless ($host); + +($opt_c) || ($opt_c = shift) || ($opt_c = 120); +my $critical = $1 if ($opt_c =~ /([0-9]+)/); + +($opt_w) || ($opt_w = shift) || ($opt_w = 60); +my $warning = $1 if ($opt_w =~ /([0-9]+)/); + +$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1`; +@test = split(/ /,$low1); +$low1 = $test[2]; + +$med1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.9.1`; +@test = split(/ /,$med1); +$med1 = $test[2]; + +$high1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.10.1`; +@test = split(/ /,$high1); +$high1 = $test[2]; + +sleep(2); + +$snr = `snmpget $host public .1.3.6.1.4.1.762.2.5.2.1.17.1`; +@test = split(/ /,$snr); +$snr = $test[2]; +$snr = int($snr*25); + +$low2 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1`; +@test = split(/ /,$low2); +$low2 = $test[2]; + +$med2 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.9.1`; +@test = split(/ /,$med2); +$med2 = $test[2]; + +$high2 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.10.1`; +@test = split(/ /,$high2); +$high2 = $test[2]; + +$low = $low2 - $low1; +$med = $med2 - $med1; +$high = $high2 - $high1; + +$tot = $low + $med + $high; + +if ($tot==0) { + $ss = 0; +} else { + $lowavg = $low / $tot; + $medavg = $med / $tot; + $highavg = $high / $tot; + $ss = ($medavg*50) + ($highavg*100); +} + +printf("Signal Strength at: %3.0f%, SNR at $snr%",$ss); + +if ($ss<$critical) { + exit(2); +} elsif ($ss<$warning) { + exit(1); +} else { + exit(0); +} + + +sub print_usage () { + print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>]\n"; +} + +sub print_help () { + print_revision($PROGNAME,'$Revision$'); + print "Copyright (c) 2000 Jeffery Blank/Karl DeBisschop\n"; + print "\n"; + print_usage(); + print "\n"; + print "<warn> = Signal strength at which a warning message will be generated.\n"; + print "<crit> = Signal strength at which a critical message will be generated.\n\n"; + support(); +} diff --git a/plugins-scripts/subst.in b/plugins-scripts/subst.in new file mode 100644 index 00000000..cc0fd1b6 --- /dev/null +++ b/plugins-scripts/subst.in @@ -0,0 +1,56 @@ +#!/usr/bin/awk + +function which(c,path) { + cmd = "test -x " c; + + if (system(cmd)==0) { + return c; + } + + sub(/\/.*\//,"",c); + for (dir in path) { + cmd = "test -x " path[dir] "/" c; + if (system(cmd)==0) { + return path[dir] "/" c; + } + } + + + return c; +} + +BEGIN { + split(ENVIRON["PATH"] ":/sbin:/usr/sbin",path,/:/); +} + +# scripting language (first line) + +/^#! ?\/.*\/python/ {sub(/^#! ?\/.*\/python/,"#! @PYTHON@");} +/^#! ?\/.*\/perl/ {sub(/^#! ?\/.*\/perl/,"#! @PERL@");} +/^#! ?\/.*\/[a-z]{0,2}awk/ {sub(/^#! ?\/.*\/[a-z]{0,2}awk/,"#! @AWK@");} +/^#! ?\/.*\/sh/ {sub(/^#! ?\/.*\/sh/,"#! @SHELL@");} + +# Trusted path mechanism (deprecated) + +/^[ \t]*\$ENV[ \t]*\{[ \t'"]*PATH[ \t"']*\}[ \t]*=/ { + sub(/\=[ \t]*['"][^"']+["']/,"='@trusted_path@' # autoconf-derived"); +} + +/^[\t ]*(export[\t ]*)?PATH[\t ]*=['"]+.+["']$/ { + sub(/\=.*$/,"='@trusted_path@' # autoconf-derived"); +} + +# Specific programs + +# +/^[^#]/ && /(\/.*)?\/(bin|sbin|lib|libexec)\// { + match($0,/(\/.*)?\/(bin|sbin|lib|libexec)\/[-_a-zA-Z0-9]+/); + start=RSTART+RLENGTH; + c=substr($0,RSTART,RLENGTH); + sub(c,which(c,path)); +} + +{ + print; +} + diff --git a/plugins-scripts/t/check_rpc.t b/plugins-scripts/t/check_rpc.t new file mode 100644 index 00000000..afcb867c --- /dev/null +++ b/plugins-scripts/t/check_rpc.t @@ -0,0 +1,19 @@ +use strict; +use Test; +use vars qw($tests); + +BEGIN {$tests = 2; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t=0; + +$cmd = "./check_rpc -V"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^check_rpc/'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins-scripts/utils.pm.in b/plugins-scripts/utils.pm.in new file mode 100644 index 00000000..361bfe99 --- /dev/null +++ b/plugins-scripts/utils.pm.in @@ -0,0 +1,38 @@ +package utils; + +require Exporter; +@ISA = qw(Exporter); +@EXPORT_OK = qw($TIMEOUT %ERRORS &print_revision &support &usage); + +#use strict; +#use vars($TIMEOUT %ERRORS); +sub print_revision ($$); +sub usage; +sub support(); + +$TIMEOUT = 15; +%ERRORS=('UNKNOWN'=>-1,'OK'=>0,'WARNING'=>1,'CRITICAL'=>2); + +sub print_revision ($$) { + my $commandName = shift; + my $pluginRevision = shift; + $pluginRevision =~ s/^\$Revision: //; + $pluginRevision =~ s/ \$\s*$//; + print "$commandName (@PACKAGE@ @VERSION@) $pluginRevision\n"; + print "@WARRANTY@"; +} + +sub support () { + my $support='@SUPPORT@'; + $support =~ s/@/\@/g; + $support =~ s/\\n/\n/g; + print $support; +} + +sub usage { + my $format=shift; + printf($format,@_); + exit $ERRORS{'UNKNOWN'}; +} + +1; diff --git a/plugins-scripts/utils.sh.in b/plugins-scripts/utils.sh.in new file mode 100644 index 00000000..1e835e67 --- /dev/null +++ b/plugins-scripts/utils.sh.in @@ -0,0 +1,22 @@ +#! /bin/sh + +STATE_DEPENDENT=-2 +STATE_UNKNOWN=-1 +STATE_OK=0 +STATE_WARNING=1 +STATE_CRITICAL=2 + +if test -x /usr/bin/printf; then + ECHO=/usr/bin/printf +else + ECHO=echo +fi + +print_revision() { + echo "$1 (@PACKAGE@ @VERSION@) $2" + $ECHO "@WARRANTY@" | /bin/sed -e 's/\n/ /g' +} + +support() { + $ECHO "@SUPPORT@" | /bin/sed -e 's/\n/ /g' +}
\ No newline at end of file diff --git a/plugins/.cvsignore b/plugins/.cvsignore new file mode 100644 index 00000000..58f14fe8 --- /dev/null +++ b/plugins/.cvsignore @@ -0,0 +1,43 @@ +check_disk +check_dns +check_dummy +check_ftp +check_http +check_imap +check_load +check_mrtg +check_mrtgtraf +check_nagios +check_nntp +check_nwstat +check_overcr +check_ping +check_pop +check_procs +check_real +check_reply +check_smtp +check_ssh +check_tcp +check_time +check_udp +check_ups +check_users +check_vsz +check_by_ssh +urlize +check_pgsql +check_radius +check_ldap +check_mysql +check_netsaint +check_hpjd +check_snmp +check_by_ssh +check_swap +stamp-h* +*.h +Makefile +Makefile.in +config.h.in +.deps diff --git a/plugins/Makefile.am b/plugins/Makefile.am new file mode 100644 index 00000000..64b14bfb --- /dev/null +++ b/plugins/Makefile.am @@ -0,0 +1,139 @@ +## Process this file with automake to produce Makefile.in + +VPATH = $(top_srcdir) $(top_srcdir)/plugins $(top_srcdir)/plugins/t + +INCLUDES = @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@ + +libexec_PROGRAMS = check_disk check_dummy check_ftp check_http \ + check_imap check_load check_mrtg check_mrtgtraf \ + check_nntp check_nwstat check_overcr \ + check_ping check_pop check_procs check_real \ + check_smtp check_ssh check_tcp check_time check_udp \ + check_ups check_users check_vsz urlize \ + @EXTRAS@ + +EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ + check_swap check_fping check_ldap check_game check_dig \ + check_nagios check_by_ssh check_dns check_nt + +EXTRA_DIST = t utils.c netutils.c popen.c getopt.h getopt.c getopt1.c snprintf.c + +PLUGINHDRS = common.h config.h + +BASEOBJS = utils.o +NETOBJS = netutils.o $(BASEOBJS) +NETLIBS = $(NETOBJS) $(SOCKETLIBS) + +TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir) + +TESTS = @PLUGIN_TEST@ + +test: + perl -I $(top_builddir) -I $(top_srcdir) ../test.pl + +AM_INSTALL_PROGRAM_FLAGS = @INSTALL_OPTS@ + +############################################################################## +# the actual targets + +check_dig_LDADD = $(BASEOBJS) popen.o +check_disk_LDADD = $(BASEOBJS) popen.o +check_dns_LDADD = $(BASEOBJS) popen.o +check_dummy_LDADD = $(BASEOBJS) +check_fping_LDADD = $(BASEOBJS) popen.o +check_ftp_LDADD = $(NETLIBS) +check_game_LDADD = $(BASEOBJS) +check_http_LDADD = $(NETLIBS) $(SSLLIBS) +check_hpjd_LDADD = $(BASEOBJS) popen.o +check_imap_LDADD = $(NETLIBS) +check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) +check_load_LDADD = $(BASEOBJS) popen.o +check_mrtg_LDADD = $(BASEOBJS) +check_mrtgtraf_LDADD = $(BASEOBJS) +check_mysql_LDADD = $(BASEOBJS) $(MYSQLLIBS) +check_nagios_LDADD = $(BASEOBJS) popen.o +check_nntp_LDADD = $(NETLIBS) +check_nt_LDADD = $(NETLIBS) +check_nwstat_LDADD = $(NETLIBS) +check_overcr_LDADD = $(NETLIBS) +check_pgsql_LDADD = $(BASEOBJS) $(PGLIBS) +check_ping_LDADD = $(BASEOBJS) popen.o +check_pop_LDADD = $(NETLIBS) +check_procs_LDADD = $(BASEOBJS) popen.o +check_radius_LDADD = $(BASEOBJS) $(RADIUSLIBS) +check_real_LDADD = $(NETLIBS) +check_snmp_LDADD = $(BASEOBJS) popen.o +check_smtp_LDADD = $(NETLIBS) +check_ssh_LDADD = $(NETLIBS) +check_swap_LDADD = $(BASEOBJS) popen.o +check_tcp_LDADD = $(NETLIBS) $(SSLLIBS) +check_time_LDADD = $(NETLIBS) +check_udp_LDADD = $(NETLIBS) +check_ups_LDADD = $(NETLIBS) +check_users_LDADD = $(BASEOBJS) popen.o +check_vsz_LDADD = $(BASEOBJS) popen.o +check_by_ssh_LDADD = $(BASEOBJS) popen.o +urlize_LDADD = $(BASEOBJS) popen.o + +check_dig_DEPENDENCIES = check_dig.c $(BASEOBJS) popen.o $(DEPLIBS) +check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS) +check_dns_DEPENDENCIES = check_dns.c $(BASEOBJS) popen.o $(DEPLIBS) +check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS) +check_fping_DEPENDENCIES = check_fping.c $(BASEOBJS) popen.o $(DEPLIBS) +check_ftp_DEPENDENCIES = check_ftp.c $(NETOBJS) $(DEPLIBS) +check_game_DEPENDENCIES = check_game.c $(DEPLIBS) +check_http_DEPENDENCIES = check_http.c $(NETOBJS) $(DEPLIBS) +check_hpjd_DEPENDENCIES = check_hpjd.c $(BASEOBJS) popen.o $(DEPLIBS) +check_imap_DEPENDENCIES = check_imap.c $(NETOBJS) $(DEPLIBS) +check_ldap_DEPENDENCIES = check_ldap.c $(NETOBJS) $(DEPLIBS) +check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS) +check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS) +check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS) +check_mysql_DEPENDENCIES = check_mysql.c $(DEPLIBS) +check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) popen.o $(DEPLIBS) +check_nntp_DEPENDENCIES = check_nntp.c $(NETOBJS) $(DEPLIBS) +check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS) +check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS) +check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS) +check_pgsql_DEPENDENCIES = check_pgsql.c $(DEPLIBS) +check_ping_DEPENDENCIES = check_ping.c $(BASEOBJS) popen.o $(DEPLIBS) +check_pop_DEPENDENCIES = check_pop.c $(NETOBJS) $(DEPLIBS) +check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS) +check_radius_DEPENDENCIES = check_radius.c $(DEPLIBS) +check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS) +check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) popen.o $(DEPLIBS) +check_smtp_DEPENDENCIES = check_smtp.c $(NETOBJS) $(DEPLIBS) +check_ssh_DEPENDENCIES = check_ssh.c $(NETOBJS) $(DEPLIBS) +check_swap_DEPENDENCIES = check_swap.c $(BASEOBJS) popen.o $(DEPLIBS) +check_tcp_DEPENDENCIES = check_tcp.c $(NETOBJS) $(DEPLIBS) +check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS) +check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS) +check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) +check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) +check_vsz_DEPENDENCIES = check_vsz.c $(BASEOBJS) popen.o $(DEPLIBS) +check_by_ssh_DEPENDENCIES = check_by_ssh.c $(BASEOBJS) popen.o $(DEPLIBS) +urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) + +############################################################################## +# secondary dependencies + +popen.o: popen.c popen.h $(PLUGINHDRS) + +utils.o: utils.c utils.h $(PLUGINHDRS) + +netutils.o: netutils.c netutils.h $(PLUGINHDRS) + +getopt.o: getopt.c getopt.h + $(COMPILE) -c $(srcdir)/getopt.c -o $@ + +getopt1.o: getopt1.c getopt.h + $(COMPILE) -c $(srcdir)/getopt1.c -o $@ + +snprintf.o: snprintf.c + $(COMPILE) @NEED_VA_LIST@ -c $? -o $@ + +libgetopt.a: getopt.o getopt1.o + $(AR) -r $@ getopt.o getopt1.o + +libsnprintf.a: snprintf.o + $(AR) -r $@ snprintf.o diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c new file mode 100644 index 00000000..a81b333f --- /dev/null +++ b/plugins/check_by_ssh.c @@ -0,0 +1,412 @@ +/****************************************************************************** + * + * This file is part of the Nagios Plugins. + * + * Copyright (c) 1999, 2000, 2001 Karl DeBisschop <karl@debisschop.net> + * + * The Nagios Plugins are free software; you can redistribute them + * and/or modify them 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGRAM check_by_ssh +#define DESCRIPTION "Run checks on a remote system using ssh, wrapping the proper timeout around the ssh invocation." +#define AUTHOR "Karl DeBisschop" +#define EMAIL "karl@debisschop.net" +#define COPYRIGHTDATE "1999, 2000, 2001" + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" +#include <time.h> + +#define PROGNAME "check_by_ssh" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (char *command_name); +void print_usage (void); + + +int commands; +char *remotecmd = NULL; +char *comm = NULL; +char *hostname = NULL; +char *outputfile = NULL; +char *host_shortname = NULL; +char *servicelist = NULL; +int passive = FALSE; +int verbose = FALSE; + + +int +main (int argc, char **argv) +{ + + char input_buffer[MAX_INPUT_BUFFER] = ""; + char *result_text = NULL; + char *status_text; + char *output = NULL; + char *eol = NULL; + char *srvc_desc = NULL; + int cresult; + int result = STATE_UNKNOWN; + time_t local_time; + FILE *fp = NULL; + + + /* process arguments */ + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + + /* Set signal handling and alarm timeout */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + alarm (timeout_interval); + + + /* run the command */ + + if (verbose) + printf ("%s\n", comm); + + child_process = spopen (comm); + + if (child_process == NULL) { + printf ("Unable to open pipe: %s", comm); + return STATE_UNKNOWN; + } + + + /* open STDERR for spopen */ + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", SSH_COMMAND); + } + + + /* get results from remote command */ + result_text = realloc (result_text, 1); + result_text[0] = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + result_text = strscat (result_text, input_buffer); + + + /* WARNING if output found on stderr */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + printf ("%s\n", input_buffer); + return STATE_WARNING; + } + (void) fclose (child_stderr); + + + /* close the pipe */ + result = spclose (child_process); + + + /* process output */ + if (passive) { + + if (!(fp = fopen (outputfile, "a"))) { + printf ("SSH WARNING: could not open %s\n", outputfile); + exit (STATE_UNKNOWN); + } + + time (&local_time); + srvc_desc = strtok (servicelist, ":"); + while (result_text != NULL) { + status_text = (strstr (result_text, "STATUS CODE: ")); + if (status_text == NULL) { + printf ("%s", result_text); + return result; + } + output = result_text; + result_text = strnl (status_text); + eol = strpbrk (output, "\r\n"); + if (eol != NULL) + eol[0] = 0; + if (srvc_desc && status_text + && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) { + fprintf (fp, "%d PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", + (int) local_time, host_shortname, srvc_desc, cresult, + output); + srvc_desc = strtok (NULL, ":"); + } + } + + } + + /* print the first line from the remote command */ + else { + eol = strpbrk (result_text, "\r\n"); + if (eol) + eol[0] = 0; + printf ("%s\n", result_text); + + } + + + /* return error status from remote command */ + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + remotecmd = realloc (remotecmd, 1); + remotecmd[0] = 0; + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + comm = strscpy (comm, SSH_COMMAND); + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + + if (argc <= c) + break; + + if (hostname == NULL) { + if (!is_host (argv[c])) + terminate (STATE_UNKNOWN, "%s: Invalid host name %s\n", PROGNAME, + argv[c]); + hostname = argv[c]; + } + else if (remotecmd == NULL) { + remotecmd = strscpy (remotecmd, argv[c++]); + for (; c < argc; c++) + remotecmd = ssprintf (remotecmd, "%s %s", remotecmd, argv[c]); + } + + } + + if (commands > 1) + remotecmd = strscat (remotecmd, ";echo STATUS CODE: $?;"); + + if (remotecmd == NULL || strlen (remotecmd) <= 1) + usage ("No remotecmd\n"); + + comm = ssprintf (comm, "%s %s '%s'", comm, hostname, remotecmd); + + return validate_arguments (); +} + + + + + +/* Call getopt */ +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {"fork", no_argument, 0, 'f'}, + {"timeout", required_argument, 0, 't'}, + {"host", required_argument, 0, 'H'}, + {"port", required_argument,0,'P'}, + {"output", required_argument, 0, 'O'}, + {"name", required_argument, 0, 'n'}, + {"services", required_argument, 0, 's'}, + {"identity", required_argument, 0, 'i'}, + {"user", required_argument, 0, 'u'}, + {"logname", required_argument, 0, 'l'}, + {"command", required_argument, 0, 'C'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+?Vvhft:H:O:P:p:i:u:l:C:n:s:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?Vvhft:H:O:P:p:i:u:l:C:n:s:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'H': + case 'O': + case 'p': + case 'i': + case 'u': + case 'l': + case 'n': + case 's': + i++; + } + + switch (c) { + case '?': /* help */ + print_usage (); + exit (STATE_UNKNOWN); + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (PROGNAME); + exit (STATE_OK); + case 'v': /* help */ + verbose = TRUE; + break; + case 'f': /* fork to background */ + comm = ssprintf (comm, "%s -f", comm); + break; + case 't': /* timeout period */ + if (!is_integer (optarg)) + usage2 ("timeout interval must be an integer", optarg); + timeout_interval = atoi (optarg); + break; + case 'H': /* host */ + if (!is_host (optarg)) + usage2 ("invalid host name", optarg); + hostname = optarg; + break; + case 'P': /* port number */ + case 'p': /* port number */ + if (!is_integer (optarg)) + usage2 ("port must be an integer", optarg); + comm = ssprintf (comm,"%s -p %s", comm, optarg); + break; + case 'O': /* output file */ + outputfile = optarg; + passive = TRUE; + break; + case 's': /* description of service to check */ + servicelist = optarg; + break; + case 'n': /* short name of host in nagios configuration */ + host_shortname = optarg; + break; + case 'u': + c = 'l'; + case 'l': /* login name */ + case 'i': /* identity */ + comm = ssprintf (comm, "%s -%c %s", comm, c, optarg); + break; + case 'C': /* Command for remote machine */ + commands++; + if (commands > 1) + remotecmd = strscat (remotecmd, ";echo STATUS CODE: $?;"); + remotecmd = strscat (remotecmd, optarg); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + if (remotecmd == NULL || hostname == NULL) + return ERROR; + return OK; +} + + + + + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + + printf + ("Copyright (c) 1999 Karl DeBisschop (kdebisschop@alum.mit.edu)\n\n" + "This plugin will execute a command on a remote host using SSH\n\n"); + + print_usage (); + + printf + ("\nOptions:\n" + "-H, --hostname=HOST\n" + " name or IP address of remote host\n" + "-C, --command='COMMAND STRING'\n" + " command to execute on the remote machine\n" + "-f tells ssh to fork rather than create a tty\n" + "-t, --timeout=INTEGER\n" + " specify timeout (default: %d seconds) [optional]\n" + "-l, --logname=USERNAME\n" + " SSH user name on remote host [optional]\n" + "-i, --identity=KEYFILE\n" + " identity of an authorized key [optional]\n" + "-O, --output=FILE\n" + " external command file for nagios [optional]\n" + "-s, --services=LIST\n" + " list of nagios service names, separated by ':' [optional]\n" + "-n, --name=NAME\n" + " short name of host in nagios configuration [optional]\n" + "\n" + "The most common mode of use is to refer to a local identity file with\n" + "the '-i' option. In this mode, the identity pair should have a null\n" + "passphrase and the public key should be listed in the authorized_keys\n" + "file of the remote host. Usually the key will be restricted to running\n" + "only one command on the remote server. If the remote SSH server tracks\n" + "invocation agruments, the one remote program may be an agent that can\n" + "execute additional commands as proxy\n" + "\n" + "To use passive mode, provide multiple '-C' options, and provide\n" + "all of -O, -s, and -n options (servicelist order must match '-C'\n" + "options)\n", DEFAULT_SOCKET_TIMEOUT); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage:\n" + "check_by_ssh [-f] [-t timeout] [-i identity] [-l user] -H <host> <command>\n" + " [-n name] [-s servicelist] [-O outputfile] [-P port]\n" + "check_by_ssh -V prints version info\n" + "check_by_ssh -h prints more detailed help\n"); +} diff --git a/plugins/check_dig.c b/plugins/check_dig.c new file mode 100644 index 00000000..57609acd --- /dev/null +++ b/plugins/check_dig.c @@ -0,0 +1,296 @@ +/****************************************************************************** +* +* check_dig.c +* +* Program: dig plugin for Nagios +* License: GPL +* Copyright (c) 2000 +* +* $Id$ +* +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" +#include "popen.h" + +#define PROGNAME "check_dig" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +char *query_address = NULL; +char *dns_server = NULL; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + char input_buffer[MAX_INPUT_BUFFER]; + char *command_line = NULL; + char *output = NULL; + int result = STATE_UNKNOWN; + + /* Set signal handling and alarm */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) + usage ("Cannot catch SIGALRM\n"); + + if (process_arguments (argc, argv) != OK) + usage ("Could not parse arguments\n"); + + /* get the command to run */ + command_line = + ssprintf (command_line, "%s @%s %s", PATH_TO_DIG, dns_server, + query_address); + + alarm (timeout_interval); + time (&start_time); + + if (verbose) + printf ("%s\n", command_line); + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", command_line); + + output = strscpy (output, ""); + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + /* the server is responding, we just got the host name... */ + if (strstr (input_buffer, ";; ANSWER SECTION:")) { + + /* get the host address */ + if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + break; + + if (strpbrk (input_buffer, "\r\n")) + input_buffer[strcspn (input_buffer, "\r\n")] = '\0'; + + if (strstr (input_buffer, query_address) == input_buffer) { + output = strscpy (output, input_buffer); + result = STATE_OK; + } + else { + strcpy (output, "Server not found in ANSWER SECTION"); + result = STATE_WARNING; + } + + continue; + } + + } + + if (result != STATE_OK) { + strcpy (output, "No ANSWER SECTION found"); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + /* If we get anything on STDERR, at least set warning */ + result = max (result, STATE_WARNING); + printf ("%s", input_buffer); + if (!strcmp (output, "")) + strcpy (output, 1 + index (input_buffer, ':')); + } + + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) { + result = max (result, STATE_WARNING); + if (!strcmp (output, "")) + strcpy (output, "nslookup returned error status"); + } + + (void) time (&end_time); + + if (result == STATE_OK) + printf ("DNS ok - %d seconds response time (%s)\n", + (int) (end_time - start_time), output); + else if (result == STATE_WARNING) + printf ("DNS WARNING - %s\n", + !strcmp (output, + "") ? " Probably a non-existent host/domain" : output); + else if (result == STATE_CRITICAL) + printf ("DNS CRITICAL - %s\n", + !strcmp (output, + "") ? " Probably a non-existent host/domain" : output); + else + printf ("DNS problem - %s\n", + !strcmp (output, + "") ? " Probably a non-existent host/domain" : output); + + return result; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (dns_server == NULL) { + if (is_host (argv[c])) { + dns_server = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (dns_server == NULL) + dns_server = strscpy (NULL, "127.0.0.1"); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"query_address", required_argument, 0, 'e'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVvt:l:H:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVvt:l:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'l': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + dns_server = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'l': /* username */ + query_address = optarg; + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + timeout_interval = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Karl DeBisschop\n\n" + "This plugin use dig to test the DNS service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -l, --lookup=STRING\n" + " machine name to lookup\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host -l lookup [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_disk.c b/plugins/check_disk.c new file mode 100644 index 00000000..d7aad072 --- /dev/null +++ b/plugins/check_disk.c @@ -0,0 +1,353 @@ +/****************************************************************************** + * + * CHECK_DISK.C + * + * Program: Disk space plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) + * + * $Id$ + * + * Description: + * + * This plugin will use the /bin/df command to check the free space on + * currently mounted filesystems. If the percent used disk space is + * above <c_dfp>, a STATE_CRITICAL is returned. If the percent used + * disk space is above <w_dfp>, a STATE_WARNING is returned. If the + * speicified filesystem cannot be read, a STATE_CRITICAL is returned, + * other errors with reading the output result in a STATE_UNKNOWN + * error. + * + * Notes: + * - IRIX support added by Charlie Cook 4-16-1999 + * - Modifications by Karl DeBisschop 1999-11-24 + * reformat code to 80 char screen width + * set STATE_WARNING if stderr is written or spclose status set + * set default result to STAT_UNKNOWN + * initailize usp to -1, eliminate 'found' variable + * accept any filename/filesystem + * use sscanf, drop while loop + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" +#include <stdarg.h> + +#define PROGNAME "check_disk" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int w_df = -1; +int c_df = -1; +float w_dfp = -1.0; +float c_dfp = -1.0; +char *path = NULL; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int len; + int usp = -1; + int total_disk = -1; + int used_disk = -1; + int free_disk = -1; + int result = STATE_UNKNOWN; + char *command_line = NULL; + char input_buffer[MAX_INPUT_BUFFER] = ""; + char file_system[MAX_INPUT_BUFFER] = ""; + char outbuf[MAX_INPUT_BUFFER] = ""; + char *output = NULL; + + if (process_arguments (argc, argv) != OK) + usage ("Could not parse arguments\n"); + + command_line = ssprintf (command_line, "%s %s", DF_COMMAND, path); + + if (verbose) + printf ("%s ==> ", command_line); + + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + if (!index (input_buffer, '/')) + continue; + + if (sscanf + (input_buffer, "%s %d %d %d %d%%", file_system, &total_disk, + &used_disk, &free_disk, &usp) == 5 + || sscanf (input_buffer, "%s %*s %d %d %d %d%%", file_system, + &total_disk, &used_disk, &free_disk, &usp) == 5) { + result = max (result, check_disk (usp, free_disk)); + len = + snprintf (outbuf, MAX_INPUT_BUFFER - 1, + " [%d kB (%d%%) free on %s]", free_disk, 100 - usp, + file_system); + outbuf[len] = 0; + output = strscat (output, outbuf); + } + else { + printf ("Unable to read output:\n%s\n%s\n", command_line, input_buffer); + return result; + } + } + + /* If we get anything on stderr, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + else if (usp < 0) + printf ("Disk %s not mounted or nonexistant\n", argv[3]); + else if (result == STATE_UNKNOWN) + printf ("Unable to read output\n%s\n%s\n", command_line, input_buffer); + else + printf ("DISK %s -%s\n", state_text (result), output); + + return result; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) { + strcpy (argv[c], "-t"); + } + } + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (w_dfp == -1 && is_intnonneg (argv[c])) + w_dfp = (100.0 - atof (argv[c])); + else if (c_dfp == -1 && is_intnonneg (argv[c])) + c_dfp = (100.0 - atof (argv[c])); + else if (path == NULL || path[0] == 0) + path = strscpy (path, argv[c]); + } + + if (path == NULL) { + path = malloc (1); + if (path == NULL) + terminate (STATE_UNKNOWN, "Could not malloc empty path\n"); + path[0] = 0; + } + + return validate_arguments (); +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"timeout", required_argument, 0, 't'}, + {"path", required_argument, 0, 'p'}, + {"partition", required_argument, 0, 'p'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+?Vhvt:c:w:p:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?Vhvt:c:w:p:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'c': + case 'w': + case 'p': + i++; + } + + switch (c) { + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + w_df = atoi (optarg); + break; + } + else if (strpbrk (optarg, ",:") && + strstr (optarg, "%") && + sscanf (optarg, "%d%*[:,]%f%%", &w_df, &w_dfp) == 2) { + break; + } + else if (strstr (optarg, "%") && sscanf (optarg, "%f%%", &w_dfp) == 1) { + break; + } + else { + usage ("Warning threshold must be integer or percentage!\n"); + } + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + c_df = atoi (optarg); + break; + } + else if (strpbrk (optarg, ",:") && + strstr (optarg, "%") && + sscanf (optarg, "%d%*[,:]%f%%", &c_df, &c_dfp) == 2) { + break; + } + else if (strstr (optarg, "%") && sscanf (optarg, "%f%%", &c_dfp) == 1) { + break; + } + else { + usage ("Critical threshold must be integer or percentage!\n"); + } + case 't': /* timeout period */ + if (is_integer (optarg)) { + timeout_interval = atoi (optarg); + break; + } + else { + usage ("Timeout Interval must be an integer!\n"); + } + case 'p': /* path or partition */ + path = optarg; + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("check_disk: unrecognized option\n"); + break; + } + } + return i; +} + +int +validate_arguments () +{ + if (w_df < 0 && c_df < 0 && w_dfp < 0 && c_dfp < 0) { + printf ("INPUT ERROR: Unable to parse command line\n"); + return ERROR; + } + else if ((w_dfp >= 0 || c_dfp >= 0) + && (w_dfp < 0 || c_dfp < 0 || w_dfp > 100 || c_dfp > 100 + || c_dfp > w_dfp)) { + printf + ("INPUT ERROR: C_DFP (%f) should be less than W_DFP (%f) and both should be between zero and 100 percent, inclusive\n", + c_dfp, w_dfp); + return ERROR; + } + else if ((w_df > 0 || c_df > 0) && (w_df < 0 || c_df < 0 || c_df > w_df)) { + printf + ("INPUT ERROR: C_DF (%d) should be less than W_DF (%d) and both should be greater than zero\n", + c_df, w_df); + return ERROR; + } + else { + return OK; + } +} + +int +check_disk (usp, free_disk) +{ + int result = STATE_UNKNOWN; + /* check the percent used space against thresholds */ + if (usp >= 0 && usp >= (100.0 - c_dfp)) + result = STATE_CRITICAL; + else if (c_df >= 0 && free_disk <= c_df) + result = STATE_CRITICAL; + else if (usp >= 0 && usp >= (100.0 - w_dfp)) + result = STATE_WARNING; + else if (w_df >= 0 && free_disk <= w_df) + result = STATE_WARNING; + else if (usp >= 0.0) + result = STATE_OK; + return result; +} + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin will check the percent of used disk space on a mounted\n" + "file system and generate an alert if percentage is above one of the\n" + "threshold values.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -w, --warning=INTEGER\n" + " Exit with WARNING status if less than INTEGER kilobytes of disk are free\n" + " -w, --warning=PERCENT%%\n" + " Exit with WARNING status if more than PERCENT of disk space is free\n" + " -c, --critical=INTEGER\n" + " Exit with CRITICAL status if less than INTEGER kilobytes of disk are free\n" + " -c, --critical=PERCENT%%\n" + " Exit with CRITCAL status if more than PERCENT of disk space is free\n" + " -p, --path=PATH, --partition=PARTTION\n" + " Path or partition (checks all mounted partitions if unspecified)\n" + " -v, --verbose\n" + " Show details for command-line debugging (do not use with nagios server)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n"); + support (); +} + +void +print_usage (void) +{ + printf + ("Usage: %s -w limit -c limit [-p path] [-t timeout] [--verbose]\n" + " %s (-h|--help)\n" + " %s (-V|--version)\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_dns.c b/plugins/check_dns.c new file mode 100644 index 00000000..eaff4372 --- /dev/null +++ b/plugins/check_dns.c @@ -0,0 +1,415 @@ +/****************************************************************************** + * + * CHECK_DNS.C + * + * Program: DNS plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * + * Notes: + * - Safe popen added by Karl DeBisschop 9-11-99 + * + * Command line: CHECK_DNS <query_address> [dns_server] + * + * Description: + * + * This program will use the nslookup program to obtain the IP address + * for a given host name. A optional DNS server may be specified. If + * no DNS server is specified, the default server(s) for the system + * are used. + * + * Return Values: + * OK The DNS query was successful (host IP address was returned). + * WARNING The DNS server responded, but could not fulfill the request. + * CRITICAL The DNS server is not responding or encountered an error. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_usage (char *); +void print_help (char *); +int error_scan (char *); + +#define ADDRESS_LENGTH 256 +char query_address[ADDRESS_LENGTH] = ""; +char dns_server[ADDRESS_LENGTH] = ""; +char ptr_server[ADDRESS_LENGTH] = ""; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + char *command_line = NULL; + char input_buffer[MAX_INPUT_BUFFER]; + char *output = NULL; + char *address = NULL; + char *temp_buffer = NULL; + int result = STATE_UNKNOWN; + + /* Set signal handling and alarm */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + + if (process_arguments (argc, argv) != OK) { + print_usage (my_basename (argv[0])); + return STATE_UNKNOWN; + } + + /* get the command to run */ + command_line = ssprintf (command_line, "%s %s %s", NSLOOKUP_COMMAND, + query_address, dns_server); + + alarm (timeout_interval); + time (&start_time); + + if (verbose) + printf ("%s\n", command_line); + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", command_line); + + /* scan stdout */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + if (verbose) + printf ("%s\n", input_buffer); + + if (strstr (input_buffer, ".in-addr.arpa")) { + if ((temp_buffer = strstr (input_buffer, "name = "))) + address = strscpy (address, temp_buffer + 7); + else { + output = strscpy (output, "Unknown error (plugin)"); + result = STATE_WARNING; + } + } + + /* the server is responding, we just got the host name... */ + if (strstr (input_buffer, "Name:")) { + + /* get the host address */ + if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + break; + + if (verbose) + printf ("%s\n", input_buffer); + + if ((temp_buffer = index (input_buffer, ':'))) { + address = strscpy (address, temp_buffer + 2); + strip (address); + result = STATE_OK; + } + else { + output = strscpy (output, "Unknown error (plugin)"); + result = STATE_WARNING; + } + + break; + } + + result = error_scan (input_buffer); + if (result != STATE_OK) { + output = strscpy (output, 1 + index (input_buffer, ':')); + break; + } + + } + + /* scan stderr */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + if (error_scan (input_buffer) != STATE_OK) { + result = max (result, error_scan (input_buffer)); + output = strscpy (output, 1 + index (input_buffer, ':')); + } + } + + /* close stderr */ + (void) fclose (child_stderr); + + /* close stdout */ + if (spclose (child_process)) { + result = max (result, STATE_WARNING); + if (!strcmp (output, "")) + output = strscpy (output, "nslookup returned error status"); + } + + (void) time (&end_time); + + if (result == STATE_OK) + printf ("DNS ok - %d seconds response time, Address(es) is/are %s\n", + (int) (end_time - start_time), address); + else if (result == STATE_WARNING) + printf ("DNS WARNING - %s\n", + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); + else if (result == STATE_CRITICAL) + printf ("DNS CRITICAL - %s\n", + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); + else + printf ("DNS problem - %s\n", + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); + + return result; +} + +int +error_scan (char *input_buffer) +{ + + /* the DNS lookup timed out */ + if (strstr (input_buffer, + "Note: nslookup is deprecated and may be removed from future releases.") + || strstr (input_buffer, + "Consider using the `dig' or `host' programs instead. Run nslookup with") + || strstr (input_buffer, + "the `-sil[ent]' option to prevent this message from appearing.")) + return STATE_OK; + + /* the DNS lookup timed out */ + else if (strstr (input_buffer, "Timed out")) + return STATE_WARNING; + + /* DNS server is not running... */ + else if (strstr (input_buffer, "No response from server")) + return STATE_CRITICAL; + + /* Host name is valid, but server doesn't have records... */ + else if (strstr (input_buffer, "No records")) + return STATE_WARNING; + + /* Host or domain name does not exist */ + else if (strstr (input_buffer, "Non-existent")) + return STATE_CRITICAL; + else if (strstr (input_buffer, "** server can't find")) + return STATE_CRITICAL; + else if(strstr(input_buffer,"NXDOMAIN")) /* 9.x */ + return STATE_CRITICAL; + + /* Connection was refused */ + else if (strstr (input_buffer, "Connection refused")) + return STATE_CRITICAL; + + /* Network is unreachable */ + else if (strstr (input_buffer, "Network is unreachable")) + return STATE_CRITICAL; + + /* Internal server failure */ + else if (strstr (input_buffer, "Server failure")) + return STATE_CRITICAL; + + /* DNS server refused to service request */ + else if (strstr (input_buffer, "Refused")) + return STATE_CRITICAL; + + /* Request error */ + else if (strstr (input_buffer, "Format error")) + return STATE_WARNING; + + else + return STATE_OK; + +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (query_address[0] == 0) { + if (is_host (argv[c]) == FALSE) { + printf ("Invalid name/address: %s\n\n", argv[c]); + return ERROR; + } + if (strlen (argv[c]) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (query_address, argv[c]); + } + else if (dns_server[0] == 0) { + if (is_host (argv[c]) == FALSE) { + printf ("Invalid name/address: %s\n\n", argv[c]); + return ERROR; + } + if (strlen (argv[c]) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (dns_server, argv[c]); + } + } + + return validate_arguments (); + +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + +#ifdef HAVE_GETOPT_H + int opt_index = 0; + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {"timeout", required_argument, 0, 't'}, + {"hostname", required_argument, 0, 'H'}, + {"server", required_argument, 0, 's'}, + {"reverse-server", required_argument, 0, 'r'}, + {0, 0, 0, 0} + }; +#endif + + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+?hVvt:H:s:r:", long_opts, &opt_index); +#else + c = getopt (argc, argv, "+?hVvt:H:s:r:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'H': + case 's': + case 'r': + i++; + } + + switch (c) { + case '?': /* args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (my_basename (argv[0])); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* version */ + verbose = TRUE; + break; + case 't': /* timeout period */ + timeout_interval = atoi (optarg); + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + if (strlen (optarg) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (query_address, optarg); + break; + case 's': /* server name */ + if (is_host (optarg) == FALSE) { + printf ("Invalid server name/address\n\n"); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + if (strlen (optarg) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (dns_server, optarg); + break; + case 'r': /* reverse server name */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + if (strlen (optarg) >= ADDRESS_LENGTH) + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); + strcpy (ptr_server, optarg); + break; + } + } + return i; +} + +int +validate_arguments () +{ + if (query_address[0] == 0) + return ERROR; + else + return OK; +} + +void +print_usage (char *cmd) +{ + printf ("Usage: %s -H host [-s server] [-t timeout]\n" " %s --help\n" + " %s --version\n", cmd, cmd, cmd); +} + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n"); + print_usage (cmd); + printf ("\n"); + printf + ("-H, --hostname=HOST\n" + " The name or address you want to query\n" + "-s, --server=HOST\n" + " Optional DNS server you want to use for the lookup\n" + "-t, --timeout=INTEGER\n" + " Seconds before connection times out (default: %d)\n" + "-h, --help\n" + " Print detailed help\n" + "-V, --version\n" + " Print version numbers and license information\n" + "\n" + "This plugin uses the nslookup program to obtain the IP address\n" + "for the given host/domain query. A optional DNS server to use may\n" + "be specified. If no DNS server is specified, the default server(s)\n" + "specified in /etc/resolv.conf will be used.\n", DEFAULT_SOCKET_TIMEOUT); +} diff --git a/plugins/check_dummy.c b/plugins/check_dummy.c new file mode 100644 index 00000000..c2a5b7eb --- /dev/null +++ b/plugins/check_dummy.c @@ -0,0 +1,100 @@ +/************************************************************* + * + * CHECK_DUMMY.C + * + * Program: Dummy plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * + * Command line: CHECK_DUMMY <state> + * + * Description: + * + * This plugin will simply return the state corresponding to the + * numerical value of the <state> argument. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + **************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +void print_help (char *); +void print_usage (char *); + +int +main (int argc, char **argv) +{ + int result; + + if (argc != 2) { + printf ("Incorrect number of arguments supplied\n"); + exit (STATE_UNKNOWN); + } + else if (strcmp (argv[1], "-V") == 0 || strcmp (argv[1], "--version") == 0) { + print_revision (argv[0], "$Revision$"); + exit (STATE_OK); + } + else if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { + print_help (argv[0]); + exit (STATE_OK); + } + else if (!is_integer (argv[1])) { + print_usage (argv[0]); + exit (STATE_UNKNOWN); + } + result = atoi (argv[1]); + + switch (result) { + case STATE_OK: + printf ("Status is OK\n"); + break; + case STATE_WARNING: + printf ("Status is at WARNING level\n"); + break; + case STATE_CRITICAL: + printf ("Status is CRITICAL\n"); + break; + default: + printf ("Status is UNKNOWN\n"); + result = STATE_UNKNOWN; + } + + return result; +} + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n" + "License: GPL\n\n"); + print_usage (cmd); + printf + ("\nThis plugin will simply return the state corresponding to the numeric value\n" + "of the <state> argument.\n"); +} + +void +print_usage (char *cmd) +{ + printf ("Usage: %s <integer state>\n", cmd); +} diff --git a/plugins/check_fping.c b/plugins/check_fping.c new file mode 100644 index 00000000..f6531a54 --- /dev/null +++ b/plugins/check_fping.c @@ -0,0 +1,386 @@ +/****************************************************************************** +* +* CHECK_FPING.C +* +* Program: Fping plugin for Nagios +* License: GPL +* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* $Id$ +* +* Modifications: +* +* 08-24-1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* Intial Coding +* 09-11-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* Change to spopen +* Fix so that state unknown is returned by default +* (formerly would give state ok if no fping specified) +* Add server_name to output +* Reformat to 80-character standard screen +* 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) +* set STATE_WARNING of stderr written or nonzero status returned +* +* Description: +* +* This plugin will use the /bin/fping command (form saint) to ping +* the specified host for a fast check if the host is alive. Note that +* it is necessary to set the suid flag on fping. +******************************************************************************/ + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_fping" +#define PACKET_COUNT 1 +#define PACKET_SIZE 56 +#define UNKNOWN_PACKET_LOSS 200 /* 200% */ +#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ + +#define PL 0 +#define RTA 1 + +int textscan (char *buf); +int process_arguments (int, char **); +int get_threshold (char *arg, char *rv[2]); +void print_usage (void); +void print_help (void); + +char *server_name = NULL; +int cpl = UNKNOWN_PACKET_LOSS; +int wpl = UNKNOWN_PACKET_LOSS; +double crta = UNKNOWN_TRIP_TIME; +double wrta = UNKNOWN_TRIP_TIME; +int packet_size = PACKET_SIZE; +int packet_count = PACKET_COUNT; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int status = STATE_UNKNOWN; + char *server = NULL; + char *command_line = NULL; + char *input_buffer = NULL; + input_buffer = malloc (MAX_INPUT_BUFFER); + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + server = strscpy (server, server_name); + + /* compose the command */ + command_line = ssprintf + (command_line, "%s -b %d -c %d %s", + PATH_TO_FPING, packet_size, packet_count, server); + + if (verbose) + printf ("%s\n", command_line); + + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Unable to open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + if (verbose) + printf ("%s", input_buffer); + status = max (status, textscan (input_buffer)); + } + + /* If we get anything on STDERR, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + status = max (status, STATE_WARNING); + if (verbose) + printf ("%s", input_buffer); + status = max (status, textscan (input_buffer)); + } + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + status = max (status, STATE_WARNING); + + printf ("FPING %s - %s\n", state_text (status), server_name); + + return status; +} + + + + +int +textscan (char *buf) +{ + char *rtastr = NULL; + char *losstr = NULL; + double loss; + double rta; + int status = STATE_UNKNOWN; + + if (strstr (buf, "not found")) { + terminate (STATE_CRITICAL, "FPING unknown - %s not found\n", server_name); + + } + else if (strstr (buf, "is unreachable") || strstr (buf, "Unreachable")) { + terminate (STATE_CRITICAL, "FPING critical - %s is unreachable\n", + "host"); + + } + else if (strstr (buf, "is down")) { + terminate (STATE_CRITICAL, "FPING critical - %s is down\n", server_name); + + } + else if (strstr (buf, "is alive")) { + status = STATE_OK; + + } + else if (strstr (buf, "xmt/rcv/%loss") && strstr (buf, "min/avg/max")) { + losstr = strstr (buf, "="); + losstr = 1 + strstr (losstr, "/"); + losstr = 1 + strstr (losstr, "/"); + rtastr = strstr (buf, "min/avg/max"); + rtastr = strstr (rtastr, "="); + rtastr = 1 + index (rtastr, '/'); + loss = strtod (losstr, NULL); + rta = strtod (rtastr, NULL); + if (cpl != UNKNOWN_PACKET_LOSS && loss > cpl) + status = STATE_CRITICAL; + else if (crta != UNKNOWN_TRIP_TIME && rta > crta) + status = STATE_CRITICAL; + else if (wpl != UNKNOWN_PACKET_LOSS && loss > wpl) + status = STATE_WARNING; + else if (wrta != UNKNOWN_TRIP_TIME && rta > wrta) + status = STATE_WARNING; + else + status = STATE_OK; + terminate (status, "FPING %s - %s (loss=%f%%, rta=%f ms)\n", + state_text (status), server_name, loss, rta); + + } + else { + status = max (status, STATE_WARNING); + } + + return status; +} + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + char *rv[2]; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"bytes", required_argument, 0, 'b'}, + {"number", required_argument, 0, 'n'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + rv[PL] = NULL; + rv[RTA] = NULL; + + if (argc < 2) + return ERROR; + + if (!is_option (argv[1])) { + server_name = argv[1]; + argv[1] = argv[0]; + argv = &argv[1]; + argc--; + } + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:c:w:b:n:", long_options, &option_index); +#else + c = getopt (argc, argv, "+hVvH:c:w:b:n:"); +#endif + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); + } + server_name = strscpy (server_name, optarg); + break; + case 'c': + get_threshold (optarg, rv); + if (rv[RTA]) { + crta = strtod (rv[RTA], NULL); + rv[RTA] = NULL; + } + if (rv[PL]) { + cpl = atoi (rv[PL]); + rv[PL] = NULL; + } + break; + case 'w': + get_threshold (optarg, rv); + if (rv[RTA]) { + wrta = strtod (rv[RTA], NULL); + rv[RTA] = NULL; + } + if (rv[PL]) { + wpl = atoi (rv[PL]); + rv[PL] = NULL; + } + break; + case 'b': /* bytes per packet */ + if (is_intpos (optarg)) + packet_size = atoi (optarg); + else + usage ("Packet size must be a positive integer"); + break; + case 'n': /* number of packets */ + if (is_intpos (optarg)) + packet_count = atoi (optarg); + else + usage ("Packet count must be a positive integer"); + break; + } + } + + + if (server_name == NULL) + usage ("Host name was not supplied\n\n"); + + return OK; +} + + + + + +int +get_threshold (char *arg, char *rv[2]) +{ + char *arg1 = NULL; + char *arg2 = NULL; + + arg1 = strscpy (arg1, arg); + if (strpbrk (arg1, ",:")) + arg2 = 1 + strpbrk (arg1, ",:"); + + if (arg2) { + arg1[strcspn (arg1, ",:")] = 0; + if (strstr (arg1, "%") && strstr (arg2, "%")) + terminate (STATE_UNKNOWN, + "%s: Only one threshold may be packet loss (%s)\n", PROGNAME, + arg); + if (!strstr (arg1, "%") && !strstr (arg2, "%")) + terminate (STATE_UNKNOWN, + "%s: Only one threshold must be packet loss (%s)\n", + PROGNAME, arg); + } + + if (arg2 && strstr (arg2, "%")) { + rv[PL] = arg2; + rv[RTA] = arg1; + } + else if (arg2) { + rv[PL] = arg1; + rv[RTA] = arg2; + } + else if (strstr (arg1, "%")) { + rv[PL] = arg1; + } + else { + rv[RTA] = arg1; + } + + return OK; +} + + + + + +void +print_usage (void) +{ + printf ("Usage: %s <host_address>\n", PROGNAME); +} + + + + + +void +print_help (void) +{ + + print_revision (PROGNAME, "$Revision$"); + + printf + ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n\n" + "This plugin will use the /bin/fping command (from saint) to ping the\n" + "specified host for a fast check if the host is alive. Note that it is\n" + "necessary to set the suid flag on fping.\n\n"); + + print_usage (); + + printf + ("\nOptions:\n" + "-H, --hostname=HOST\n" + " Name or IP Address of host to ping (IP Address bypasses name lookup,\n" + " reducing system load)\n" + "-w, --warning=THRESHOLD\n" + " warning threshold pair\n" + "-c, --critical=THRESHOLD\n" + " critical threshold pair\n" + "-b, --bytes=INTEGER\n" + " Size of ICMP packet (default: %d)\n" + "-n, --number=INTEGER\n" + " Number of ICMP packets to send (default: %d)\n" + "-v, --verbose\n" + " Show details for command-line debugging (do not use with nagios server)\n" + "-h, --help\n" + " Print this help screen\n" + "-V, --version\n" + " Print version information\n" + "THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel\n" + "time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the\n" + "percentage of packet loss to trigger an alarm state.\n", + PACKET_SIZE, PACKET_COUNT); +} diff --git a/plugins/check_ftp.c b/plugins/check_ftp.c new file mode 100644 index 00000000..1c65d642 --- /dev/null +++ b/plugins/check_ftp.c @@ -0,0 +1,337 @@ +/****************************************************************************** + * + * CHECK_FTP.C + * + * Program: FTP plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * $Id$ + * + * Description: + * + * This plugin will attempt to open an FTP connection with the host. + * Successul connects return STATE_OK, refusals and timeouts return + * STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful + * connects, but incorrect reponse messages from the host result in + * STATE_WARNING return values. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_ftp" + +#define FTP_PORT 21 +#define FTP_EXPECT "220" +#define FTP_QUIT "QUIT\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +void print_usage (void); +void print_help (void); + +time_t start_time, end_time; +int server_port = FTP_PORT; +char *server_address = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + /* watch for the FTP connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* strip the buffer of carriage returns */ + strip (buffer); + + /* return a WARNING status if we couldn't read any data */ + if (result == -1) { + printf ("recv() failed\n"); + result = STATE_WARNING; + } + + else { + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, server_expect)) { + + if (server_port == FTP_PORT) + printf ("Invalid FTP response received from host\n"); + else + printf ("Invalid FTP response received from host on port %d\n", + server_port); + result = STATE_WARNING; + } + + else { + time (&end_time); + + result = STATE_OK; + + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = + STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + + if (verbose == TRUE) + printf ("FTP %s - %d sec. response time, %s\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time), buffer); + else + printf ("FTP %s - %d second response time\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time)); + } + } + + /* close the connection */ + send (sd, FTP_QUIT, strlen (FTP_QUIT), 0); + close (sd); + } + + /* reset the alarm */ + alarm (0); + + return result; +} + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + usage ("\n"); + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + c = 0; + while ((c += call_getopt (argc - c, &argv[c])) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (argc > c) { + if (is_host (argv[c]) == FALSE) + usage ("Invalid host name/address\n"); + server_address = argv[c]; + } + else { + usage ("Host name was not supplied\n"); + } + } + } + + if (server_expect == NULL) + server_expect = strscpy (NULL, FTP_EXPECT); + + return OK; +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"timeout", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'p'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:e:c:w:t:p:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVvH:e:c:w:t:p:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'e': + case 'c': + case 'w': + case 't': + case 'p': + i++; + } + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) + usage ("Invalid host name/address\n"); + server_address = optarg; + break; + case 'e': /* expect */ + server_expect = optarg; + break; + case 'c': /* critical */ + if (!is_intnonneg (optarg)) + usage ("Critical threshold must be a nonnegative integer\n"); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'w': /* warning */ + if (!is_intnonneg (optarg)) + usage ("Warning threshold must be a nonnegative integer\n"); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 't': /* timeout */ + if (!is_intnonneg (optarg)) + usage ("Timeout interval must be a nonnegative integer\n"); + socket_timeout = atoi (optarg); + break; + case 'p': /* port */ + if (!is_intnonneg (optarg)) + usage ("Serevr port must be a nonnegative integer\n"); + server_port = atoi (optarg); + break; + } + } + return i; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H <host_address> [-e expect] [-p port] [-w warn_time]\n" + " [-c crit_time] [-t to_sec] [-v]\n", PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n" + "This plugin tests an FTP connection with the specified host.\n\n"); + print_usage (); + printf + ("Options:\n" + " -H, --hostname=ADDRESS\n" + " Host name argument for servers using host headers (use numeric\n" + " address if possible to bypass DNS lookup).\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -p, --port=INTEGER\n" + " Port number (default: %d)\n" + " -w, --warning=INTEGER\n" + " Response time to result in warning status (seconds)\n" + " -c, --critical=INTEGER\n" + " Response time to result in critical status (seconds)\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection times out (default: %d)\n" + " -v" + " Show details for command-line debugging (do not use with nagios server)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n", + FTP_EXPECT, FTP_PORT, DEFAULT_SOCKET_TIMEOUT); +} diff --git a/plugins/check_game.c b/plugins/check_game.c new file mode 100644 index 00000000..63d1be62 --- /dev/null +++ b/plugins/check_game.c @@ -0,0 +1,287 @@ +/****************************************************************************** + * + * CHECK_GAME.C + * + * Program: GAME plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ian Cass (ian@knowledge.com) + * + * Last Modified: $Date$ + * + * Mod History + * + * 25-8-99 Ethan Galstad <nagios@nagios.org> + * Integrated with common plugin code, minor cleanup stuff + * + * 17-8-99 version 1.1b + * + * 17-8-99 make port a separate argument so we can use something like + * check_game q2s!27910 with the probe set up as + * check_game $ARG1$ $HOSTADDRESS$ $ARG2$ + * + * 17-8-99 Put in sanity check for ppl who enter the wrong server type + * + * 17-8-99 Release version 1.0b + * + * Command line: CHECK_GAME <server type> <ip_address> [port] + * + * server type = a server type that qstat understands (type qstat & look at the -default line) + * ip_address = either a dotted address or a FQD name + * port = defaults game default port + * + * + * Description: + * + * Needed to explore writing my own probes for nagios. It looked + * pretty simple so I thought I'd write one for monitoring the status + * of game servers. It uses qstat to do the actual monitoring and + * analyses the result. Doing it this way means I can support all the + * servers that qstat does and will do in the future. + * + * + * Dependencies: + * + * This plugin uses the 'qstat' command If you don't + * have the package installed you will need to download it from + * http://www.activesw.com/people/steve/qstat.html or any popular files archive + * before you can use this plugin. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +int process_arguments (int, char **); + +#define QSTAT_DATA_DELIMITER "," + +#define QSTAT_HOST_ERROR "ERROR" +#define QSTAT_HOST_DOWN "DOWN" +#define QSTAT_HOST_TIMEOUT "TIMEOUT" +#define QSTAT_MAX_RETURN_ARGS 12 + +char server_ip[MAX_HOST_ADDRESS_LENGTH]; +char game_type[MAX_INPUT_BUFFER]; +char port[MAX_INPUT_BUFFER]; + +int qstat_game_field = 2; +int qstat_map_field = 3; +int qstat_ping_field = 5; + + +int +main (int argc, char **argv) +{ + char command_line[MAX_INPUT_BUFFER]; + int result; + FILE *fp; + char input_buffer[MAX_INPUT_BUFFER]; + char response[MAX_INPUT_BUFFER]; + char *temp_ptr; + int found; + char *p, *ret[QSTAT_MAX_RETURN_ARGS]; + int i; + + result = process_arguments (argc, argv); + + if (result != OK) { + printf ("Incorrect arguments supplied\n"); + printf ("\n"); + print_revision (argv[0], "$Revision$"); + printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n"); + printf ("License: GPL\n"); + printf ("\n"); + printf + ("Usage: %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field] [-pf ping_field]\n", + argv[0]); + printf ("\n"); + printf ("Options:\n"); + printf + (" <game> = Game type that is recognised by qstat (without the leading dash)\n"); + printf + (" <ip_address> = The IP address of the device you wish to query\n"); + printf (" [port] = Optional port of which to connect\n"); + printf + (" [game_field] = Field number in raw qstat output that contains game name\n"); + printf + (" [map_field] = Field number in raw qstat output that contains map name\n"); + printf + (" [ping_field] = Field number in raw qstat output that contains ping time\n"); + printf ("\n"); + printf ("Notes:\n"); + printf + ("- This plugin uses the 'qstat' command, the popular game server status query tool .\n"); + printf + (" If you don't have the package installed, you will need to download it from\n"); + printf + (" http://www.activesw.com/people/steve/qstat.html before you can use this plugin.\n"); + printf ("\n"); + return STATE_UNKNOWN; + } + + result = STATE_OK; + + /* create the command line to execute */ + snprintf (command_line, sizeof (command_line) - 1, "%s -raw %s -%s %s%s", + PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip, port); + command_line[sizeof (command_line) - 1] = 0; + + /* run the command */ + fp = popen (command_line, "r"); + if (fp == NULL) { + printf ("Error - Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + found = 0; + fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */ + + /* strip the newline character from the end of the input */ + input_buffer[strlen (input_buffer) - 1] = 0; + + /* sanity check */ + /* was thinking about running qstat without any options, capturing the + -default line, parsing it & making an array of all know server types + but thought this would be too much hassle considering this is a tool + for intelligent sysadmins (ha). Could put a static array of known + server types in a header file but then we'd be limiting ourselves + + In the end, I figured I'd simply let an error occur & then trap it + */ + + if (!strncmp (input_buffer, "unknown option", 14)) { + printf ("ERROR: Host type parameter incorrect!\n"); + result = STATE_CRITICAL; + return result; + } + + /* initialize the returned data buffer */ + for (i = 0; i < QSTAT_MAX_RETURN_ARGS; i++) + ret[i] = ""; + + i = 0; + p = (char *) strtok (input_buffer, QSTAT_DATA_DELIMITER); + while (p != NULL) { + ret[i] = p; + p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER); + i++; + if (i >= QSTAT_MAX_RETURN_ARGS) + break; + } + + if (strstr (ret[2], QSTAT_HOST_ERROR)) { + printf ("ERROR: Host not found\n"); + result = STATE_CRITICAL; + } + else if (strstr (ret[2], QSTAT_HOST_DOWN)) { + printf ("ERROR: Game server down or unavailable\n"); + result = STATE_CRITICAL; + } + else if (strstr (ret[2], QSTAT_HOST_TIMEOUT)) { + printf ("ERROR: Game server timeout\n"); + result = STATE_CRITICAL; + } + else { + printf ("OK: %s (%s), Ping: %s ms\n", ret[qstat_game_field], + ret[qstat_map_field], ret[qstat_ping_field]); + } + + /* close the pipe */ + pclose (fp); + + return result; +} + + + +int +process_arguments (int argc, char **argv) +{ + int x; + + /* not enough options were supplied */ + if (argc < 3) + return ERROR; + + /* first option is always the game type */ + strncpy (game_type, argv[1], sizeof (game_type) - 1); + game_type[sizeof (game_type) - 1] = 0; + + /* Second option is always the server name */ + strncpy (server_ip, argv[2], sizeof (server_ip) - 1); + server_ip[sizeof (server_ip) - 1] = 0; + + /* process all remaining arguments */ + for (x = 4; x <= argc; x++) { + + /* we got the port number to connect to */ + if (!strcmp (argv[x - 1], "-p")) { + if (x < argc) { + snprintf (port, sizeof (port) - 2, ":%s", argv[x]); + port[sizeof (port) - 1] = 0; + x++; + } + else + return ERROR; + } + + /* we got the game field */ + else if (!strcmp (argv[x - 1], "-gf")) { + if (x < argc) { + qstat_game_field = atoi (argv[x]); + if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS) + return ERROR; + x++; + } + else + return ERROR; + } + + /* we got the map field */ + else if (!strcmp (argv[x - 1], "-mf")) { + if (x < argc) { + qstat_map_field = atoi (argv[x]); + if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS) + return ERROR; + x++; + } + else + return ERROR; + } + + /* we got the ping field */ + else if (!strcmp (argv[x - 1], "-pf")) { + if (x < argc) { + qstat_ping_field = atoi (argv[x]); + if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS) + return ERROR; + x++; + } + else + return ERROR; + } + + /* else we got something else... */ + else + return ERROR; + } + + return OK; +} diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c new file mode 100644 index 00000000..8234abdf --- /dev/null +++ b/plugins/check_hpjd.c @@ -0,0 +1,571 @@ +/****************************************************************************** +* +* CHECK_HPJD.C +* +* Program: HP printer plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Command line: CHECK_HPJD <ip_address> [community] +* +* Description: +* +* This plugin will attempt to check the status of an HP printer. The +* printer must have a JetDirect card installed and TCP/IP protocol +* stack enabled. This plugin has only been tested on a few printers +* and may not work well on all models of JetDirect cards. Multiple +* port JetDirect devices must have an IP address assigned to each +* port in order to be monitored. +* +* Dependencies: +* +* This plugin used the 'snmpget' command included with the UCD-SNMP +* package. If you don't have the package installed you will need to +* download it from http://ucd-snmp.ucdavis.edu before you can use +* this plugin. +* +* Return Values: +* +* UNKNOWN = The plugin could not read/process the output from the printer +* OK = Printer looks normal +* WARNING = Low toner, paper jam, intervention required, paper out, etc. +* CRITICAL = The printer could not be reached (it's probably turned off) +* +* Acknowledgements: +* +* The idea for the plugin (as well as some code) were taken from Jim +* Trocki's pinter alert script in his "mon" utility, found at +* http://www.kernel.org/software/mon +* +* Notes: +* 'JetDirect' is copyrighted by Hewlett-Packard. +* HP, please don't sue me... :-) +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_hpjd" + +#define HPJD_LINE_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.1" +#define HPJD_PAPER_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.2" +#define HPJD_INTERVENTION_REQUIRED ".1.3.6.1.4.1.11.2.3.9.1.1.2.3" +#define HPJD_GD_PERIPHERAL_ERROR ".1.3.6.1.4.1.11.2.3.9.1.1.2.6" +#define HPJD_GD_PAPER_JAM ".1.3.6.1.4.1.11.2.3.9.1.1.2.8" +#define HPJD_GD_PAPER_OUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.9" +#define HPJD_GD_TONER_LOW ".1.3.6.1.4.1.11.2.3.9.1.1.2.10" +#define HPJD_GD_PAGE_PUNT ".1.3.6.1.4.1.11.2.3.9.1.1.2.11" +#define HPJD_GD_MEMORY_OUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.12" +#define HPJD_GD_DOOR_OPEN ".1.3.6.1.4.1.11.2.3.9.1.1.2.17" +#define HPJD_GD_PAPER_OUTPUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.19" +#define HPJD_GD_STATUS_DISPLAY ".1.3.6.1.4.1.11.2.3.9.1.1.3" + +#define ONLINE 0 +#define OFFLINE 1 + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (void); +void print_usage (void); + +char *community = NULL; +char *address = NULL; + +int +main (int argc, char **argv) +{ + char command_line[1024]; + int result; + int line; + char input_buffer[MAX_INPUT_BUFFER]; + char query_string[512]; + char error_message[MAX_INPUT_BUFFER]; + char *temp_buffer; + int line_status = ONLINE; + int paper_status = 0; + int intervention_required = 0; + int peripheral_error = 0; + int paper_jam = 0; + int paper_out = 0; + int toner_low = 0; + int page_punt = 0; + int memory_out = 0; + int door_open = 0; + int paper_output = 0; + char display_message[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* removed ' 2>1' at end of command 10/27/1999 - EG */ + /* create the query string */ + sprintf + (query_string, + "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", + HPJD_LINE_STATUS, + HPJD_PAPER_STATUS, + HPJD_INTERVENTION_REQUIRED, + HPJD_GD_PERIPHERAL_ERROR, + HPJD_GD_PAPER_JAM, + HPJD_GD_PAPER_OUT, + HPJD_GD_TONER_LOW, + HPJD_GD_PAGE_PUNT, + HPJD_GD_MEMORY_OUT, + HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); + + /* get the command to run */ + sprintf (command_line, "%s -v 1 %s %s %s", PATH_TO_SNMPGET, address, + community, query_string); + + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + result = STATE_OK; + + line = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + /* strip the newline character from the end of the input */ + if (input_buffer[strlen (input_buffer) - 1] == '\n') + input_buffer[strlen (input_buffer) - 1] = 0; + + line++; + + temp_buffer = strtok (input_buffer, "="); + temp_buffer = strtok (NULL, "="); + + switch (line) { + + case 1: /* 1st line should contain the line status */ + if (temp_buffer != NULL) + line_status = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 2: /* 2nd line should contain the paper status */ + if (temp_buffer != NULL) + paper_status = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 3: /* 3rd line should be intervention required */ + if (temp_buffer != NULL) + intervention_required = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 4: /* 4th line should be peripheral error */ + if (temp_buffer != NULL) + peripheral_error = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 5: /* 5th line should contain the paper jam status */ + if (temp_buffer != NULL) + paper_jam = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 6: /* 6th line should contain the paper out status */ + if (temp_buffer != NULL) + paper_out = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 7: /* 7th line should contain the toner low status */ + if (temp_buffer != NULL) + toner_low = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 8: /* did data come too slow for engine */ + if (temp_buffer != NULL) + page_punt = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 9: /* did we run out of memory */ + if (temp_buffer != NULL) + memory_out = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 10: /* is there a door open */ + if (temp_buffer != NULL) + door_open = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 11: /* is output tray full */ + if (temp_buffer != NULL) + paper_output = atoi (temp_buffer); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + case 12: /* display panel message */ + if (temp_buffer != NULL) + strcpy (display_message, temp_buffer + 1); + else { + result = STATE_UNKNOWN; + strcpy (error_message, input_buffer); + } + break; + + default: + break; + } + + /* break out of the read loop if we encounter an error */ + if (result != STATE_OK) + break; + } + + /* WARNING if output found on stderr */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + /* if there wasn't any output, display an error */ + if (line == 0) { + + /* + result=STATE_UNKNOWN; + strcpy(error_message,"Error: Could not read plugin output\n"); + */ + + /* might not be the problem, but most likely is.. */ + result = STATE_UNKNOWN; + sprintf (error_message, "Timeout: No response from %s\n", address); + } + + /* if we had no read errors, check the printer status results... */ + if (result == STATE_OK) { + + if (paper_jam) { + result = STATE_WARNING; + strcpy (error_message, "Paper Jam"); + } + else if (paper_out) { + result = STATE_WARNING; + strcpy (error_message, "Out of Paper"); + } + else if (line_status == OFFLINE) { + if (strcmp (error_message, "POWERSAVE ON") != 0) { + result = STATE_WARNING; + strcpy (error_message, "Printer Offline"); + } + } + else if (peripheral_error) { + result = STATE_WARNING; + strcpy (error_message, "Peripheral Error"); + } + else if (intervention_required) { + result = STATE_WARNING; + strcpy (error_message, "Intervention Required"); + } + else if (toner_low) { + result = STATE_WARNING; + strcpy (error_message, "Toner Low"); + } + else if (memory_out) { + result = STATE_WARNING; + strcpy (error_message, "Insufficient Memory"); + } + else if (door_open) { + result = STATE_WARNING; + strcpy (error_message, "A Door is Open"); + } + else if (paper_output) { + result = STATE_WARNING; + strcpy (error_message, "Output Tray is Full"); + } + else if (page_punt) { + result = STATE_WARNING; + strcpy (error_message, "Data too Slow for Engine"); + } + else if (paper_status) { + result = STATE_WARNING; + strcpy (error_message, "Unknown Paper Error"); + } + } + + if (result == STATE_OK) + printf ("Printer ok - (%s)\n", display_message); + + else if (result == STATE_UNKNOWN) { + + printf ("%s\n", error_message); + + /* if printer could not be reached, escalate to critical */ + if (strstr (error_message, "Timeout")) + result = STATE_CRITICAL; + } + + else if (result == STATE_WARNING) + printf ("%s (%s)\n", error_message, display_message); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (address == NULL) { + if (is_host (argv[c])) { + address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + else if (community == NULL) { + community = argv[c]; + } + } + + if (address == NULL) + address = strscpy (NULL, "127.0.0.1"); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, +/* {"critical", required_argument,0,'c'}, */ +/* {"warning", required_argument,0,'w'}, */ +/* {"port", required_argument,0,'P'}, */ + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVH:C:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVH:C:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'C': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'C': /* community */ + community = optarg; + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin tests the STATUS of an HP printer with a JetDirect card.\n" + "Ucd-snmp must be installed on the computer running the plugin.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -C, --community=STRING\n" + " The SNMP community name\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n"); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-C community]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} + + +/* + if(argc<2||argc>3){ + printf("Incorrect number of arguments supplied\n"); + printf("\n"); + print_revision(argv[0],"$Revision$"); + printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"); + printf("License: GPL\n"); + printf("\n"); + printf("Usage: %s <ip_address> [community]\n",argv[0]); + printf("\n"); + printf("Note:\n"); + printf(" <ip_address> = The IP address of the JetDirect card\n"); + printf(" [community] = An optional community string used for SNMP communication\n"); + printf(" with the JetDirect card. The default is 'public'.\n"); + printf("\n"); + return STATE_UNKNOWN; + } + + // get the IP address of the JetDirect device + strcpy(address,argv[1]); + + // get the community name to use for SNMP communication + if(argc>=3) + strcpy(community,argv[2]); + else + strcpy(community,"public"); +*/ diff --git a/plugins/check_http.c b/plugins/check_http.c new file mode 100644 index 00000000..db5d50dd --- /dev/null +++ b/plugins/check_http.c @@ -0,0 +1,1067 @@ +/**************************************************************************** + * + * Program: HTTP plugin for Nagios + * License: GPL + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_http" +#define REVISION "$Revision$" +#define COPYRIGHT "1999-2001" +#define AUTHORS "Ethan Galstad/Karl DeBisschop" +#define EMAIL "kdebisschop@users.sourceforge.net" + +#include "config.h" +#include "common.h" +#include "version.h" +#include "netutils.h" +#include "utils.h" + +#define SUMMARY "\ +This plugin tests the HTTP service on the specified host. It can test\n\ +normal (http) and secure (https) servers, follow redirects, search for\n\ +strings and regular expressions, check connection times, and report on\n\ +certificate expiration times.\n" + +#define OPTIONS "\ +\(-H <vhost> | -I <IP-address>) [-u <uri>] [-p <port>]\n\ + [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L]\n\ + [-a auth] [-f <ok | warn | critcal | follow>] [-e <expect>]\n\ + [-s string] [-r <regex> | -R <case-insensitive regex>]\n\ + [-P string]" + +#define LONGOPTIONS "\ + -H, --hostname=ADDRESS\n\ + Host name argument for servers using host headers (virtual host)\n\ + -I, --IP-address=ADDRESS\n\ + IP address or name (use numeric address if possible to bypass DNS lookup).\n\ + -e, --expect=STRING\n\ + String to expect in first line of server response (default: %s)\n\ + -s, --string=STRING\n\ + String to expect in the content\n\ + -u, --url=PATH\n\ + URL to GET or POST (default: /)\n\ + -p, --port=INTEGER\n\ + Port number (default: %d)\n\ + -P, --post=STRING\n\ + URL encoded http POST data\n\ + -w, --warning=INTEGER\n\ + Response time to result in warning status (seconds)\n\ + -c, --critical=INTEGER\n\ + Response time to result in critical status (seconds)\n\ + -t, --timeout=INTEGER\n\ + Seconds before connection times out (default: %d)\n\ + -a, --authorization=AUTH_PAIR\n\ + Username:password on sites with basic authentication\n\ + -L, --link=URL\n\ + Wrap output in HTML link (obsoleted by urlize)\n\ + -f, --onredirect=<ok|warning|critical|follow>\n\ + How to handle redirected pages\n%s\ + -v, --verbose\n\ + Show details for command-line debugging (do not use with nagios server)\n\ + -h, --help\n\ + Print detailed help screen\n\ + -V, --version\n\ + Print version information\n" + +#ifdef HAVE_SSL +#define SSLOPTIONS "\ + -S, --ssl\n\ + Connect via SSL\n\ + -C, --certificate=INTEGER\n\ + Minimum number of days a certificate has to be valid.\n\ + (when this option is used the url is not checked.)\n" +#else +#define SSLOPTIONS "" +#endif + +#define DESCRIPTION "\ +This plugin will attempt to open an HTTP connection with the host. Successul\n\ +connects return STATE_OK, refusals and timeouts return STATE_CRITICAL, other\n\ +errors return STATE_UNKNOWN. Successful connects, but incorrect reponse\n\ +messages from the host result in STATE_WARNING return values. If you are\n\ +checking a virtual server that uses \"host headers\" you must supply the FQDN\n\ +\(fully qualified domain name) as the [host_name] argument.\n" + +#define SSLDESCRIPTION "\ +This plugin can also check whether an SSL enabled web server is able to\n\ +serve content (optionally within a specified time) or whether the X509 \n\ +certificate is still valid for the specified number of days.\n\n\ +CHECK CONTENT: check_http -w 5 -c 10 --ssl www.verisign.com\n\n\ +When the 'www.verisign.com' server returns its content within 5 seconds, a\n\ +STATE_OK will be returned. When the server returns its content but exceeds\n\ +the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,\n\ +a STATE_CRITICAL will be returned.\n\n\ +CHECK CERTIFICATE: check_http www.verisign.com -C 14\n\n\ +When the certificate of 'www.verisign.com' is valid for more than 14 days, a\n\ +STATE_OK is returned. When the certificate is still valid, but for less than\n\ +14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when\n\ +the certificate is expired.\n" + +#ifdef HAVE_SSL_H +#include <rsa.h> +#include <crypto.h> +#include <x509.h> +#include <pem.h> +#include <ssl.h> +#include <err.h> +#include <rand.h> +#endif + +#ifdef HAVE_OPENSSL_SSL_H +#include <openssl/rsa.h> +#include <openssl/crypto.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#endif + +#ifdef HAVE_SSL +int check_cert = FALSE; +int days_till_exp; +unsigned char *randbuff; +SSL_CTX *ctx; +SSL *ssl; +X509 *server_cert; +int connect_SSL (void); +int check_certificate (X509 **); +#endif + +#ifdef HAVE_REGEX_H +#define REGS 2 +#define MAX_RE_SIZE 256 +#include <regex.h> +regex_t preg; +regmatch_t pmatch[REGS]; +char regexp[MAX_RE_SIZE]; +char errbuf[MAX_INPUT_BUFFER]; +int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; +int errcode; +#endif + +#define server_type_check(server_type) \ +(strcmp (server_type, "https") ? FALSE : TRUE) + +#define server_port_check(use_ssl) (use_ssl ? HTTPS_PORT : HTTP_PORT) + +#define MAX_IPV4_HOSTLENGTH 64 +#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: " +#define URI_HTTP "%[HTPShtps]://" +#define URI_HOST "%[a-zA-Z0-9.-]" +#define URI_PORT ":%[0-9]" +#define URI_PATH "%[/a-zA-Z0-9._-=@,]" + +#define HTTP_PORT 80 +#define HTTPS_PORT 443 +#define HTTP_EXPECT "HTTP/1." +#define HTTP_URL "/" + +time_t start_time, end_time; +char timestamp[10] = ""; +int specify_port = FALSE; +int server_port = HTTP_PORT; +char server_port_text[6] = ""; +char server_type[6] = "http"; +char *server_address = NULL; +char *host_name = NULL; +char *server_url = NULL; +int server_url_length = 0; +char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; +char string_expect[MAX_INPUT_BUFFER] = ""; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +char user_auth[MAX_INPUT_BUFFER] = ""; +int display_html = FALSE; +int onredirect = STATE_OK; +int use_ssl = FALSE; +int verbose = FALSE; +int sd; +char *http_method = NULL; +char *http_post_data = NULL; +char buffer[MAX_INPUT_BUFFER]; + +void print_usage (void); +void print_help (void); +int process_arguments (int, char **); +int call_getopt (int, char **); +static char *base64 (char *bin, int len); +int check_http (void); +int my_recv (void); +int my_close (void); + +int +main (int argc, char **argv) +{ + int result = STATE_UNKNOWN; + + if (process_arguments (argc, argv) == ERROR) + usage ("check_http: could not parse arguments\n"); + + if (strstr (timestamp, ":")) { + if (strstr (server_url, "?")) + sprintf (server_url, "%s&%s", server_url, timestamp); + else + sprintf (server_url, "%s?%s", server_url, timestamp); + } + + if (display_html == TRUE) + printf ("<A HREF=\"http://%s:%d%s\" target=\"_blank\">", + host_name, server_port, server_url); + + /* initialize alarm signal handling, set socket timeout, start timer */ + signal (SIGALRM, socket_timeout_alarm_handler); + alarm (socket_timeout); + time (&start_time); + +#ifdef HAVE_SSL + if (use_ssl && check_cert == TRUE) { + if (connect_SSL () != OK) + terminate (STATE_CRITICAL, + "HTTP CRITICAL - Could not make SSL connection\n"); + if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { + result = check_certificate (&server_cert); + X509_free (server_cert); + } + else { + printf ("ERROR: Cannot retrieve server certificate.\n"); + result = STATE_CRITICAL; + } + SSL_shutdown (ssl); + SSL_free (ssl); + SSL_CTX_free (ctx); + close (sd); + } + else { + result = check_http (); + } +#else + result = check_http (); +#endif + return result; +} + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c, i = 1; + char optchars[MAX_INPUT_BUFFER]; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + STD_OPTS_LONG, + {"link", no_argument, 0, 'L'}, + {"nohtml", no_argument, 0, 'n'}, + {"ssl", no_argument, 0, 'S'}, + {"verbose", no_argument, 0, 'v'}, + {"post", required_argument, 0, 'P'}, + {"IP-address", required_argument, 0, 'I'}, + {"string", required_argument, 0, 's'}, + {"regex", required_argument, 0, 'r'}, + {"ereg", required_argument, 0, 'r'}, + {"eregi", required_argument, 0, 'R'}, + {"onredirect", required_argument, 0, 'f'}, + {"certificate", required_argument, 0, 'C'}, + {0, 0, 0, 0} + }; +#endif + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + if (strcmp ("-hn", argv[c]) == 0) + strcpy (argv[c], "-H"); + if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + if (strcmp ("-nohtml", argv[c]) == 0) + strcpy (argv[c], "-n"); + } + + snprintf (optchars, MAX_INPUT_BUFFER, "%s%s", STD_OPTS, + "P:I:a:e:p:s:R:r:u:f:C:nLS"); + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, optchars, long_options, &option_index); +#else + c = getopt (argc, argv, optchars); +#endif + if (c == -1 || c == EOF) + break; + + switch (c) { + case '?': /* usage */ + usage2 ("unknown argument", optarg); + break; + case 'h': /* help */ + print_help (); + exit (STATE_OK); + break; + case 'V': /* version */ + print_revision (PROGNAME, REVISION); + exit (STATE_OK); + break; + case 't': /* timeout period */ + if (!is_intnonneg (optarg)) + usage2 ("timeout interval must be a non-negative integer", optarg); + socket_timeout = atoi (optarg); + break; + case 'c': /* critical time threshold */ + if (!is_intnonneg (optarg)) + usage2 ("invalid critical threshold", optarg); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'w': /* warning time threshold */ + if (!is_intnonneg (optarg)) + usage2 ("invalid warning threshold", optarg); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 'L': /* show html link */ + display_html = TRUE; + break; + case 'n': /* do not show html link */ + display_html = FALSE; + break; + case 'S': /* use SSL */ +#ifndef HAVE_SSL + usage ("check_http: invalid option - SSL is not available\n"); +#endif + use_ssl = TRUE; + if (specify_port == FALSE) + server_port = HTTPS_PORT; + break; + case 'C': /* warning time threshold */ +#ifdef HAVE_SSL + if (!is_intnonneg (optarg)) + usage2 ("invalid certificate expiration period", optarg); + days_till_exp = atoi (optarg); + check_cert = TRUE; +#else + usage ("check_http: invalid option - SSL is not available\n"); +#endif + break; + case 'f': /* onredirect */ + if (!strcmp (optarg, "follow")) + onredirect = STATE_DEPENDENT; + if (!strcmp (optarg, "unknown")) + onredirect = STATE_UNKNOWN; + if (!strcmp (optarg, "ok")) + onredirect = STATE_OK; + if (!strcmp (optarg, "warning")) + onredirect = STATE_WARNING; + if (!strcmp (optarg, "critical")) + onredirect = STATE_CRITICAL; + break; + /* Note: H, I, and u must be malloc'd or will fail on redirects */ + case 'H': /* Host Name (virtual host) */ + host_name = strscpy (host_name, optarg); + break; + case 'I': /* Server IP-address */ + server_address = strscpy (server_address, optarg); + break; + case 'u': /* Host or server */ + server_url = strscpy (server_url, optarg); + server_url_length = strlen (optarg); + break; + case 'p': /* Host or server */ + if (!is_intnonneg (optarg)) + usage2 ("invalid port number", optarg); + server_port = atoi (optarg); + specify_port = TRUE; + break; + case 'a': /* authorization info */ + strncpy (user_auth, optarg, MAX_INPUT_BUFFER - 1); + user_auth[MAX_INPUT_BUFFER - 1] = 0; + break; + case 'P': /* HTTP POST data in URL encoded format */ + http_method = strscpy (http_method, "POST"); + http_post_data = strscpy (http_post_data, optarg); + break; + case 's': /* string or substring */ + strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); + string_expect[MAX_INPUT_BUFFER - 1] = 0; + break; + case 'e': /* string or substring */ + strncpy (server_expect, optarg, MAX_INPUT_BUFFER - 1); + server_expect[MAX_INPUT_BUFFER - 1] = 0; + break; + case 'R': /* regex */ +#ifdef HAVE_REGEX_H + cflags = REG_ICASE; +#else + usage ("check_http: call for regex which was not a compiled option\n"); +#endif + case 'r': /* regex */ +#ifdef HAVE_REGEX_H + cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; + strncpy (regexp, optarg, MAX_INPUT_BUFFER - 1); + regexp[MAX_INPUT_BUFFER - 1] = 0; + errcode = regcomp (&preg, regexp, cflags); + if (errcode != 0) { + regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf ("Could Not Compile Regular Expression: %s", errbuf); + return ERROR; + } +#else + usage ("check_http: call for regex which was not a compiled option\n"); +#endif + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + } + } + + c = optind; + + if (server_address == NULL && host_name == NULL) { + server_address = strscpy (NULL, argv[c]); + host_name = strscpy (NULL, argv[c++]); + } + + if (server_address == NULL && host_name == NULL) + usage ("check_http: you must specify a host name\n"); + + if (server_address == NULL) + server_address = strscpy (NULL, host_name); + + if (host_name == NULL) + host_name = strscpy (NULL, server_address); + + if (http_method == NULL) + http_method = strscpy (http_method, "GET"); + + if (server_url == NULL) { + server_url = strscpy (NULL, "/"); + server_url_length = strlen(HTTP_URL); + } + + return TRUE; +} + + + +/* written by lauri alanko */ +static char * +base64 (char *bin, int len) +{ + + char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1); + int i = 0, j = 0; + + char BASE64_END = '='; + char base64_table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + while (j < len - 2) { + buf[i++] = base64_table[bin[j] >> 2]; + buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)]; + buf[i++] = base64_table[((bin[j + 1] & 15) << 2) | (bin[j + 2] >> 6)]; + buf[i++] = base64_table[bin[j + 2] & 63]; + j += 3; + } + + switch (len - j) { + case 1: + buf[i++] = base64_table[bin[j] >> 2]; + buf[i++] = base64_table[(bin[j] & 3) << 4]; + buf[i++] = BASE64_END; + buf[i++] = BASE64_END; + break; + case 2: + buf[i++] = base64_table[bin[j] >> 2]; + buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)]; + buf[i++] = base64_table[(bin[j + 1] & 15) << 2]; + buf[i++] = BASE64_END; + break; + case 0: + break; + } + + buf[i] = '\0'; + return buf; +} + + + +int +check_http (void) +{ + char *msg = NULL; + char *status_line = NULL; + char *header = NULL; + char *page = NULL; + char *auth = NULL; + int i = 0; + size_t pagesize = 0; + char *full_page = NULL; + char *pos = NULL; + + /* try to connect to the host at the given port number */ +#ifdef HAVE_SSL + if (use_ssl == TRUE) { + + if (connect_SSL () != OK) { + msg = ssprintf (msg, "Unable to open TCP socket"); + terminate (STATE_CRITICAL, msg); + } + + if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { + X509_free (server_cert); + } + else { + printf ("ERROR: Cannot retrieve server certificate.\n"); + return STATE_CRITICAL; + } + + sprintf (buffer, "%s %s HTTP/1.0\r\n", http_method, server_url); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + + /* optionally send the host header info (not clear if it's usable) */ + if (strcmp (host_name, "")) { + sprintf (buffer, "Host: %s\r\n", host_name); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + } + + /* send user agent */ + sprintf (buffer, "User-Agent: check_http/%s (nagios-plugins %s)\r\n", + clean_revstring (REVISION), PACKAGE_VERSION); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + + /* optionally send the authentication info */ + if (strcmp (user_auth, "")) { + auth = base64 (user_auth, strlen (user_auth)); + sprintf (buffer, "Authorization: Basic %s\r\n", auth); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + } + + /* optionally send http POST data */ + if (http_post_data) { + sprintf (buffer, "Content-Type: application/x-www-form-urlencoded\r\n"); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + sprintf (buffer, "Content-Length: %i\r\n\r\n", strlen (http_post_data)); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + http_post_data = strscat (http_post_data, "\r\n"); + if (SSL_write (ssl, http_post_data, strlen (http_post_data)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + } + + /* send a newline so the server knows we're done with the request */ + sprintf (buffer, "\r\n\r\n"); + if (SSL_write (ssl, buffer, strlen (buffer)) == -1) { + ERR_print_errors_fp (stderr); + return STATE_CRITICAL; + } + + } + else { +#endif + if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) { + msg = ssprintf (msg, "Unable to open TCP socket"); + terminate (STATE_CRITICAL, msg); + } + sprintf (buffer, "%s %s HTTP/1.0\r\n", http_method, server_url); + send (sd, buffer, strlen (buffer), 0); + + /* optionally send the host header info */ + if (strcmp (host_name, "")) { + sprintf (buffer, "Host: %s\r\n", host_name); + send (sd, buffer, strlen (buffer), 0); + } + + /* send user agent */ + sprintf (buffer, + "User-Agent: check_http/%s (nagios-plugins %s)\r\n", + clean_revstring (REVISION), PACKAGE_VERSION); + send (sd, buffer, strlen (buffer), 0); + + /* optionally send the authentication info */ + if (strcmp (user_auth, "")) { + auth = base64 (user_auth, strlen (user_auth)); + sprintf (buffer, "Authorization: Basic %s\r\n", auth); + send (sd, buffer, strlen (buffer), 0); + } + + /* optionally send http POST data */ + /* written by Chris Henesy <lurker@shadowtech.org> */ + if (http_post_data) { + sprintf (buffer, "Content-Type: application/x-www-form-urlencoded\r\n"); + send (sd, buffer, strlen (buffer), 0); + sprintf (buffer, "Content-Length: %i\r\n\r\n", strlen (http_post_data)); + send (sd, buffer, strlen (buffer), 0); + http_post_data = strscat (http_post_data, "\r\n"); + send (sd, http_post_data, strlen (http_post_data), 0); + } + + /* send a newline so the server knows we're done with the request */ + sprintf (buffer, "\r\n\r\n"); + send (sd, buffer, strlen (buffer), 0); +#ifdef HAVE_SSL + } +#endif + + /* fetch the page */ + pagesize = (size_t) 0; + while ((i = my_recv ()) > 0) { + full_page = strscat (full_page, buffer); + pagesize += i; + } + + if (i < 0) + terminate (STATE_CRITICAL, "Error in recv()"); + + /* return a CRITICAL status if we couldn't read any data */ + if (pagesize == (size_t) 0) + terminate (STATE_CRITICAL, "No data received %s", timestamp); + + /* close the connection */ + my_close (); + + /* reset the alarm */ + alarm (0); + + /* leave full_page untouched so we can free it later */ + page = full_page; + + if (verbose) + printf ("Page is %d characters\n", pagesize); + + /* find status line and null-terminate it */ + status_line = page; + page += (size_t) strcspn (page, "\r\n"); + pos = page; + page += (size_t) strspn (page, "\r\n"); + status_line[pos - status_line] = 0; + strip (status_line); + if (verbose) + printf ("STATUS: %s\n", status_line); + + /* find header info and null terminate it */ + header = page; + while (strcspn (page, "\r\n") > 0) { + page += (size_t) strcspn (page, "\r\n"); + pos = page; + if ((strspn (page, "\r") == 1 && strspn (page, "\r\n") >= 2) || + (strspn (page, "\n") == 1 && strspn (page, "\r\n") >= 2)) + page += (size_t) 2; + else + page += (size_t) 1; + } + page += (size_t) strspn (page, "\r\n"); + header[pos - header] = 0; + if (verbose) + printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, page); + + /* make sure the status line matches the response we are looking for */ + if (!strstr (status_line, server_expect)) { + if (server_port == HTTP_PORT) + msg = ssprintf (msg, "Invalid HTTP response received from host\n"); + else + msg = ssprintf (msg, + "Invalid HTTP response received from host on port %d\n", + server_port); + terminate (STATE_CRITICAL, msg); + } + + /* check the return code */ + /* server errors result in a critical state */ + if (strstr (status_line, "500") || + strstr (status_line, "501") || + strstr (status_line, "502") || + strstr (status_line, "503")) { + msg = ssprintf (msg, "HTTP CRITICAL: %s\n", status_line); + terminate (STATE_CRITICAL, msg); + } + + /* client errors result in a warning state */ + if (strstr (status_line, "400") || + strstr (status_line, "401") || + strstr (status_line, "402") || + strstr (status_line, "403") || + strstr (status_line, "404")) { + msg = ssprintf (msg, "HTTP WARNING: %s\n", status_line); + terminate (STATE_WARNING, msg); + } + + /* check redirected page if specified */ + if (strstr (status_line, "300") || + strstr (status_line, "301") || + strstr (status_line, "302") || + strstr (status_line, "303") || + strstr (status_line, "304")) { + if (onredirect == STATE_DEPENDENT) { + + pos = header; + while (pos) { + server_address = realloc (server_address, MAX_IPV4_HOSTLENGTH); + if (server_address == NULL) + terminate (STATE_UNKNOWN, + "HTTP UNKNOWN: could not allocate server_address"); + if (strspn (pos, "\r\n") > server_url_length) { + server_url = realloc (server_url, strspn (pos, "\r\n")); + if (server_url == NULL) + terminate (STATE_UNKNOWN, + "HTTP UNKNOWN: could not allocate server_url"); + server_url_length = strspn (pos, "\r\n"); + } + if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PORT URI_PATH, server_type, server_address, server_port_text, server_url) == 4) { + host_name = strscpy (host_name, server_address); + use_ssl = server_type_check (server_type); + server_port = atoi (server_port_text); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PATH, server_type, server_address, server_url) == 3) { + host_name = strscpy (host_name, server_address); + use_ssl = server_type_check (server_type); + server_port = server_port_check (use_ssl); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PORT, server_type, server_address, server_port_text) == 3) { + host_name = strscpy (host_name, server_address); + strcpy (server_url, "/"); + use_ssl = server_type_check (server_type); + server_port = atoi (server_port_text); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST, server_type, server_address) == 2) { + host_name = strscpy (host_name, server_address); + strcpy (server_url, "/"); + use_ssl = server_type_check (server_type); + server_port = server_port_check (use_ssl); + check_http (); + } + else if (sscanf (pos, HDR_LOCATION URI_PATH, server_url) == 1) { + check_http (); + } + pos += (size_t) strcspn (pos, "\r\n"); + pos += (size_t) strspn (pos, "\r\n"); + } /* end while (pos) */ + printf ("HTTP UNKNOWN: Could not find redirect location - %s%s", + status_line, (display_html ? "</A>" : "")); + exit (STATE_UNKNOWN); + } /* end if (onredirect == STATE_DEPENDENT) */ + else if (onredirect == STATE_UNKNOWN) + printf ("HTTP UNKNOWN"); + else if (onredirect == STATE_OK) + printf ("HTTP ok"); + else if (onredirect == STATE_WARNING) + printf ("HTTP WARNING"); + else if (onredirect == STATE_CRITICAL) + printf ("HTTP CRITICAL"); + time (&end_time); + msg = ssprintf (msg, ": %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "</A>" : "")); + terminate (onredirect, msg); + } /* end if (strstr (status_line, "30[0-4]") */ + + /* check elapsed time */ + time (&end_time); + msg = ssprintf (msg, "HTTP problem: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "</A>" : "")); + if (check_critical_time == TRUE && (end_time - start_time) > critical_time) + terminate (STATE_CRITICAL, msg); + if (check_warning_time == TRUE && (end_time - start_time) > warning_time) + terminate (STATE_WARNING, msg); + + /* Page and Header content checks go here */ + /* these checks should be last */ + + if (strlen (string_expect)) { + if (strstr (page, string_expect)) { + printf ("HTTP ok: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "</A>" : "")); + exit (STATE_OK); + } + else { + printf ("HTTP CRITICAL: string not found%s\n", + (display_html ? "</A>" : "")); + exit (STATE_CRITICAL); + } + } +#ifdef HAVE_REGEX_H + if (strlen (regexp)) { + errcode = regexec (&preg, page, REGS, pmatch, 0); + if (errcode == 0) { + printf ("HTTP ok: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "</A>" : "")); + exit (STATE_OK); + } + else { + if (errcode == REG_NOMATCH) { + printf ("HTTP CRITICAL: pattern not found%s\n", + (display_html ? "</A>" : "")); + exit (STATE_CRITICAL); + } + else { + regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf ("Execute Error: %s\n", errbuf); + exit (STATE_CRITICAL); + } + } + } +#endif + + /* We only get here if all tests have been passed */ + msg = ssprintf (msg, "HTTP ok: %s - %d second response time %s%s\n", + status_line, (int) (end_time - start_time), + timestamp, (display_html ? "</A>" : "")); + terminate (STATE_OK, msg); + return STATE_UNKNOWN; +} + + + +#ifdef HAVE_SSL +int +connect_SSL (void) +{ + SSL_METHOD *meth; + + randbuff = strscpy (NULL, "qwertyuiopasdfghjkl"); + RAND_seed (randbuff, strlen (randbuff)); + /* Initialize SSL context */ + SSLeay_add_ssl_algorithms (); + meth = SSLv23_client_method (); + SSL_load_error_strings (); + if ((ctx = SSL_CTX_new (meth)) == NULL) { + printf ("ERROR: Cannot create SSL context.\n"); + return STATE_CRITICAL; + } + + /* Initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* Set socket timeout */ + alarm (socket_timeout); + + /* Save start time */ + time (&start_time); + + /* Make TCP connection */ + if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK) { + /* Do the SSL handshake */ + if ((ssl = SSL_new (ctx)) != NULL) { + SSL_set_cipher_list(ssl, "ALL"); + SSL_set_fd (ssl, sd); + if (SSL_connect (ssl) != -1) + return OK; + ERR_print_errors_fp (stderr); + } + else { + printf ("ERROR: Cannot initiate SSL handshake.\n"); + } + SSL_free (ssl); + } + + SSL_CTX_free (ctx); + close (sd); + + return STATE_CRITICAL; +} +#endif + +#ifdef HAVE_SSL +int +check_certificate (X509 ** certificate) +{ + ASN1_STRING *tm; + int offset; + struct tm stamp; + int days_left; + /* int result = STATE_OK; */ + /* char timestamp[14]; */ + + + /* Retrieve timestamp of certificate */ + tm = X509_get_notAfter (*certificate); + + /* Generate tm structure to process timestamp */ + if (tm->type == V_ASN1_UTCTIME) { + if (tm->length < 10) { + printf ("ERROR: Wrong time format in certificate.\n"); + return STATE_CRITICAL; + } + else { + stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); + if (stamp.tm_year < 50) + stamp.tm_year += 100; + offset = 0; + } + } + else { + if (tm->length < 12) { + printf ("ERROR: Wrong time format in certificate.\n"); + return STATE_CRITICAL; + } + else { + stamp.tm_year = + (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); + stamp.tm_year -= 1900; + offset = 2; + } + } + stamp.tm_mon = + (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; + stamp.tm_mday = + (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); + stamp.tm_hour = + (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0'); + stamp.tm_min = + (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0'); + stamp.tm_sec = 0; + stamp.tm_isdst = -1; + + days_left = (mktime (&stamp) - time (NULL)) / 86400; + sprintf + (timestamp, "%02d/%02d/%04d %02d:%02d", + stamp.tm_mon + 1, + stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min); + + if (days_left > 0 && days_left <= days_till_exp) { + printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp); + return STATE_WARNING; + } + if (days_left < 0) { + printf ("Certificate expired on %s.\n", timestamp); + return STATE_CRITICAL; + } + + if (days_left == 0) { + printf ("Certificate expires today (%s).\n", timestamp); + return STATE_WARNING; + } + + printf ("Certificate will expire on %s.\n", timestamp); + + return STATE_OK; +} +#endif + + + +int +my_recv (void) +{ + int i; +#ifdef HAVE_SSL + if (use_ssl) { + i = SSL_read (ssl, buffer, MAX_INPUT_BUFFER - 1); + } + else { + i = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + } +#else + i = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); +#endif + return i; +} + + +int +my_close (void) +{ +#ifdef HAVE_SSL + if (use_ssl == TRUE) { + SSL_shutdown (ssl); + SSL_free (ssl); + SSL_CTX_free (ctx); + return 0; + } + else { +#endif + return close (sd); +#ifdef HAVE_SSL + } +#endif +} + + + +void +print_help (void) +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) %s %s <%s>\n\n%s\n", + COPYRIGHT, AUTHORS, EMAIL, SUMMARY); + print_usage (); + printf ("NOTE: One or both of -H and -I must be specified\n"); + printf ("\nOptions:\n" LONGOPTIONS "\n", HTTP_EXPECT, HTTP_PORT, + DEFAULT_SOCKET_TIMEOUT, SSLOPTIONS); +#ifdef HAVE_SSL + printf (SSLDESCRIPTION); +#endif +} + + +void +print_usage (void) +{ + printf ("Usage:\n" " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} diff --git a/plugins/check_ide-smart.c b/plugins/check_ide-smart.c new file mode 100644 index 00000000..869f7dc0 --- /dev/null +++ b/plugins/check_ide-smart.c @@ -0,0 +1,448 @@ +/* + * check_ide-smart v.1 - hacked version of ide-smart for Nagios + * Copyright (C) 2000 Robert Dale <rdale@digital-mission.com> + * + * Net Saint - http://www.nagios.org + * + * Notes: + * ide-smart has the same functionality as before. Some return + * values were changed, otherwise the --net-saint option was added. + * + * Run with: check_ide-smart --net-saint [-d] <DRIVE> + * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc + * + * - Returns 0 on no errors + * - Returns 1 on advisories + * - Returns 2 on prefailure + * - Returns -1 not too often + * + * ide-smart 1.3 - IDE S.M.A.R.T. cheking tool + * Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org> + * 1998 Gadi Oxman <gadio@netvision.net.il> + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <linux/hdreg.h> +#include <linux/types.h> +#include <getopt.h> +#include <errno.h> + +#define NR_ATTRIBUTES 30 + +#ifndef TRUE +#define TRUE 1 +#endif /* */ + +#define PREFAILURE 2 +#define ADVISORY 1 +#define OPERATIONAL 0 +#define UNKNOWN -1 + typedef struct threshold_s +{ + __u8 id; + __u8 threshold; + __u8 reserved[10]; +} +__attribute__ ((packed)) threshold_t; +typedef struct thresholds_s +{ + __u16 revision; + threshold_t thresholds[NR_ATTRIBUTES]; + __u8 reserved[18]; + __u8 vendor[131]; + __u8 checksum; +} +__attribute__ ((packed)) thresholds_t; +typedef struct value_s +{ + __u8 id; + __u16 status; + __u8 value; + __u8 vendor[8]; +} +__attribute__ ((packed)) value_t; +typedef struct values_s +{ + __u16 revision; + value_t values[NR_ATTRIBUTES]; + __u8 offline_status; + __u8 vendor1; + __u16 offline_timeout; + __u8 vendor2; + __u8 offline_capability; + __u16 smart_capability; + __u8 reserved[16]; + __u8 vendor[125]; + __u8 checksum; +} +__attribute__ ((packed)) values_t; +struct +{ + __u8 value; + char *text; + } +offline_status_text[] = +{ + { + 0x00, "NeverStarted"} + , { + 0x02, "Completed"} + , { + 0x04, "Suspended"} + , { + 0x05, "Aborted"} + , { + 0x06, "Failed"} + , { + 0, 0} +}; +struct +{ + __u8 value; + char *text; + } +smart_command[] = +{ + { + SMART_ENABLE, "SMART_ENABLE"} + , { + SMART_DISABLE, "SMART_DISABLE"} + , { + SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"} + , { + SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"} +, }; + + +/* Index to smart_command table, keep in order */ +enum SmartCommand +{ SMART_CMD_ENABLE, SMART_CMD_DISABLE, SMART_CMD_IMMEDIATE_OFFLINE, + SMART_CMD_AUTO_OFFLINE +}; +char * +get_offline_text (int status) +{ + int i; + for (i = 0; offline_status_text[i].text; i++) { + if (offline_status_text[i].value == status) { + return offline_status_text[i].text; + } + } + return "unknown"; +} +int +smart_read_values (int fd, values_t * values) +{ + __u8 args[4 + 512] = { + WIN_SMART, 0, SMART_READ_VALUES, 1,}; + if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { + int e = errno; + printf ("Critical: SMART_READ_VALUES: %s\n", strerror (errno)); + return e; + } + memcpy (values, args + 4, 512); + return 0; +} +int +values_not_passed (values_t * p, thresholds_t * t) +{ + value_t * value = p->values; + threshold_t * threshold = t->thresholds; + int failed = 0; + int passed = 0; + int i; + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (value->id && threshold->id && value->id == threshold->id) { + if (value->value <= threshold->threshold) { + ++failed; + } + else { + ++passed; + } + } + ++value; + ++threshold; + } + return (passed ? -failed : 2); +} +int +net_saint (values_t * p, thresholds_t * t) +{ + value_t * value = p->values; + threshold_t * threshold = t->thresholds; + int status = OPERATIONAL; + int prefailure = 0; + int advisory = 0; + int failed = 0; + int passed = 0; + int total = 0; + int i; + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (value->id && threshold->id && value->id == threshold->id) { + if (value->value <= threshold->threshold) { + ++failed; + if (value->status & 1) { + status = PREFAILURE; + ++prefailure; + } + else { + status = ADVISORY; + ++advisory; + } + } + else { + ++passed; + } + ++total; + } + ++value; + ++threshold; + } + switch (status) { + case PREFAILURE: + printf ("Critical: %d Harddrive PreFailure%cDetected! " + "%d/%d tests failed.\n", prefailure, prefailure > 1 ? 's' : ' ', + failed, total); + break; + case ADVISORY: + printf ("Warning: %d Harddrive Advisor%s Detected. " + "%d/%d tests failed.\n", advisory, advisory > 1 ? "ies" : "y", + failed, total); + break; + case OPERATIONAL: + printf ("Status: Operational (%d/%d tests passed)\n", passed, total); + break; + default: + printf ("Error: Status '%d' uknown. %d/%d tests passed\n", status, + passed, total); + status = -1; + break; + } + return status; +} +void +print_value (value_t * p, threshold_t * t) +{ + printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", + p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", + p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, + p->value > t->threshold ? "Passed" : "Failed"); +} +void +print_values (values_t * p, thresholds_t * t) +{ + value_t * value = p->values; + threshold_t * threshold = t->thresholds; + int i; + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (value->id && threshold->id && value->id == threshold->id) { + print_value (value++, threshold++); + } + } + printf + ("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n", + p->offline_status, get_offline_text (p->offline_status & 0x7f), + (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); + printf ("OffLineCapability=%d {%s %s %s}\n", p->offline_capability, + p->offline_capability & 1 ? "Immediate" : "", + p->offline_capability & 2 ? "Auto" : "", + p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); + printf ("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n", + p->revision, p->checksum, p->smart_capability, + p->smart_capability & 1 ? "SaveOnStandBy" : "", + p->smart_capability & 2 ? "AutoSave" : ""); +} +void +print_thresholds (thresholds_t * p) +{ + threshold_t * threshold = p->thresholds; + int i; + printf ("\n"); + printf ("SmartRevision=%d\n", p->revision); + for (i = 0; i < NR_ATTRIBUTES; i++) { + if (threshold->id) { + printf ("Id=%3d, Threshold=%3d\n", threshold->id, + threshold->threshold); } + ++threshold; + } + printf ("CheckSum=%d\n", p->checksum); +} +int +smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, + char show_error) +{ + __u8 args[4] = { + WIN_SMART, val0, smart_command[command].value, 0}; + int e = 0; + if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { + e = errno; + if (show_error) { + printf ("Critical: %s: %s\n", smart_command[command].text, + strerror (errno)); } + } + return e; +} +int +smart_read_thresholds (int fd, thresholds_t * thresholds) +{ + __u8 args[4 + 512] = { + WIN_SMART, 0, SMART_READ_THRESHOLDS, 1,}; + if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { + int e = errno; + printf ("Critical: SMART_READ_THRESHOLDS: %s\n", strerror (errno)); + return e; + } + memcpy (thresholds, args + 4, 512); + return 0; +} +void +show_version () +{ + printf ("check_ide-smart v.1 - FREE Software with NO WARRANTY\n"); + printf ("Nagios feature - Robert Dale <rdale@digital-mission.com>\n"); + printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n"); +} +void +show_help () +{ + printf ("Usage: check_ide-smart [DEVICE] [OPTION]\n" + " -d, --device=DEVICE Select device DEVICE\n" + " -i, --immediate Perform immediately offline tests\n" + " -q, --quiet-check Returns the number of failed tests\n" + " -1, --auto-on Turn on automatic offline tests\n" + " -0, --auto-off Turn off automatic offline tests\n" + " -n, --net-saint Output suitable for Net Saint\n" + " -h, --help\n" " -V, --version\n"); +} +int +main (int argc, char *argv[]) +{ + char *device = NULL; + int command = -1; + int o, longindex; + int retval = 0; + +#ifdef HAVE_GETOPT_H + const struct option longopts[] = { + {"device", required_argument, 0, 'd'}, + {"immediate", no_argument, 0, 'i'}, + {"quiet-check", no_argument, 0, 'q'}, + {"auto-on", no_argument, 0, '1'}, + {"auto-off", no_argument, 0, '0'}, + {"net-saint", no_argument, 0, 'n'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, {0, 0, 0, 0} + }; + +#endif /* */ + while (1) { + +#ifdef HAVE_GETOPT_H + o = getopt_long (argc, argv, "+d:iq10nhV", longopts, &longindex); + +#else /* */ + o = getopt (argc, argv, "+d:iq10nhV"); + +#endif /* */ + if (o == -1 || o == EOF) + break; + switch (o) { + case 'd': + device = optarg; + break; + case 'q': + command = 3; + break; + case 'i': + command = 2; + break; + case '1': + command = 1; + break; + case '0': + command = 0; + break; + case 'n': + command = 4; + break; + case 'h': + show_help (); + return 0; + case 'V': + show_version (); + return 0; + default: + printf ("Try `%s --help' for more information.\n", argv[0]); + return 1; + } + if (optind < argc) { + device = argv[optind]; + } + if (!device) { + show_help (); + show_version (); + return -1; + } + if (1) { + thresholds_t thresholds; + values_t values; + int fd = open (device, O_RDONLY); + if (fd < 0) { + printf ("Critical: Couldn't open device: %s\n", strerror (errno)); + return 2; + } + if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, TRUE)) { + printf ("Critical: SMART_CMD_ENABLE\n"); + return 2; + } + switch (command) { + case 0: + retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0, TRUE); + break; + case 1: + retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0xF8, TRUE); + break; + case 2: + retval = smart_cmd_simple (fd, SMART_CMD_IMMEDIATE_OFFLINE, 0, TRUE); + break; + case 3: + smart_read_values (fd, &values); + smart_read_thresholds (fd, &thresholds); + retval = values_not_passed (&values, &thresholds); + break; + case 4: + smart_read_values (fd, &values); + smart_read_thresholds (fd, &thresholds); + retval = net_saint (&values, &thresholds); + break; + default: + smart_read_values (fd, &values); + smart_read_thresholds (fd, &thresholds); + print_values (&values, &thresholds); + break; + } + close (fd); + } + return retval; + } + diff --git a/plugins/check_imap.c b/plugins/check_imap.c new file mode 100644 index 00000000..5ec0439b --- /dev/null +++ b/plugins/check_imap.c @@ -0,0 +1,340 @@ +/****************************************************************************** +* +* CHECK_IMAP.C +* +* Program: IMAP4 plugin for Nagios +* License: GPL +* Copyright (c) 1999 Tom Shields (tom.shields@basswood.com) +* +* $Id$ +* +* Description: +* +* This plugin will attempt to open an IMAP connection with the host. +* Successul connects return STATE_OK, refusals and timeouts return +* STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful +* connects, but incorrect reponse messages from the host result in +* STATE_WARNING return values. +* +* Modifications: +* 04-13-1999 Tom Shields +* Initial code +* 08-18-1999 Ethan Galstad <nagios@nagios.org> +* Modified code to work with common plugin functions, added socket +* timeout, string * length checking +* 09-19-1999 Ethan Galstad <nagios@nagios.org> +* Changed expect string from "+OK" to "* OK" and default port to 143 +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_imap" + +#define PORT 143 +#define EXPECT "* OK" +#define QUIT "a1 LOGOUT\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int server_port = PORT; +char *server_address = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + /* watch for the IMAP connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* strip carriange returns */ + strip (buffer); + + /* return a WARNING status if we couldn't read any data */ + if (result == -1) { + printf ("recv() failed\n"); + result = STATE_WARNING; + } + + else { + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, server_expect)) { + if (server_port == server_port) + printf ("Invalid IMAP response received from host\n"); + else + printf ("Invalid IMAP response received from host on port %d\n", + server_port); + result = STATE_WARNING; + } + + else { + time (&end_time); + printf ("IMAP ok - %d second response time\n", + (int) (end_time - start_time)); + result = STATE_OK; + } + } + + /* close the connection */ + send (sd, QUIT, strlen (QUIT), 0); + close (sd); + } + + /* reset the alarm handler */ + alarm (0); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_address == NULL) + server_address = strscpy (NULL, "127.0.0.1"); + + if (server_expect == NULL) + server_expect = strscpy (NULL, EXPECT); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'P'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvt:p:e:c:w:H:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVvt:p:e:c:w:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'p': + case 'e': + case 'c': + case 'w': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'e': /* username */ + server_expect = optarg; + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_time = atoi (optarg); + check_critical_time = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_time = atoi (optarg); + check_warning_time = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Tom Shields/Karl DeBisschop\n\n" + "This plugin tests the IMAP4 service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", + PORT, EXPECT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit]\n" + " [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c new file mode 100644 index 00000000..d3f06158 --- /dev/null +++ b/plugins/check_ldap.c @@ -0,0 +1,291 @@ +/***************************************************************************** * + * CHECK_LDAP.C + * + * Program: Ldap plugin for Nagios + * License: GPL + * Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) + * + * Last Modified: $Date$ + * + * Command line: check_ldap -h <host> -b <base_dn> -p <port> -w <warn_time> -w <crit_time> + * + * Description: + * + * This plugin is for testing a ldap server. + * + * Modifications: + * + * 08-25-1999 Ethan Galstad (nagios@nagios.org) + * Modified to use common plugin include file + * + *****************************************************************************/ + +#define PROGNAME "check_ldap" +#define REVISION "$Revision$" + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#include <lber.h> +#include <ldap.h> + +#define UNKNOWN -1 + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +static void print_help (void); +static void print_usage (void); + +char ld_defattr[] = "(objectclass=*)"; +char *ld_attr = ld_defattr; +char *ld_host = NULL, *ld_base = NULL, *ld_passwd = NULL, *ld_binddn = NULL; +unsigned int ld_port = 389; +int warn_time = UNKNOWN, crit_time = UNKNOWN; + +int +main (int argc, char *argv[]) +{ + + LDAP *ld; + LDAPMessage *result; + + int t_diff; + time_t time0, time1; + + if (process_arguments (argc, argv) == ERROR) + usage ("check_ldap: could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* get the start time */ + time (&time0); + + /* initialize ldap */ + if (!(ld = ldap_open (ld_host, ld_port))) { + /*ldap_perror(ld, "ldap_open"); */ + printf ("Could not connect to the server at port %i\n", ld_port); + return STATE_CRITICAL; + } + + /* bind to the ldap server */ + if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != + LDAP_SUCCESS) { + /*ldap_perror(ld, "ldap_bind"); */ + printf ("Could not bind to the ldap-server\n"); + return STATE_CRITICAL; + } + + /* do a search of all objectclasses in the base dn */ + if (ldap_search_s (ld, ld_base, LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result) + != LDAP_SUCCESS) { + /*ldap_perror(ld, "ldap_search"); */ + printf ("Could not search/find objectclasses in %s\n", ld_base); + return STATE_CRITICAL; + } + + /* unbind from the ldap server */ + ldap_unbind (ld); + + /* reset the alarm handler */ + alarm (0); + + /* get the finish time */ + time (&time1); + + /* calcutate the elapsed time */ + t_diff = time1 - time0; + + /* check if warn_time or crit_time was exceeded */ + if ((t_diff >= warn_time) && (t_diff < crit_time)) { + printf ("LDAP warning - %i seconds response time\n", t_diff); + return STATE_WARNING; + } + if (t_diff >= crit_time) { + printf ("LDAP critical - %i seconds response time\n", t_diff); + return STATE_CRITICAL; + } + + /* print out the result */ + printf ("LDAP ok - %i seconds response time\n", t_diff); + + return STATE_OK; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + } + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (ld_host[0] == 0) { + strncpy (ld_host, argv[c], sizeof (ld_host) - 1); + ld_host[sizeof (ld_host) - 1] = 0; + } + } + + return c; +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; +#ifdef HAVE_GETOPT_H + int option_index = 0; + /* initialize the long option struct */ + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"timeout", required_argument, 0, 't'}, + {"host", required_argument, 0, 'H'}, + {"base", required_argument, 0, 'b'}, + {"attr", required_argument, 0, 'a'}, + {"bind", required_argument, 0, 'D'}, + {"pass", required_argument, 0, 'P'}, + {"port", required_argument, 0, 'p'}, + {"warn", required_argument, 0, 'w'}, + {"crit", required_argument, 0, 'c'}, + {0, 0, 0, 0} + }; +#endif + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVt:c:w:H:b:p:a:D:P:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVt:c:w:H:b:p:a:D:P:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'c': + case 'w': + case 'H': + case 'b': + case 'p': + case 'a': + case 'D': + case 'P': + i++; + } + + switch (c) { + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (PROGNAME, REVISION); + exit (STATE_OK); + case 't': /* timeout period */ + if (!is_intnonneg (optarg)) + usage2 ("timeout interval must be an integer", optarg); + socket_timeout = atoi (optarg); + break; + case 'H': + ld_host = optarg; + break; + case 'b': + ld_base = optarg; + break; + case 'p': + ld_port = atoi (optarg); + break; + case 'a': + ld_attr = optarg; + break; + case 'D': + ld_binddn = optarg; + break; + case 'P': + ld_passwd = optarg; + break; + case 'w': + warn_time = atoi (optarg); + break; + case 'c': + crit_time = atoi (optarg); + break; + default: + usage ("check_ldap: could not parse arguments\n"); + break; + } + } + return i; +} + +int +validate_arguments () +{ + if (ld_host[0] == 0 || + ld_base[0] == 0 || + ld_port == UNKNOWN || warn_time == UNKNOWN || crit_time == UNKNOWN) { + return ERROR; + } + else { + return OK; + } +} + + + +/* function print_help */ +static void +print_help () +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n" + "License: GPL\n" "\n"); + print_usage (); + printf + ("\n" + "Options:\n" + "\t-H [--host] ... host\n" + "\t-a [--attr] ... ldap attribute to search (default: \"(objectclass=*)\"\n" + "\t-b [--base] ... ldap base (eg. ou=my unit, o=my org, c=at)\n" + "\t-D [--bind] ... ldap bind DN (if required)\n" + "\t-P [--pass] ... ldap password (if required)\n" + "\t-p [--port] ... ldap port (normaly 389)\n" + "\t-w [--warn] ... time in secs. - if the exceeds <warn> the STATE_WARNING will be returned\n" + "\t-c [--crit] ... time in secs. - if the exceeds <crit> the STATE_CRITICAL will be returned\n" + "\n"); +} + + +static void +print_usage () +{ + printf + ("Usage: %s -H <host> -b <base_dn> -p <port> [-a <attr>] [-D <binddn>]\n" + " [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]\n" + "(Note: all times are in seconds.)\n", PROGNAME); +} diff --git a/plugins/check_load.c b/plugins/check_load.c new file mode 100644 index 00000000..6673b1dc --- /dev/null +++ b/plugins/check_load.c @@ -0,0 +1,321 @@ +/****************************************************************************** + * + * CHECK_LOAD.C + * + * Written by Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br> + * License: GPL + * Command line: CHECK_LOAD <wload1> <cload1> <wload5> <cload5> <wload15> <cload15> + * First Written: 04/17/99 + * + * Modifications: + * + * 05/18/1999 - Modified to work getloadavg where available, and use uptime + * where neither proc or getloadavg are found. Also use autoconf. + * mods by Karl DeBisschop (kdebiss@alum.mit.edu) + * 07/01/1999 - Added some #DEFINEs to allow compilation under NetBSD, as + * suggested by Andy Doran. + * mods by Ethan Galstad (nagios@nagios.org) + * 07/17/1999 - Initialized la[] array to prevent NetBSD from complaining + * mods by Ethan Galstad (nagios@nagios.org) + * 08/18/1999 - Integrated some code with common plugin utilities + * mods by Ethan Galstad (nagios@nagios.org) + * $Date$ + * Note: The load format is the same used by "uptime" and "w" + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +#ifdef HAVE_SYS_LOADAVG_H +#include <sys/loadavg.h> +#endif + +/* needed for compilation under NetBSD, as suggested by Andy Doran */ +#ifndef LOADAVG_1MIN +#define LOADAVG_1MIN 0 +#define LOADAVG_5MIN 1 +#define LOADAVG_15MIN 2 +#endif /* !defined LOADAVG_1MIN */ + +#include "popen.h" +#ifdef HAVE_PROC_LOADAVG + +#endif + +#define PROGNAME "check_load" + +int process_arguments (int argc, char **argv); +int call_getopt (int argc, char **argv); +int validate_arguments (void); +void print_usage (void); +void print_help (void); + +float wload1 = -1, wload5 = -1, wload15 = -1; +float cload1 = -1, cload5 = -1, cload15 = -1; + +int +main (int argc, char **argv) +{ +#if HAVE_GETLOADAVG==1 + int result; + double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */ +#elif HAVE_PROC_LOADAVG==1 + FILE *fp; + char input_buffer[MAX_INPUT_BUFFER]; + char *tmp_ptr; +#else + int result; + char input_buffer[MAX_INPUT_BUFFER]; +#endif + + float la1, la5, la15; + + if (process_arguments (argc, argv) == ERROR) + usage ("\n"); + +#if HAVE_GETLOADAVG==1 + result = getloadavg (la, 3); + if (result == -1) + return STATE_UNKNOWN; + la1 = la[LOADAVG_1MIN]; + la5 = la[LOADAVG_5MIN]; + la15 = la[LOADAVG_15MIN]; +#elif HAVE_PROC_LOADAVG==1 + fp = fopen (PROC_LOADAVG, "r"); + if (fp == NULL) { + printf ("Error opening %s\n", PROC_LOADAVG); + return STATE_UNKNOWN; + } + + la1 = la5 = la15 = -1; + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + tmp_ptr = strtok (input_buffer, " "); + la1 = atof (tmp_ptr); + tmp_ptr = strtok (NULL, " "); + la5 = atof (tmp_ptr); + tmp_ptr = strtok (NULL, " "); + la15 = atof (tmp_ptr); + } + + fclose (fp); +#else + child_process = spopen (PATH_TO_UPTIME); + if (child_process == NULL) { + printf ("Error opening %s\n", PATH_TO_UPTIME); + return STATE_UNKNOWN; + } + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", PATH_TO_UPTIME); + } + fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); + sscanf (input_buffer, "%*[^l]load average: %f, %f, %f", &la1, &la5, &la15); + + result = spclose (child_process); + if (result) { + printf ("Error code %d returned in %s\n", result, PATH_TO_UPTIME); + return STATE_UNKNOWN; + } +#endif + + if ((la1 == -1) || (la5 == -1) || (la15 == -1)) { +#if HAVE_GETLOADAVG==1 + printf ("Error in getloadavg()\n"); +#elif HAVE_PROC_LOADAVG==1 + printf ("Error processing %s\n", PROC_LOADAVG); +#else + printf ("Error processing %s\n", PATH_TO_UPTIME); +#endif + return STATE_UNKNOWN; + } + printf ("load average: %.2f, %.2f, %.2f", la1, la5, la15); + if ((la1 >= cload1) || (la5 >= cload5) || (la15 >= cload15)) { + printf (" CRITICAL\n"); + return STATE_CRITICAL; + } + if ((la1 >= wload1) || (la5 >= wload5) || (la15 >= wload15)) { + printf (" WARNING\n"); + return STATE_WARNING; + } + printf ("\n"); + return STATE_OK; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + + if (wload1 < 0 && is_nonnegative (argv[c])) + wload1 = atof (argv[c]); + else if (cload1 < 0 && is_nonnegative (argv[c])) + cload1 = atof (argv[c]); + else if (wload5 < 0 && is_nonnegative (argv[c])) + wload5 = atof (argv[c]); + else if (cload5 < 0 && is_nonnegative (argv[c])) + cload5 = atof (argv[c]); + else if (wload15 < 0 && is_nonnegative (argv[c])) + wload15 = atof (argv[c]); + else if (cload15 < 0 && is_nonnegative (argv[c])) + cload15 = atof (argv[c]); + } + + return validate_arguments (); +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?Vhc:w:"); +#endif + + i++; + + if (c == -1 || c == EOF) + break; + + switch (c) { + case 'c': + case 'w': + i++; + } + + switch (c) { + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + if (wload1 < 0 && is_nonnegative (argv[c])) + wload1 = atof (argv[c]); + else if (wload5 < 0 && is_nonnegative (argv[c])) + wload5 = atof (argv[c]); + else if (wload15 < 0 && is_nonnegative (argv[c])) + wload15 = atof (argv[c]); + break; + } + else if (strstr (optarg, ",") && + sscanf (optarg, "%f,%f,%f", &wload1, &wload5, &wload15) == 3) { + break; + } + else { + usage ("Warning threshold must be float or float triplet!\n"); + } + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + if (cload1 < 0 && is_nonnegative (argv[c])) + cload1 = atof (argv[c]); + else if (cload5 < 0 && is_nonnegative (argv[c])) + cload5 = atof (argv[c]); + else if (cload15 < 0 && is_nonnegative (argv[c])) + cload15 = atof (argv[c]); + break; + } + else if (strstr (optarg, ",") && + sscanf (optarg, "%f,%f,%f", &cload1, &cload5, &cload15) == 3) { + break; + } + else { + usage ("Critical threshold must be float or float triplet!\n"); + } + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + if ((wload1 > cload1) || (wload5 > cload5) || (wload15 > cload15)) { + printf + ("Inconsistence in parameters: \"warning load\" greater than \"critical load\".\n"); + return STATE_UNKNOWN; + } + + return OK; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: check_load -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n" + " check_load --version\n" " check_load --help\n"); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n" + "Copyright (c) 2000 Karl DeBisschop\n\n" + "This plugin tests the current system load average.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -w, --warning=WLOAD1,WLOAD5,WLOAD15\n" + " Exit with WARNING status if load average exceeds WLOADn\n" + " -c, --critical=CLOAD1,CLOAD5,CLOAD15\n" + " Exit with CRITICAL status if load average exceed CLOADn\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n" + "the load average format is the same used by \"uptime\" and \"w\"\n\n"); + support (); +} diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c new file mode 100644 index 00000000..b86686d7 --- /dev/null +++ b/plugins/check_mrtg.c @@ -0,0 +1,413 @@ +/****************************************************************************** + * + * Program: MRTG (Multi-Router Traffic Grapher) generic plugin for Nagios + * License: GPL + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_mrtg" +#define REVISION "$Revision$" +#define COPYRIGHT "Copyright (c) 1999-2001 Ethan Galstad" + +#define SUMMARY "\ +This plugin will check either the average or maximum value of one of the\n\ +two variables recorded in an MRTG log file.\n" + +/* old command line: + <log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */ +#define OPTIONS "\ +-F log_file -a <AVG | MAX> -v variable -w warning -c critical\n\ + [-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]" + +#define LONGOPTIONS "\ + -F, --logfile=FILE\n\ + The MRTG log file containing the data you want to monitor\n\ + -e, --expires=MINUTES\n\ + Minutes before MRTG data is considered to be too old\n\ + -a, --aggregation=AVG|MAX\n\ + Should we check average or maximum values?\n\ + -v, --variable=INTEGER\n\ + Which variable set should we inspect? 1 or 2?\n\ + -w, --warning=INTEGER\n\ + Threshold value for data to result in WARNING status\n\ + -c, --critical=INTEGER\n\ + Threshold value for data to result in CRITICAL status\n\ + -l, --label=STRING\n\ + Type label for data (Examples: Conns, \"Processor Load\", In, Out)\n\ + -u, --units=STRING\n\ + Option units label for data (Example: Packets/Sec, Errors/Sec, \n\ + \"Bytes Per Second\", \"%% Utilization\")\n\ + -h, --help\n\ + Print detailed help screen\n\ + -V, --version\n\ + Print version information\n" + +#define DESCRIPTION "\ +If the value exceeds the <vwl> threshold, a WARNING status is returned. If\n\ +the value exceeds the <vcl> threshold, a CRITICAL status is returned. If\n\ +the data in the log file is older than <expire_minutes> old, a WARNING\n\ +status is returned and a warning message is printed.\n\ +\n\ +This plugin is useful for monitoring MRTG data that does not correspond to\n\ +bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).\n\ +It can be used to monitor any kind of data that MRTG is monitoring - errors,\n\ +packets/sec, etc. I use MRTG in conjuction with the Novell NLM that allows\n\ +me to track processor utilization, user connections, drive space, etc and\n\ +this plugin works well for monitoring that kind of data as well.\n\ +\n\ +Notes:\n\ +- This plugin only monitors one of the two variables stored in the MRTG log\n\ + file. If you want to monitor both values you will have to define two\n\ + commands with different values for the <variable> argument. Of course,\n\ + you can always hack the code to make this plugin work for you...\n\ +- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from\n\ + http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html\n" + +#include "config.h" +#include "common.h" +#include "utils.h" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (void); +void print_usage (void); + +char *log_file = NULL; +int expire_minutes = 0; +int use_average = TRUE; +int variable_number = -1; +unsigned long value_warning_threshold = 0L; +unsigned long value_critical_threshold = 0L; +char *value_label = NULL; +char *units_label = NULL; + +int +main (int argc, char **argv) +{ + int result = STATE_OK; + FILE *fp; + int line; + char input_buffer[MAX_INPUT_BUFFER]; + char *temp_buffer; + time_t current_time; + char error_message[MAX_INPUT_BUFFER]; + time_t timestamp = 0L; + unsigned long average_value_rate = 0L; + unsigned long maximum_value_rate = 0L; + unsigned long value_rate = 0L; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* open the MRTG log file for reading */ + fp = fopen (log_file, "r"); + if (fp == NULL) { + printf ("Unable to open MRTG log file\n"); + return STATE_UNKNOWN; + } + + line = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + + line++; + + /* skip the first line of the log file */ + if (line == 1) + continue; + + /* break out of read loop if we've passed the number of entries we want to read */ + if (line > 2) + break; + + /* grab the timestamp */ + temp_buffer = strtok (input_buffer, " "); + timestamp = strtoul (temp_buffer, NULL, 10); + + /* grab the average value 1 rate */ + temp_buffer = strtok (NULL, " "); + if (variable_number == 1) + average_value_rate = strtoul (temp_buffer, NULL, 10); + + /* grab the average value 2 rate */ + temp_buffer = strtok (NULL, " "); + if (variable_number == 2) + average_value_rate = strtoul (temp_buffer, NULL, 10); + + /* grab the maximum value 1 rate */ + temp_buffer = strtok (NULL, " "); + if (variable_number == 1) + maximum_value_rate = strtoul (temp_buffer, NULL, 10); + + /* grab the maximum value 2 rate */ + temp_buffer = strtok (NULL, " "); + if (variable_number == 2) + maximum_value_rate = strtoul (temp_buffer, NULL, 10); + } + + /* close the log file */ + fclose (fp); + + /* if we couldn't read enough data, return an unknown error */ + if (line <= 2) { + result = STATE_UNKNOWN; + sprintf (error_message, "Unable to process MRTG log file\n"); + } + + /* make sure the MRTG data isn't too old */ + if (result == STATE_OK) { + time (¤t_time); + if (expire_minutes > 0 + && (current_time - timestamp) > (expire_minutes * 60)) { + result = STATE_WARNING; + sprintf (error_message, "MRTG data has expired (%d minutes old)\n", + (int) ((current_time - timestamp) / 60)); + } + } + + /* else check the incoming/outgoing rates */ + if (result == STATE_OK) { + + if (use_average == TRUE) + value_rate = average_value_rate; + else + value_rate = maximum_value_rate; + + if (value_rate > value_critical_threshold) + result = STATE_CRITICAL; + else if (value_rate > value_warning_threshold) + result = STATE_WARNING; + } + + sprintf (error_message, "%s. %s = %lu %s", + (use_average == TRUE) ? "Ave" : "Max", value_label, value_rate, + units_label); + printf ("%s\n", error_message); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (log_file == NULL) { + log_file = argv[c]; + } + else if (expire_minutes <= 0) { + if (is_intpos (argv[c])) + expire_minutes = atoi (argv[c]); + else + terminate (STATE_UNKNOWN, + "%s is not a valid expiration time\nUse '%s -h' for additional help\n", + argv[c], PROGNAME); + } + else if (strcmp (argv[c], "MAX") == 0) { + use_average = FALSE; + } + else if (strcmp (argv[c], "AVG") == 0) { + use_average = TRUE; + } + else if (variable_number == -1) { + variable_number = atoi (argv[c]); + if (variable_number < 1 || variable_number > 2) { + printf ("%s :", argv[c]); + usage ("Invalid variable number\n"); + } + } + else if (value_warning_threshold == 0) { + value_warning_threshold = strtoul (argv[c], NULL, 10); + } + else if (value_critical_threshold == 0) { + value_critical_threshold = strtoul (argv[c], NULL, 10); + } + else if (value_label == NULL) { + value_label = argv[c]; + } + else if (units_label == NULL) { + units_label = argv[c]; + } + } + + if (value_label == NULL) + value_label = strscpy (NULL, ""); + + if (units_label == NULL) + units_label = strscpy (NULL, ""); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"logfile", required_argument, 0, 'F'}, + {"expires", required_argument, 0, 'e'}, + {"aggregation", required_argument, 0, 'a'}, + {"variable", required_argument, 0, 'v'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"label", required_argument, 0, 'l'}, + {"units", required_argument, 0, 'u'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVF:e:a:v:c:w:l:u:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVF:e:a:v:c:w:l:u:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'F': + case 'e': + case 'a': + case 'v': + case 'c': + case 'w': + case 'l': + case 'u': + i++; + } + + switch (c) { + case 'F': /* input file */ + log_file = optarg; + break; + case 'e': /* ups name */ + expire_minutes = atoi (optarg); + break; + case 'a': /* port */ + if (!strcmp (optarg, "MAX")) + use_average = FALSE; + else + use_average = TRUE; + break; + case 'v': + variable_number = atoi (optarg); + if (variable_number < 1 || variable_number > 2) + usage ("Invalid variable number\n"); + break; + case 'w': /* critical time threshold */ + value_warning_threshold = strtoul (optarg, NULL, 10); + break; + case 'c': /* warning time threshold */ + value_critical_threshold = strtoul (optarg, NULL, 10); + break; + case 'l': /* label */ + value_label = optarg; + break; + case 'u': /* timeout */ + units_label = optarg; + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + +int +validate_arguments (void) +{ + if (variable_number == -1) + usage ("You must supply the variable number\n"); + + return OK; +} + +void +print_help (void) +{ + print_revision (PROGNAME, REVISION); + printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY); + print_usage (); + printf ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n"); + support (); +} + +void +print_usage (void) +{ + printf ("Usage:\n" " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c new file mode 100644 index 00000000..11f5146b --- /dev/null +++ b/plugins/check_mrtgtraf.c @@ -0,0 +1,419 @@ +/****************************************************************************** + * + * CHECK_MRTGTRAF.C + * + * Program: MRTG (Multi-Router Traffic Grapher) traffic plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * + * Command line: CHECK_MRTGTRAF <log_file> <expire_minutes> <AVG|MAX> <iwl> <icl> <owl> <ocl> + * + * Description: + * + * This plugin will check the incoming/outgoing transfer rates of a + * router, switch, etc recorded in an MRTG log. If the newest log + * entry is older than <expire_minutes>, a WARNING status is returned. + * If either the incoming or outgoing rates exceed the <icl> or <ocl> + * thresholds (in Bytes/sec), a CRITICAL status results. If either of + * the rates exceed the <iwl> or <owl> thresholds (in Bytes/sec), a + * WARNING status results. + * + * Notes: + * - MRTG stands for the Multi Router Traffic Grapher. It can be + * downloaded from + * http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html + * - While MRTG can monitor things other than traffic rates, this + * plugin probably won't work with much else without modification. + * - The calculated i/o rates are a little off from what MRTG actually + * reports. I'm not sure why this is right now, but will look into it + * for future enhancements of this plugin. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "utils.h" + +#define PROGNAME "check_mrtgtraf" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (void); +void print_usage (void); + +char *log_file = NULL; +int expire_minutes = -1; +int use_average = TRUE; +unsigned long incoming_warning_threshold = 0L; +unsigned long incoming_critical_threshold = 0L; +unsigned long outgoing_warning_threshold = 0L; +unsigned long outgoing_critical_threshold = 0L; + +int +main (int argc, char **argv) +{ + int result = STATE_OK; + FILE *fp; + int line; + char input_buffer[MAX_INPUT_BUFFER]; + char *temp_buffer; + time_t current_time; + char error_message[MAX_INPUT_BUFFER]; + time_t timestamp = 0L; + unsigned long average_incoming_rate = 0L; + unsigned long average_outgoing_rate = 0L; + unsigned long maximum_incoming_rate = 0L; + unsigned long maximum_outgoing_rate = 0L; + unsigned long incoming_rate = 0L; + unsigned long outgoing_rate = 0L; + double adjusted_incoming_rate = 0.0; + double adjusted_outgoing_rate = 0.0; + char incoming_speed_rating[8]; + char outgoing_speed_rating[8]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* open the MRTG log file for reading */ + fp = fopen (log_file, "r"); + if (fp == NULL) + usage ("Unable to open MRTG log file\n"); + + line = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + + line++; + + /* skip the first line of the log file */ + if (line == 1) + continue; + + /* break out of read loop */ + /* if we've passed the number of entries we want to read */ + if (line > 2) + break; + + /* grab the timestamp */ + temp_buffer = strtok (input_buffer, " "); + timestamp = strtoul (temp_buffer, NULL, 10); + + /* grab the average incoming transfer rate */ + temp_buffer = strtok (NULL, " "); + average_incoming_rate = strtoul (temp_buffer, NULL, 10); + + /* grab the average outgoing transfer rate */ + temp_buffer = strtok (NULL, " "); + average_outgoing_rate = strtoul (temp_buffer, NULL, 10); + + /* grab the maximum incoming transfer rate */ + temp_buffer = strtok (NULL, " "); + maximum_incoming_rate = strtoul (temp_buffer, NULL, 10); + + /* grab the maximum outgoing transfer rate */ + temp_buffer = strtok (NULL, " "); + maximum_outgoing_rate = strtoul (temp_buffer, NULL, 10); + } + + /* close the log file */ + fclose (fp); + + /* if we couldn't read enough data, return an unknown error */ + if (line <= 2) + usage ("Unable to process MRTG log file\n"); + + /* make sure the MRTG data isn't too old */ + time (¤t_time); + if (expire_minutes > 0 + && (current_time - timestamp) > + (expire_minutes * 60)) terminate (STATE_WARNING, + "MRTG data has expired (%d minutes old)\n", + (int) ((current_time - timestamp) / + 60)); + + /* else check the incoming/outgoing rates */ + if (use_average == TRUE) { + incoming_rate = average_incoming_rate; + outgoing_rate = average_outgoing_rate; + } + else { + incoming_rate = maximum_incoming_rate; + outgoing_rate = maximum_outgoing_rate; + } + + /* report incoming traffic in Bytes/sec */ + if (incoming_rate < 1024) { + strcpy (incoming_speed_rating, "B/s"); + adjusted_incoming_rate = (double) incoming_rate; + } + + /* report incoming traffic in KBytes/sec */ + else if (incoming_rate < (1024 * 1024)) { + strcpy (incoming_speed_rating, "KB/s"); + adjusted_incoming_rate = (double) (incoming_rate / 1024.0); + } + + /* report incoming traffic in MBytes/sec */ + else { + strcpy (incoming_speed_rating, "MB/s"); + adjusted_incoming_rate = (double) (incoming_rate / 1024.0 / 1024.0); + } + + /* report outgoing traffic in Bytes/sec */ + if (outgoing_rate < 1024) { + strcpy (outgoing_speed_rating, "B/s"); + adjusted_outgoing_rate = (double) outgoing_rate; + } + + /* report outgoing traffic in KBytes/sec */ + else if (outgoing_rate < (1024 * 1024)) { + strcpy (outgoing_speed_rating, "KB/s"); + adjusted_outgoing_rate = (double) (outgoing_rate / 1024.0); + } + + /* report outgoing traffic in MBytes/sec */ + else { + strcpy (outgoing_speed_rating, "MB/s"); + adjusted_outgoing_rate = (double) (outgoing_rate / 1024.0 / 1024.0); + } + + if (incoming_rate > incoming_critical_threshold + || outgoing_rate > outgoing_critical_threshold) { + result = STATE_CRITICAL; + sprintf (error_message, "%s. In = %0.1f %s, %s. Out = %0.1f %s", + (use_average == TRUE) ? "Ave" : "Max", adjusted_incoming_rate, + incoming_speed_rating, (use_average == TRUE) ? "Ave" : "Max", + adjusted_outgoing_rate, outgoing_speed_rating); + } + else if (incoming_rate > incoming_warning_threshold + || outgoing_rate > outgoing_warning_threshold) { + result = STATE_WARNING; + sprintf (error_message, "%s. In = %0.1f %s, %s. Out = %0.1f %s", + (use_average == TRUE) ? "Ave" : "Max", adjusted_incoming_rate, + incoming_speed_rating, (use_average == TRUE) ? "Ave" : "Max", + adjusted_outgoing_rate, outgoing_speed_rating); + } + + if (result == STATE_OK) + printf ("Traffic ok - %s. In = %0.1f %s, %s. Out = %0.1f %s\n", + (use_average == TRUE) ? "Ave" : "Max", adjusted_incoming_rate, + incoming_speed_rating, (use_average == TRUE) ? "Ave" : "Max", + adjusted_outgoing_rate, outgoing_speed_rating); + else + printf ("%s\n", error_message); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (log_file == NULL) { + log_file = argv[c]; + } + else if (expire_minutes == -1) { + expire_minutes = atoi (optarg); + } + else if (strcmp (argv[c], "MAX") == 0) { + use_average = FALSE; + } + else if (strcmp (argv[c], "AVG") == 0) { + use_average = TRUE; + } + else if (incoming_warning_threshold == 0) { + incoming_warning_threshold = strtoul (argv[c], NULL, 10); + } + else if (incoming_critical_threshold == 0) { + incoming_critical_threshold = strtoul (argv[c], NULL, 10); + } + else if (outgoing_warning_threshold == 0) { + outgoing_warning_threshold = strtoul (argv[c], NULL, 10); + } + else if (outgoing_critical_threshold == 0) { + outgoing_critical_threshold = strtoul (argv[c], NULL, 10); + } + } + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"logfile", required_argument, 0, 'F'}, + {"expires", required_argument, 0, 'e'}, + {"aggregation", required_argument, 0, 'a'}, + {"variable", required_argument, 0, 'v'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVF:e:a:c:w:", long_options, &option_index); +#else + c = getopt (argc, argv, "+hVF:e:a:c:w:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'F': + case 'e': + case 'a': + case 'c': + case 'w': + i++; + } + + switch (c) { + case 'F': /* input file */ + log_file = optarg; + break; + case 'e': /* expiration time */ + expire_minutes = atoi (optarg); + break; + case 'a': /* aggregation (AVE or MAX) */ + if (!strcmp (optarg, "MAX")) + use_average = FALSE; + else + use_average = TRUE; + break; + case 'c': /* warning threshold */ + sscanf (optarg, "%lu,%lu", &incoming_critical_threshold, + &outgoing_critical_threshold); + break; + case 'w': /* critical threshold */ + sscanf (optarg, "%lu,%lu", &incoming_warning_threshold, + &outgoing_warning_threshold); + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Tom Shields/Karl DeBisschop\n\n" + "This plugin tests the UPS service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -F, --filename=STRING\n" + " File to read log from\n" + " -e, --expires=INTEGER\n" + " Minutes after which log expires\n" + " -a, --aggregation=(AVG|MAX)\n" + " Test average or maximum" + " -w, --warning\n" + " Warning threshold pair \"<incoming>,<outgoing>\"\n" + " -c, --critical\n" + " Critical threshold pair \"<incoming>,<outgoing>\"\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n"); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -F <log_file> -a <AVG | MAX> -v <variable> -w <warning_pair> -c <critical_pair>\n" + " [-e expire_minutes] [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c new file mode 100644 index 00000000..50836f91 --- /dev/null +++ b/plugins/check_mysql.c @@ -0,0 +1,297 @@ +/****************************************************************************** +* +* CHECK_MYSQL.C +* +* Program: Mysql plugin for Nagios +* License: GPL +* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at) +* portions (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) +* +* $Id$ +* +* Description: +* +* This plugin is for testing a mysql server. +******************************************************************************/ + +#define PROGNAME "check_mysql" + +#include "common.h" +#include "utils.h" + +#include <mysql/mysql.h> +#include <mysql/errmsg.h> + +char *db_user = NULL; +char *db_host = NULL; +char *db_pass = NULL; +char *db = NULL; +unsigned int db_port = MYSQL_PORT; + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int +main (int argc, char **argv) +{ + + MYSQL mysql; + char result[1024]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize mysql */ + mysql_init (&mysql); + + /* establish a connection to the server and error checking */ + if (!mysql_real_connect + (&mysql, db_host, db_user, db_pass, db, db_port, NULL, 0)) { + + if (mysql_errno (&mysql) == CR_UNKNOWN_HOST) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_WARNING; + + } + else if (mysql_errno (&mysql) == CR_VERSION_ERROR) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_WARNING; + + } + else if (mysql_errno (&mysql) == CR_OUT_OF_MEMORY) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_WARNING; + + } + else if (mysql_errno (&mysql) == CR_IPSOCK_ERROR) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_WARNING; + + } + else if (mysql_errno (&mysql) == CR_SOCKET_CREATE_ERROR) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_WARNING; + + } + else { + printf ("%s\n", mysql_error (&mysql)); + return STATE_CRITICAL; + } + + } + + /* get the server stats */ + sprintf (result, mysql_stat (&mysql)); + + /* error checking once more */ + if (mysql_error (&mysql)) { + + if (mysql_errno (&mysql) == CR_SERVER_GONE_ERROR) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_CRITICAL; + + } + else if (mysql_errno (&mysql) == CR_SERVER_LOST) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_CRITICAL; + + } + else if (mysql_errno (&mysql) == CR_UNKNOWN_ERROR) { + printf ("%s\n", mysql_error (&mysql)); + return STATE_UNKNOWN; + } + + } + + /* close the connection */ + mysql_close (&mysql); + + /* print out the result of stats */ + printf ("%s\n", result); + + return STATE_OK; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 1) + return ERROR; + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (db_host == NULL) + if (is_host (argv[c])) { + db_host = argv[c]; + } + else { + usage ("Invalid host name"); + } + else if (db_user == NULL) + db_user = argv[c]; + else if (db_pass == NULL) + db_pass = argv[c]; + else if (db == NULL) + db = argv[c]; + else if (is_intnonneg (argv[c])) + db_port = atoi (argv[c]); + } + + if (db_host == NULL) + db_host = strscpy (db_host, "127.0.0.1"); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"database", required_argument, 0, 'd'}, + {"username", required_argument, 0, 'u'}, + {"password", required_argument, 0, 'p'}, + {"port", required_argument, 0, 'P'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVP:p:u:d:H:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVP:p:u:d:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'P': + case 'p': + case 'u': + case 'd': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + db_host = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'd': /* hostname */ + db = optarg; + break; + case 'u': /* username */ + db_user = optarg; + break; + case 'p': /* authentication information: password */ + db_pass = optarg; + break; + case 'P': /* critical time threshold */ + db_port = atoi (optarg); + break; + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Didi Rieder/Karl DeBisschop\n\n" + "This plugin is for testing a mysql server.\n"); + print_usage (); + printf + ("\nThere are no required arguments. By default, the local database with\n" + "a server listening on MySQL standard port %d will be checked\n\n" + "Options:\n" + " -d, --database=STRING\n" + " Check database with indicated name\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -P, --port=INTEGER\n" + " Make connection on the indicated port\n" + " -u, --username=STRING\n" + " Connect using the indicated username\n" + " -p, --password=STRING\n" + " Use the indicated password to authenticate the connection\n" + " ==> IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!! <==\n" + " Your clear-text password will be visible as a process table entry\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n", MYSQL_PORT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s [-d database] [-H host] [-P port] [-u user] [-p password]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_nagios.c b/plugins/check_nagios.c new file mode 100644 index 00000000..04258354 --- /dev/null +++ b/plugins/check_nagios.c @@ -0,0 +1,267 @@ +/****************************************************************************** + * + * CHECK_NAGIOS.C + * + * Program: Nagios process plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * $Id$ + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_nagios" + +int process_arguments (int, char **); +void print_usage (void); +void print_help (void); + +char *status_log = NULL; +char *process_string = NULL; +int expire_minutes = 0; + +int +main (int argc, char **argv) +{ + int result = STATE_UNKNOWN; + char input_buffer[MAX_INPUT_BUFFER]; + unsigned long latest_entry_time = 0L; + unsigned long temp_entry_time = 0L; + int proc_entries = 0; + time_t current_time; + char *temp_ptr; + FILE *fp; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* Set signal handling and alarm */ + if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + + /* handle timeouts gracefully... */ + alarm (timeout_interval); + + /* open the status log */ + fp = fopen (status_log, "r"); + if (fp == NULL) { + printf ("Error: Cannot open status log for reading!\n"); + return STATE_CRITICAL; + } + + /* get the date/time of the last item updated in the log */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + temp_ptr = strtok (input_buffer, "]"); + temp_entry_time = + (temp_ptr == NULL) ? 0L : strtoul (temp_ptr + 1, NULL, 10); + if (temp_entry_time > latest_entry_time) + latest_entry_time = temp_entry_time; + } + fclose (fp); + + /* run the command to check for the Nagios process.. */ + child_process = spopen (PS_RAW_COMMAND); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", PS_RAW_COMMAND); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", PS_RAW_COMMAND); + } + + /* cound the number of matching Nagios processes... */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + if (strstr (input_buffer, process_string)) + proc_entries++; + } + + /* If we get anything on stderr, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + /* reset the alarm handler */ + alarm (0); + + if (proc_entries == 0) { + printf ("Could not locate a running Nagios process!\n"); + return STATE_CRITICAL; + } + + result = STATE_OK; + + time (¤t_time); + if ((current_time - latest_entry_time) > (expire_minutes * 60)) + result = STATE_WARNING; + + printf + ("Nagios %s: located %d process%s, status log updated %d second%s ago\n", + (result == STATE_OK) ? "ok" : "problem", proc_entries, + (proc_entries == 1) ? "" : "es", + (int) (current_time - latest_entry_time), + ((int) (current_time - latest_entry_time) == 1) ? "" : "s"); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"filename", required_argument, 0, 'F'}, + {"expires", required_argument, 0, 'e'}, + {"command", required_argument, 0, 'C'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + if (argc < 2) + return ERROR; + + if (!is_option (argv[1])) { + status_log = argv[1]; + if (is_intnonneg (argv[2])) + expire_minutes = atoi (argv[2]); + else + terminate (STATE_UNKNOWN, + "Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n", + PROGNAME); + process_string = argv[3]; + return OK; + } + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVF:C:e:", long_options, &option_index); +#else + c = getopt (argc, argv, "+hVF:C:e:"); +#endif + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %c\n\n", my_basename (argv[0]), optopt); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'F': /* hostname */ + status_log = optarg; + break; + case 'C': /* hostname */ + process_string = optarg; + break; + case 'e': /* hostname */ + if (is_intnonneg (optarg)) + expire_minutes = atoi (optarg); + else + terminate (STATE_UNKNOWN, + "Expiration time must be an integer (seconds)\nType '%s -h' for additional help\n", + PROGNAME); + break; + } + } + + + if (status_log == NULL) + terminate (STATE_UNKNOWN, + "You must provide the status_log\nType '%s -h' for additional help\n", + PROGNAME); + else if (process_string == NULL) + terminate (STATE_UNKNOWN, + "You must provide a process string\nType '%s -h' for additional help\n", + PROGNAME); + + return OK; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -F <status log file> -e <expire_minutes> -C <process_string>\n", + PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin attempts to check the status of the Nagios process on the local\n" + "machine. The plugin will check to make sure the Nagios status log is no older\n" + "than the number of minutes specified by the <expire_minutes> option. It also\n" + "uses the /bin/ps command to check for a process matching whatever you specify\n" + "by the <process_string> argument.\n"); + print_usage (); + printf + ("\nOptions:\n" + "-F, --filename=FILE\n" + " Name of the log file to check\n" + "-e, --expires=INTEGER\n" + " Seconds aging afterwhich logfile is condsidered stale\n" + "-C, --command=STRING\n" + " Command to search for in process table\n" + "-h, --help\n" + " Print this help screen\n" + "-V, --version\n" + " Print version information\n\n" + "Example:\n" + " ./check_nagios -H /usr/local/nagios/var/status.log -e 5 -C /usr/local/nagios/bin/nagios\n"); +} diff --git a/plugins/check_nntp.c b/plugins/check_nntp.c new file mode 100644 index 00000000..4bdc83ab --- /dev/null +++ b/plugins/check_nntp.c @@ -0,0 +1,418 @@ +/****************************************************************************** + * + * CHECK_NNTP.C + * + * Program: NNTP plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * $Id$ + * + * Description: + * + * This plugin will attempt to open an NNTP connection with the host. + * Successul connects return STATE_OK, refusals and timeouts return + * STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful + * connects, but incorrect reponse messages from the host result in + * STATE_WARNING return values. An invalid newsgroup (if the -g + * option is used) results in a STATE_WARNING value. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_nntp" + +#define PORT 119 +#define EXPECT1A "200" /* posting allowed */ +#define EXPECT1B "201" /* posting not allowed */ +#define EXPECT "NNTP" +#define QUIT "QUIT\r\n" +#define MODEREADER "MODE READER\r\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int server_port = PORT; +char *server_expect = NULL; +char *server_address = NULL; +char *newsgroup = NULL; +int check_newsgroup = FALSE; +int send_modereader = FALSE; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + + +int +main (int argc, char **argv) +{ + char buffer[MAX_INPUT_BUFFER] = ""; + int sd; + int result; + int recv_result; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected */ + if (result == STATE_OK) { + + /* watch for the NNTP connection string */ + recv_result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* return a WARNING status if we couldn't read any data */ + if (recv_result == -1) { + + printf ("recv() failed\n"); + result = STATE_WARNING; + + } + else { + + /* strip carriage returns from buffer */ + strip (buffer); + + /* make sure we find the response we are looking for */ + if (strstr (buffer, EXPECT1A) != buffer + && strstr (buffer, EXPECT1B) != buffer) { + printf ("Invalid NNTP response received from host: %s\n", buffer); + result = STATE_WARNING; + } + + /* optionally send mode reader */ + /* added 2000-09-18 by Andreas M. Kirchwitz <amk@krell.snafu.de> including some other minor fixes */ + if (send_modereader == TRUE) { + send (sd, MODEREADER, strlen (MODEREADER), 0); + recv_result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + if (recv_result == -1) + strcpy (buffer, ""); + else + buffer[recv_result] = 0; + strip (buffer); + if ((strstr (buffer, EXPECT1A) != buffer) + && (strstr (buffer, EXPECT1B) != buffer)) { + printf ("Unexpected NNTP response received from host"); + result = STATE_WARNING; + } + } + + if (server_expect && !strstr (buffer, server_expect)) { + printf ("Invalid NNTP header received from host: %s\n", buffer); + result = STATE_WARNING; + } + + if (check_newsgroup == TRUE) { + sprintf (buffer, "GROUP %s\r\n", newsgroup); + send (sd, buffer, strlen (buffer), 0); + recv_result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + if (recv_result == -1) + strcpy (buffer, ""); + else + buffer[recv_result] = 0; + strip (buffer); + if (strstr (buffer, "211") != buffer) { + printf ("NNTP problem - newsgroup '%s' not found\n", newsgroup); + result = STATE_WARNING; + } + } + + if (result == STATE_OK) { + time (&end_time); + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = + STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + if (verbose) + printf ("NNTP %s - %d sec. response time, %s\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time), buffer); + else + printf ("NNTP %s - %d second response time\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time)); + } + + } + + /* close the connection */ + send (sd, QUIT, strlen (QUIT), 0); + close (sd); + + } + + /* reset the alarm timeout */ + alarm (0); + + return result; +} + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_address == NULL) + server_address = strscpy (NULL, "127.0.0.1"); + +/* if (server_expect==NULL) */ +/* server_expect=strscpy(NULL,EXPECT); */ + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'P'}, + {"modereader", required_argument, 0, 'M'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVMvt:p:e:c:w:H:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVMvt:p:e:c:w:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'p': + case 'e': + case 'c': + case 'w': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'M': /* mode reader */ + send_modereader = TRUE; + break; + case 'e': /* expect */ + server_expect = optarg; + break; + case 'g': /* newsgroup */ + newsgroup = optarg; + check_newsgroup = TRUE; + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_time = atoi (optarg); + check_critical_time = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_time = atoi (optarg); + check_warning_time = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin tests the NNTP service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -g, --group=STRING\n" + " Newsgroup to poll\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -M\n" + " Send \"MODE READER\" after initial connect.\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", + PORT, EXPECT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-g group] [-p port] [-w warn] [-c crit]\n" + " [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_nt.c b/plugins/check_nt.c new file mode 100644 index 00000000..ed0dc98b --- /dev/null +++ b/plugins/check_nt.c @@ -0,0 +1,548 @@ +/****************************************************************************** + * + * This file is part of the Nagios Plugins. + * + * Copyright (c) 2000 Yves Rubin <rubiyz@yahoo.com> + * + * The Nagios Plugins are free software; you can redistribute them + * and/or modify them 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGRAM check_nt +#define DESCRIPTION "Windows NT plugin for Nagios" +#define AUTHOR "Yves Rubin" +#define EMAIL "rubiyz@yahoo.com" +#define COPYRIGHTDATE "2000" + +//#include "stdlib.h" +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define CHECK_NONE 0 +#define CHECK_CLIENTVERSION 1 +#define CHECK_CPULOAD 2 +#define CHECK_UPTIME 3 +#define CHECK_USEDDISKSPACE 4 +#define CHECK_SERVICESTATE 5 +#define CHECK_PROCSTATE 6 +#define CHECK_MEMUSE 7 +#define CHECK_COUNTER 8 +#define MAX_VALUE_LIST 30 + +#define PORT 1248 + +char *server_address=NULL; +char *volume_name=NULL; +int server_port=PORT; +char *value_list=NULL; +char *req_password=NULL; +unsigned long lvalue_list[MAX_VALUE_LIST]; +unsigned long warning_value=0L; +unsigned long critical_value=0L; +int check_value_list=FALSE; +int check_warning_value=FALSE; +int check_critical_value=FALSE; +int vars_to_check=CHECK_NONE; +int show_all=FALSE; + +#define PROGNAME "check_nt" + +int process_arguments(int, char **); +void print_usage(void); +void print_help(void); +void preparelist(char *string); + +int main(int argc, char **argv){ + int result; + int return_code; + char *send_buffer=NULL; + char recv_buffer[MAX_INPUT_BUFFER]; + char *output_message=NULL; + char *temp_buffer=NULL; + char *temp_string=NULL; + char *sep_string=NULL; + char *description=NULL; + + double total_disk_space=0; + double free_disk_space=0; + double percent_used_space=0; + double mem_commitLimit=0; + double mem_commitByte=0; + unsigned long current_connections=0; + unsigned long utilization; + unsigned long uptime; + unsigned long cache_hits; + unsigned long cache_buffers; + unsigned long lru_time; + double counter_value; + int offset=0; + int updays=0; + int uphours=0; + int upminutes=0; + req_password=strscpy(req_password,"None"); + + if(process_arguments(argc,argv)==ERROR) + usage("Could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal(SIGALRM,socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm(socket_timeout); + + if (vars_to_check==CHECK_CLIENTVERSION) { + + send_buffer = strscpy(send_buffer,strcat(req_password,"&1")); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + output_message = strscpy(output_message,recv_buffer); + return_code=STATE_OK; + } + else if(vars_to_check==CHECK_CPULOAD){ + + if (check_value_list==TRUE) { + if (strtolarray(&lvalue_list,value_list,",")==TRUE) { + // -l parameters is present with only integers + return_code=STATE_OK; + temp_string = strscpy(temp_string,"CPU Load"); + while (lvalue_list[0+offset]>0 && lvalue_list[0+offset]<=17280 && + lvalue_list[1+offset]>=0 && lvalue_list[1+offset]<=100 && + lvalue_list[2+offset]>=0 && lvalue_list[2+offset]<=100) { + // loop until one of the parameters is wrong or not present + + // Send request and retrieve data + send_buffer = ssprintf(send_buffer,"%s&2&%lu",req_password,lvalue_list[0+offset]); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strncmp(recv_buffer,"ERROR",5)) { + printf("NSClient - %s\n",recv_buffer); + exit(STATE_UNKNOWN); + } + + utilization=strtoul(recv_buffer,NULL,10); + + // Check if any of the request is in a warning or critical state + if(utilization >= lvalue_list[2+offset]) + return_code=STATE_CRITICAL; + else if(utilization >= lvalue_list[1+offset] && return_code<STATE_WARNING) + return_code=STATE_WARNING; + + output_message = ssprintf(output_message," (%lu min. %lu%)",lvalue_list[0+offset], utilization); + temp_string = strscat(temp_string,output_message); + offset+=3; //move accross the array + } + if (strlen(temp_string)>10) { + // we had at least on loop + output_message = ssprintf(output_message,"%s",temp_string); + } + else + output_message = strscpy(output_message,"not enough values for -l parameters"); + + } else + output_message = strscpy(output_message,"wrong -l parameter."); + + } else + output_message = strscpy(output_message,"missing -l parameters"); + } + + else if(vars_to_check==CHECK_UPTIME){ + + send_buffer = strscpy(send_buffer,strcat(req_password,"&3")); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strncmp(recv_buffer,"ERROR",5)) { + printf("NSClient - %s\n",recv_buffer); + exit(STATE_UNKNOWN); + } + + uptime=strtoul(recv_buffer,NULL,10); + updays = uptime / 86400; + uphours = (uptime % 86400) / 3600; + upminutes = ((uptime % 86400) % 3600) / 60; + output_message = ssprintf(output_message,"System Uptime : %u day(s) %u hour(s) %u minute(s)",updays,uphours, upminutes); + return_code=STATE_OK; + } + + else if(vars_to_check==CHECK_USEDDISKSPACE){ + + return_code=STATE_UNKNOWN; + if (check_value_list==TRUE) { + if (strlen(value_list)==1) { + send_buffer = ssprintf(send_buffer,"%s&4&%s", req_password, value_list); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strncmp(recv_buffer,"ERROR",5)) { + printf("NSClient - %s\n",recv_buffer); + exit(STATE_UNKNOWN); + } + + free_disk_space=atof(strtok(recv_buffer,"&")); + total_disk_space=atof(strtok(NULL,"&")); + percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; + + if (free_disk_space>=0) { + temp_string = ssprintf(temp_string,"%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)", + value_list, total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space, + free_disk_space / 1073741824, (free_disk_space / total_disk_space)*100); + + + if(check_critical_value==TRUE && percent_used_space >= critical_value) + return_code=STATE_CRITICAL; + else if (check_warning_value==TRUE && percent_used_space >= warning_value) + return_code=STATE_WARNING; + else + return_code=STATE_OK; + + output_message = ssprintf(output_message,"%s",temp_string); + + } + else { + output_message = ssprintf(output_message,"Free disk space : Invalid drive "); + return_code=STATE_UNKNOWN; + } + } + else + output_message = strscpy(output_message,"wrong -l argument"); + } else + output_message = strscpy(output_message,"missing -l parameters"); + + } + + else if(vars_to_check==CHECK_SERVICESTATE || vars_to_check==CHECK_PROCSTATE){ + + if (check_value_list==TRUE) { + preparelist(value_list); // replace , between services with & to send the request + send_buffer = ssprintf(send_buffer,"%s&%u&%s&%s", req_password,(vars_to_check==CHECK_SERVICESTATE)?5:6, + (show_all==TRUE)?"ShowAll":"ShowFail",value_list); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strncmp(recv_buffer,"ERROR",5)) { + printf("NSClient - %s\n",recv_buffer); + exit(STATE_UNKNOWN); + } + return_code=atoi(strtok(recv_buffer,"&")); + temp_string=strtok(NULL,"&"); + output_message = ssprintf(output_message, "%s",temp_string); + } + else + output_message = strscpy(output_message,"No service/process specified"); + } + + else if(vars_to_check==CHECK_MEMUSE) { + + send_buffer = ssprintf(send_buffer,"%s&7", req_password); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if (result!=STATE_OK) + return result; + + if (!strncmp(recv_buffer,"ERROR",5)) { + printf("NSClient - %s\n",recv_buffer); + exit(STATE_UNKNOWN); + } + + mem_commitLimit=atof(strtok(recv_buffer,"&")); + mem_commitByte=atof(strtok(NULL,"&")); + percent_used_space = (mem_commitByte / mem_commitLimit) * 100; + output_message = ssprintf(output_message,"Memory usage: total:%.2f Mb - used: %.2f Mb (%.0f%%) - free: %.2f Mb (%.0f%%)", + mem_commitLimit / 1048576, mem_commitByte / 1048567, percent_used_space, + (mem_commitLimit - mem_commitByte) / 1048576, (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100); + + if(check_critical_value==TRUE && percent_used_space >= critical_value) + return_code=STATE_CRITICAL; + else if (check_warning_value==TRUE && percent_used_space >= warning_value) + return_code=STATE_WARNING; + else + return_code=STATE_OK; + + } + + else if(vars_to_check==CHECK_COUNTER) { + + if (check_value_list==TRUE) { + preparelist(value_list); // replace , between services with & to send the request + send_buffer = ssprintf(send_buffer,"%s&8&%s", req_password,value_list); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if (result!=STATE_OK) + return result; + + if (!strncmp(recv_buffer,"ERROR",5)) { + printf("NSClient - %s\n",recv_buffer); + exit(STATE_UNKNOWN); + } + + strtok(value_list,"&"); // burn the first parameters + description = strtok(NULL,"&"); + counter_value = atof(recv_buffer); + if (description == NULL) + output_message = ssprintf(output_message, "%.f", counter_value); + else + output_message = ssprintf(output_message, description, counter_value); + + if (critical_value > warning_value) { + // Normal thresholds + if(check_critical_value==TRUE && counter_value >= critical_value) + return_code=STATE_CRITICAL; + else if (check_warning_value==TRUE && counter_value >= warning_value) + return_code=STATE_WARNING; + else + return_code=STATE_OK; + } + else { + // inverse thresholds + if(check_critical_value==TRUE && counter_value <= critical_value) + return_code=STATE_CRITICAL; + else if (check_warning_value==TRUE && counter_value <= warning_value) + return_code=STATE_WARNING; + else + return_code=STATE_OK; + } + + } + else { + output_message = strscpy(output_message,"No counter specified"); + result=STATE_UNKNOWN; + } + } + + /* reset timeout */ + alarm(0); + + printf("%s\n",output_message); + + return return_code; +} + + +/* process command-line arguments */ +int process_arguments(int argc, char **argv){ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = + { + {"port", required_argument,0,'p'}, + {"timeout", required_argument,0,'t'}, + {"critical", required_argument,0,'c'}, + {"warning", required_argument,0,'w'}, + {"variable", required_argument,0,'v'}, + {"hostname", required_argument,0,'H'}, + {"version", no_argument, 0,'V'}, + {"help", no_argument, 0,'h'}, + {0,0,0,0} + }; +#endif + + /* no options were supplied */ + if(argc<2) return ERROR; + + /* backwards compatibility */ + if (! is_option(argv[1])) { + server_address=argv[1]; + argv[1]=argv[0]; + argv=&argv[1]; + argc--; + } + + for (c=1;c<argc;c++) { + if(strcmp("-to",argv[c])==0) + strcpy(argv[c],"-t"); + else if (strcmp("-wv",argv[c])==0) + strcpy(argv[c],"-w"); + else if (strcmp("-cv",argv[c])==0) + strcpy(argv[c],"-c"); + } + + while (1){ +#ifdef HAVE_GETOPT_H + c = getopt_long(argc,argv,"+hVH:t:c:w:p:v:l:s:d:",long_options,&option_index); +#else + c = getopt(argc,argv,"+hVH:t:c:w:p:v:l:s:d:"); +#endif + + if (c==-1||c==EOF||c==1) + break; + + switch (c) + { + case '?': /* print short usage statement if args not parsable */ + printf("%s: Unknown argument: %s\n\n",my_basename(argv[0]),optarg); + print_usage(); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_OK); + case 'V': /* version */ + print_revision(my_basename(argv[0]),"$Revision$"); + exit(STATE_OK); + case 'H': /* hostname */ + server_address=optarg; + break; + case 's': /* password */ + req_password=strscpy(req_password,optarg); + break; + case 'p': /* port */ + if (is_intnonneg(optarg)) + server_port=atoi(optarg); + else + terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",PROGNAME); + break; + case 'v': + if(strlen(optarg)<4) + return ERROR; + if(!strcmp(optarg,"CLIENTVERSION")) + vars_to_check=CHECK_CLIENTVERSION; + else if(!strcmp(optarg,"CPULOAD")) + vars_to_check=CHECK_CPULOAD; + else if(!strcmp(optarg,"UPTIME")) + vars_to_check=CHECK_UPTIME; + else if(!strcmp(optarg,"USEDDISKSPACE")) + vars_to_check=CHECK_USEDDISKSPACE; + else if(!strcmp(optarg,"SERVICESTATE")) + vars_to_check=CHECK_SERVICESTATE; + else if(!strcmp(optarg,"PROCSTATE")) + vars_to_check=CHECK_PROCSTATE; + else if(!strcmp(optarg,"MEMUSE")) + vars_to_check=CHECK_MEMUSE; + else if(!strcmp(optarg,"COUNTER")) + vars_to_check=CHECK_COUNTER; + else + return ERROR; + break; + case 'l': /* value list */ + value_list=strscpy(value_list,optarg); + check_value_list=TRUE; + break; + case 'w': /* warning threshold */ + warning_value=strtoul(optarg,NULL,10); + check_warning_value=TRUE; + break; + case 'c': /* critical threshold */ + critical_value=strtoul(optarg,NULL,10); + check_critical_value=TRUE; + break; + case 'd': /* Display select for services */ + if (!strcmp(optarg,"SHOWALL")) + show_all = TRUE; + break; + case 't': /* timeout */ + socket_timeout=atoi(optarg); + if(socket_timeout<=0) + return ERROR; + } + + } + + return OK; +} + + +void print_usage(void) +{ + printf("Usage: %s -H host [-p port] [-v variable] [-w warning] [-c critical] [-l params] [-d SHOWALL] [-t timeout]\n",PROGNAME); +} + + +void print_help(void) +{ + print_revision(PROGNAME,"$Revision$"); + printf + ("Copyright (c) 2000 Yves Rubin (rubiyz@yahoo.com)\n\n" + "This plugin attempts to contact the NSClient service running on a Windows NT or Windows 2000 server to\n" + "gather the requested system information.\n\n"); + print_usage(); + printf + ("\nOptions:\n" + "-H, --hostname=HOST\n" + " Name of the host to check\n" + "-p, --port=INTEGER\n" + " Optional port number (default: %d)\n" + "-s <password>\n" + " Password needed for the request\n" + "-v, --variable=STRING\n" + " Variable to check. Valid variables are:\n" + " CLIENTVERSION = Get the NSClient version\n" + " CPULOAD = Average CPU load on last x minutes. Request a -l parameter with the following syntax:\n" + " -l <minutes range>,<warning threshold>,<critical threshold>. <minute range> should be less than 24*60.\n" + " Thresholds are percentage and up to 10 requests can be done in one shot. ie: -l 60,90,95,120,90,95\n" + " UPTIME = Get the uptime of the machine. No specific parameters. No warning or critical threshold\n" + " USEDDISKSPACE = Size and percentage of disk use. Request a -l parameter containing the drive letter only.\n" + " Warning and critical thresholds can be specified with -w and -c.\n" + " MEMUSE = Memory use. Warning and critical thresholds can be specified with -w and -c.\n" + " SERVICESTATE = Check the state of one or several services. Request a -l parameters with the following syntax:\n" + " -l <service1>,<service2>,<service3>,... You can specify -d SHOWALL in case you want to see working services\n" + " in the returned string.\n" + " PROCSTATE = Check if one or several process are running. Same syntax as SERVICESTATE.\n" + " COUNTER = Check any performance counter of Windows NT/2000. Request a -l parameters with the following syntax:\n" + " -l \"\\\\<performance object>\\\\counter\",\"<description>\" The <description> parameter is optional and \n" + " is given to a printf output command which require a float parameters. Some examples:\n" + " \"Paging file usage is %%.2f %%%%\" or \"%%.f %%%% paging file used.\"\n" + " -w, --warning=INTEGER\n" + " Threshold which will result in a warning status\n" + " -c, --critical=INTEGER\n" + " Threshold which will result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + "-h, --help\n" + " Print this help screen\n" + "-V, --version\n" + " Print version information\n\n" + "Notes:\n" + " - The NSClient service should be running on the server to get any information.\n" + " - Critical thresholds should be lower than warning thresholds\n", PORT, DEFAULT_SOCKET_TIMEOUT); +} + +int strtolarray(unsigned long *array, char *string, char *delim) { + // split a <delim> delimited string into a long array + int idx=0; + char *t1; + + for (idx=0;idx<MAX_VALUE_LIST;idx++) + array[idx]=-1; + + idx=0; + for(t1 = strtok(string,delim);t1 != NULL; t1 = strtok(NULL, delim)) { + if (is_numeric(t1) && idx<MAX_VALUE_LIST) { + array[idx]=strtoul(t1,NULL,10); + idx++; + } else + return FALSE; + } + return TRUE; +} + +void preparelist(char *string) { + // Replace all , with & which is the delimiter for the request + int i; + + for (i = 0; i < strlen(string); i++) + if (string[i] == ',') { + string[i]='&'; + } +} + diff --git a/plugins/check_nwstat.c b/plugins/check_nwstat.c new file mode 100644 index 00000000..e1426702 --- /dev/null +++ b/plugins/check_nwstat.c @@ -0,0 +1,821 @@ +/****************************************************************************** + * + * Program: NetWare statistics plugin for Nagios + * License: GPL + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_nwstat" +#define REVISION "$Revision$" +#define COPYRIGHT "Copyright (c) 1999-2001 Ethan Galstad" + +#define SUMMARY "\ +This plugin attempts to contact the MRTGEXT NLM running on a Novell server\n\ +to gather the requested system information.\n" + +#define OPTIONS "\ +-H host [-v variable] [-w warning] [-c critical]\n\ + [-p port] [-t timeout]" + +#define LONGOPTIONS "\ +-H, --hostname=HOST\n\ + Name of the host to check\n\ +-v, --variable=STRING\n\ + Variable to check. Valid variables include:\n\ + LOAD1 = 1 minute average CPU load\n\ + LOAD5 = 5 minute average CPU load\n\ + LOAD15 = 15 minute average CPU load\n\ + CONNS = number of currently licensed connections\n\ + VPF<vol> = percent free space on volume <vol>\n\ + VKF<vol> = KB of free space on volume <vol>\n\ + LTCH = percent long term cache hits\n\ + CBUFF = current number of cache buffers\n\ + CDBUFF = current number of dirty cache buffers\n\ + LRUM = LRU sitting time in minutes\n\ + DSDB = check to see if DS Database is open\n\ + LOGINS = check to see if logins are enabled\n\ + UPRB = used packet receive buffers\n\ + PUPRB = percent (of max) used packet receive buffers\n\ + SAPENTRIES = number of entries in the SAP table\n\ + SAPENTRIES<n> = number of entries in the SAP table for SAP type <n>\n\ + OFILES = number of open files\n\ + VPP<vol> = percent purgeable space on volume <vol>\n\ + VKP<vol> = KB of purgeable space on volume <vol>\n\ + VPNP<vol> = percent not yet purgeable space on volume <vol>\n\ + VKNP<vol> = KB of not yet purgeable space on volume <vol>\n\ + ABENDS = number of abended threads (NW 5.x only)\n\ + CSPROCS = number of current service processes (NW 5.x only)\n\ +-w, --warning=INTEGER\n\ + Threshold which will result in a warning status\n\ +-c, --critical=INTEGER\n\ + Threshold which will result in a critical status\n\ +-p, --port=INTEGER\n\ + Optional port number (default: %d)\n\ +-t, --timeout=INTEGER\n\ + Seconds before connection attempt times out (default: %d)\n\ +-o, --osversion\n\ + Include server version string in results\n\ +-h, --help\n\ + Print this help screen\n\ +-V, --version\n\ + Print version information\n" + +#define DESCRIPTION "\ +Notes:\n\ +- This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG\n\ + extension for NetWare be loaded on the Novell servers you wish to check.\n\ + (available from http://www.engr.wisc.edu/~drews/mrtg/)\n\ +- Values for critical thresholds should be lower than warning thresholds\n\ + when the following variables are checked: VPF, VKF, LTCH, CBUFF, and LRUM.\n" + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define CHECK_NONE 0 +#define CHECK_LOAD1 1 /* check 1 minute CPU load */ +#define CHECK_LOAD5 2 /* check 5 minute CPU load */ +#define CHECK_LOAD15 3 /* check 15 minute CPU load */ +#define CHECK_CONNS 4 /* check number of connections */ +#define CHECK_VPF 5 /* check % free space on volume */ +#define CHECK_VKF 6 /* check KB free space on volume */ +#define CHECK_LTCH 7 /* check long-term cache hit percentage */ +#define CHECK_CBUFF 8 /* check total cache buffers */ +#define CHECK_CDBUFF 9 /* check dirty cache buffers */ +#define CHECK_LRUM 10 /* check LRU sitting time in minutes */ +#define CHECK_DSDB 11 /* check to see if DS Database is open */ +#define CHECK_LOGINS 12 /* check to see if logins are enabled */ +#define CHECK_PUPRB 13 /* check % of used packet receive buffers */ +#define CHECK_UPRB 14 /* check used packet receive buffers */ +#define CHECK_SAPENTRIES 15 /* check SAP entries */ +#define CHECK_OFILES 16 /* check number of open files */ +#define CHECK_VKP 17 /* check KB purgeable space on volume */ +#define CHECK_VPP 18 /* check % purgeable space on volume */ +#define CHECK_VKNP 19 /* check KB not yet purgeable space on volume */ +#define CHECK_VPNP 20 /* check % not yet purgeable space on volume */ +#define CHECK_ABENDS 21 /* check abended thread count */ +#define CHECK_CSPROCS 22 /* check number of current service processes */ + +#define PORT 9999 + +char *server_address=NULL; +char *volume_name=NULL; +int server_port=PORT; +unsigned long warning_value=0L; +unsigned long critical_value=0L; +int check_warning_value=FALSE; +int check_critical_value=FALSE; +int check_netware_version=FALSE; +unsigned long vars_to_check=CHECK_NONE; +int sap_number=-1; + +#define PROGNAME "check_nwstat" + +int process_arguments(int, char **); +void print_usage(void); +void print_help(void); + +int main(int argc, char **argv){ + int result; + char *send_buffer=NULL; + char recv_buffer[MAX_INPUT_BUFFER]; + char *output_message=NULL; + char *temp_buffer=NULL; + char *netware_version=NULL; + + int open_files=0; + int abended_threads=0; + int max_service_processes=0; + int current_service_processes=0; + unsigned long free_disk_space=0L; + unsigned long total_disk_space=0L; + unsigned long purgeable_disk_space=0L; + unsigned long non_purgeable_disk_space=0L; + int percent_free_space=0; + int percent_purgeable_space=0; + int percent_non_purgeable_space=0; + unsigned long current_connections=0L; + unsigned long utilization=0L; + int cache_hits=0; + unsigned long cache_buffers=0L; + unsigned long lru_time=0L; + char uptime[MAX_INPUT_BUFFER]; + int max_packet_receive_buffers=0; + int used_packet_receive_buffers=0; + unsigned long percent_used_packet_receive_buffers=0L; + int sap_entries=0; + + if(process_arguments(argc,argv)==ERROR) + usage("Could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal(SIGALRM,socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm(socket_timeout); + + /* get OS version string */ + if (check_netware_version==TRUE) { + send_buffer = strscpy(send_buffer,"S19\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + if(!strcmp(recv_buffer,"-1\n")) + netware_version = ssprintf(netware_version,""); + else { + recv_buffer[strlen(recv_buffer)-1]=0; + netware_version = ssprintf(netware_version,"NetWare %s: ",recv_buffer); + } + } else + netware_version = ssprintf(netware_version,""); + + + /* check CPU load */ + if (vars_to_check==CHECK_LOAD1 || vars_to_check==CHECK_LOAD5 || vars_to_check==CHECK_LOAD15) { + + switch(vars_to_check){ + case CHECK_LOAD1: + temp_buffer = strscpy(temp_buffer,"1"); + break; + case CHECK_LOAD5: + temp_buffer = strscpy(temp_buffer,"5"); + break; + default: + temp_buffer = strscpy(temp_buffer,"15"); + break; + } + + send_buffer = ssprintf(send_buffer,"UTIL%s\r\n",temp_buffer); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + utilization=strtoul(recv_buffer,NULL,10); + send_buffer = strscpy(send_buffer,"UPTIME\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + recv_buffer[strlen(recv_buffer)-1]=0; + sprintf(uptime,"Up %s,",recv_buffer); + + if(check_critical_value==TRUE && utilization >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && utilization >= warning_value) + result=STATE_WARNING; + + output_message = ssprintf(output_message,"Load %s - %s %s-min load average = %lu%%",(result==STATE_OK)?"ok":"problem",uptime,temp_buffer,utilization); + + /* check number of user connections */ + } else if (vars_to_check==CHECK_CONNS) { + + send_buffer = strscpy(send_buffer,"CONNECT\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + current_connections=strtoul(recv_buffer,NULL,10); + + if(check_critical_value==TRUE && current_connections >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && current_connections >= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"Conns %s - %lu current connections",(result==STATE_OK)?"ok":"problem",current_connections); + + /* check % long term cache hits */ + } else if (vars_to_check==CHECK_LTCH) { + + send_buffer = strscpy(send_buffer,"S1\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + cache_hits=atoi(recv_buffer); + + if(check_critical_value==TRUE && cache_hits <= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && cache_hits <= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"Long term cache hits = %d%%",cache_hits); + + /* check cache buffers */ + } else if (vars_to_check==CHECK_CBUFF) { + + send_buffer = strscpy(send_buffer,"S2\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + cache_buffers=strtoul(recv_buffer,NULL,10); + + if(check_critical_value==TRUE && cache_buffers <= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && cache_buffers <= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"Total cache buffers = %lu",cache_buffers); + + /* check dirty cache buffers */ + } else if (vars_to_check==CHECK_CDBUFF) { + + send_buffer = strscpy(send_buffer,"S3\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + cache_buffers=strtoul(recv_buffer,NULL,10); + + if(check_critical_value==TRUE && cache_buffers >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && cache_buffers >= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"Dirty cache buffers = %lu",cache_buffers); + + /* check LRU sitting time in minutes */ + } else if (vars_to_check==CHECK_LRUM) { + + send_buffer = strscpy(send_buffer,"S5\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + lru_time=strtoul(recv_buffer,NULL,10); + + if(check_critical_value==TRUE && lru_time <= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && lru_time <= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"LRU sitting time = %lu minutes",lru_time); + + + /* check KB free space on volume */ + } else if (vars_to_check==CHECK_VKF) { + + send_buffer = ssprintf(send_buffer,"VKF%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strcmp(recv_buffer,"-1\n")) { + output_message = ssprintf(output_message,"Error: Volume '%s' does not exist!",volume_name); + result=STATE_CRITICAL; + } else { + free_disk_space=strtoul(recv_buffer,NULL,10); + if(check_critical_value==TRUE && free_disk_space <= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && free_disk_space <= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"%s%lu KB free on volume %s",(result==STATE_OK)?"":"Only ",free_disk_space,volume_name); + } + + /* check % free space on volume */ + } else if (vars_to_check==CHECK_VPF) { + + send_buffer = ssprintf(send_buffer,"VKF%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if(!strcmp(recv_buffer,"-1\n")){ + + output_message = ssprintf(output_message,"Error: Volume '%s' does not exist!",volume_name); + result=STATE_CRITICAL; + + } else { + + free_disk_space=strtoul(recv_buffer,NULL,10); + + send_buffer = ssprintf(send_buffer,"VKS%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + total_disk_space=strtoul(recv_buffer,NULL,10); + + percent_free_space=(int)(((double)free_disk_space/(double)total_disk_space)*100.0); + + if(check_critical_value==TRUE && percent_free_space <= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && percent_free_space <= warning_value) + result=STATE_WARNING; + free_disk_space/=1024; + output_message = ssprintf(output_message,"%lu MB (%d%%) free on volume %s",free_disk_space,percent_free_space,volume_name); + } + + /* check to see if DS Database is open or closed */ + } else if(vars_to_check==CHECK_DSDB) { + + send_buffer = strscpy(send_buffer,"S11\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + if(atoi(recv_buffer)==1) + result=STATE_OK; + else + result=STATE_WARNING; + + send_buffer = strscpy(send_buffer,"S13\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + temp_buffer=strtok(recv_buffer,"\r\n"); + + output_message = ssprintf(output_message,"Directory Services Database is %s (DS version %s)",(result==STATE_OK)?"open":"closed",temp_buffer); + + /* check to see if logins are enabled */ + } else if (vars_to_check==CHECK_LOGINS) { + + send_buffer = strscpy(send_buffer,"S12\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + if(atoi(recv_buffer)==1) + result=STATE_OK; + else + result=STATE_WARNING; + + output_message = ssprintf(output_message,"Logins are %s",(result==STATE_OK)?"enabled":"disabled"); + + /* check packet receive buffers */ + } else if (vars_to_check==CHECK_UPRB || vars_to_check==CHECK_PUPRB) { + + send_buffer = ssprintf(send_buffer,"S15\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + used_packet_receive_buffers=atoi(recv_buffer); + + send_buffer = ssprintf(send_buffer,"S16\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + max_packet_receive_buffers=atoi(recv_buffer); + + percent_used_packet_receive_buffers=(unsigned long)(((double)used_packet_receive_buffers/(double)max_packet_receive_buffers)*100.0); + + if(vars_to_check==CHECK_UPRB){ + if(check_critical_value==TRUE && used_packet_receive_buffers >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && used_packet_receive_buffers >= warning_value) + result=STATE_WARNING; + } else { + if(check_critical_value==TRUE && percent_used_packet_receive_buffers >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && percent_used_packet_receive_buffers >= warning_value) + result=STATE_WARNING; + } + + output_message = ssprintf(output_message,"%d of %d (%lu%%) packet receive buffers used",used_packet_receive_buffers,max_packet_receive_buffers,percent_used_packet_receive_buffers); + + /* check SAP table entries */ + } else if (vars_to_check==CHECK_SAPENTRIES) { + + if(sap_number==-1) + send_buffer = ssprintf(send_buffer,"S9\r\n"); + else + send_buffer = ssprintf(send_buffer,"S9.%d\r\n",sap_number); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + sap_entries=atoi(recv_buffer); + + if(check_critical_value==TRUE && sap_entries >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && sap_entries >= warning_value) + result=STATE_WARNING; + + if(sap_number==-1) + output_message = ssprintf(output_message,"%d entries in SAP table",sap_entries); + else + output_message = ssprintf(output_message,"%d entries in SAP table for SAP type %d",sap_entries,sap_number); + + /* check KB purgeable space on volume */ + } else if (vars_to_check==CHECK_VKP) { + + send_buffer = ssprintf(send_buffer,"VKP%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strcmp(recv_buffer,"-1\n")) { + output_message = ssprintf(output_message,"Error: Volume '%s' does not exist!",volume_name); + result=STATE_CRITICAL; + } else { + purgeable_disk_space=strtoul(recv_buffer,NULL,10); + if(check_critical_value==TRUE && purgeable_disk_space >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && purgeable_disk_space >= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"%s%lu KB purgeable on volume %s",(result==STATE_OK)?"":"Only ",purgeable_disk_space,volume_name); + } + + /* check % purgeable space on volume */ + } else if (vars_to_check==CHECK_VPP) { + + send_buffer = ssprintf(send_buffer,"VKP%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if(!strcmp(recv_buffer,"-1\n")){ + + output_message = ssprintf(output_message,"Error: Volume '%s' does not exist!",volume_name); + result=STATE_CRITICAL; + + } else { + + purgeable_disk_space=strtoul(recv_buffer,NULL,10); + + send_buffer = ssprintf(send_buffer,"VKS%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + total_disk_space=strtoul(recv_buffer,NULL,10); + + percent_purgeable_space=(int)(((double)purgeable_disk_space/(double)total_disk_space)*100.0); + + if(check_critical_value==TRUE && percent_purgeable_space >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && percent_purgeable_space >= warning_value) + result=STATE_WARNING; + purgeable_disk_space/=1024; + output_message = ssprintf(output_message,"%lu MB (%d%%) purgeable on volume %s",purgeable_disk_space,percent_purgeable_space,volume_name); + } + + /* check KB not yet purgeable space on volume */ + } else if (vars_to_check==CHECK_VKNP) { + + send_buffer = ssprintf(send_buffer,"VKNP%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if (!strcmp(recv_buffer,"-1\n")) { + output_message = ssprintf(output_message,"Error: Volume '%s' does not exist!",volume_name); + result=STATE_CRITICAL; + } else { + non_purgeable_disk_space=strtoul(recv_buffer,NULL,10); + if(check_critical_value==TRUE && non_purgeable_disk_space >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && non_purgeable_disk_space >= warning_value) + result=STATE_WARNING; + output_message = ssprintf(output_message,"%s%lu KB not yet purgeable on volume %s",(result==STATE_OK)?"":"Only ",non_purgeable_disk_space,volume_name); + } + + /* check % not yet purgeable space on volume */ + } else if (vars_to_check==CHECK_VPNP) { + + send_buffer = ssprintf(send_buffer,"VKNP%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + if(!strcmp(recv_buffer,"-1\n")){ + + output_message = ssprintf(output_message,"Error: Volume '%s' does not exist!",volume_name); + result=STATE_CRITICAL; + + } else { + + non_purgeable_disk_space=strtoul(recv_buffer,NULL,10); + + send_buffer = ssprintf(send_buffer,"VKS%s\r\n",volume_name); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + total_disk_space=strtoul(recv_buffer,NULL,10); + + percent_non_purgeable_space=(int)(((double)non_purgeable_disk_space/(double)total_disk_space)*100.0); + + if(check_critical_value==TRUE && percent_non_purgeable_space >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && percent_non_purgeable_space >= warning_value) + result=STATE_WARNING; + purgeable_disk_space/=1024; + output_message = ssprintf(output_message,"%lu MB (%d%%) not yet purgeable on volume %s",non_purgeable_disk_space,percent_non_purgeable_space,volume_name); + } + + /* check # of open files */ + } else if (vars_to_check==CHECK_OFILES) { + + send_buffer = ssprintf(send_buffer,"S18\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + open_files=atoi(recv_buffer); + + if(check_critical_value==TRUE && open_files >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && open_files >= warning_value) + result=STATE_WARNING; + + output_message = ssprintf(output_message,"%d open files",open_files); + + /* check # of abended threads (Netware 5.x only) */ + } else if (vars_to_check==CHECK_ABENDS) { + + send_buffer = ssprintf(send_buffer,"S17\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + abended_threads=atoi(recv_buffer); + + if(check_critical_value==TRUE && abended_threads >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && abended_threads >= warning_value) + result=STATE_WARNING; + + output_message = ssprintf(output_message,"%d abended threads",abended_threads); + + /* check # of current service processes (Netware 5.x only) */ + } else if (vars_to_check==CHECK_CSPROCS) { + + send_buffer = ssprintf(send_buffer,"S20\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + max_service_processes=atoi(recv_buffer); + + send_buffer = ssprintf(send_buffer,"S21\r\n"); + result=process_tcp_request(server_address,server_port,send_buffer,recv_buffer,sizeof(recv_buffer)); + if(result!=STATE_OK) + return result; + + current_service_processes=atoi(recv_buffer); + + if(check_critical_value==TRUE && current_service_processes >= critical_value) + result=STATE_CRITICAL; + else if(check_warning_value==TRUE && current_service_processes >= warning_value) + result=STATE_WARNING; + + output_message = ssprintf(output_message,"%d current service processes (%d max)",current_service_processes,max_service_processes); + + } else { + + output_message = strscpy(output_message,"Nothing to check!\n"); + result=STATE_UNKNOWN; + + } + + /* reset timeout */ + alarm(0); + + printf("%s%s\n",netware_version,output_message); + + return result; +} + + +/* process command-line arguments */ +int process_arguments(int argc, char **argv){ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = + { + {"port", required_argument,0,'p'}, + {"timeout", required_argument,0,'t'}, + {"critical", required_argument,0,'c'}, + {"warning", required_argument,0,'w'}, + {"variable", required_argument,0,'v'}, + {"hostname", required_argument,0,'H'}, + {"osversion",no_argument, 0,'o'}, + {"version", no_argument, 0,'V'}, + {"help", no_argument, 0,'h'}, + {0,0,0,0} + }; +#endif + + /* no options were supplied */ + if(argc<2) return ERROR; + + /* backwards compatibility */ + if (! is_option(argv[1])) { + server_address=argv[1]; + argv[1]=argv[0]; + argv=&argv[1]; + argc--; + } + + for (c=1;c<argc;c++) { + if(strcmp("-to",argv[c])==0) + strcpy(argv[c],"-t"); + else if (strcmp("-wv",argv[c])==0) + strcpy(argv[c],"-w"); + else if (strcmp("-cv",argv[c])==0) + strcpy(argv[c],"-c"); + } + + while (1){ +#ifdef HAVE_GETOPT_H + c = getopt_long(argc,argv,"+hoVH:t:c:w:p:v:",long_options,&option_index); +#else + c = getopt(argc,argv,"+hoVH:t:c:w:p:v:"); +#endif + + if (c==-1||c==EOF||c==1) + break; + + switch (c) + { + case '?': /* print short usage statement if args not parsable */ + printf("%s: Unknown argument: %s\n\n",my_basename(argv[0]),optarg); + print_usage(); + exit(STATE_UNKNOWN); + case 'h': /* help */ + print_help(); + exit(STATE_OK); + case 'V': /* version */ + print_revision(my_basename(argv[0]),"$Revision$"); + exit(STATE_OK); + case 'H': /* hostname */ + server_address=optarg; + break; + case 'o': /* display nos version */ + check_netware_version=TRUE; + break; + case 'p': /* port */ + if (is_intnonneg(optarg)) + server_port=atoi(optarg); + else + terminate(STATE_UNKNOWN,"Server port an integer (seconds)\nType '%s -h' for additional help\n",PROGNAME); + break; + case 'v': + if(strlen(optarg)<3) + return ERROR; + if(!strcmp(optarg,"LOAD1")) + vars_to_check=CHECK_LOAD1; + else if(!strcmp(optarg,"LOAD5")) + vars_to_check=CHECK_LOAD5; + else if(!strcmp(optarg,"LOAD15")) + vars_to_check=CHECK_LOAD15; + else if(!strcmp(optarg,"CONNS")) + vars_to_check=CHECK_CONNS; + else if(!strcmp(optarg,"LTCH")) + vars_to_check=CHECK_LTCH; + else if(!strcmp(optarg,"CBUFF")) + vars_to_check=CHECK_CBUFF; + else if(!strcmp(optarg,"CDBUFF")) + vars_to_check=CHECK_CDBUFF; + else if(!strcmp(optarg,"LRUM")) + vars_to_check=CHECK_LRUM; + else if(strncmp(optarg,"VPF",3)==0){ + vars_to_check=CHECK_VPF; + volume_name = strscpy(volume_name,optarg+3); + if(!strcmp(volume_name,"")) + volume_name = strscpy(volume_name,"SYS"); + } + else if(strncmp(optarg,"VKF",3)==0){ + vars_to_check=CHECK_VKF; + volume_name = strscpy(volume_name,optarg+3); + if(!strcmp(volume_name,"")) + volume_name = strscpy(volume_name,"SYS"); + } + else if(!strcmp(optarg,"DSDB")) + vars_to_check=CHECK_DSDB; + else if(!strcmp(optarg,"LOGINS")) + vars_to_check=CHECK_LOGINS; + else if(!strcmp(optarg,"UPRB")) + vars_to_check=CHECK_UPRB; + else if(!strcmp(optarg,"PUPRB")) + vars_to_check=CHECK_PUPRB; + else if(!strncmp(optarg,"SAPENTRIES",10)){ + vars_to_check=CHECK_SAPENTRIES; + if(strlen(optarg)>10) + sap_number=atoi(optarg+10); + else + sap_number=-1; + } + else if(!strcmp(optarg,"OFILES")) + vars_to_check=CHECK_OFILES; + else if(strncmp(optarg,"VKP",3)==0){ + vars_to_check=CHECK_VKP; + volume_name = strscpy(volume_name,optarg+3); + if(!strcmp(volume_name,"")) + volume_name = strscpy(volume_name,"SYS"); + } + else if(strncmp(optarg,"VPP",3)==0){ + vars_to_check=CHECK_VPP; + volume_name = strscpy(volume_name,optarg+3); + if(!strcmp(volume_name,"")) + volume_name = strscpy(volume_name,"SYS"); + } + else if(strncmp(optarg,"VKNP",4)==0){ + vars_to_check=CHECK_VKNP; + volume_name = strscpy(volume_name,optarg+4); + if(!strcmp(volume_name,"")) + volume_name = strscpy(volume_name,"SYS"); + } + else if(strncmp(optarg,"VPNP",4)==0){ + vars_to_check=CHECK_VPNP; + volume_name = strscpy(volume_name,optarg+4); + if(!strcmp(volume_name,"")) + volume_name = strscpy(volume_name,"SYS"); + } + else if(!strcmp(optarg,"ABENDS")) + vars_to_check=CHECK_ABENDS; + else if(!strcmp(optarg,"CSPROCS")) + vars_to_check=CHECK_CSPROCS; + else + return ERROR; + break; + case 'w': /* warning threshold */ + warning_value=strtoul(optarg,NULL,10); + check_warning_value=TRUE; + break; + case 'c': /* critical threshold */ + critical_value=strtoul(optarg,NULL,10); + check_critical_value=TRUE; + break; + case 't': /* timeout */ + socket_timeout=atoi(optarg); + if(socket_timeout<=0) + return ERROR; + } + + } + + return OK; +} + + +void print_usage(void) +{ + printf + ("Usage:\n" + " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} + +void print_help(void) +{ + print_revision (PROGNAME, REVISION); + printf ("%s\n\n%s\n", COPYRIGHT, SUMMARY); + print_usage(); + printf + ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n", + PORT, DEFAULT_SOCKET_TIMEOUT); + support (); +} diff --git a/plugins/check_overcr.c b/plugins/check_overcr.c new file mode 100644 index 00000000..305a8242 --- /dev/null +++ b/plugins/check_overcr.c @@ -0,0 +1,489 @@ +/****************************************************************************** +* +* CHECK_OVERCR.C +* +* Program: Over-CR collector plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* $Id$ +* +* Description: +* +* Notes: +* - This plugin requires that Eric Molitors' Over-CR collector daemon +* be running on any UNIX boxes you want to monitor. Over-CR +* is available from * http://www.molitor.org/overcr/ +* +* Modifications: +* +* 08-11-999 Jacob Lundqvist <jaclu@grm.se> +* Load was presented as a one digit percentage - changed to two digit +* value * before load of 11.2 was presented as "1.2%" (not very +* high). Warning and Critical params were int's, not very good +* for load, changed to doubles, so we can trap loadlimits like +* 1.5. Also added more informative LOAD error messages. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define CHECK_NONE 0 +#define CHECK_LOAD1 1 +#define CHECK_LOAD5 2 +#define CHECK_LOAD15 4 +#define CHECK_DPU 8 +#define CHECK_PROCS 16 +#define CHECK_NETSTAT 32 +#define CHECK_UPTIME 64 + +#define PORT 2000 + +#define PROGNAME "check_overcr" + +char *server_address = NULL; +int server_port = PORT; +double warning_value = 0L; +double critical_value = 0L; +int check_warning_value = FALSE; +int check_critical_value = FALSE; +int vars_to_check = CHECK_NONE; +int cmd_timeout = 1; + +int netstat_port = 0; +char *disk_name = NULL; +char *process_name = NULL; + +int process_arguments (int, char **); +void print_usage (void); +void print_help (void); + +int +main (int argc, char **argv) +{ + int result; + char send_buffer[MAX_INPUT_BUFFER]; + char recv_buffer[MAX_INPUT_BUFFER]; + char output_message[MAX_INPUT_BUFFER]; + char temp_buffer[MAX_INPUT_BUFFER]; + char *temp_ptr = NULL; + int found_disk = FALSE; + unsigned long percent_used_disk_space = 100; + double load; + double load_1min; + double load_5min; + double load_15min; + int port_connections = 0; + int processes = 0; + double uptime_raw_hours; + int uptime_raw_minutes = 0; + int uptime_days = 0; + int uptime_hours = 0; + int uptime_minutes = 0; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + result = STATE_OK; + + if (vars_to_check == CHECK_LOAD1 || vars_to_check == CHECK_LOAD5 + || vars_to_check == CHECK_LOAD15) { + + strcpy (send_buffer, "LOAD\r\nQUIT\r\n"); + result = + process_tcp_request2 (server_address, server_port, send_buffer, + recv_buffer, sizeof (recv_buffer)); + if (result != STATE_OK) + return result; + + temp_ptr = (char *) strtok (recv_buffer, "\r\n"); + if (temp_ptr == NULL) { + printf ("Invalid response from server - no load information\n"); + return STATE_CRITICAL; + } + load_1min = strtod (temp_ptr, NULL); + temp_ptr = (char *) strtok (NULL, "\r\n"); + if (temp_ptr == NULL) { + printf ("Invalid response from server after load 1\n"); + return STATE_CRITICAL; + } + load_5min = strtod (temp_ptr, NULL); + temp_ptr = (char *) strtok (NULL, "\r\n"); + if (temp_ptr == NULL) { + printf ("Invalid response from server after load 5\n"); + return STATE_CRITICAL; + } + load_15min = strtod (temp_ptr, NULL); + + + switch (vars_to_check) { + case CHECK_LOAD1: + strcpy (temp_buffer, "1"); + load = load_1min; + break; + case CHECK_LOAD5: + strcpy (temp_buffer, "5"); + load = load_5min; + break; + default: + strcpy (temp_buffer, "15"); + load = load_15min; + break; + } + + if (check_critical_value == TRUE && (load >= critical_value)) + result = STATE_CRITICAL; + else if (check_warning_value == TRUE && (load >= warning_value)) + result = STATE_WARNING; + sprintf (output_message, "Load %s - %s-min load average = %0.2f", + (result == STATE_OK) ? "ok" : "problem", temp_buffer, load); + } + + + else if (vars_to_check == CHECK_DPU) { + + sprintf (send_buffer, "DISKSPACE\r\n"); + result = + process_tcp_request2 (server_address, server_port, send_buffer, + recv_buffer, sizeof (recv_buffer)); + if (result != STATE_OK) + return result; + + for (temp_ptr = (char *) strtok (recv_buffer, " "); temp_ptr != NULL; + temp_ptr = (char *) strtok (NULL, " ")) { + + if (!strcmp (temp_ptr, disk_name)) { + found_disk = TRUE; + temp_ptr = (char *) strtok (NULL, "%"); + if (temp_ptr == NULL) { + printf ("Invalid response from server\n"); + return STATE_CRITICAL; + } + percent_used_disk_space = strtoul (temp_ptr, NULL, 10); + break; + } + + temp_ptr = (char *) strtok (NULL, "\r\n"); + } + + /* error if we couldn't find the info for the disk */ + if (found_disk == FALSE) { + sprintf (output_message, "Error: Disk '%s' non-existent or not mounted", + disk_name); + result = STATE_CRITICAL; + } + + /* else check the disk space used */ + else { + + if (check_critical_value == TRUE + && (percent_used_disk_space >= critical_value)) result = + STATE_CRITICAL; + else if (check_warning_value == TRUE + && (percent_used_disk_space >= warning_value)) result = + STATE_WARNING; + + sprintf (output_message, "Disk %s - %lu%% used on %s", + (result == STATE_OK) ? "ok" : "problem", + percent_used_disk_space, disk_name); + } + } + + else if (vars_to_check == CHECK_NETSTAT) { + + sprintf (send_buffer, "NETSTAT %d\r\n", netstat_port); + result = + process_tcp_request2 (server_address, server_port, send_buffer, + recv_buffer, sizeof (recv_buffer)); + if (result != STATE_OK) + return result; + + port_connections = strtod (recv_buffer, NULL); + + if (check_critical_value == TRUE && (port_connections >= critical_value)) + result = STATE_CRITICAL; + else if (check_warning_value == TRUE + && (port_connections >= warning_value)) result = STATE_WARNING; + + sprintf (output_message, "Net %s - %d connection%s on port %d", + (result == STATE_OK) ? "ok" : "problem", port_connections, + (port_connections == 1) ? "" : "s", netstat_port); + } + + else if (vars_to_check == CHECK_PROCS) { + + sprintf (send_buffer, "PROCESS %s\r\n", process_name); + result = + process_tcp_request2 (server_address, server_port, send_buffer, + recv_buffer, sizeof (recv_buffer)); + if (result != STATE_OK) + return result; + + temp_ptr = (char *) strtok (recv_buffer, "("); + if (temp_ptr == NULL) { + printf ("Invalid response from server\n"); + return STATE_CRITICAL; + } + temp_ptr = (char *) strtok (NULL, ")"); + if (temp_ptr == NULL) { + printf ("Invalid response from server\n"); + return STATE_CRITICAL; + } + processes = strtod (temp_ptr, NULL); + + if (check_critical_value == TRUE && (processes >= critical_value)) + result = STATE_CRITICAL; + else if (check_warning_value == TRUE && (processes >= warning_value)) + result = STATE_WARNING; + + sprintf (output_message, "Process %s - %d instance%s of %s running", + (result == STATE_OK) ? "ok" : "problem", processes, + (processes == 1) ? "" : "s", process_name); + } + + else if (vars_to_check == CHECK_UPTIME) { + + sprintf (send_buffer, "UPTIME\r\n"); + result = + process_tcp_request2 (server_address, server_port, send_buffer, + recv_buffer, sizeof (recv_buffer)); + if (result != STATE_OK) + return result; + + uptime_raw_hours = strtod (recv_buffer, NULL); + uptime_raw_minutes = (unsigned long) (uptime_raw_hours * 60.0); + + if (check_critical_value == TRUE + && (uptime_raw_minutes <= critical_value)) result = STATE_CRITICAL; + else if (check_warning_value == TRUE + && (uptime_raw_minutes <= warning_value)) result = STATE_WARNING; + + uptime_days = uptime_raw_minutes / 1440; + uptime_raw_minutes %= 1440; + uptime_hours = uptime_raw_minutes / 60; + uptime_raw_minutes %= 60; + uptime_minutes = uptime_raw_minutes; + + sprintf (output_message, "Uptime %s - Up %d days %d hours %d minutes", + (result == STATE_OK) ? "ok" : "problem", uptime_days, + uptime_hours, uptime_minutes); + } + + else { + strcpy (output_message, "Nothing to check!\n"); + result = STATE_UNKNOWN; + } + + /* reset timeout */ + alarm (0); + + printf ("%s\n", output_message); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"port", required_argument, 0, 'p'}, + {"timeout", required_argument, 0, 't'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"variable", required_argument, 0, 'v'}, + {"hostname", required_argument, 0, 'H'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + /* no options were supplied */ + if (argc < 2) + return ERROR; + + /* backwards compatibility */ + if (!is_option (argv[1])) { + server_address = argv[1]; + argv[1] = argv[0]; + argv = &argv[1]; + argc--; + } + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wv", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-cv", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVH:t:c:w:p:v:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVH:t:c:w:p:v:"); +#endif + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'H': /* hostname */ + server_address = optarg; + break; + case 'p': /* port */ + if (is_intnonneg (optarg)) + server_port = atoi (optarg); + else + terminate (STATE_UNKNOWN, + "Server port an integer (seconds)\nType '%s -h' for additional help\n", + PROGNAME); + break; + case 'v': /* variable */ + if (strcmp (optarg, "LOAD1") == 0) + vars_to_check = CHECK_LOAD1; + else if (strcmp (optarg, "LOAD5") == 0) + vars_to_check = CHECK_LOAD5; + else if (strcmp (optarg, "LOAD15") == 0) + vars_to_check = CHECK_LOAD15; + else if (strcmp (optarg, "UPTIME") == 0) + vars_to_check = CHECK_UPTIME; + else if (strstr (optarg, "PROC") == optarg) { + vars_to_check = CHECK_PROCS; + process_name = strscpy (process_name, optarg + 4); + } + else if (strstr (optarg, "NET") == optarg) { + vars_to_check = CHECK_NETSTAT; + netstat_port = atoi (optarg + 3); + } + else if (strstr (optarg, "DPU") == optarg) { + vars_to_check = CHECK_DPU; + disk_name = strscpy (disk_name, optarg + 3); + } + else + return ERROR; + break; + case 'w': /* warning threshold */ + warning_value = strtoul (optarg, NULL, 10); + check_warning_value = TRUE; + break; + case 'c': /* critical threshold */ + critical_value = strtoul (optarg, NULL, 10); + check_critical_value = TRUE; + break; + case 't': /* timeout */ + socket_timeout = atoi (optarg); + if (socket_timeout <= 0) + return ERROR; + } + + } + return OK; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", + PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin attempts to contact the Over-CR collector daemon running on the\n" + "remote UNIX server in order to gather the requested system information. This\n" + "plugin requres that Eric Molitors' Over-CR collector daemon be running on the\n" + "remote server. Over-CR can be downloaded from http://www.molitor.org/overcr\n" + "(This plugin was tested with version 0.99.53 of the Over-CR collector)\n\n"); + print_usage (); + printf + ("\nOptions:\n" + "-H, --hostname=HOST\n" + " Name of the host to check\n" + "-p, --port=INTEGER\n" + " Optional port number (default: %d)\n" + "-v, --variable=STRING\n" + " Variable to check. Valid variables include:\n" + " LOAD1 = 1 minute average CPU load\n" + " LOAD5 = 5 minute average CPU load\n" + " LOAD15 = 15 minute average CPU load\n" + " DPU<filesys> = percent used disk space on filesystem <filesys>\n" + " PROC<process> = number of running processes with name <process>\n" + " NET<port> = number of active connections on TCP port <port>\n" + " UPTIME = system uptime in seconds\n" + " -w, --warning=INTEGER\n" + " Threshold which will result in a warning status\n" + " -c, --critical=INTEGER\n" + " Threshold which will result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + "-h, --help\n" + " Print this help screen\n" + "-V, --version\n" + " Print version information\n\n" + "Notes:\n" + " - For the available options, the critical threshold value should always be\n" + " higher than the warning threshold value, EXCEPT with the uptime variable\n" + " (i.e. lower uptimes are worse).\n", PORT, DEFAULT_SOCKET_TIMEOUT); +} diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c new file mode 100644 index 00000000..03614ab1 --- /dev/null +++ b/plugins/check_pgsql.c @@ -0,0 +1,440 @@ +/****************************************************************************** + * + * Program: PostgreSQL plugin for Nagios + * License: GPL + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_pgsql" +#define REVISION "$Revision$" +#define COPYRIGHT "1999-2001" +#define AUTHOR "Karl DeBisschop" +#define EMAIL "kdebisschop@users.sourceforge.net" +#define SUMMARY "Tests to see if a PostgreSQL DBMS is accepting connections.\n" + +#define OPTIONS "\ +\[-c critical_time] [-w warning_time] [-t timeout] [-H host]\n\ + [-P port] [-d database] [-l logname] [-p password]" + +#define LONGOPTIONS "\ + -c, --critical=INTEGER\n\ + Exit STATE_CRITICAL if connection time exceeds threshold (default: %d)\n\ + -w, --warning=INTEGER\n\ + Exit STATE_WARNING if connection time exceeds threshold (default: %d)\n\ + -t, --timeout=INTEGER\n\ + Terminate test if timeout limit is exceeded (default: %d)\n\ + -H, --hostname=STRING\n\ + Name or numeric IP address of machine running backend\n\ + -P, --port=INTEGER\n\ + Port running backend (default: %s)\n\ + -d, --database=STRING\n\ + Database to check (default: %s)\n\ + -l, --logname = STRING\n\ + Login name of user\n\ + -p, --password = STRING\n\ + Password (BIG SECURITY ISSUE)\n" + +#define DESCRIPTION "All parameters are optional.\n\ +\n\ +This plugin tests a PostgreSQL DBMS to determine whether it is active and\n\ +accepting queries. In its current operation, it simply connects to the\n\ +specified database, and then disconnects. If no database is specified, it\n\ +connects to the template1 database, which is present in every functioning \n\ +PostgreSQL DBMS.\n\ +\n\ +The plugin will connect to a local postmaster if no host is specified. To\n\ +connect to a remote host, be sure that the remote postmaster accepts TCP/IP\n\ +connections (start the postmaster with the -i option).\n\ +\n\ +Typically, the nagios user (unless the --logname option is used) should be\n\ +able to connect to the database without a password. The plugin can also send\n\ +a password, but no effort is made to obsure or encrypt the password.\n" + +#define DEFAULT_DB "template1" +#define DEFAULT_HOST "127.0.0.1" +#define DEFAULT_PORT "5432" +#define DEFAULT_WARN 2 +#define DEFAULT_CRIT 8 +#define DEFAULT_TIMEOUT 30 + +#include "config.h" +#include "common.h" +#include "utils.h" +#include <netdb.h> +#include <libpq-fe.h> + +int process_arguments (int, char **); +int validate_arguments (void); +void print_usage (void); +void print_help (void); +int is_pg_dbname (char *); +int is_pg_logname (char *); + +char *pghost = NULL; /* host name of the backend server */ +char *pgport = NULL; /* port of the backend server */ +char default_port[4] = DEFAULT_PORT; +char *pgoptions = NULL; +char *pgtty = NULL; +char dbName[NAMEDATALEN] = DEFAULT_DB; +char *pguser = NULL; +char *pgpasswd = NULL; +int twarn = DEFAULT_WARN; +int tcrit = DEFAULT_CRIT; + +PGconn *conn; +/*PGresult *res;*/ + + +/****************************************************************************** + +The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ +tags in the comments. With in the tags, the XML is assembled sequentially. +You can define entities in tags. You also have all the #defines available as +entities. + +Please note that all tags must be lowercase to use the DocBook XML DTD. + +@@-<article> + +<sect1> +<title>Quick Reference</title> +<!-- The refentry forms a manpage --> +<refentry> +<refmeta> +<manvolnum>5<manvolnum> +</refmeta> +<refnamdiv> +<refname>&PROGNAME;</refname> +<refpurpose>&SUMMARY;</refpurpose> +</refnamdiv> +</refentry> +</sect1> + +<sect1> +<title>FAQ</title> +</sect1> + +<sect1> +<title>Theory, Installation, and Operation</title> + +<sect2> +<title>General Description</title> +<para> +&DESCRIPTION; +</para> +</sect2> + +<sect2> +<title>Future Enhancements</title> +<para>ToDo List</para> +<itemizedlist> +<listitem>Add option to get password from a secured file rather than the command line</listitem> +<listitem>Add option to specify the query to execute</listitem> +</itemizedlist> +</sect2> + + +<sect2> +<title>Functions</title> +-@@ +******************************************************************************/ + +int +main (int argc, char **argv) +{ + int elapsed_time; + + /* begin, by setting the parameters for a backend connection if the + * parameters are null, then the system will try to use reasonable + * defaults by looking up environment variables or, failing that, + * using hardwired constants */ + + pgoptions = NULL; /* special options to start up the backend server */ + pgtty = NULL; /* debugging tty for the backend server */ + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments"); + + /* Set signal handling and alarm */ + if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + alarm (timeout_interval); + + /* make a connection to the database */ + time (&start_time); + conn = + PQsetdbLogin (pghost, pgport, pgoptions, pgtty, dbName, pguser, pgpasswd); + time (&end_time); + elapsed_time = (int) (end_time - start_time); + + /* check to see that the backend connection was successfully made */ + if (PQstatus (conn) == CONNECTION_BAD) { + printf ("PGSQL: CRITICAL - no connection to '%s' (%s).\n", dbName, + PQerrorMessage (conn)); + PQfinish (conn); + return STATE_CRITICAL; + } + else if (elapsed_time > tcrit) { + PQfinish (conn); + printf ("PGSQL: CRITICAL - database %s (%d sec.)\n", dbName, + elapsed_time); + return STATE_CRITICAL; + } + else if (elapsed_time > twarn) { + PQfinish (conn); + printf ("PGSQL: WARNING - database %s (%d sec.)\n", dbName, elapsed_time); + return STATE_WARNING; + } + else { + PQfinish (conn); + printf ("PGSQL: ok - database %s (%d sec.)\n", dbName, elapsed_time); + return STATE_OK; + } +} + + + + +void +print_help (void) +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) %s %s <%s>\n\n%s\n", + COPYRIGHT, AUTHOR, EMAIL, SUMMARY); + print_usage (); + printf + ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n", + DEFAULT_WARN, DEFAULT_CRIT, DEFAULT_TIMEOUT, DEFAULT_PORT, DEFAULT_DB); + support (); +} + +void +print_usage (void) +{ + printf ("Usage:\n" " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"timeout", required_argument, 0, 't'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"hostname", required_argument, 0, 'H'}, + {"logname", required_argument, 0, 'l'}, + {"password", required_argument, 0, 'p'}, + {"authorization", required_argument, 0, 'a'}, + {"port", required_argument, 0, 'P'}, + {"database", required_argument, 0, 'd'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+?hVt:c:w:H:P:d:l:p:a:", + long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVt:c:w:H:P:d:l:p:a:"); +#endif + if (c == EOF) + break; + + switch (c) { + case '?': /* help */ + usage2 ("Unknown argument", optarg); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (PROGNAME, REVISION); + exit (STATE_OK); + case 't': /* timeout period */ + if (!is_integer (optarg)) + usage2 ("Timeout Interval must be an integer", optarg); + timeout_interval = atoi (optarg); + break; + case 'c': /* critical time threshold */ + if (!is_integer (optarg)) + usage2 ("Invalid critical threshold", optarg); + tcrit = atoi (optarg); + break; + case 'w': /* warning time threshold */ + if (!is_integer (optarg)) + usage2 ("Invalid critical threshold", optarg); + twarn = atoi (optarg); + break; + case 'H': /* host */ + if (!is_host (optarg)) + usage2 ("You gave an invalid host name", optarg); + pghost = optarg; + break; + case 'P': /* port */ + if (!is_integer (optarg)) + usage2 ("Port must be an integer", optarg); + pgport = optarg; + break; + case 'd': /* database name */ + if (!is_pg_dbname (optarg)) + usage2 ("Database name is not valid", optarg); + strncpy (dbName, optarg, NAMEDATALEN - 1); + dbName[NAMEDATALEN - 1] = 0; + break; + case 'l': /* login name */ + if (!is_pg_logname (optarg)) + usage2 ("user name is not valid", optarg); + pguser = optarg; + break; + case 'p': /* authentication password */ + case 'a': + pgpasswd = optarg; + break; + } + } + + return validate_arguments (); +} + + +/****************************************************************************** + +@@- +<sect3> +<title>validate_arguments</title> + +<para>&PROTO_validate_arguments;</para> + +<para>Given a database name, this function returns TRUE if the string +is a valid PostgreSQL database name, and returns false if it is +not.</para> + +<para>Valid PostgreSQL database names are less than &NAMEDATALEN; +characters long and consist of letters, numbers, and underscores. The +first character cannot be a number, however.</para> + +</sect3> +-@@ +******************************************************************************/ + +int +validate_arguments () +{ + return OK; +} + + + +/****************************************************************************** + +@@- +<sect3> +<title>is_pg_dbname</title> + +<para>&PROTO_is_pg_dbname;</para> + +<para>Given a database name, this function returns TRUE if the string +is a valid PostgreSQL database name, and returns false if it is +not.</para> + +<para>Valid PostgreSQL database names are less than &NAMEDATALEN; +characters long and consist of letters, numbers, and underscores. The +first character cannot be a number, however.</para> + +</sect3> +-@@ +******************************************************************************/ + +int +is_pg_dbname (char *dbname) +{ + char txt[NAMEDATALEN]; + char tmp[NAMEDATALEN]; + if (strlen (dbname) > NAMEDATALEN - 1) + return (FALSE); + strncpy (txt, dbname, NAMEDATALEN - 1); + txt[NAMEDATALEN - 1] = 0; + if (sscanf (txt, "%[_a-zA-Z]%[^_a-zA-Z0-9]", tmp, tmp) == 1) + return (TRUE); + if (sscanf (txt, "%[_a-zA-Z]%[_a-zA-Z0-9]%[^_a-zA-Z0-9]", tmp, tmp, tmp) == + 2) return (TRUE); + return (FALSE); +} + +/** + +the tango program should eventually create an entity here based on the +function prototype + +@@- +<sect3> +<title>is_pg_logname</title> + +<para>&PROTO_is_pg_logname;</para> + +<para>Given a username, this function returns TRUE if the string is a +valid PostgreSQL username, and returns false if it is not. Valid PostgreSQL +usernames are less than &NAMEDATALEN; characters long and consist of +letters, numbers, dashes, and underscores, plus possibly some other +characters.</para> + +<para>Currently this function only checks string length. Additional checks +should be added.</para> + +</sect3> +-@@ +******************************************************************************/ + +int +is_pg_logname (char *username) +{ + if (strlen (username) > NAMEDATALEN - 1) + return (FALSE); + return (TRUE); +} + +/****************************************************************************** +@@- +</sect2> +</sect1> +</article> +-@@ +******************************************************************************/ diff --git a/plugins/check_ping.c b/plugins/check_ping.c new file mode 100644 index 00000000..b61b41b5 --- /dev/null +++ b/plugins/check_ping.c @@ -0,0 +1,492 @@ +/***************************************************************************** +* +* CHECK_PING.C +* +* Program: Ping plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* $Id$ +* +*****************************************************************************/ + +#define PROGNAME "check_pgsql" +#define REVISION "$Revision$" +#define COPYRIGHT "1999-2001" +#define AUTHOR "Ethan Galstad/Karl DeBisschop" +#define EMAIL "kdebisschop@users.sourceforge.net" +#define SUMMARY "Use ping to check connection statistics for a remote host.\n" + +#define OPTIONS "\ +-H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n\ + [-p packets] [-t timeout] [-L]\n" + +#define LONGOPTIONS "\ +-H, --hostname=HOST\n\ + host to ping\n\ +-w, --warning=THRESHOLD\n\ + warning threshold pair\n\ +-c, --critical=THRESHOLD\n\ + critical threshold pair\n\ +-p, --packets=INTEGER\n\ + number of ICMP ECHO packets to send (Default: %d)\n\ +-t, --timeout=INTEGER\n\ + optional specified timeout in second (Default: %d)\n\ +-L, --link\n\ + show HTML in the plugin output (obsoleted by urlize)\n\ +THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel\n\ +time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the\n\ +percentage of packet loss to trigger an alarm state.\n" + +#define DESCRIPTION "\ +This plugin uses the ping command to probe the specified host for packet loss\n\ +(percentage) and round trip average (milliseconds). It can produce HTML output\n\ +linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in\n\ +the contrib area of the downloads section at http://www.nagios.org\n\n" + +#include "config.h" +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define UNKNOWN_PACKET_LOSS 200 /* 200% */ +#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ +#define DEFAULT_MAX_PACKETS 5 /* default no. of ICMP ECHO packets */ + +#define WARN_DUPLICATES "DUPLICATES FOUND! " + +int process_arguments (int, char **); +int call_getopt (int, char **); +int get_threshold (char *, float *, int *); +int validate_arguments (void); +int run_ping (char *); +void print_usage (void); +void print_help (void); + +int display_html = FALSE; +int wpl = UNKNOWN_PACKET_LOSS; +int cpl = UNKNOWN_PACKET_LOSS; +float wrta = UNKNOWN_TRIP_TIME; +float crta = UNKNOWN_TRIP_TIME; +char *server_address = NULL; +int max_packets = -1; +int verbose = FALSE; + +float rta = UNKNOWN_TRIP_TIME; +int pl = UNKNOWN_PACKET_LOSS; + +char *warn_text = NULL; + +int +main (int argc, char **argv) +{ + char *command_line = NULL; + int result = STATE_UNKNOWN; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments"); + + /* does the host address of number of packets argument come first? */ +#ifdef PING_PACKETS_FIRST + command_line = + ssprintf (command_line, PING_COMMAND, max_packets, server_address); +#else + command_line = + ssprintf (command_line, PING_COMMAND, server_address, max_packets); +#endif + + /* Set signal handling and alarm */ + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { + printf ("Cannot catch SIGALRM"); + return STATE_UNKNOWN; + } + + /* handle timeouts gracefully */ + alarm (timeout_interval); + + if (verbose) + printf ("%s ==> ", command_line); + + /* run the command */ + run_ping (command_line); + + if (pl == UNKNOWN_PACKET_LOSS || rta == UNKNOWN_TRIP_TIME) { + printf ("%s\n", command_line); + terminate (STATE_UNKNOWN, + "Error: Could not interpret output from ping command\n"); + } + + if (pl >= cpl || rta >= crta || rta < 0) + result = STATE_CRITICAL; + else if (pl >= wpl || rta >= wrta) + result = STATE_WARNING; + else if (pl < wpl && rta < wrta && pl >= 0 && rta >= 0) + result = max (result, STATE_OK); + + if (display_html == TRUE) + printf ("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, server_address); + if (pl == 100) + printf ("PING %s - %sPacket loss = %d%%", state_text (result), warn_text, + pl); + else + printf ("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms", + state_text (result), warn_text, pl, rta); + if (display_html == TRUE) + printf ("</A>"); + printf ("\n"); + + if (verbose) + printf ("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl); + + return result; +} + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + if (strcmp ("-nohtml", argv[c]) == 0) + strcpy (argv[c], "-n"); + } + + c = 0; + while ((c += call_getopt (argc - c, &argv[c])) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c]) == FALSE) { + printf ("Invalid host name/address: %s\n\n", argv[c]); + return ERROR; + } + server_address = argv[c]; + } + else if (wpl == UNKNOWN_PACKET_LOSS) { + if (is_intpercent (argv[c]) == FALSE) { + printf ("<wpl> (%s) must be an integer percentage\n", argv[c]); + return ERROR; + } + wpl = atoi (argv[c]); + } + else if (cpl == UNKNOWN_PACKET_LOSS) { + if (is_intpercent (argv[c]) == FALSE) { + printf ("<cpl> (%s) must be an integer percentage\n", argv[c]); + return ERROR; + } + cpl = atoi (argv[c]); + } + else if (wrta == UNKNOWN_TRIP_TIME) { + if (is_negative (argv[c])) { + printf ("<wrta> (%s) must be a non-negative number\n", argv[c]); + return ERROR; + } + wrta = atof (argv[c]); + } + else if (crta == UNKNOWN_TRIP_TIME) { + if (is_negative (argv[c])) { + printf ("<crta> (%s) must be a non-negative number\n", argv[c]); + return ERROR; + } + crta = atof (argv[c]); + } + else if (max_packets == -1) { + if (is_intnonneg (argv[c])) { + max_packets = atoi (argv[c]); + } + else { + printf ("<max_packets> (%s) must be a non-negative number\n", + argv[c]); + return ERROR; + } + } + + } + + return validate_arguments (); +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {"nohtml", no_argument, 0, 'n'}, + {"link", no_argument, 0, 'L'}, + {"timeout", required_argument, 0, 't'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"hostname", required_argument, 0, 'H'}, + {"packets", required_argument, 0, 'p'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvt:c:w:H:p:nL", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVvt:c:w:H:p:nL"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'c': + case 'w': + case 'H': + case 'p': + i++; + } + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + usage2 ("Unknown argument", optarg); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (PROGNAME, REVISION); + exit (STATE_OK); + case 't': /* timeout period */ + timeout_interval = atoi (optarg); + break; + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) + usage2 ("Invalid host name/address", optarg); + server_address = optarg; + break; + case 'p': /* number of packets to send */ + if (is_intnonneg (optarg)) + max_packets = atoi (optarg); + else + usage2 ("<max_packets> (%s) must be a non-negative number\n", optarg); + break; + case 'n': /* no HTML */ + display_html = FALSE; + break; + case 'L': /* show HTML */ + display_html = TRUE; + break; + case 'c': + get_threshold (optarg, &crta, &cpl); + break; + case 'w': + get_threshold (optarg, &wrta, &wpl); + break; + } + } + + return i; +} + +int +get_threshold (char *arg, float *trta, int *tpl) +{ + if (is_intnonneg (arg) && sscanf (arg, "%f", trta) == 1) + return OK; + else if (strpbrk (arg, ",:") && strstr (arg, "%") && sscanf (arg, "%f%*[:,]%d%%", trta, tpl) == 2) + return OK; + else if (strstr (arg, "%") && sscanf (arg, "%d%%", tpl) == 1) + return OK; + else + usage2 ("%s: Warning threshold must be integer or percentage!\n\n", arg); + +} + +int +validate_arguments () +{ + float max_seconds; + + if (wrta == UNKNOWN_TRIP_TIME) { + printf ("<wrta> was not set\n"); + return ERROR; + } + else if (crta == UNKNOWN_TRIP_TIME) { + printf ("<crta> was not set\n"); + return ERROR; + } + else if (wpl == UNKNOWN_PACKET_LOSS) { + printf ("<wpl> was not set\n"); + return ERROR; + } + else if (cpl == UNKNOWN_PACKET_LOSS) { + printf ("<cpl> was not set\n"); + return ERROR; + } + else if (wrta > crta) { + printf ("<wrta> (%f) cannot be larger than <crta> (%f)\n", wrta, crta); + return ERROR; + } + else if (wpl > cpl) { + printf ("<wpl> (%d) cannot be larger than <cpl> (%d)\n", wpl, cpl); + return ERROR; + } + + if (max_packets == -1) + max_packets = DEFAULT_MAX_PACKETS; + + max_seconds = crta / 1000.0 * max_packets + max_packets; + if (max_seconds > timeout_interval) + timeout_interval = (int)max_seconds; + + return OK; +} + + +int +run_ping (char *command_line) +{ + char input_buffer[MAX_INPUT_BUFFER]; + int result = STATE_UNKNOWN; + + warn_text = malloc (1); + if (warn_text == NULL) + terminate (STATE_UNKNOWN, "unable to malloc warn_text"); + warn_text[0] = 0; + + if ((child_process = spopen (command_line)) == NULL) { + printf ("Cannot open pipe: "); + terminate (STATE_UNKNOWN, command_line); + } + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Cannot open stderr for %s\n", command_line); + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + if (strstr (input_buffer, "(DUP!)")) { + result = max (result, STATE_WARNING); + warn_text = realloc (warn_text, strlen (WARN_DUPLICATES) + 1); + if (warn_text == NULL) + terminate (STATE_UNKNOWN, "unable to realloc warn_text"); + strcpy (warn_text, WARN_DUPLICATES); + } + + /* get the percent loss statistics */ + if (sscanf + (input_buffer, + "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss", + &pl) == 1 + || sscanf (input_buffer, + "%*d packets transmitted, %*d packets received, %d%% packet loss", + &pl) == 1) + continue; + + /* get the round trip average */ + else + if (sscanf (input_buffer, "round-trip min/avg/max = %*f/%f/%*f", &rta) + == 1 + || sscanf (input_buffer, + "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f", + &rta) == 1 + || sscanf (input_buffer, + "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f", + &rta) == 1 + || sscanf (input_buffer, + "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f", + &rta) == 1 + || sscanf (input_buffer, + "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f", + &rta) == 1 + || sscanf (input_buffer, "round-trip (ms) min/avg/max = %*f/%f/%*f", + &rta) == 1) + continue; + } + + /* this is needed because there is no rta if all packets are lost */ + if (pl == 100) + rta = crta; + + + /* check stderr */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + if (strstr + (input_buffer, + "Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP")) + continue; + + if (strstr (input_buffer, "Network is unreachable")) + terminate (STATE_CRITICAL, "PING CRITICAL - Network unreachable (%s)", + server_address); + else if (strstr (input_buffer, "Destination Host Unreachable")) + terminate (STATE_CRITICAL, "PING CRITICAL - Host Unreachable (%s)", + server_address); + + warn_text = + realloc (warn_text, strlen (warn_text) + strlen (input_buffer) + 2); + if (warn_text == NULL) + terminate (STATE_UNKNOWN, "unable to realloc warn_text"); + if (strlen (warn_text) == 0) + strcpy (warn_text, input_buffer); + else + sprintf (warn_text, "%s %s", warn_text, input_buffer); + + if (strstr (input_buffer, "DUPLICATES FOUND")) + result = max (result, STATE_WARNING); + else + result = max (result, STATE_CRITICAL); + } + (void) fclose (child_stderr); + + + /* close the pipe - WARNING if status is set */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + return result; +} + + +void +print_usage (void) +{ + printf ("Usage:\n" " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} + +void +print_help (void) +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) %s %s <%s>\n\n%s\n", + COPYRIGHT, AUTHOR, EMAIL, SUMMARY); + print_usage (); + printf + ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n", + DEFAULT_MAX_PACKETS, DEFAULT_SOCKET_TIMEOUT); + support (); +} diff --git a/plugins/check_pop.c b/plugins/check_pop.c new file mode 100644 index 00000000..9fcfaec6 --- /dev/null +++ b/plugins/check_pop.c @@ -0,0 +1,364 @@ +/****************************************************************************** + * + * CHECK_POP.C + * + * Program: POP3 plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * $Id$ + * + * Description: + * + * This plugin will attempt to open an POP connection with the host. + * Successul connects return STATE_OK, refusals and timeouts return + * STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful + * connects, but incorrect reponse messages from the host result in + * STATE_WARNING return values. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_pop" + +#define POP_PORT 110 +#define POP_EXPECT "+OK" +#define POP_QUIT "QUIT\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int server_port = POP_PORT; +char *server_address = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + /* watch for the SMTP connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* strip the buffer of carriage returns */ + strip (buffer); + + /* return a WARNING status if we couldn't read any data */ + if (result == -1) { + printf ("recv() failed\n"); + result = STATE_WARNING; + } + + else { + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, server_expect)) { + if (server_port == POP_PORT) + printf ("Invalid POP response received from host\n"); + else + printf ("Invalid POP response received from host on port %d\n", + server_port); + result = STATE_WARNING; + } + + else { + time (&end_time); + + result = STATE_OK; + + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = + STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + + if (verbose == TRUE) + printf ("POP %s - %d sec. response time, %s\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time), buffer); + else + printf ("POP %s - %d second response time\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time)); + } + } + + /* close the connection */ + send (sd, POP_QUIT, strlen (POP_QUIT), 0); + close (sd); + } + + /* reset the alarm */ + alarm (0); + + return result; +} + + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_address == NULL) + server_address = strscpy (NULL, "127.0.0.1"); + + if (server_expect == NULL) + server_expect = strscpy (NULL, POP_EXPECT); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'P'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvt:p:e:c:w:H:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVvt:p:e:c:w:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'p': + case 'e': + case 'c': + case 'w': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'e': /* username */ + server_expect = optarg; + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_time = atoi (optarg); + check_critical_time = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_time = atoi (optarg); + check_warning_time = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin tests the POP service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", + POP_PORT, POP_EXPECT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit] [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_procs.c b/plugins/check_procs.c new file mode 100644 index 00000000..c66d33de --- /dev/null +++ b/plugins/check_procs.c @@ -0,0 +1,510 @@ +/****************************************************************************** +* +* CHECK_PROCS.C +* +* Program: Process plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* $Id$ +* +* Description: +* +* This plugin checks the number of currently running processes and +* generates WARNING or CRITICAL states if the process count is outside +* the specified threshold ranges. The process count can be filtered by +* process owner, parent process PID, current state (e.g., 'Z'), or may +* be the total number of running processes +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +******************************************************************************/ + +#include "config.h" +#include <pwd.h> +#include "common.h" +#include "popen.h" +#include "utils.h" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_usage (void); +void print_help (char *); + +int wmax = -1; +int cmax = -1; +int wmin = -1; +int cmin = -1; + +int options = 0; +#define ALL 1 +#define STAT 2 +#define PPID 4 +#define USER 8 +#define PROG 16 +#define ARGS 32 + +int verbose = FALSE; +int uid; +int ppid; +char *statopts = NULL; +char *prog = NULL; +char *args = NULL; +char *format = NULL; +char tmp[MAX_INPUT_BUFFER]; + +int +main (int argc, char **argv) +{ + char input_buffer[MAX_INPUT_BUFFER]; + + int procuid = 0; + int procppid = 0; + char procstat[8]; + char procprog[MAX_INPUT_BUFFER]; + char *procargs; + + int resultsum = 0; + int found = 0; + int procs = 0; + int pos; + + int result = STATE_UNKNOWN; + + procargs = malloc (MAX_INPUT_BUFFER); + + if (process_arguments (argc, argv) == ERROR) + usage ("Unable to parse command line\n"); + + /* run the command */ + if (verbose) + printf ("%s\n", PS_COMMAND); + child_process = spopen (PS_COMMAND); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", PS_COMMAND); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", PS_COMMAND); + + fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + if ( +#ifdef USE_PS_VARS + sscanf (input_buffer, PS_FORMAT, PS_VARLIST) >= 4 +#else + sscanf (input_buffer, PS_FORMAT, procstat, &procuid, &procppid, &pos, + procprog) >= 4 +#endif + ) { + found++; + resultsum = 0; + procargs = strcpy (procargs, &input_buffer[pos]); + strip (procargs); + if ((options & STAT) && (strstr (statopts, procstat))) + resultsum |= STAT; + if ((options & ARGS) && (strstr (procargs, args) == procargs)) + resultsum |= ARGS; + if ((options & PROG) && (strcmp (prog, procprog) == 0)) + resultsum |= PROG; + if ((options & PPID) && (procppid == ppid)) + resultsum |= PPID; + if ((options & USER) && (procuid == uid)) + resultsum |= USER; +#ifdef DEBUG1 + if (procargs == NULL) + printf ("%d %d %d %s %s\n", procs, procuid, procppid, procstat, + procprog); + else + printf ("%d %d %d %s %s %s\n", procs, procuid, procppid, procstat, + procprog, procargs); +#endif + if (options == resultsum) + procs++; + } + } + + /* If we get anything on STDERR, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { + if (verbose) + printf ("%s", input_buffer); + result = max (result, STATE_WARNING); + } + if (result > STATE_OK) + printf ("System call sent warnings to stderr\n"); + + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) { + printf ("System call returned nonzero status\n"); + return max (result, STATE_WARNING); + } + + if (options == ALL) + procs = found; + + if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ + printf ("Unable to read output\n"); + return max (result, STATE_UNKNOWN); + } + + if (verbose && (options & STAT)) + printf ("%s ", statopts); + if (verbose && (options & PROG)) + printf ("%s ", prog); + if (verbose && (options & PPID)) + printf ("%d ", ppid); + if (verbose && (options & USER)) + printf ("%d ", uid); + + if (cmax >= 0 && cmin >= 0 && cmax < cmin) { + if (procs > cmax && procs < cmin) { + printf (format, "CRITICAL", procs); + return STATE_CRITICAL; + } + } + else if (cmax >= 0 && procs > cmax) { + printf (format, "CRITICAL", procs); + return STATE_CRITICAL; + } + else if (cmin >= 0 && procs < cmin) { + printf (format, "CRITICAL", procs); + return STATE_CRITICAL; + } + + if (wmax >= 0 && wmin >= 0 && wmax < wmin) { + if (procs > wmax && procs < wmin) { + printf (format, "CRITICAL", procs); + return STATE_CRITICAL; + } + } + else if (wmax >= 0 && procs > wmax) { + printf (format, "WARNING", procs); + return max (result, STATE_WARNING); + } + else if (wmin >= 0 && procs < wmin) { + printf (format, "WARNING", procs); + return max (result, STATE_WARNING); + } + + printf (format, "OK", procs); + return max (result, STATE_OK); +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (wmax == -1) + wmax = atoi (argv[c]); + else if (cmax == -1) + cmax = atoi (argv[c]); + else if (statopts == NULL) { + statopts = strscpy (statopts, argv[c]); + format = + strscat (format, + ssprintf (NULL, "%sSTATE = %s", (options ? ", " : ""), + statopts)); + options |= STAT; + } + } + + return validate_arguments (); +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + char *user; + struct passwd *pw; +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"timeout", required_argument, 0, 't'}, + {"status", required_argument, 0, 's'}, + {"ppid", required_argument, 0, 'p'}, + {"command", required_argument, 0, 'C'}, + {"argument-array", required_argument, 0, 'a'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+Vvht:c:w:p:s:u:C:a:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+Vvht:c:w:p:s:u:C:a:"); +#endif + + if (c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'c': + case 'w': + case 'p': + case 's': + case 'a': + case 'u': + case 'C': + i++; + } + + switch (c) { + case '?': /* help */ + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (my_basename (argv[0])); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 't': /* timeout period */ + if (!is_integer (optarg)) { + printf ("%s: Timeout Interval must be an integer!\n\n", + my_basename (argv[0])); + print_usage (); + exit (STATE_UNKNOWN); + } + timeout_interval = atoi (optarg); + break; + case 'c': /* critical threshold */ + if (is_integer (optarg)) { + cmax = atoi (optarg); + break; + } + else if (sscanf (optarg, ":%d", &cmax) == 1) { + break; + } + else if (sscanf (optarg, "%d:%d", &cmin, &cmax) == 2) { + break; + } + else if (sscanf (optarg, "%d:", &cmin) == 1) { + break; + } + else { + printf ("%s: Critical Process Count must be an integer!\n\n", + my_basename (argv[0])); + print_usage (); + exit (STATE_UNKNOWN); + } + case 'w': /* warning time threshold */ + if (is_integer (optarg)) { + wmax = atoi (optarg); + break; + } + else if (sscanf (optarg, ":%d", &wmax) == 1) { + break; + } + else if (sscanf (optarg, "%d:%d", &wmin, &wmax) == 2) { + break; + } + else if (sscanf (optarg, "%d:", &wmin) == 1) { + break; + } + else { + printf ("%s: Warning Process Count must be an integer!\n\n", + my_basename (argv[0])); + print_usage (); + exit (STATE_UNKNOWN); + } + case 'p': /* process id */ + if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) { + format = + strscat (format, + ssprintf (NULL, "%sPPID = %d", (options ? ", " : ""), + ppid)); + options |= PPID; + break; + } + printf ("%s: Parent Process ID must be an integer!\n\n", + my_basename (argv[0])); + print_usage (); + exit (STATE_UNKNOWN); + case 's': /* status */ + statopts = strscpy (statopts, optarg); + format = + strscat (format, + ssprintf (NULL, "%sSTATE = %s", (options ? ", " : ""), + statopts)); + options |= STAT; + break; + case 'u': /* user or user id */ + if (is_integer (optarg)) { + uid = atoi (optarg); + pw = getpwuid ((uid_t) uid); + /* check to be sure user exists */ + if (pw == NULL) { + printf ("UID %d was not found\n", uid); + print_usage (); + exit (STATE_UNKNOWN); + } + } + else { + pw = getpwnam (optarg); + /* check to be sure user exists */ + if (pw == NULL) { + printf ("User name %s was not found\n", optarg); + print_usage (); + exit (STATE_UNKNOWN); + } + /* then get uid */ + uid = pw->pw_uid; + } + user = pw->pw_name; + format = + strscat (format, + ssprintf (NULL, "%sUID = %d (%s)", (options ? ", " : ""), + uid, user)); + options |= USER; + break; + case 'C': /* command */ + prog = strscpy (prog, optarg); + format = + strscat (format, + ssprintf (NULL, "%scommand name %s", (options ? ", " : ""), + prog)); + options |= PROG; + break; + case 'a': /* args (full path name with args) */ + args = strscpy (args, optarg); + format = + strscat (format, + ssprintf (NULL, "%sargs %s", (options ? ", " : ""), args)); + options |= ARGS; + break; + case 'v': /* command */ + verbose = TRUE; + break; + } + } + return i; +} + + +int +validate_arguments () +{ + + if (wmax >= 0 && wmin == -1) + wmin = 0; + if (cmax >= 0 && cmin == -1) + cmin = 0; + if (wmax >= wmin && cmax >= cmin) { /* standard ranges */ + if (wmax > cmax && cmax != -1) { + printf ("wmax (%d) cannot be greater than cmax (%d)\n", wmax, cmax); + return ERROR; + } + if (cmin > wmin && wmin != -1) { + printf ("wmin (%d) cannot be less than cmin (%d)\n", wmin, cmin); + return ERROR; + } + } + + if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { + printf ("At least one threshold must be set\n"); + return ERROR; + } + + if (options == 0) { + options = 1; + format = ssprintf (format, "%%s - %%d processes running\n"); + } + else { + format = + ssprintf (format, "%%s - %%d processes running with %s\n", format); + } + + return options; +} + + +void +print_help (char *cmd) +{ + print_revision (cmd, "$Revision$"); + printf + ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n" + "This plugin checks the number of currently running processes and\n" + "generates WARNING or CRITICAL states if the process count is outside\n" + "the specified threshold ranges. The process count can be filtered by\n" + "process owner, parent process PID, current state (e.g., 'Z'), or may\n" + "be the total number of running processes\n\n"); + print_usage (); + printf + ("\nRequired Arguments:\n" + " -w, --warning=RANGE\n" + " generate warning state if process count is outside this range\n" + " -c, --critical=RANGE\n" + " generate critical state if process count is outside this range\n\n" + "Optional Filters:\n" + " -s, --state=STATUSFLAGS\n" + " Only scan for processes that have, in the output of `ps`, one or\n" + " more of the status flags you specify (for example R, Z, S, RS,\n" + " RSZDT, plus others based on the output of your 'ps' command).\n" + " -p, --ppid=PPID\n" + " Only scan for children of the parent process ID indicated.\n" + " -u, --user=USER\n" + " Only scan for proceses with user name or ID indicated.\n" + " -a, --argument-array=STRING\n" + " Only scan for ARGS that match up to the length of the given STRING\n" + " -C, --command=COMMAND\n" + " Only scan for exact matches to the named COMMAND.\n\n" + "RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n" + "specified 'max:min', a warning status will be generated if the\n" + + "count is inside the specified range\n");} + + +void +print_usage (void) +{ + printf + ("Usage:\n" + " check_procs -w <range> -c <range> [-s state] [-p ppid] [-u user]\n" + " [-a argument-array] [-C command]\n" + " check_procs --version\n" " check_procs --help\n"); +} diff --git a/plugins/check_radius.c b/plugins/check_radius.c new file mode 100644 index 00000000..614d467b --- /dev/null +++ b/plugins/check_radius.c @@ -0,0 +1,345 @@ +/****************************************************************************** + * + * Program: radius server check plugin for Nagios + * License: GPL + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGNAME "check_radius" +#define REVISION "$Revision$" +#define COPYRIGHT "1999-2001" +#define AUTHORS "Robert August Vincent II/Karl DeBisschop" +#define EMAIL "kdebisschop@users.sourceforge.net" +#define SUMMARY "Tests to see if a radius server is accepting connections.\n" + +#define OPTIONS "\ +-H host -F config_file -u username -p password\'\ + [-P port] [-t timeout] [-r retries] [-e expect]" + +#define LONGOPTIONS "\ + -H, --hostname=HOST\n\ + Host name argument for servers using host headers (use numeric\n\ + address if possible to bypass DNS lookup).\n\ + -P, --port=INTEGER\n\ + Port number (default: %d)\n\ + -u, --username=STRING\n\ + The user to authenticate\n\ + -p, --password=STRING\n\ + Password for autentication (SECURITY RISK)\n\ + -F, --filename=STRING\n\ + Configuration file\n\ + -e, --expect=STRING\n\ + Response string to expect from the server\n\ + -r, --retries=INTEGER\n\ + Number of times to retry a failed connection\n\ + -t, --timeout=INTEGER\n\ + Seconds before connection times out (default: %d)\n\ + -v\n\ + Show details for command-line debugging (do not use with nagios server)\n\ + -h, --help\n\ + Print detailed help screen\n\ + -V, --version\n\ + Print version information\n" + +#define DESCRIPTION "\ +The password option presents a substantial security issue because the +password can be determined by careful watching of the command line in +a process listing. This risk is exacerbated because nagios will +run the plugin at regular prdictable intervals. Please be sure that +the password used does not allow access to sensitive system resources, +otherwise compormise could occur.\n" + +#include "config.h" +#include "common.h" +#include "utils.h" +#include <radiusclient.h> + +int process_arguments (int, char **); +void print_usage (void); +void print_help (void); + +char *server = NULL; +int port = PW_AUTH_UDP_PORT; +char *username = NULL; +char *password = NULL; +char *expect = NULL; +char *config_file = NULL; +int retries = 1; +int verbose = FALSE; + +ENV *env = NULL; + +/****************************************************************************** + +The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ +tags in the comments. With in the tags, the XML is assembled sequentially. +You can define entities in tags. You also have all the #defines available as +entities. + +Please note that all tags must be lowercase to use the DocBook XML DTD. + +@@-<article> + +<sect1> +<title>Quick Reference</title> +<!-- The refentry forms a manpage --> +<refentry> +<refmeta> +<manvolnum>5<manvolnum> +</refmeta> +<refnamdiv> +<refname>&PROGNAME;</refname> +<refpurpose>&SUMMARY;</refpurpose> +</refnamdiv> +</refentry> +</sect1> + +<sect1> +<title>FAQ</title> +</sect1> + +<sect1> +<title>Theory, Installation, and Operation</title> + +<sect2> +<title>General Description</title> +<para> +&DESCRIPTION; +</para> +</sect2> + +<sect2> +<title>Future Enhancements</title> +<para>ToDo List</para> +<itemizedlist> +<listitem>Add option to get password from a secured file rather than the command line</listitem> +</itemizedlist> +</sect2> + + +<sect2> +<title>Functions</title> +-@@ +******************************************************************************/ + +int +main (int argc, char **argv) +{ + UINT4 service; + char msg[BUFFER_LEN]; + SEND_DATA data = { 0 }; + int result; + UINT4 client_id; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + if ((config_file && rc_read_config (config_file)) || + rc_read_dictionary (rc_conf_str ("dictionary"))) + terminate (STATE_UNKNOWN, "Config file error"); + + service = PW_AUTHENTICATE_ONLY; + + if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && + rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) && + rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0))) + terminate (STATE_UNKNOWN, "Out of Memory?"); + + /* + * Fill in NAS-IP-Address + */ + + if ((client_id = rc_own_ipaddress ()) == 0) + return (ERROR_RC); + + if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == + NULL) return (ERROR_RC); + + rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, timeout_interval, + retries); + + result = rc_send_server (&data, msg); + rc_avpair_free (data.send_pairs); + if (data.receive_pairs) + rc_avpair_free (data.receive_pairs); + + if (result == TIMEOUT_RC) + terminate (STATE_CRITICAL, "Timeout"); + if (result == ERROR_RC) + terminate (STATE_CRITICAL, "Auth Error"); + if (result == BADRESP_RC) + terminate (STATE_WARNING, "Auth Failed"); + if (expect && !strstr (msg, expect)) + terminate (STATE_WARNING, msg); + if (result == OK_RC) + terminate (STATE_OK, "Auth OK"); + return (0); +} + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"port", required_argument, 0, 'P'}, + {"username", required_argument, 0, 'u'}, + {"password", required_argument, 0, 'p'}, + {"filename", required_argument, 0, 'F'}, + {"expect", required_argument, 0, 'e'}, + {"retries", required_argument, 0, 'r'}, + {"timeout", required_argument, 0, 't'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + if (argc < 2) + return ERROR; + + if (argc == 9) { + config_file = argv[1]; + username = argv[2]; + password = argv[3]; + if (is_intpos (argv[4])) + timeout_interval = atoi (argv[4]); + else + usage ("Timeout interval must be a positive integer"); + if (is_intpos (argv[5])) + retries = atoi (argv[5]); + else + usage ("Number of retries must be a positive integer"); + server = argv[6]; + if (is_intpos (argv[7])) + port = atoi (argv[7]); + else + usage ("Server port must be a positive integer"); + expect = argv[8]; + return OK; + } + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:P:F:u:p:t:r:e:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVvH:P:F:u:p:t:r:e:"); +#endif + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) { + printf ("Invalid host name/address\n\n"); + print_usage (); + exit (STATE_UNKNOWN); + } + server = optarg; + break; + case 'P': /* port */ + if (is_intnonneg (optarg)) + port = atoi (optarg); + else + usage ("Server port must be a positive integer"); + break; + case 'u': /* username */ + username = optarg; + break; + case 'p': /* password */ + password = optarg; + break; + case 'F': /* configuration file */ + config_file = optarg; + break; + case 'e': /* expect */ + expect = optarg; + break; + case 'r': /* retries */ + if (is_intpos (optarg)) + retries = atoi (optarg); + else + usage ("Number of retries must be a positive integer"); + break; + case 't': /* timeout */ + if (is_intpos (optarg)) + timeout_interval = atoi (optarg); + else + usage ("Timeout interval must be a positive integer"); + break; + } + } + return OK; +} + + + +void +print_help (void) +{ + print_revision (PROGNAME, REVISION); + printf + ("Copyright (c) %s %s <%s>\n\n%s\n", + COPYRIGHT, AUTHORS, EMAIL, SUMMARY); + print_usage (); + printf + ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n", + port, timeout_interval); + support (); +} + + +void +print_usage (void) +{ + printf ("Usage:\n" " %s %s\n" +#ifdef HAVE_GETOPT_H + " %s (-h | --help) for detailed help\n" + " %s (-V | --version) for version information\n", +#else + " %s -h for detailed help\n" + " %s -V for version information\n", +#endif + PROGNAME, OPTIONS, PROGNAME, PROGNAME); +} diff --git a/plugins/check_real.c b/plugins/check_real.c new file mode 100644 index 00000000..ba746b81 --- /dev/null +++ b/plugins/check_real.c @@ -0,0 +1,661 @@ +/***************************************************************************** +* +* CHECK_REAL.C +* +* Program: RealMedia plugin for Nagios +* License: GPL +* Copyright (c) 1999 Pedro Leite (leite@cic.ua.pt) +* +* Based on CHECK_HTTP.C +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Command line: CHECK_REAL <host_address> [-e expect] [-u url] [-p port] +* [-hn host_name] [-wt warn_time] [-ct crit_time] +* [-to to_sec] +* +* Description: +* +* This plugin will attempt to open an RTSP connection with the host. +* Successul connects return STATE_OK, refusals and timeouts return +* STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects, +* but incorrect reponse messages from the host result in STATE_WARNING return +* values. If you are checking a virtual server that uses "host headers"you +* must supply the FQDN (fully qualified domain name) as the [host_name] +* argument. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_real" + +#define PORT 554 +#define EXPECT "RTSP/1." +#define URL "" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int server_port = PORT; +char *server_address = NULL; +char *host_name = NULL; +char *server_url = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER]; + char *status_line = NULL; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + time (&start_time); + + /* try to connect to the host at the given port number */ + if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) + terminate (STATE_CRITICAL, "Unable to connect to %s on port %d\n", + server_address, server_port); + + /* Part I - Server Check */ + + /* send the OPTIONS request */ + sprintf (buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\n", host_name, server_port); + result = send (sd, buffer, strlen (buffer), 0); + + /* send the header sync */ + sprintf (buffer, "CSeq: 1\n"); + result = send (sd, buffer, strlen (buffer), 0); + + /* send a newline so the server knows we're done with the request */ + sprintf (buffer, "\n"); + result = send (sd, buffer, strlen (buffer), 0); + + /* watch for the REAL connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* return a CRITICAL status if we couldn't read any data */ + if (result == -1) + terminate (STATE_CRITICAL, "No data received from %s\n", host_name); + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, EXPECT)) { + if (server_port == PORT) + printf ("Invalid REAL response received from host\n"); + else + printf ("Invalid REAL response received from host on port %d\n", + server_port); + } + else { + /* else we got the REAL string, so check the return code */ + + time (&end_time); + + result = STATE_OK; + + status_line = (char *) strtok (buffer, "\n"); + + if (strstr (status_line, "200")) + result = STATE_OK; + + /* client errors result in a warning state */ + else if (strstr (status_line, "400")) + result = STATE_WARNING; + else if (strstr (status_line, "401")) + result = STATE_WARNING; + else if (strstr (status_line, "402")) + result = STATE_WARNING; + else if (strstr (status_line, "403")) + result = STATE_WARNING; + else if (strstr (status_line, "404")) + result = STATE_WARNING; + + /* server errors result in a critical state */ + else if (strstr (status_line, "500")) + result = STATE_CRITICAL; + else if (strstr (status_line, "501")) + result = STATE_CRITICAL; + else if (strstr (status_line, "502")) + result = STATE_CRITICAL; + else if (strstr (status_line, "503")) + result = STATE_CRITICAL; + + else + result = STATE_UNKNOWN; + } + + /* Part II - Check stream exists and is ok */ + if ((result == STATE_OK) && (server_url != NULL)) { + + /* Part I - Server Check */ + + /* send the OPTIONS request */ + sprintf (buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\n", host_name, + server_port, server_url); + result = send (sd, buffer, strlen (buffer), 0); + + /* send the header sync */ + sprintf (buffer, "CSeq: 2\n"); + result = send (sd, buffer, strlen (buffer), 0); + + /* send a newline so the server knows we're done with the request */ + sprintf (buffer, "\n"); + result = send (sd, buffer, strlen (buffer), 0); + + /* watch for the REAL connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* return a CRITICAL status if we couldn't read any data */ + if (result == -1) { + printf ("No data received from host\n"); + result = STATE_CRITICAL; + } + else { + /* make sure we find the response we are looking for */ + if (!strstr (buffer, EXPECT)) { + if (server_port == PORT) + printf ("Invalid REAL response received from host\n"); + else + printf ("Invalid REAL response received from host on port %d\n", + server_port); + } + else { + + /* else we got the REAL string, so check the return code */ + + time (&end_time); + + result = STATE_OK; + + status_line = (char *) strtok (buffer, "\n"); + + if (strstr (status_line, "200")) + result = STATE_OK; + + /* client errors result in a warning state */ + else if (strstr (status_line, "400")) + result = STATE_WARNING; + else if (strstr (status_line, "401")) + result = STATE_WARNING; + else if (strstr (status_line, "402")) + result = STATE_WARNING; + else if (strstr (status_line, "403")) + result = STATE_WARNING; + else if (strstr (status_line, "404")) + result = STATE_WARNING; + + /* server errors result in a critical state */ + else if (strstr (status_line, "500")) + result = STATE_CRITICAL; + else if (strstr (status_line, "501")) + result = STATE_CRITICAL; + else if (strstr (status_line, "502")) + result = STATE_CRITICAL; + else if (strstr (status_line, "503")) + result = STATE_CRITICAL; + + else + result = STATE_UNKNOWN; + } + } + } + + /* Return results */ + if (result == STATE_OK) { + + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + + /* Put some HTML in here to create a dynamic link */ + printf ("REAL %s - %d second response time\n", + (result == STATE_OK) ? "ok" : "problem", + (int) (end_time - start_time)); + } + else + printf ("%s\n", status_line); + + /* close the connection */ + close (sd); + + /* reset the alarm */ + alarm (0); + + return result; +} + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_expect == NULL) + server_expect = strscpy (NULL, EXPECT); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"IPaddress", required_argument, 0, 'I'}, + {"expect", required_argument, 0, 'e'}, + {"url", required_argument, 0, 'u'}, + {"port", required_argument, 0, 'p'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"timeout", required_argument, 0, 't'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVI:H:e:u:p:w:c:t:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVI:H:e:u:p:w:c:t"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'I': + case 'H': + case 'e': + case 'u': + case 'p': + case 'w': + case 'c': + case 't': + i++; + } + + switch (c) { + case 'I': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'e': /* string to expect in response header */ + server_expect = optarg; + break; + case 'u': /* string to expect in response header */ + server_url = optarg; + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_time = atoi (optarg); + check_warning_time = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_time = atoi (optarg); + check_critical_time = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Pedro Leite (leite@cic.ua.pt)/Karl DeBisschop\n\n" + "This plugin tests the REAL service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check this server on the indicated host\n" + " -I, --IPaddress=STRING or IPADDRESS\n" + " Check server at this host address\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -u, --url=STRING\n" + " Connect to this url\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", + PORT, EXPECT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit]\n" + " [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} + + + + +/* +// process command-line arguments +int +process_arguments (int argc, char **argv) +{ + int x; + + // no options were supplied + if (argc < 2) + return ERROR; + + // first option is always the server name/address + strncpy (server_address, argv[1], sizeof (server_address) - 1); + server_address[sizeof (server_address) - 1] = 0; + + // set the host name to the server address (until its overridden) + strcpy (host_name, server_address); + + // process all remaining arguments + for (x = 3; x <= argc; x++) + { + + // we got the string to expect from the server + if (!strcmp (argv[x - 1], "-e")) + { + if (x < argc) + { + strncpy (server_expect, argv[x], sizeof (server_expect) - 1); + server_expect[sizeof (server_expect) - 1] = 0; + x++; + } + else + return ERROR; + } + + // we got the URL to check + else if (!strcmp (argv[x - 1], "-u")) + { + if (x < argc) + { + strncpy (server_url, argv[x], sizeof (server_url) - 1); + server_url[sizeof (server_url) - 1] = 0; + x++; + } + else + return ERROR; + } + + // we go the host name to use in the host header + else if (!strcmp (argv[x - 1], "-hn")) + { + if (x < argc) + { + strncpy (host_name, argv[x], sizeof (host_name) - 1); + host_name[sizeof (host_name) - 1] = 0; + x++; + } + else + return ERROR; + } + + // we got the port number to use + else if (!strcmp (argv[x - 1], "-p")) + { + if (x < argc) + { + server_port = atoi (argv[x]); + x++; + } + else + return ERROR; + } + + // we got the socket timeout + else if (!strcmp (argv[x - 1], "-to")) + { + if (x < argc) + { + socket_timeout = atoi (argv[x]); + if (socket_timeout <= 0) + return ERROR; + x++; + } + else + return ERROR; + } + + // we got the warning threshold time + else if (!strcmp (argv[x - 1], "-wt")) + { + if (x < argc) + { + warning_time = atoi (argv[x]); + check_warning_time = TRUE; + x++; + } + else + return ERROR; + } + + // we got the critical threshold time + else if (!strcmp (argv[x - 1], "-ct")) + { + if (x < argc) + { + critical_time = atoi (argv[x]); + check_critical_time = TRUE; + x++; + } + else + return ERROR; + } + + // else we got something else... + else + return ERROR; + } + + return OK; +} + + result = process_arguments (argc, argv); + + if (result != OK) + { + + printf ("Incorrect number of arguments supplied\n"); + printf ("\n"); + print_revision(argv[0],"$Revision$"); + printf ("Copyright (c) 1999 Pedro Leite (leite@cic.ua.pt)\n"); + printf ("Last Modified: 30-10-1999\n"); + printf ("License: GPL\n"); + printf ("\n"); + printf ("Usage: %s <host_address> [-e expect] [-u url] [-p port] [-hn host_name] [-wt warn_time]\n",argv[0]); + printf(" [-ct crit_time] [-to to_sec] [-a auth]\n"); + printf ("\n"); + printf ("Options:\n"); + printf (" [expect] = String to expect in first line of server response - default is \"%s\"\n", EXPECT); + printf (" [url] = Optional URL to GET - default is root document\n"); + printf (" [port] = Optional port number to use - default is %d\n", PORT); + printf (" [host_name] = Optional host name argument to GET command - used for servers using host headers\n"); + printf (" [warn_time] = Response time in seconds necessary to result in a warning status\n"); + printf (" [crit_time] = Response time in seconds necessary to result in a critical status\n"); + printf (" [to_sec] = Number of seconds before connection attempt times out - default is %d seconds\n", DEFAULT_SOCKET_TIMEOUT); + printf (" [auth] = Optional username:password for sites requiring basic authentication\n"); + printf ("\n"); + printf ("This plugin attempts to contact the REAL service on the specified host.\n"); + printf ("If possible, supply an IP address for the host address, as this will bypass the DNS lookup.\n"); + printf ("\n"); + + return STATE_UNKNOWN; + } + +*/ diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c new file mode 100644 index 00000000..d57b7841 --- /dev/null +++ b/plugins/check_smtp.c @@ -0,0 +1,362 @@ +/****************************************************************************** +* +* CHECK_SMTP.C +* +* Program: SMTP plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* $Id$ +* +* Description: +* +* This plugin will attempt to open an SMTP connection with the host. +* Successul connects return STATE_OK, refusals and timeouts return +* STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful +* connects, but incorrect reponse messages from the host result in +* STATE_WARNING return values. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_smtp" + +#define SMTP_PORT 25 +#define SMTP_EXPECT "220" +#define SMTP_QUIT "QUIT\n" + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +int check_disk (int usp, int free_disk); +void print_help (void); +void print_usage (void); + +int server_port = SMTP_PORT; +char *server_address = NULL; +char *server_expect = NULL; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; + +int +main (int argc, char **argv) +{ + int sd; + int result; + char buffer[MAX_INPUT_BUFFER] = ""; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); + result = my_tcp_connect (server_address, server_port, &sd); + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + /* watch for the SMTP connection string */ + result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); + + /* strip the buffer of carriage returns */ + strip (buffer); + + /* return a WARNING status if we couldn't read any data */ + if (result == -1) { + printf ("recv() failed\n"); + result = STATE_WARNING; + } + + else { + + /* make sure we find the response we are looking for */ + if (!strstr (buffer, server_expect)) { + if (server_port == SMTP_PORT) + printf ("Invalid SMTP response received from host\n"); + else + printf ("Invalid SMTP response received from host on port %d\n", + server_port); + result = STATE_WARNING; + } + + else { + + time (&end_time); + + result = STATE_OK; + + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = + STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + + if (verbose == TRUE) + printf ("SMTP %s - %d sec. response time, %s\n", + state_text (result), (int) (end_time - start_time), buffer); + else + printf ("SMTP %s - %d second response time\n", state_text (result), + (int) (end_time - start_time)); + } + } + + /* close the connection */ + send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0); + close (sd); + } + + /* reset the alarm */ + alarm (0); + + return result; +} + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_address == NULL) + server_address = strscpy (NULL, "127.0.0.1"); + + if (server_expect == NULL) + server_expect = strscpy (NULL, SMTP_EXPECT); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"expect", required_argument, 0, 'e'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"port", required_argument, 0, 'P'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvt:p:e:c:w:H:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVvt:p:e:c:w:H:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 't': + case 'p': + case 'e': + case 'c': + case 'w': + case 'H': + i++; + } + + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'e': /* username */ + server_expect = optarg; + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_time = atoi (optarg); + check_critical_time = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_time = atoi (optarg); + check_warning_time = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'v': /* verbose */ + verbose = TRUE; + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin test the SMTP service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -e, --expect=STRING\n" + " String to expect in first line of server response (default: %s)\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", + SMTP_PORT, SMTP_EXPECT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit] [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c new file mode 100644 index 00000000..2f970b3d --- /dev/null +++ b/plugins/check_snmp.c @@ -0,0 +1,805 @@ +/****************************************************************************** + * + * CHECK_SNMP.C + * + * Program: SNMP plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * + * Description: + * + * This plugin uses the 'snmpget' command included with the UCD-SNMP + * package. If you don't have the package installed you will need to + * download it from http://ucd-snmp.ucdavis.edu before you can use + * this plugin. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + *./plugins/check_snmp 127.0.0.1 -c public -o .1.3.6.1.4.1.2021.9.1.2.1 + *****************************************************************************/ + +#include "common.h" +#include "utils.h" +#include "popen.h" + +#define PROGNAME check_snmp + +#define mark(a) ((a)!=0?"*":"") + +#define CHECK_UNDEF 0 +#define CRIT_PRESENT 1 +#define CRIT_STRING 2 +#define CRIT_REGEX 4 +#define CRIT_GT 8 +#define CRIT_LT 16 +#define CRIT_GE 32 +#define CRIT_LE 64 +#define CRIT_EQ 128 +#define CRIT_NE 256 +#define CRIT_RANGE 512 +#define WARN_PRESENT 1024 +#define WARN_STRING 2048 +#define WARN_REGEX 4096 +#define WARN_GT 8192 +#define WARN_LT 16384 +#define WARN_GE 32768 +#define WARN_LE 65536 +#define WARN_EQ 131072 +#define WARN_NE 262144 +#define WARN_RANGE 524288 + +#define MAX_OIDS 8 +#define MAX_DELIM_LENGTH 8 +#define DEFAULT_DELIMITER "=" +#define DEFAULT_OUTPUT_DELIMITER " " + +void print_usage (void); +void print_help (char *); +int process_arguments (int, char **); +int call_getopt (int, char **); +int check_num (int); +char *clarify_message (char *); +int lu_getll (unsigned long *, char *); +int lu_getul (unsigned long *, char *); +char *thisarg (char *str); +char *nextarg (char *str); + +#ifdef HAVE_REGEX_H +#include <regex.h> +char regex_expect[MAX_INPUT_BUFFER] = ""; +regex_t preg; +regmatch_t pmatch[10]; +char timestamp[10] = ""; +char regex[MAX_INPUT_BUFFER]; +char errbuf[MAX_INPUT_BUFFER]; +int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; +int eflags = 0; +int errcode, excode; +#endif + +char *server_address = NULL; +char *community = NULL; +char oid[MAX_INPUT_BUFFER] = ""; +char *label = NULL; +char *units = NULL; +char string_value[MAX_INPUT_BUFFER] = ""; +char **labels = NULL; +char **unitv = NULL; +int nlabels = 0; +int labels_size = 8; +int nunits = 0; +int unitv_size = 8; +unsigned long lower_warn_lim[MAX_OIDS]; +unsigned long upper_warn_lim[MAX_OIDS]; +unsigned long lower_crit_lim[MAX_OIDS]; +unsigned long upper_crit_lim[MAX_OIDS]; +unsigned long response_value[MAX_OIDS]; +int check_warning_value = FALSE; +int check_critical_value = FALSE; +int eval_method[MAX_OIDS]; +char *delimiter = NULL; +char *output_delim = NULL; + + +int +main (int argc, char **argv) +{ + int i = 0; + int iresult = STATE_UNKNOWN; + int found = 0; + int result = STATE_DEPENDENT; + char input_buffer[MAX_INPUT_BUFFER]; + char *command_line = NULL; + char *response = NULL; + char *outbuff = NULL; + char *output = NULL; + char *ptr = NULL; + char *p2 = NULL; + char *show = NULL; + + labels = malloc (labels_size); + unitv = malloc (unitv_size); + outbuff = strscpy (outbuff, ""); + for (i = 0; i < MAX_OIDS; i++) + eval_method[i] = CHECK_UNDEF; + i = 0; + + if (process_arguments (argc, argv) == ERROR) + usage ("Incorrect arguments supplied\n"); + + /* create the command line to execute */ + command_line = ssprintf + (command_line, + "%s -m ALL -v 1 %s %s %s", + PATH_TO_SNMPGET, server_address, community, oid); + + /* run the command */ + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + exit (STATE_UNKNOWN); + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) + output = strscat (output, input_buffer); + + ptr = output; + + while (ptr) { + + ptr = strstr (ptr, delimiter); + if (ptr == NULL) + break; + + ptr += strlen (delimiter); + ptr += strspn (ptr, " "); + + found++; + + if (ptr[0] == '"') { + ptr++; + response = strpcpy (response, ptr, "\""); + ptr = strpbrk (ptr, "\""); + ptr += strspn (ptr, "\"\n"); + } + else { + response = strpcpy (response, ptr, "\n"); + ptr = strpbrk (ptr, "\n"); + ptr += strspn (ptr, "\n"); + while + (strstr (ptr, delimiter) && + strstr (ptr, "\n") && strstr (ptr, "\n") < strstr (ptr, delimiter)) { + response = strpcat (response, ptr, "\n"); + ptr = strpbrk (ptr, "\n"); + } + if (ptr && strstr (ptr, delimiter) == NULL) { + response = strscat (response, ptr); + ptr = NULL; + } + } + + if (strstr (response, "Gauge: ")) + show = strstr (response, "Gauge: ") + 7; + else if (strstr (response, "Gauge32: ")) + show = strstr (response, "Gauge32: ") + 9; + else + show = response; + p2 = show; + + if (eval_method[i] & CRIT_GT || + eval_method[i] & CRIT_LT || + eval_method[i] & CRIT_GE || + eval_method[i] & CRIT_LE || + eval_method[i] & CRIT_EQ || + eval_method[i] & CRIT_NE || + eval_method[i] & WARN_GT || + eval_method[i] & WARN_LT || + eval_method[i] & WARN_GE || + eval_method[i] & WARN_LE || + eval_method[i] & WARN_EQ || eval_method[i] & WARN_NE) { + p2 = strpbrk (p2, "0123456789"); + response_value[i] = strtoul (p2, NULL, 10); + iresult = check_num (i); + show = ssprintf (show, "%d", response_value[i]); + } + + else if (eval_method[i] & CRIT_STRING) { + if (strcmp (response, string_value)) + iresult = STATE_CRITICAL; + else + iresult = STATE_OK; + } + + else if (eval_method[i] & CRIT_REGEX) { +#ifdef HAVE_REGEX_H + excode = regexec (&preg, response, 10, pmatch, eflags); + if (excode == 0) { + iresult = STATE_OK; + } + else if (excode != REG_NOMATCH) { + regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER); + printf ("Execute Error: %s\n", errbuf); + exit (STATE_CRITICAL); + } + else { + iresult = STATE_CRITICAL; + } +#else + printf ("SNMP UNKNOWN: call for regex which was not a compiled option"); + exit (STATE_UNKNOWN); +#endif + } + + else { + if (response) + iresult = STATE_OK; + else if (eval_method[i] & CRIT_PRESENT) + iresult = STATE_CRITICAL; + else + iresult = STATE_WARNING; + } + + result = max (result, iresult); + + if (nlabels > 1 && i < nlabels && labels[i] != NULL) + outbuff = ssprintf + (outbuff, + "%s%s%s %s%s%s", + outbuff, + (i == 0) ? " " : output_delim, + labels[i], mark (iresult), show, mark (iresult)); + else + outbuff = ssprintf + (outbuff, + "%s%s%s%s%s", + outbuff, + (i == 0) ? " " : output_delim, mark (iresult), show, mark (iresult)); + + if (nunits > 0 && i < nunits) + outbuff = ssprintf (outbuff, "%s %s", outbuff, unitv[i]); + + i++; + + } /* end while */ + + if (found == 0) + terminate + (STATE_UNKNOWN, + "%s problem - No data recieved from host\nCMD: %s\n", + label, command_line); + + /* WARNING if output found on stderr */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + if (nunits > 0) + printf ("%s %s -%s\n", label, state_text (result), outbuff); + else + printf ("%s %s -%s %s\n", label, state_text (result), outbuff, units); + + return result; +} + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + if (strcmp ("-wv", argv[c]) == 0) + strcpy (argv[c], "-w"); + if (strcmp ("-cv", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (server_address == NULL) + server_address = strscpy (NULL, argv[c]); + } + + if (community == NULL) + community = strscpy (NULL, "public"); + + if (delimiter == NULL) + delimiter = strscpy (NULL, DEFAULT_DELIMITER); + + if (output_delim == NULL) + output_delim = strscpy (NULL, DEFAULT_OUTPUT_DELIMITER); + + if (label == NULL) + label = strscpy (NULL, "SNMP"); + + if (units == NULL) + units = strscpy (NULL, ""); + + return c; +} + +int +call_getopt (int argc, char **argv) +{ + char *ptr; + int c, i = 1; + int j = 0, jj = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"timeout", required_argument, 0, 't'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"hostname", required_argument, 0, 'H'}, + {"community", required_argument, 0, 'C'}, + {"oid", required_argument, 0, 'o'}, + {"object", required_argument, 0, 'o'}, + {"delimiter", required_argument, 0, 'd'}, + {"output-delimiter", required_argument, 0, 'D'}, + {"string", required_argument, 0, 's'}, + {"regex", required_argument, 0, 'r'}, + {"ereg", required_argument, 0, 'r'}, + {"eregi", required_argument, 0, 'R'}, + {"label", required_argument, 0, 'l'}, + {"units", required_argument, 0, 'u'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+?hVt:c:w:H:C:o:d:D:s:R:r:l:u:", + long_options, &option_index); +#else + c = getopt (argc, argv, "+?hVt:c:w:H:C:o:d:D:s:R:r:l:u:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'c': + case 'w': + case 'H': + case 'C': + case 'o': + case 'd': + case 'D': + case 's': + case 'R': + case 'r': + case 'l': + case 'u': + i++; + } + + switch (c) { + case '?': /* help */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (my_basename (argv[0])); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 't': /* timeout period */ + if (!is_integer (optarg)) { + printf ("%s: Timeout Interval must be an integer!\n\n", + my_basename (argv[0])); + print_usage (); + exit (STATE_UNKNOWN); + } + timeout_interval = atoi (optarg); + break; + case 'c': /* critical time threshold */ + if (strspn (optarg, "0123456789:,") < strlen (optarg)) { + printf ("Invalid critical threshold: %s\n", optarg); + print_usage (); + exit (STATE_UNKNOWN); + } + for (ptr = optarg, jj = 0; ptr && jj < MAX_OIDS; jj++) { + if (lu_getll (&lower_crit_lim[jj], ptr) == 1) + eval_method[jj] |= CRIT_LT; + if (lu_getul (&upper_crit_lim[jj], ptr) == 1) + eval_method[jj] |= CRIT_GT; + (ptr = index (ptr, ',')) ? ptr++ : ptr; + } + break; + case 'w': /* warning time threshold */ + if (strspn (optarg, "0123456789:,") < strlen (optarg)) { + printf ("Invalid warning threshold: %s\n", optarg); + print_usage (); + exit (STATE_UNKNOWN); + } + for (ptr = optarg, jj = 0; ptr && jj < MAX_OIDS; jj++) { + if (lu_getll (&lower_warn_lim[jj], ptr) == 1) + eval_method[jj] |= WARN_LT; + if (lu_getul (&upper_warn_lim[jj], ptr) == 1) + eval_method[jj] |= WARN_GT; + (ptr = index (ptr, ',')) ? ptr++ : ptr; + } + break; + case 'H': /* Host or server */ + server_address = strscpy (server_address, optarg); + break; + case 'C': /* group or community */ + community = strscpy (community, optarg); + break; + case 'o': /* object identifier */ + for (ptr = optarg; (ptr = index (ptr, ',')); ptr++) + ptr[0] = ' '; + strncpy (oid, optarg, sizeof (oid) - 1); + oid[sizeof (oid) - 1] = 0; + for (ptr = optarg, j = 1; (ptr = index (ptr, ' ')); ptr++) + j++; + break; + case 'd': /* delimiter */ + delimiter = strscpy (delimiter, optarg); + break; + case 'D': /* output-delimiter */ + output_delim = strscpy (output_delim, optarg); + break; + case 's': /* string or substring */ + strncpy (string_value, optarg, sizeof (string_value) - 1); + string_value[sizeof (string_value) - 1] = 0; + eval_method[jj++] = CRIT_STRING; + break; + case 'R': /* regex */ +#ifdef HAVE_REGEX_H + cflags = REG_ICASE; +#endif + case 'r': /* regex */ +#ifdef HAVE_REGEX_H + cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; + strncpy (regex_expect, optarg, sizeof (regex_expect) - 1); + regex_expect[sizeof (regex_expect) - 1] = 0; + errcode = regcomp (&preg, regex_expect, cflags); + if (errcode != 0) { + regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf ("Could Not Compile Regular Expression"); + return ERROR; + } + eval_method[jj++] = CRIT_REGEX; +#else + printf ("SNMP UNKNOWN: call for regex which was not a compiled option"); + exit (STATE_UNKNOWN); +#endif + break; + case 'l': /* label */ + label = optarg; + nlabels++; + if (nlabels >= labels_size) { + labels_size += 8; + labels = realloc (labels, labels_size); + if (labels == NULL) + terminate (STATE_UNKNOWN, + "Could not realloc() labels[%d]", nlabels); + } + labels[nlabels - 1] = optarg; + ptr = thisarg (optarg); + if (strstr (ptr, "'") == ptr) + labels[nlabels - 1] = ptr + 1; + else + labels[nlabels - 1] = ptr; + while (ptr && (ptr = nextarg (ptr))) { + if (nlabels >= labels_size) { + labels_size += 8; + labels = realloc (labels, labels_size); + if (labels == NULL) + terminate (STATE_UNKNOWN, "Could not realloc() labels\n"); + } + labels++; + ptr = thisarg (ptr); + if (strstr (ptr, "'") == ptr) + labels[nlabels - 1] = ptr + 1; + else + labels[nlabels - 1] = ptr; + } + break; + case 'u': /* units */ + units = optarg; + nunits++; + if (nunits >= unitv_size) { + unitv_size += 8; + unitv = realloc (unitv, unitv_size); + if (unitv == NULL) + terminate (STATE_UNKNOWN, + "Could not realloc() units [%d]\n", nunits); + } + unitv[nunits - 1] = optarg; + ptr = thisarg (optarg); + if (strstr (ptr, "'") == ptr) + unitv[nunits - 1] = ptr + 1; + else + unitv[nunits - 1] = ptr; + while (ptr && (ptr = nextarg (ptr))) { + if (nunits >= unitv_size) { + unitv_size += 8; + unitv = realloc (unitv, unitv_size); + if (units == NULL) + terminate (STATE_UNKNOWN, "Could not realloc() units\n"); + } + nunits++; + ptr = thisarg (ptr); + if (strstr (ptr, "'") == ptr) + unitv[nunits - 1] = ptr + 1; + else + unitv[nunits - 1] = ptr; + } + break; + } + } + return i; +} + +void +print_usage (void) +{ + printf + ("Usage: check_snmp -H <ip_address> -o <OID> [-w warn_range] [-c crit_range] \n" + " [-C community] [-s string] [-r regex] [-R regexi] [-t timeout]\n" + " [-l label] [-u units] [-d delimiter] [-D output-delimiter]\n" + " check_snmp --help\n" " check_snmp --version\n"); +} + +void +print_help (char *cmd) +{ + printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n" + "License: GPL\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n" + " -H, --hostname=HOST\n" + " Name or IP address of the device you wish to query\n" + " -o, --oid=OID(s)\n" + " Object identifier(s) whose value you wish to query\n" + " -w, --warning=INTEGER_RANGE(s)\n" + " Range(s) which will not result in a WARNING status\n" + " -c, --critical=INTEGER_RANGE(s)\n" + " Range(s) which will not result in a CRITICAL status\n" + " -C, --community=STRING\n" + " Optional community string for SNMP communication\n" + " (default is \"public\")\n" + " -u, --units=STRING\n" + " Units label(s) for output data (e.g., 'sec.').\n" + " -d, --delimiter=STRING\n" + " Delimiter to use when parsing returned data. Default is \"%s\"\n" + " Any data on the right hand side of the delimiter is considered\n" + " to be the data that should be used in the evaluation.\n" + " -t, --timeout=INTEGER\n" + " Seconds to wait before plugin times out (see also nagios server timeout)\n" + " -D, --output-delimiter=STRING\n" + " Separates output on multiple OID requests\n" + " -s, --string=STRING\n" + " Return OK state (for that OID) if STRING is an exact match\n" + " -r, --ereg=REGEX\n" + " Return OK state (for that OID) if extended regular expression REGEX matches\n" + " -R, --eregi=REGEX\n" + " Return OK state (for that OID) if case-insensitive extended REGEX matches\n" + " -l, --label=STRING\n" + " Prefix label for output from plugin (default -s 'SNMP')\n\n" + "- This plugin uses the 'snmpget' command included with the UCD-SNMP package.\n" + " If you don't have the package installed, you will need to download it from\n" + " http://ucd-snmp.ucdavis.edu before you can use this plugin.\n" + "- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with\n" + " internal spaces must be quoted)\n" + "- Ranges are inclusive and are indicated with colons. When specified as\n" + " 'min:max' a STATE_OK will be returned if the result is within the indicated\n" + " range or is equal to the upper or lower bound. A non-OK state will be\n" + " returned if the result is outside the specified range.\n" + "- If spcified in the order 'max:min' a non-OK state will be returned if the\n" + " result is within the (inclusive) range.\n" + "- Upper or lower bounds may be omitted to skip checking the respective limit.\n" + "- Bare integers are interpreted as upper limits.\n" + "- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'\n" + "- Note that only one string and one regex may be checked at present\n" + "- All evaluation methods other than PR, STR, and SUBSTR expect that the value\n" + " returned from the SNMP query is an unsigned integer.\n\n", + DEFAULT_DELIMITER); +} + +char * +clarify_message (char *msg) +{ + int i = 0; + int foo; + char tmpmsg_c[MAX_INPUT_BUFFER]; + char *tmpmsg = (char *) &tmpmsg_c; + tmpmsg = strcpy (tmpmsg, msg); + if (!strncmp (tmpmsg, " Hex:", 5)) { + tmpmsg = strtok (tmpmsg, ":"); + while ((tmpmsg = strtok (NULL, " "))) { + foo = strtol (tmpmsg, NULL, 16); + /* Translate chars that are not the same value in the printers + * character set. + */ + switch (foo) { + case 208: + { + foo = 197; + break; + } + case 216: + { + foo = 196; + break; + } + } + msg[i] = foo; + i++; + } + msg[i] = 0; + } + return (msg); +} + + +int +check_num (int i) +{ + int result; + result = STATE_OK; + if (eval_method[i] & WARN_GT && eval_method[i] & WARN_LT && + lower_warn_lim[i] > upper_warn_lim[i]) { + if (response_value[i] <= lower_warn_lim[i] && + response_value[i] >= upper_warn_lim[i]) { + result = STATE_WARNING; + } + } + else if + ((eval_method[i] & WARN_GT && response_value[i] > upper_warn_lim[i]) || + (eval_method[i] & WARN_GE && response_value[i] >= upper_warn_lim[i]) || + (eval_method[i] & WARN_LT && response_value[i] < lower_warn_lim[i]) || + (eval_method[i] & WARN_LE && response_value[i] <= lower_warn_lim[i]) || + (eval_method[i] & WARN_EQ && response_value[i] == upper_warn_lim[i]) || + (eval_method[i] & WARN_NE && response_value[i] != upper_warn_lim[i])) { + result = STATE_WARNING; + } + + if (eval_method[i] & CRIT_GT && eval_method[i] & CRIT_LT && + lower_warn_lim[i] > upper_warn_lim[i]) { + if (response_value[i] <= lower_crit_lim[i] && + response_value[i] >= upper_crit_lim[i]) { + result = STATE_CRITICAL; + } + } + else if + ((eval_method[i] & CRIT_GT && response_value[i] > upper_crit_lim[i]) || + (eval_method[i] & CRIT_GE && response_value[i] >= upper_crit_lim[i]) || + (eval_method[i] & CRIT_LT && response_value[i] < lower_crit_lim[i]) || + (eval_method[i] & CRIT_LE && response_value[i] <= lower_crit_lim[i]) || + (eval_method[i] & CRIT_EQ && response_value[i] == upper_crit_lim[i]) || + (eval_method[i] & CRIT_NE && response_value[i] != upper_crit_lim[i])) { + result = STATE_CRITICAL; + } + + return result; +} + + +int +lu_getll (unsigned long *ll, char *str) +{ + char tmp[100]; + if (strchr (str, ':') == NULL) + return 0; + if (strchr (str, ',') != NULL && (strchr (str, ',') < strchr (str, ':'))) + return 0; + if (sscanf (str, "%lu%[:]", ll, tmp) == 2) + return 1; + return 0; +} + +int +lu_getul (unsigned long *ul, char *str) +{ + char tmp[100]; + if (sscanf (str, "%lu%[^,]", ul, tmp) == 1) + return 1; + if (sscanf (str, ":%lu%[^,]", ul, tmp) == 1) + return 1; + if (sscanf (str, "%*u:%lu%[^,]", ul, tmp) == 1) + return 1; + return 0; +} + + + + + + +/* trim leading whitespace + if there is a leading quote, make sure it balances */ + +char * +thisarg (char *str) +{ + str += strspn (str, " \t\r\n"); /* trim any leading whitespace */ + if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */ + if (strlen (str) == 1 || !strstr (str + 1, "'")) + terminate (STATE_UNKNOWN, "Unbalanced quotes\n"); + } + return str; +} + + +/* if there's a leading quote, advance to the trailing quote + set the trailing quote to '\x0' + if the string continues, advance beyond the comma */ + +char * +nextarg (char *str) +{ + if (strstr (str, "'") == str) { + if (strlen (str) > 1) { + str = strstr (str + 1, "'"); + str[0] = 0; + return (++str); + } + else { + str[0] = 0; + return NULL; + } + } + if (strstr (str, ",") == str) { + if (strlen (str) > 1) { + str[0] = 0; + return (++str); + } + else { + str[0] = 0; + return NULL; + } + } + if ((str = strstr (str, ",")) && strlen (str) > 1) { + str[0] = 0; + return (++str); + } + return NULL; +} diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c new file mode 100644 index 00000000..d78189fc --- /dev/null +++ b/plugins/check_ssh.c @@ -0,0 +1,285 @@ +/* +* check_ssh.c +* +* Made by (Remi PAULMIER) +* Login <remi@sinfomic.fr> +* +* Started on Fri Jul 9 09:18:23 1999 Remi PAULMIER +* Update Thu Jul 22 12:50:04 1999 remi paulmier +* $Id$ +* +*/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_ssh" + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif + +#define SSH_DFL_PORT 22 +#define BUFF_SZ 256 + +short port = -1; +char *server_name = NULL; +int verbose = FALSE; + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (void); +void print_usage (void); + +char *ssh_resolve (char *hostname); +int ssh_connect (char *haddr, short hport); + +int +main (int argc, char **argv) +{ + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + alarm (socket_timeout); + + /* ssh_connect exits if error is found */ + ssh_connect (ssh_resolve (server_name), port); + + alarm (0); + + return (STATE_OK); +} + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (server_name == NULL) { + server_name = argv[c]; + } + else if (port == -1) { + if (is_intpos (argv[c])) { + port = atoi (argv[c]); + } + else { + print_usage (); + exit (STATE_UNKNOWN); + } + } + } + + return validate_arguments (); +} + + +/************************************************************************ +* +* Run the getopt until we encounter a non-option entry in the arglist +* +*-----------------------------------------------------------------------*/ + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {"timeout", required_argument, 0, 't'}, + {"host", required_argument, 0, 'H'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+Vhvt:H:p:", long_options, &option_index); +#else + c = getopt (argc, argv, "+Vhvt:H:p:"); +#endif + + if (c == -1 || c == EOF) + break; + + i++; + switch (c) { + case 't': + case 'H': + case 'p': + i++; + } + + switch (c) { + case '?': /* help */ + usage (""); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'v': /* verose */ + verbose = TRUE; + break; + case 't': /* timeout period */ + if (!is_integer (optarg)) + usage ("Timeout Interval must be an integer!\n\n"); + socket_timeout = atoi (optarg); + break; + case 'H': /* host */ + server_name = optarg; + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + port = atoi (optarg); + } + else { + printf ("Port number nust be a positive integer: %s\n", optarg); + usage (""); + } + } + + } + return i; +} + +int +validate_arguments (void) +{ + if (server_name == NULL) + return ERROR; + if (port == -1) /* funky, but allows -p to override stray integer in args */ + port = SSH_DFL_PORT; + return OK; +} + + +/************************************************************************ +* +* Resolve hostname into IP address +* +*-----------------------------------------------------------------------*/ + +char * +ssh_resolve (char *hostname) +{ + struct hostent *host; + + host = gethostbyname (hostname); + if (!host) { + herror (hostname); + exit (STATE_CRITICAL); + } + return (host->h_addr); +} + + +/************************************************************************ +* +* Try to connect to SSH server at specified server and port +* +*-----------------------------------------------------------------------*/ + +int +ssh_connect (char *haddr, short hport) +{ + int s; + struct sockaddr_in addr; + int addrlen; + int len; + char *output = NULL; + char *buffer = NULL; + char *ssh_proto = NULL; + char *ssh_server = NULL; + char revision[20]; + + sscanf ("$Revision$", "$Revision: %[0123456789.]", revision); + + addrlen = sizeof (addr); + memset (&addr, 0, addrlen); + addr.sin_port = htons (hport); + addr.sin_family = AF_INET; + bcopy (haddr, (void *) &addr.sin_addr.s_addr, 4); + + s = socket (AF_INET, SOCK_STREAM, 0); + if (!s) { + printf ("socket(): %s for %s:%d\n", strerror (errno), server_name, hport); + exit (STATE_CRITICAL); + } + + if (connect (s, (struct sockaddr *) &addr, addrlen)) { + printf ("connect(): %s for %s:%d\n", strerror (errno), server_name, + hport); + exit (STATE_CRITICAL); + } + + output = (char *) malloc (BUFF_SZ + 1); + memset (output, 0, BUFF_SZ + 1); + recv (s, output, BUFF_SZ, 0); + if (strncmp (output, "SSH", 3)) { + printf ("Server answer: %s", output); + exit (STATE_CRITICAL); + } + else { + strip (output); + if (verbose) + printf ("%s\n", output); + ssh_proto = output + 4; + ssh_server = ssh_proto + strspn (ssh_proto, "0123456789-. "); + ssh_proto[strspn (ssh_proto, "0123456789-. ")] = 0; + printf + ("SSH ok - protocol version %s - server version %s\n", + ssh_proto, ssh_server); + buffer = + ssprintf (buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, revision); + send (s, buffer, strlen (buffer), MSG_DONTWAIT); + if (verbose) + printf ("%s\n", buffer); + exit (STATE_OK); + } +} + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf ("Copyright (c) 1999 Remi Paulmier (remi@sinfomic.fr)\n\n"); + print_usage (); + printf ("by default, port is %d\n", SSH_DFL_PORT); +} + +void +print_usage (void) +{ + printf + ("Usage:\n" + " %s -t [timeout] -p [port] <host>\n" + " %s -V prints version info\n" + " %s -h prints more detailed help\n", PROGNAME, PROGNAME, PROGNAME); +} + +/* end of check_ssh.c */ diff --git a/plugins/check_swap.c b/plugins/check_swap.c new file mode 100644 index 00000000..d225e1dc --- /dev/null +++ b/plugins/check_swap.c @@ -0,0 +1,325 @@ +/****************************************************************************** +* +* CHECK_SWAP.C +* +* Program: Process plugin for Nagios +* License: GPL +* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) +* +* $Id$ +* +******************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_swap" + +int process_arguments (int argc, char **argv); +int call_getopt (int argc, char **argv); +int validate_arguments (void); +void print_usage (void); +void print_help (void); + +int warn_percent = 200, crit_percent = 200, warn_size = -1, crit_size = -1; + +int +main (int argc, char **argv) +{ + int total_swap, used_swap, free_swap, percent_used; + int result = STATE_OK; + char input_buffer[MAX_INPUT_BUFFER]; +#ifdef HAVE_SWAP + char *temp_buffer; +#endif +#ifdef HAVE_PROC_MEMINFO + FILE *fp; +#endif + char str[32]; + char *status = NULL; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + +#ifdef HAVE_PROC_MEMINFO + fp = fopen (PROC_MEMINFO, "r"); + status = ssprintf (status, "%s", "Swap used:"); + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { + sscanf (input_buffer, " %s %d %d %d", str, &total_swap, &used_swap, + &free_swap); + if (strstr (str, "Swap")) { + percent_used = 100 * (((float) used_swap) / ((float) total_swap)); + status = ssprintf + (status, + "%s %2d%% (%d bytes out of %d)", + status, percent_used, used_swap, total_swap); + if (percent_used >= crit_percent || free_swap <= crit_size) + result = STATE_CRITICAL; + else if (percent_used >= warn_percent || free_swap <= warn_size) + result = STATE_WARNING; + break; + } + } + fclose (fp); +#else +#ifdef HAVE_SWAP + child_process = spopen (SWAP_COMMAND); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", SWAP_COMMAND); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", SWAP_COMMAND); + + sprintf (str, "%s", ""); + /* read 1st line */ + fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); + if (strcmp (SWAP_FORMAT, "") == 0) { + temp_buffer = strtok (input_buffer, " \n"); + while (temp_buffer) { + if (strstr (temp_buffer, "blocks")) + sprintf (str, "%s %s", str, "%f"); + else if (strstr (temp_buffer, "free")) + sprintf (str, "%s %s", str, "%f"); + else + sprintf (str, "%s %s", str, "%*s"); + temp_buffer = strtok (NULL, " \n"); + } + } + + status = ssprintf (status, "%s", "Swap used:"); + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + sscanf (input_buffer, SWAP_FORMAT, &total_swap, &free_swap); + used_swap = total_swap - free_swap; + percent_used = 100 * ((float) used_swap) / ((float) total_swap); + status = ssprintf + (status, + "%s %2d%% (%d bytes out of %d)", + status, percent_used, used_swap, total_swap); + if (percent_used >= crit_percent || free_swap <= crit_size) + result = STATE_CRITICAL; + else if (percent_used >= warn_percent || free_swap <= warn_size) + result = STATE_WARNING; + } + + /* If we get anything on STDERR, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); +#endif +#endif + +#ifndef SWAP_COMMAND +#ifndef SWAP_FILE +#ifndef HAVE_PROC_MEMINFO + return STATE_UNKNOWN; +#endif +#endif +#endif + + if (result == STATE_OK) + printf ("Swap ok - %s\n", status); + else if (result == STATE_CRITICAL) + printf ("CRITICAL - %s\n", status); + else if (result == STATE_WARNING) + printf ("WARNING - %s\n", status); + else if (result == STATE_UNKNOWN) + printf ("Unable to read output\n"); + else { + result = STATE_UNKNOWN; + printf ("UNKNOWN - %s\n", status); + } + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + + if (warn_percent > 100 && is_intnonneg (argv[c])) + warn_percent = atoi (argv[c]); + else if (crit_percent > 100 && is_intnonneg (argv[c])) + crit_percent = atoi (argv[c]); + else if (warn_size < 0 && is_intnonneg (argv[c])) + warn_size = atoi (argv[c]); + else if (crit_size < 0 && is_intnonneg (argv[c])) + crit_size = atoi (argv[c]); + } + + return validate_arguments (); +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"warning", required_argument, 0, 'w'}, + {"critical", required_argument, 0, 'c'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index); +#else + c = getopt (argc, argv, "+?Vhc:w:"); +#endif + + i++; + + if (c == -1 || c == EOF) + break; + + switch (c) { + case 'c': + case 'w': + i++; + } + + switch (c) { + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warn_size = atoi (optarg); + break; + } + else if (strstr (optarg, ",") && + strstr (optarg, "%") && + sscanf (optarg, "%d,%d%%", &warn_size, &warn_percent) == 2) { + break; + } + else if (strstr (optarg, "%") && + sscanf (optarg, "%d%%", &warn_percent) == 1) { + break; + } + else { + usage ("Warning threshold must be integer or percentage!\n"); + } + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + crit_size = atoi (optarg); + break; + } + else if (strstr (optarg, ",") && + strstr (optarg, "%") && + sscanf (optarg, "%d,%d%%", &crit_size, &crit_percent) == 2) { + break; + } + else if (strstr (optarg, "%") && + sscanf (optarg, "%d%%", &crit_percent) == 1) { + break; + } + else { + usage ("Critical threshold must be integer or percentage!\n"); + } + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case '?': /* help */ + usage ("Invalid argument\n"); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + if (warn_percent > 100 && crit_percent > 100 && warn_size < 0 + && crit_size < 0) { + return ERROR; + } + else if (warn_percent > crit_percent) { + usage + ("Warning percentage should not be less than critical percentage\n"); + } + else if (warn_size < crit_size) { + usage + ("Warning free space should not be more than critical free space\n"); + } + return OK; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: check_swap -w <used_percentage>%% -c <used_percentage>%%\n" + " check_swap -w <bytes_free> -c <bytes_free>\n" + " check_swap (-V|--version)\n" " check_swap (-h|--help)\n"); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Karl DeBisschop\n\n" + "This plugin will check all of the swap partitions and return an\n" + "error if the the avalable swap space is less than specified.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -w, --warning=INTEGER\n" + " Exit with WARNING status if less than INTEGER bytes of swap space are free\n" + " -w, --warning=PERCENT%%\n" + " Exit with WARNING status if more than PERCENT of swap space has been used\n" + " -c, --critical=INTEGER\n" + " Exit with CRITICAL status if less than INTEGER bytes of swap space are free\n" + " -c, --critical=PERCENT%%\n" + " Exit with CRITCAL status if more than PERCENT of swap space has been used\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n\n"); + support (); +} diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c new file mode 100644 index 00000000..bef0e752 --- /dev/null +++ b/plugins/check_tcp.c @@ -0,0 +1,563 @@ +/****************************************************************************** + * + * This file is part of the Nagios Plugins. + * + * Copyright (c) 1999 Ethan Galstad <nagios@nagios.org> + * + * The Nagios Plugins are free software; you can redistribute them + * and/or modify them 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + * + *****************************************************************************/ + +#define PROGRAM check_tcp +#define DESCRIPTION "Check a TCP port" +#define AUTHOR "Ethan Galstad" +#define EMAIL "nagios@nagios.org" +#define COPYRIGHTDATE "1999" + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#ifdef HAVE_SSL_H +#include <rsa.h> +#include <crypto.h> +#include <x509.h> +#include <pem.h> +#include <ssl.h> +#include <err.h> +#endif + +#ifdef HAVE_OPENSSL_SSL_H +#include <openssl/rsa.h> +#include <openssl/crypto.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#endif + +#ifdef HAVE_SSL +SSL_CTX *ctx; +SSL *ssl; +int connect_SSL (void); +#endif + +#define TCP_PROTOCOL 1 +#define UDP_PROTOCOL 2 + +int process_arguments (int, char **); +void print_usage (void); +void print_help (void); + +char *PROGNAME = NULL; +char *SERVICE = NULL; +char *SEND = NULL; +char *EXPECT = NULL; +char *QUIT = NULL; +int PROTOCOL = 0; +int PORT = 0; + +int server_port = 0; +char *server_address = NULL; +char *server_send = NULL; +char *server_quit = NULL; +char **server_expect = NULL; +int server_expect_count = 0; +char **warn_codes = NULL; +int warn_codes_count = 0; +char **crit_codes = NULL; +int crit_codes_count = 0; +int delay = 0; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +int verbose = FALSE; +int use_ssl = FALSE; +int sd; + +int +main (int argc, char **argv) +{ + int result; + int i; + char buffer[MAX_INPUT_BUFFER] = ""; + char *status = NULL; + char *output = NULL; + char *ptr = NULL; + + if (strstr (argv[0], "check_udp")) { + PROGNAME = strscpy (PROGNAME, "check_udp"); + SERVICE = strscpy (SERVICE, "UDP"); + SEND = NULL; + EXPECT = NULL; + QUIT = NULL; + PROTOCOL = UDP_PROTOCOL; + PORT = 0; + } + else if (strstr (argv[0], "check_tcp")) { + PROGNAME = strscpy (PROGNAME, "check_tcp"); + SERVICE = strscpy (SERVICE, "TCP"); + SEND = NULL; + EXPECT = NULL; + QUIT = NULL; + PROTOCOL = TCP_PROTOCOL; + PORT = 0; + } + else if (strstr (argv[0], "check_ftp")) { + PROGNAME = strscpy (PROGNAME, "check_ftp"); + SERVICE = strscpy (SERVICE, "FTP"); + SEND = NULL; + EXPECT = strscpy (EXPECT, "220"); + QUIT = strscpy (QUIT, "QUIT\r\n"); + PROTOCOL = TCP_PROTOCOL; + PORT = 21; + } + else if (strstr (argv[0], "check_smtp")) { + PROGNAME = strscpy (PROGNAME, "check_smtp"); + SERVICE = strscpy (SERVICE, "SMTP"); + SEND = NULL; + EXPECT = strscpy (EXPECT, "220"); + QUIT = strscpy (QUIT, "QUIT\r\n"); + PROTOCOL = TCP_PROTOCOL; + PORT = 25; + } + else if (strstr (argv[0], "check_pop")) { + PROGNAME = strscpy (PROGNAME, "check_pop"); + SERVICE = strscpy (SERVICE, "POP"); + SEND = NULL; + EXPECT = strscpy (EXPECT, "110"); + QUIT = strscpy (QUIT, "QUIT\r\n"); + PROTOCOL = TCP_PROTOCOL; + PORT = 110; + } + else if (strstr (argv[0], "check_imap")) { + PROGNAME = strscpy (PROGNAME, "check_imap"); + SERVICE = strscpy (SERVICE, "IMAP"); + SEND = NULL; + EXPECT = strscpy (EXPECT, "* OK"); + QUIT = strscpy (QUIT, "a1 LOGOUT\r\n"); + PROTOCOL = TCP_PROTOCOL; + PORT = 143; + } +#ifdef HAVE_SSL + else if (strstr(argv[0],"check_simap")) { + PROGNAME=strscpy(PROGNAME,"check_simap"); + SERVICE=strscpy(SERVICE,"SIMAP"); + SEND=NULL; + EXPECT=strscpy(EXPECT,"* OK"); + QUIT=strscpy(QUIT,"a1 LOGOUT\n"); + PROTOCOL=TCP_PROTOCOL; + use_ssl=TRUE; + PORT=993; + } +#endif + else if (strstr (argv[0], "check_nntp")) { + PROGNAME = strscpy (PROGNAME, "check_nntp"); + SERVICE = strscpy (SERVICE, "NNTP"); + SEND = NULL; + EXPECT = NULL; + server_expect = realloc (server_expect, ++server_expect_count); + server_expect[server_expect_count - 1] = strscpy (EXPECT, "200"); + server_expect = realloc (server_expect, ++server_expect_count); + server_expect[server_expect_count - 1] = strscpy (NULL, "201"); + QUIT = strscpy (QUIT, "QUIT\r\n"); + PROTOCOL = TCP_PROTOCOL; + PORT = 119; + } + else { + usage ("ERROR: Generic check_tcp called with unknown service\n"); + } + + server_address = strscpy (NULL, "127.0.0.1"); + server_port = PORT; + server_send = SEND; + server_quit = QUIT; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* use default expect if none listed in process_arguments() */ + if (EXPECT && server_expect_count == 0) { + server_expect = malloc (1); + server_expect[server_expect_count - 1] = EXPECT; + } + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* try to connect to the host at the given port number */ + time (&start_time); +#ifdef HAVE_SSL + if (use_ssl) + result = connect_SSL (); + else +#endif + { + if (PROTOCOL == UDP_PROTOCOL) + result = my_udp_connect (server_address, server_port, &sd); + else /* default is TCP */ + result = my_tcp_connect (server_address, server_port, &sd); + } + + if (result == STATE_CRITICAL) + return STATE_CRITICAL; + + if (server_send != NULL) { /* Something to send? */ + snprintf (buffer, MAX_INPUT_BUFFER - 1, "%s\r\n", server_send); + buffer[MAX_INPUT_BUFFER - 1] = 0; +#ifdef HAVE_SSL + if (use_ssl) + SSL_write(ssl,buffer,strlen(buffer)); + else +#endif + send (sd, buffer, strlen (buffer), 0); + } + + if (delay > 0) { + start_time = start_time + delay; + sleep (delay); + } + + if (server_send || server_expect_count > 0) { + + /* watch for the expect string */ +#ifdef HAVE_SSL + if (use_ssl && SSL_read (ssl, buffer, MAX_INPUT_BUFFER - 1)>=0) + status = strscat(status,buffer); + else +#endif + { + if (recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0) >= 0) + status = strscat (status, buffer); + } + strip (status); + + /* return a CRITICAL status if we couldn't read any data */ + if (status == NULL) + terminate (STATE_CRITICAL, "No data received from host\n"); + + if (status && verbose) + printf ("%s\n", status); + + if (server_expect_count > 0) { + for (i = 0;; i++) { + printf ("%d %d\n", i, server_expect_count); + if (i >= server_expect_count) + terminate (STATE_WARNING, "Invalid response from host\n"); + if (strstr (status, server_expect[i])) + break; + } + } + } + + if (server_quit) +#ifdef HAVE_SSL + if (use_ssl) { + SSL_write (ssl, QUIT, strlen (QUIT)); + SSL_shutdown (ssl); + SSL_free (ssl); + SSL_CTX_free (ctx); + } + else +#endif + send (sd, server_quit, strlen (server_quit), 0); + + /* close the connection */ + close (sd); + + time (&end_time); + + if (check_critical_time == TRUE && (end_time - start_time) > critical_time) + result = STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = STATE_WARNING; + + /* reset the alarm */ + alarm (0); + + printf + ("%s %s - %d second response time on port %d", + SERVICE, + state_text (result), (int) (end_time - start_time), server_port); + + if (status) + printf (" [%s]\n", status); + else + printf ("\n"); + + return result; +} + + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"critical-time", required_argument, 0, 'c'}, + {"warning-time", required_argument, 0, 'w'}, + {"critical-codes", required_argument, 0, 'C'}, + {"warning-codes", required_argument, 0, 'W'}, + {"timeout", required_argument, 0, 't'}, + {"protocol", required_argument, 0, 'P'}, + {"port", required_argument, 0, 'p'}, + {"send", required_argument, 0, 's'}, + {"expect", required_argument, 0, 'e'}, + {"quit", required_argument, 0, 'q'}, + {"delay", required_argument, 0, 'd'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + if (argc < 2) + usage ("No arguments found\n"); + + /* backwards compatibility */ + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + if (!is_option (argv[1])) { + server_address = argv[1]; + argv[1] = argv[0]; + argv = &argv[1]; + argc--; + } + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:s:e:q:c:w:t:p:C:W:d:S", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVvH:s:e:q:c:w:t:p:C:W:d:S"); +#endif + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) + usage ("Invalid host name/address\n"); + server_address = optarg; + break; + case 'c': /* critical */ + if (!is_intnonneg (optarg)) + usage ("Critical threshold must be a nonnegative integer\n"); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'w': /* warning */ + if (!is_intnonneg (optarg)) + usage ("Warning threshold must be a nonnegative integer\n"); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 'C': + crit_codes = realloc (crit_codes, ++crit_codes_count); + crit_codes[crit_codes_count - 1] = optarg; + break; + case 'W': + warn_codes = realloc (warn_codes, ++warn_codes_count); + warn_codes[warn_codes_count - 1] = optarg; + break; + case 't': /* timeout */ + if (!is_intpos (optarg)) + usage ("Timeout interval must be a positive integer\n"); + socket_timeout = atoi (optarg); + break; + case 'p': /* port */ + if (!is_intpos (optarg)) + usage ("Server port must be a positive integer\n"); + server_port = atoi (optarg); + break; + case 's': + server_send = optarg; + break; + case 'e': + EXPECT = NULL; + if (server_expect_count == 0) + server_expect = malloc (++server_expect_count); + else + server_expect = realloc (server_expect, ++server_expect_count); + server_expect[server_expect_count - 1] = optarg; + break; + case 'q': + server_quit = optarg; + break; + case 'd': + if (is_intpos (optarg)) + delay = atoi (optarg); + else + usage ("Delay must be a positive integer\n"); + break; + case 'S': +#ifndef HAVE_SSL + terminate (STATE_UNKNOWN, + "SSL support not available. Install OpenSSL and recompile."); +#endif + use_ssl = TRUE; + break; + } + } + + if (server_address == NULL) + usage ("You must provide a server address\n"); + + return OK; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host -p port [-w warn_time] [-c crit_time] [-s send]\n" + " [-e expect] [-W wait] [-t to_sec] [-v]\n", PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n" + "This plugin tests %s connections with the specified host.\n\n", + SERVICE); + print_usage (); + printf + ("Options:\n" + " -H, --hostname=ADDRESS\n" + " Host name argument for servers using host headers (use numeric\n" + " address if possible to bypass DNS lookup).\n" + " -p, --port=INTEGER\n" + " Port number\n" + " -s, --send=STRING\n" + " String to send to the server\n" + " -e, --expect=STRING\n" + " String to expect in server response" + " -W, --wait=INTEGER\n" + " Seconds to wait between sending string and polling for response\n" + " -w, --warning=INTEGER\n" + " Response time to result in warning status (seconds)\n" + " -c, --critical=INTEGER\n" + " Response time to result in critical status (seconds)\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection times out (default: %d)\n" + " -v" + " Show details for command-line debugging (do not use with nagios server)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n", DEFAULT_SOCKET_TIMEOUT); +} + + +#ifdef HAVE_SSL +int +connect_SSL (void) +{ + SSL_METHOD *meth; + + /* Initialize SSL context */ + SSLeay_add_ssl_algorithms (); + meth = SSLv2_client_method (); + SSL_load_error_strings (); + if ((ctx = SSL_CTX_new (meth)) == NULL) + { + printf ("ERROR: Cannot create SSL context.\n"); + return STATE_CRITICAL; + } + + /* Initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* Set socket timeout */ + alarm (socket_timeout); + + /* Save start time */ + time (&start_time); + + /* Make TCP connection */ + if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK) + { + /* Do the SSL handshake */ + if ((ssl = SSL_new (ctx)) != NULL) + { + SSL_set_fd (ssl, sd); + if (SSL_connect (ssl) != -1) + return OK; + ERR_print_errors_fp (stderr); + } + else + { + printf ("ERROR: Cannot initiate SSL handshake.\n"); + } + SSL_free (ssl); + } + + SSL_CTX_free (ctx); + close (sd); + + return STATE_CRITICAL; +} +#endif + diff --git a/plugins/check_time.c b/plugins/check_time.c new file mode 100644 index 00000000..86c414e2 --- /dev/null +++ b/plugins/check_time.c @@ -0,0 +1,370 @@ +/****************************************************************************** +* +* CHECK_TIME.C +* +* Program: Network time server plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) +* +* $Id$ +* +* Description: +* +* This plugin will attempt to connect to the specified port +* on the host. Successul connects return STATE_OK, refusals +* and timeouts return STATE_CRITICAL, other errors return +* STATE_UNKNOWN. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_time" + +#define TIME_PORT 37 +#define UNIX_EPOCH 2208988800UL + +unsigned long server_time, raw_server_time; +time_t diff_time; +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; +unsigned long warning_diff = 0; +int check_warning_diff = FALSE; +unsigned long critical_diff = 0; +int check_critical_diff = FALSE; +int server_port = TIME_PORT; +char *server_address = NULL; + + +int process_arguments (int, char **); +int call_getopt (int, char **); +void print_usage (void); +void print_help (void); + + +int +main (int argc, char **argv) +{ + int sd; + int result; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + time (&start_time); + + /* try to connect to the host at the given port number */ + if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) { + if (check_critical_time == TRUE) + result = STATE_CRITICAL; + else if (check_warning_time == TRUE) + result = STATE_WARNING; + else + result = STATE_UNKNOWN; + terminate (result, + "TIME UNKNOWN - could not connect to server %s, port %d\n", + server_address, server_port); + } + + /* watch for the FTP connection string */ + result = recv (sd, &raw_server_time, sizeof (raw_server_time), 0); + + /* close the connection */ + close (sd); + + /* reset the alarm */ + time (&end_time); + alarm (0); + + /* return a WARNING status if we couldn't read any data */ + if (result <= 0) { + if (check_critical_time == TRUE) + result = STATE_CRITICAL; + else if (check_warning_time == TRUE) + result = STATE_WARNING; + else + result = STATE_UNKNOWN; + terminate (result, + "TIME UNKNOWN - no data on recv() from server %s, port %d\n", + server_address, server_port); + } + + result = STATE_OK; + + if (check_critical_time == TRUE && (end_time - start_time) > critical_time) + result = STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = STATE_WARNING; + + if (result != STATE_OK) + terminate (result, "TIME %s - %d second response time\n", + state_text (result), (int) (end_time - start_time)); + + server_time = ntohl (raw_server_time) - UNIX_EPOCH; + if (server_time > end_time) + diff_time = server_time - end_time; + else + diff_time = end_time - server_time; + + if (check_critical_diff == TRUE && diff_time > critical_diff) + result = STATE_CRITICAL; + else if (check_warning_diff == TRUE && diff_time > warning_diff) + result = STATE_WARNING; + + printf ("TIME %s - %lu second time difference\n", state_text (result), + diff_time); + return result; +} + + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + usage ("\n"); + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wd", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-cd", argv[c]) == 0) + strcpy (argv[c], "-c"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-W"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-C"); + } + + c = 0; + while ((c += call_getopt (argc - c, &argv[c])) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (argc > c) { + if (is_host (argv[c]) == FALSE) + usage ("Invalid host name/address\n"); + server_address = argv[c]; + } + else { + usage ("Host name was not supplied\n"); + } + } + } + + return OK; +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"warning-variance", required_argument, 0, 'w'}, + {"critical-variance", required_argument, 0, 'c'}, + {"warning-connect", required_argument, 0, 'W'}, + {"critical-connect", required_argument, 0, 'C'}, + {"port", required_argument, 0, 'p'}, + {"timeout", required_argument, 0, 't'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVH:w:c:W:C:p:t:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVH:w:c:W:C:p:t:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'w': + case 'c': + case 'W': + case 'C': + case 'p': + case 't': + i++; + } + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) + usage ("Invalid host name/address\n"); + server_address = optarg; + break; + case 'w': /* warning-variance */ + if (is_intnonneg (optarg)) { + warning_diff = strtoul (optarg, NULL, 10); + check_warning_diff = TRUE; + } + else if (strspn (optarg, "0123456789:,") > 0) { + if (sscanf (optarg, "%lu%*[:,]%d", &warning_diff, &warning_time) == 2) { + check_warning_diff = TRUE; + check_warning_time = TRUE; + } + else { + usage ("Warning thresholds must be a nonnegative integer\n"); + } + } + else { + usage ("Warning threshold must be a nonnegative integer\n"); + } + break; + case 'c': /* critical-variance */ + if (is_intnonneg (optarg)) { + critical_diff = strtoul (optarg, NULL, 10); + check_critical_diff = TRUE; + } + else if (strspn (optarg, "0123456789:,") > 0) { + if (sscanf (optarg, "%lu%*[:,]%d", &critical_diff, &critical_time) == + 2) { + check_critical_diff = TRUE; + check_critical_time = TRUE; + } + else { + usage ("Critical thresholds must be a nonnegative integer\n"); + } + } + else { + usage ("Critical threshold must be a nonnegative integer\n"); + } + break; + case 'W': /* warning-connect */ + if (!is_intnonneg (optarg)) + usage ("Warning threshold must be a nonnegative integer\n"); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 'C': /* critical-connect */ + if (!is_intnonneg (optarg)) + usage ("Critical threshold must be a nonnegative integer\n"); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'p': /* port */ + if (!is_intnonneg (optarg)) + usage ("Serevr port must be a nonnegative integer\n"); + server_port = atoi (optarg); + break; + case 't': /* timeout */ + if (!is_intnonneg (optarg)) + usage ("Timeout interval must be a nonnegative integer\n"); + socket_timeout = atoi (optarg); + break; + } + } + return i; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: check_time -H <host_address> [-p port] [-w variance] [-c variance]\n" + " [-W connect_time] [-C connect_time] [-t timeout]\n"); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n" + "This plugin connects to a time port on the specified host.\n\n"); + print_usage (); + printf + ("Options:\n" + " -H, --hostname=ADDRESS\n" + " Host name argument for servers using host headers (use numeric\n" + " address if possible to bypass DNS lookup).\n" + " -w, --warning-variance=INTEGER\n" + " Time difference (sec.) necessary to result in a warning status\n" + " -c, --critical-variance=INTEGER\n" + " Time difference (sec.) necessary to result in a critical status\n" + " -W, --warning-connect=INTEGER\n" + " Response time (sec.) necessary to result in warning status\n" + " -C, --critical-connect=INTEGER\n" + " Response time (sec.) necessary to result in critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection times out (default: %d)\n" + " -p, --port=INTEGER\n" + " Port number (default: %d)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", DEFAULT_SOCKET_TIMEOUT, TIME_PORT); + support (); +} diff --git a/plugins/check_udp.c b/plugins/check_udp.c new file mode 100644 index 00000000..d00ce9c3 --- /dev/null +++ b/plugins/check_udp.c @@ -0,0 +1,315 @@ +/****************************************************************************** +* +* CHECK_UDP.C +* +* Program: UDP port plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Command line: CHECK_UDP <host_address> [-p port] [-s send] [-e expect] \ +* [-wt warn_time] [-ct crit_time] [-to to_sec] +* +* Description: +* +* This plugin will attempt to connect to the specified port +* on the host. Successul connects return STATE_OK, refusals +* and timeouts return STATE_CRITICAL, other errors return +* STATE_UNKNOWN. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_udp" + +int warning_time = 0; +int check_warning_time = FALSE; +int critical_time = 0; +int check_critical_time = FALSE; + +int process_arguments (int, char **); +int call_getopt (int, char **); +void print_usage (void); +void print_help (void); + +int verbose = FALSE; +int server_port = 0; +char *server_address = NULL; +char *server_expect = NULL; +char *server_send = NULL; + +int +main (int argc, char **argv) +{ + int result; + char recv_buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) == ERROR) + usage ("\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + time (&start_time); + result = + process_udp_request (server_address, server_port, server_send, + recv_buffer, MAX_INPUT_BUFFER - 1); + time (&end_time); + + if (result != STATE_OK) { + printf ("No response from host on port %d\n", server_port); + result = STATE_CRITICAL; + } + + else { + + /* check to see if we got the response we wanted */ + if (server_expect) { + if (!strstr (recv_buffer, server_expect)) { + printf ("Invalid response received from host on port %d\n", + server_port); + result = STATE_CRITICAL; + } + } + } + + /* we connected, so close connection before exiting */ + if (result == STATE_OK) { + + if (check_critical_time == TRUE + && (end_time - start_time) > critical_time) result = STATE_CRITICAL; + else if (check_warning_time == TRUE + && (end_time - start_time) > warning_time) result = + STATE_WARNING; + + printf ("Connection %s on port %d - %d second response time\n", + (result == STATE_OK) ? "accepted" : "problem", server_port, + (int) (end_time - start_time)); + } + + /* reset the alarm */ + alarm (0); + + return result; +} + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + usage ("\n"); + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + c = 0; + while ((c += call_getopt (argc - c, &argv[c])) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (argc > c) { + if (is_host (argv[c]) == FALSE) + usage ("Invalid host name/address\n"); + server_address = argv[c]; + } + else { + usage ("Host name was not supplied\n"); + } + } + } + + if (server_send == NULL) + server_send = strscpy (server_send, ""); + + return OK; +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"timeout", required_argument, 0, 't'}, + {"port", required_argument, 0, 'p'}, + {"expect", required_argument, 0, 'e'}, + {"send", required_argument, 0, 's'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVvH:e:s:c:w:t:p:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+hVvH:e:s:c:w:t:p:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'c': + case 'w': + case 't': + case 'p': + case 'e': + case 's': + i++; + } + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'v': /* verbose mode */ + verbose = TRUE; + break; + case 'H': /* hostname */ + if (is_host (optarg) == FALSE) + usage ("Invalid host name/address\n"); + server_address = optarg; + break; + case 'c': /* critical */ + if (!is_intnonneg (optarg)) + usage ("Critical threshold must be a nonnegative integer\n"); + critical_time = atoi (optarg); + check_critical_time = TRUE; + break; + case 'w': /* warning */ + if (!is_intnonneg (optarg)) + usage ("Warning threshold must be a nonnegative integer\n"); + warning_time = atoi (optarg); + check_warning_time = TRUE; + break; + case 't': /* timeout */ + if (!is_intnonneg (optarg)) + usage ("Timeout interval must be a nonnegative integer\n"); + socket_timeout = atoi (optarg); + break; + case 'p': /* port */ + if (!is_intnonneg (optarg)) + usage ("Serevr port must be a nonnegative integer\n"); + server_port = atoi (optarg); + break; + case 'e': /* expect */ + server_expect = optarg; + break; + case 's': /* send */ + server_send = optarg; + break; + } + } + return i; +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H <host_address> [-p port] [-w warn_time] [-c crit_time]\n" + " [-e expect] [-s send] [-t to_sec] [-v]\n", PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n" + "This plugin tests an UDP connection with the specified host.\n\n"); + print_usage (); + printf + ("Options:\n" + " -H, --hostname=ADDRESS\n" + " Host name argument for servers using host headers (use numeric\n" + " address if possible to bypass DNS lookup).\n" + " -p, --port=INTEGER\n" + " Port number\n" + " -e, --expect=STRING <optional>\n" + " String to expect in first line of server response\n" + " -s, --send=STRING <optional>\n" + " String to send to the server when initiating the connection\n" + " -w, --warning=INTEGER <optional>\n" + " Response time to result in warning status (seconds)\n" + " -c, --critical=INTEGER <optional>\n" + " Response time to result in critical status (seconds)\n" + " -t, --timeout=INTEGER <optional>\n" + " Seconds before connection times out (default: %d)\n" + " -v, --verbose <optional>\n" + " Show details for command-line debugging (do not use with nagios server)\n" + " -h, --help\n" + " Print detailed help screen and exit\n" + " -V, --version\n" + " Print version information and exit\n", DEFAULT_SOCKET_TIMEOUT); +} diff --git a/plugins/check_ups.c b/plugins/check_ups.c new file mode 100644 index 00000000..4632bdc0 --- /dev/null +++ b/plugins/check_ups.c @@ -0,0 +1,649 @@ +/****************************************************************************** +* +* CHECK_UPS.C +* +* Program: UPS monitor plugin for Nagios +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Command line: CHECK_UPS <host_address> [-u ups] [-p port] [-v variable] \ +* [-wv warn_value] [-cv crit_value] [-to to_sec] +* +* Description: +* + +* This plugin attempts to determine the status of an UPS +* (Uninterruptible Power Supply) on a remote host (or the local host) +* that is being monitored with Russel Kroll's "Smarty UPS Tools" +* package. If the UPS is online or calibrating, the plugin will +* return an OK state. If the battery is on it will return a WARNING +* state. If the UPS is off or has a low battery the plugin will +* return a CRITICAL state. You may also specify a variable to check +* (such as temperature, utility voltage, battery load, etc.) as well +* as warning and critical thresholds for the value of that variable. +* If the remote host has multiple UPS that are being monitored you +* will have to use the [ups] option to specify which UPS to check. +* +* Notes: +* +* This plugin requires that the UPSD daemon distributed with Russel +* Kroll's "Smart UPS Tools" be installed on the remote host. If you +* don't have the package installed on your system, you can download +* it from http://www.exploits.org/~rkroll/smartupstools +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +******************************************************************************/ + +#include "config.h" +#include "common.h" +#include "netutils.h" +#include "utils.h" + +#define PROGNAME "check_ups" + +#define CHECK_NONE 0 + +#define PORT 3305 + +#define UPS_NONE 0 /* no supported options */ +#define UPS_UTILITY 1 /* supports utility line voltage */ +#define UPS_BATTPCT 2 /* supports percent battery remaining */ +#define UPS_STATUS 4 /* supports UPS status */ +#define UPS_TEMP 8 /* supports UPS temperature */ +#define UPS_LOADPCT 16 /* supports load percent */ + +#define UPSSTATUS_NONE 0 +#define UPSSTATUS_OFF 1 +#define UPSSTATUS_OL 2 +#define UPSSTATUS_OB 4 +#define UPSSTATUS_LB 8 +#define UPSSTATUS_CAL 16 +#define UPSSTATUS_UNKOWN 32 + +int server_port = PORT; +char *server_address = NULL; +char *ups_name = NULL; +double warning_value = 0.0L; +double critical_value = 0.0L; +int check_warning_value = FALSE; +int check_critical_value = FALSE; +int check_variable = UPS_NONE; +int supported_options = UPS_NONE; +int status = UPSSTATUS_NONE; + +double ups_utility_voltage = 0.0L; +double ups_battery_percent = 0.0L; +double ups_load_percent = 0.0L; +double ups_temperature = 0.0L; +char ups_status[MAX_INPUT_BUFFER] = "N/A"; + +int determine_status (void); +int determine_supported_vars (void); +int get_ups_variable (const char *, char *, int); + +int process_arguments (int, char **); +int call_getopt (int, char **); +int validate_arguments (void); +void print_help (void); +void print_usage (void); + +int +main (int argc, char **argv) +{ + int result = STATE_OK; + char output_message[MAX_INPUT_BUFFER]; + char temp_buffer[MAX_INPUT_BUFFER]; + + double ups_utility_deviation = 0.0L; + + if (process_arguments (argc, argv) != OK) + usage ("Invalid command arguments supplied\n"); + + /* initialize alarm signal handling */ + signal (SIGALRM, socket_timeout_alarm_handler); + + /* set socket timeout */ + alarm (socket_timeout); + + /* determine what variables the UPS supports */ + if (determine_supported_vars () != OK) + return STATE_CRITICAL; + + /* get the ups status if possible */ + if (supported_options & UPS_STATUS) { + + if (determine_status () != OK) + return STATE_CRITICAL; + ups_status[0] = 0; + result = STATE_OK; + + if (status & UPSSTATUS_OFF) { + strcpy (ups_status, "Off"); + result = STATE_CRITICAL; + } + else if ((status & (UPSSTATUS_OB | UPSSTATUS_LB)) == + (UPSSTATUS_OB | UPSSTATUS_LB)) { + strcpy (ups_status, "On Battery, Low Battery"); + result = STATE_CRITICAL; + } + else { + if (status & UPSSTATUS_OL) { + strcat (ups_status, "Online"); + } + if (status & UPSSTATUS_OB) { + strcat (ups_status, "On Battery"); + result = STATE_WARNING; + } + if (status & UPSSTATUS_LB) { + strcat (ups_status, ", Low Battery"); + result = STATE_WARNING; + } + if (status & UPSSTATUS_CAL) { + strcat (ups_status, ", Calibrating"); + } + if (status & UPSSTATUS_UNKOWN) { + strcat (ups_status, ", Unknown"); + } + } + } + + /* get the ups utility voltage if possible */ + if (supported_options & UPS_UTILITY) { + + if (get_ups_variable ("UTILITY", temp_buffer, sizeof (temp_buffer)) != OK) + return STATE_CRITICAL; + + ups_utility_voltage = atof (temp_buffer); + + if (ups_utility_voltage > 120.0) + ups_utility_deviation = 120.0 - ups_utility_voltage; + else + ups_utility_deviation = ups_utility_voltage - 120.0; + + if (check_variable == UPS_UTILITY) { + if (check_critical_value == TRUE + && ups_utility_deviation >= critical_value) result = STATE_CRITICAL; + else if (check_warning_value == TRUE + && ups_utility_deviation >= warning_value + && result < STATE_WARNING) result = STATE_WARNING; + } + } + + /* get the ups battery percent if possible */ + if (supported_options & UPS_BATTPCT) { + + if (get_ups_variable ("BATTPCT", temp_buffer, sizeof (temp_buffer)) != OK) + return STATE_CRITICAL; + + ups_battery_percent = atof (temp_buffer); + + if (check_variable == UPS_BATTPCT) { + if (check_critical_value == TRUE + && ups_battery_percent <= critical_value) result = STATE_CRITICAL; + else if (check_warning_value == TRUE + && ups_battery_percent <= warning_value + && result < STATE_WARNING) result = STATE_WARNING; + } + } + + /* get the ups load percent if possible */ + if (supported_options & UPS_LOADPCT) { + + if (get_ups_variable ("LOADPCT", temp_buffer, sizeof (temp_buffer)) != OK) + return STATE_CRITICAL; + + ups_load_percent = atof (temp_buffer); + + if (check_variable == UPS_LOADPCT) { + if (check_critical_value == TRUE && ups_load_percent >= critical_value) + result = STATE_CRITICAL; + else if (check_warning_value == TRUE + && ups_load_percent >= warning_value && result < STATE_WARNING) + result = STATE_WARNING; + } + } + + /* get the ups temperature if possible */ + if (supported_options & UPS_TEMP) { + + if (get_ups_variable ("UPSTEMP", temp_buffer, sizeof (temp_buffer)) != OK) + return STATE_CRITICAL; + + ups_temperature = (atof (temp_buffer) * 1.8) + 32; + + if (check_variable == UPS_TEMP) { + if (check_critical_value == TRUE && ups_temperature >= critical_value) + result = STATE_CRITICAL; + else if (check_warning_value == TRUE && ups_temperature >= warning_value + && result < STATE_WARNING) + result = STATE_WARNING; + } + } + + /* if the UPS does not support any options we are looking for, report an error */ + if (supported_options == UPS_NONE) + result = STATE_CRITICAL; + + /* reset timeout */ + alarm (0); + + + sprintf (output_message, "UPS %s - ", + (result == STATE_OK) ? "ok" : "problem"); + + if (supported_options & UPS_STATUS) { + sprintf (temp_buffer, "Status=%s ", ups_status); + strcat (output_message, temp_buffer); + } + if (supported_options & UPS_UTILITY) { + sprintf (temp_buffer, "Utility=%3.1fV ", ups_utility_voltage); + strcat (output_message, temp_buffer); + } + if (supported_options & UPS_BATTPCT) { + sprintf (temp_buffer, "Batt=%3.1f%% ", ups_battery_percent); + strcat (output_message, temp_buffer); + } + if (supported_options & UPS_LOADPCT) { + sprintf (temp_buffer, "Load=%3.1f%% ", ups_load_percent); + strcat (output_message, temp_buffer); + } + if (supported_options & UPS_TEMP) { + sprintf (temp_buffer, "Temp=%3.1fF", ups_temperature); + strcat (output_message, temp_buffer); + } + if (supported_options == UPS_NONE) { + sprintf (temp_buffer, + "UPS does not appear to support any available options\n"); + strcat (output_message, temp_buffer); + } + + printf ("%s\n", output_message); + + return result; +} + + + +/* determines what options are supported by the UPS */ +int +determine_status (void) +{ + char recv_buffer[MAX_INPUT_BUFFER]; + char temp_buffer[MAX_INPUT_BUFFER]; + char *ptr; + + if (get_ups_variable ("STATUS", recv_buffer, sizeof (recv_buffer)) != + STATE_OK) { + printf ("Invalid response received from hostn"); + return ERROR; + } + + recv_buffer[strlen (recv_buffer) - 1] = 0; + + strcpy (temp_buffer, recv_buffer); + for (ptr = (char *) strtok (temp_buffer, " "); ptr != NULL; + ptr = (char *) strtok (NULL, " ")) { + if (!strcmp (ptr, "OFF")) + status |= UPSSTATUS_OFF; + else if (!strcmp (ptr, "OL")) + status |= UPSSTATUS_OL; + else if (!strcmp (ptr, "OB")) + status |= UPSSTATUS_OB; + else if (!strcmp (ptr, "LB")) + status |= UPSSTATUS_LB; + else if (!strcmp (ptr, "CAL")) + status |= UPSSTATUS_CAL; + else + status |= UPSSTATUS_UNKOWN; + } + + return OK; +} + + +/* determines what options are supported by the UPS */ +int +determine_supported_vars (void) +{ + char send_buffer[MAX_INPUT_BUFFER]; + char recv_buffer[MAX_INPUT_BUFFER]; + char temp_buffer[MAX_INPUT_BUFFER]; + char *ptr; + + + /* get the list of variables that this UPS supports */ + if (ups_name) + sprintf (send_buffer, "LISTVARS %s\r\n", ups_name); + else + sprintf (send_buffer, "LISTVARS\r\n"); + if (process_tcp_request + (server_address, server_port, send_buffer, recv_buffer, + sizeof (recv_buffer)) != STATE_OK) { + printf ("Invalid response received from host\n"); + return ERROR; + } + + recv_buffer[strlen (recv_buffer) - 1] = 0; + + if (ups_name) + ptr = recv_buffer + 5 + strlen (ups_name) + 2; + else + ptr = recv_buffer + 5; + + strcpy (temp_buffer, recv_buffer); + + for (ptr = (char *) strtok (temp_buffer, " "); ptr != NULL; + ptr = (char *) strtok (NULL, " ")) { + if (!strcmp (ptr, "UTILITY")) + supported_options |= UPS_UTILITY; + else if (!strcmp (ptr, "BATTPCT")) + supported_options |= UPS_BATTPCT; + else if (!strcmp (ptr, "LOADPCT")) + supported_options |= UPS_LOADPCT; + else if (!strcmp (ptr, "STATUS")) + supported_options |= UPS_STATUS; + else if (!strcmp (ptr, "UPSTEMP")) + supported_options |= UPS_TEMP; + } + + return OK; +} + + +/* gets a variable value for a specific UPS */ +int +get_ups_variable (const char *varname, char *buf, int buflen) +{ + /* char command[MAX_INPUT_BUFFER]; */ + char temp_buffer[MAX_INPUT_BUFFER]; + char send_buffer[MAX_INPUT_BUFFER]; + char *ptr; + + /* create the command string to send to the UPS daemon */ + if (ups_name) + sprintf (send_buffer, "REQ %s@%s\n", varname, ups_name); + else + sprintf (send_buffer, "REQ %s\n", varname); + + /* send the command to the daemon and get a response back */ + if (process_tcp_request + (server_address, server_port, send_buffer, temp_buffer, + sizeof (temp_buffer)) != STATE_OK) { + printf ("Invalid response received from host\n"); + return ERROR; + } + + if (ups_name) + ptr = temp_buffer + strlen (varname) + 5 + strlen (ups_name) + 1; + else + ptr = temp_buffer + strlen (varname) + 5; + + if (!strcmp (ptr, "NOT-SUPPORTED")) { + printf ("Error: Variable '%s' is not supported\n", varname); + return ERROR; + } + + if (!strcmp (ptr, "DATA-STALE")) { + printf ("Error: UPS data is stale\n"); + return ERROR; + } + + if (!strcmp (ptr, "UNKNOWN-UPS")) { + if (ups_name) + printf ("Error: UPS '%s' is unknown\n", ups_name); + else + printf ("Error: UPS is unknown\n"); + return ERROR; + } + + strncpy (buf, ptr, buflen - 1); + buf[buflen - 1] = 0; + + return OK; +} + + + + + +/* Command line: CHECK_UPS <host_address> [-u ups] [-p port] [-v variable] + [-wv warn_value] [-cv crit_value] [-to to_sec] */ + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + for (c = 1; c < argc; c++) { + if (strcmp ("-to", argv[c]) == 0) + strcpy (argv[c], "-t"); + else if (strcmp ("-wt", argv[c]) == 0) + strcpy (argv[c], "-w"); + else if (strcmp ("-ct", argv[c]) == 0) + strcpy (argv[c], "-c"); + } + + c = 0; + while ((c += (call_getopt (argc - c, &argv[c]))) < argc) { + + if (is_option (argv[c])) + continue; + + if (server_address == NULL) { + if (is_host (argv[c])) { + server_address = argv[c]; + } + else { + usage ("Invalid host name"); + } + } + } + + if (server_address == NULL) + server_address = strscpy (NULL, "127.0.0.1"); + + return validate_arguments (); +} + + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"hostname", required_argument, 0, 'H'}, + {"ups", required_argument, 0, 'u'}, + {"port", required_argument, 0, 'p'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"timeout", required_argument, 0, 't'}, + {"variable", required_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = + getopt_long (argc, argv, "+hVH:u:p:v:c:w:t:", long_options, + &option_index); +#else + c = getopt (argc, argv, "+?hVH:u:p:v:c:w:t:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'H': + case 'u': + case 'p': + case 'v': + case 'c': + case 'w': + case 't': + i++; + } + + switch (c) { + case '?': /* help */ + usage ("Invalid argument\n"); + case 'H': /* hostname */ + if (is_host (optarg)) { + server_address = optarg; + } + else { + usage ("Invalid host name\n"); + } + break; + case 'u': /* ups name */ + ups_name = optarg; + break; + case 'p': /* port */ + if (is_intpos (optarg)) { + server_port = atoi (optarg); + } + else { + usage ("Server port must be a positive integer\n"); + } + break; + case 'c': /* critical time threshold */ + if (is_intnonneg (optarg)) { + critical_value = atoi (optarg); + check_critical_value = TRUE; + } + else { + usage ("Critical time must be a nonnegative integer\n"); + } + break; + case 'w': /* warning time threshold */ + if (is_intnonneg (optarg)) { + warning_value = atoi (optarg); + check_warning_value = TRUE; + } + else { + usage ("Warning time must be a nonnegative integer\n"); + } + break; + case 'v': /* variable */ + if (!strcmp (optarg, "LINE")) + check_variable = UPS_UTILITY; + else if (!strcmp (optarg, "TEMP")) + check_variable = UPS_TEMP; + else if (!strcmp (optarg, "BATTPCT")) + check_variable = UPS_BATTPCT; + else if (!strcmp (optarg, "LOADPCT")) + check_variable = UPS_LOADPCT; + else + usage ("Unrecognized UPS variable\n"); + break; + case 't': /* timeout */ + if (is_intnonneg (optarg)) { + socket_timeout = atoi (optarg); + } + else { + usage ("Time interval must be a nonnegative integer\n"); + } + break; + case 'V': /* version */ + print_revision (PROGNAME, "$Revision$"); + exit (STATE_OK); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + } + } + return i; +} + + + + + +int +validate_arguments (void) +{ + return OK; +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 2000 Tom Shields/Karl DeBisschop\n\n" + "This plugin tests the UPS service on the specified host.\n\n"); + print_usage (); + printf + ("\nOptions:\n" + " -H, --hostname=STRING or IPADDRESS\n" + " Check server on the indicated host\n" + " -p, --port=INTEGER\n" + " Make connection on the indicated port (default: %d)\n" + " -u, --ups=STRING\n" + " Name of UPS\n" + " -w, --warning=INTEGER\n" + " Seconds necessary to result in a warning status\n" + " -c, --critical=INTEGER\n" + " Seconds necessary to result in a critical status\n" + " -t, --timeout=INTEGER\n" + " Seconds before connection attempt times out (default: %d)\n" + " -v, --verbose\n" + " Print extra information (command-line use only)\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" + " Print version information\n\n", PORT, DEFAULT_SOCKET_TIMEOUT); + support (); +} + + + + + +void +print_usage (void) +{ + printf + ("Usage: %s -H host [-e expect] [-p port] [-w warn] [-c crit]\n" + " [-t timeout] [-v]\n" + " %s --help\n" + " %s --version\n", PROGNAME, PROGNAME, PROGNAME); +} diff --git a/plugins/check_users.c b/plugins/check_users.c new file mode 100644 index 00000000..2b8fa15b --- /dev/null +++ b/plugins/check_users.c @@ -0,0 +1,257 @@ +/****************************************************************************** + * + * CHECK_USERS.C + * + * Program: Current users plugin for Nagios + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: $Date$ + * Modifications: + * + * 1999-11-17 Karl DeBisschop + * - check stderr and status from spoen/spclose + * - reformat commenst to fit 80-cahr screen + * - set default result to STATE_UNKNOWN + * - initialize users at -1, eliminate 'found' variable + * + * Command line: CHECK_USERS <wusers> <cusers> + * + * Description: + * + * This plugin will use the /usr/bin/who command to check the number + * of users currently logged into the system. If number of logged in + * user exceeds the number specified by the <cusers> option, a + * STATE_CRITICAL is return. It it exceeds <wusers>, a STATE_WARNING + * is returned. Errors reading the output from the who command result + * in a STATE_UNKNOWN error. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +#define PROGNAME "check_users" + +#define possibly_set(a,b) ((a) == 0 ? (b) : 0) + +int process_arguments (int, char **); +int call_getopt (int, char **); +void print_usage (void); +void print_help (void); + +int wusers = -1; +int cusers = -1; + +int +main (int argc, char **argv) +{ + int users = -1; + int result = STATE_OK; + char input_buffer[MAX_INPUT_BUFFER]; + + if (process_arguments (argc, argv) == ERROR) + usage ("Could not parse arguments\n"); + + /* run the command */ + child_process = spopen (WHO_COMMAND); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", WHO_COMMAND); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", WHO_COMMAND); + + users = 0; + + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + /* increment 'users' on all lines except total user count */ + if (input_buffer[0] != '#') { + users++; + continue; + } + + /* get total logged in users */ + if (sscanf (input_buffer, "# users=%d", &users) == 1) + break; + + } + + /* check STDERR */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = possibly_set (result, STATE_UNKNOWN); + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = possibly_set (result, STATE_UNKNOWN); + + /* else check the user count against warning and critical thresholds */ + if (users >= cusers) + result = STATE_CRITICAL; + else if (users >= wusers) + result = STATE_WARNING; + else if (users >= 0) + result = STATE_OK; + + if (result == STATE_UNKNOWN) + printf ("Unable to read output\n"); + else + printf ("USERS %s - %d users currently logged in\n", state_text (result), + users); + + return result; +} + + + + + +/* process command-line arguments */ +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + usage ("\n"); + + c = 0; + while ((c += call_getopt (argc - c, &argv[c])) < argc) { + + if (is_option (argv[c])) + continue; + + if (wusers == -1 && argc > c) { + if (is_intnonneg (argv[c]) == FALSE) + usage ("Warning threshold must be a nonnegative integer\n"); + wusers = atoi (argv[c]); + + } + else if (cusers == -1 && argc > c) { + if (is_intnonneg (argv[c]) == FALSE) + usage ("Warning threshold must be a nonnegative integer\n"); + cusers = atoi (argv[c]); + } + } + + return OK; +} + + + + + +int +call_getopt (int argc, char **argv) +{ + int c, i = 0; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"version", no_argument, 0, 'V'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVvc:w:", long_options, &option_index); +#else + c = getopt (argc, argv, "+hVvc:w:"); +#endif + + i++; + + if (c == -1 || c == EOF || c == 1) + break; + + switch (c) { + case 'c': + case 'w': + i++; + } + + switch (c) { + case '?': /* print short usage statement if args not parsable */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'c': /* critical */ + if (!is_intnonneg (optarg)) + usage ("Critical threshold must be a nonnegative integer\n"); + cusers = atoi (optarg); + break; + case 'w': /* warning */ + if (!is_intnonneg (optarg)) + usage ("Warning threshold must be a nonnegative integer\n"); + wusers = atoi (optarg); + break; + } + } + return i; +} + + + + + +void +print_usage (void) +{ + printf ("Usage: %s -w <users> -c <users>\n", PROGNAME); +} + + + + + +void +print_help (void) +{ + print_revision (PROGNAME, "$Revision$"); + printf + ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n" + "This plugin checks the number of users currently logged in on the local\n" + "system and generates an error if the number exceeds the thresholds specified.\n"); + print_usage (); + printf + ("Options:\n" + " -w, --warning=INTEGER\n" + " Set WARNING status if more than INTEGER users are logged in\n" + " -c, --critical=INTEGER\n" + " Set CRITICAL status if more than INTEGER users are logged in\n" + " -h, --help\n" + " Print detailed help screen\n" + " -V, --version\n" " Print version information\n"); +} diff --git a/plugins/check_vsz.c b/plugins/check_vsz.c new file mode 100644 index 00000000..c8ca82bd --- /dev/null +++ b/plugins/check_vsz.c @@ -0,0 +1,287 @@ +/****************************************************************************** + * + * CHECK_VSZ.C + * + * Program: Process plugin for Nagios + * License: GPL + * Copyright (c) 1999,2000 Karl DeBisschop <kdebiss@alum.mit.edu> + * + * Last Modified: $Date$ + * + * Description: + * + * This plugin will check for processes whose total image size exceeds + * the warning or critical thresholds given on the command line. With + * no command_name, everything that shows up on ps is evaluated. + * Otherwise, only jobs with the command_name given are examined. + * This program is particularly useful if you have to run a piece of + * commercial software that has a memory leak. With it you can shut + * down and restart the processes whenever the program threatens to + * take over your system. + * + * Modifications: + * + * 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) + * change to getopt, use print_help + * 08-18-1999 Ethan Galstad (nagios@nagios.org) + * Changed code to use common include file + * Changed fclose() to pclose() + * 09-09-1999 Ethan Galstad (nagios@nagios.org) + * Changed popen()/pclose() to spopen()/spclose() + * 11-18-1999 Karl DeBisschop (kdebiss@alum.mit.edu) + * set STATE_WARNING of stderr written or nonzero status returned + * + *****************************************************************************/ + +#include "common.h" +#include "popen.h" +#include "utils.h" + +int process_arguments (int argc, char **argv); +int call_getopt (int argc, char **argv); +void print_help (char *cmd); +void print_usage (char *cmd); + +int warn = -1; +int crit = -1; +char *proc = NULL; + +int +main (int argc, char **argv) +{ + int len; + int result = STATE_OK; + int line = 0; + int proc_size = -1; + char input_buffer[MAX_INPUT_BUFFER]; + char proc_name[MAX_INPUT_BUFFER]; + char *message = NULL; + + if (!process_arguments (argc, argv)) { + printf ("%s: failure parsing arguments\n", my_basename (argv[0])); + print_help (my_basename (argv[0])); + return STATE_UNKNOWN; + } + + /* run the command */ + child_process = spopen (VSZ_COMMAND); + if (child_process == NULL) { + printf ("Unable to open pipe: %s\n", VSZ_COMMAND); + return STATE_UNKNOWN; + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) + printf ("Could not open stderr for %s\n", VSZ_COMMAND); + + message = malloc ((size_t) 1); + message[0] = 0; + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + + line++; + + /* skip the first line */ + if (line == 1) + continue; + + if (sscanf (input_buffer, VSZ_FORMAT, &proc_size, proc_name) == 2) { + if (proc == NULL) { + if (proc_size > warn) { + len = strlen (message) + strlen (proc_name) + 23; + message = realloc (message, len); + if (message == NULL) + terminate (STATE_UNKNOWN, + "check_vsz: could not malloc message (1)"); + sprintf (message, "%s %s(%d)", message, proc_name, proc_size); + result = max (result, STATE_WARNING); + } + if (proc_size > crit) { + result = STATE_CRITICAL; + } + } + else if (strstr (proc_name, proc)) { + len = strlen (message) + 21; + message = realloc (message, len); + if (message == NULL) + terminate (STATE_UNKNOWN, + "check_vsz: could not malloc message (2)"); + sprintf (message, "%s %d", message, proc_size); + if (proc_size > warn) { + result = max (result, STATE_WARNING); + } + if (proc_size > crit) { + result = STATE_CRITICAL; + } + } + } + } + + /* If we get anything on STDERR, at least set warning */ + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + (void) fclose (child_stderr); + + /* close the pipe */ + if (spclose (child_process)) + result = max (result, STATE_WARNING); + + if (result == STATE_OK) + printf ("ok (all VSZ<%d): %s\n", warn, message); + else if (result == STATE_UNKNOWN) + printf ("Unable to read output\n"); + else if (result == STATE_WARNING) + printf ("WARNING (VSZ>%d):%s\n", warn, message); + else + printf ("CRITICAL (VSZ>%d):%s\n", crit, message); + + return result; +} + + + + +int +process_arguments (int argc, char **argv) +{ + int c; + + if (argc < 2) + return ERROR; + + c = 0; + while (c += (call_getopt (argc - c, &argv[c]))) { + if (argc <= c) + break; + if (warn == -1) { + if (!is_intnonneg (argv[c])) { + printf ("%s: critical threshold must be an integer: %s\n", + my_basename (argv[0]), argv[c]); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + warn = atoi (argv[c]); + } + else if (crit == -1) { + if (!is_intnonneg (argv[c])) { + printf ("%s: critical threshold must be an integer: %s\n", + my_basename (argv[0]), argv[c]); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + crit = atoi (argv[c]); + } + else if (proc == NULL) { + proc = malloc (strlen (argv[c]) + 1); + if (proc == NULL) + terminate (STATE_UNKNOWN, + "check_vsz: failed malloc of proc in process_arguments"); + strcpy (proc, argv[c]); + } + } + return c; +} + +int +call_getopt (int argc, char **argv) +{ + int c, i = 1; + +#ifdef HAVE_GETOPT_H + int option_index = 0; + static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"critical", required_argument, 0, 'c'}, + {"warning", required_argument, 0, 'w'}, + {"command", required_argument, 0, 'C'}, + {0, 0, 0, 0} + }; +#endif + + while (1) { +#ifdef HAVE_GETOPT_H + c = getopt_long (argc, argv, "+hVc:w:C:", long_options, &option_index); +#else + c = getopt (argc, argv, "+hVc:w:C:"); +#endif + if (c == EOF) + break; + + i++; + switch (c) { + case 'c': + case 'w': + case 'C': + i++; + } + + switch (c) { + case '?': /* help */ + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + case 'h': /* help */ + print_help (my_basename (argv[0])); + exit (STATE_OK); + case 'V': /* version */ + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + case 'c': /* critical threshold */ + if (!is_intnonneg (optarg)) { + printf ("%s: critical threshold must be an integer: %s\n", + my_basename (argv[0]), optarg); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + crit = atoi (optarg); + break; + case 'w': /* warning threshold */ + if (!is_intnonneg (optarg)) { + printf ("%s: warning threshold must be an integer: %s\n", + my_basename (argv[0]), optarg); + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + warn = atoi (optarg); + break; + case 'C': /* command name */ + proc = malloc (strlen (optarg) + 1); + if (proc == NULL) + terminate (STATE_UNKNOWN, + "check_vsz: failed malloc of proc in process_arguments"); + strcpy (proc, optarg); + break; + } + } + return i; +} + +void +print_usage (char *cmd) +{ + printf ("Usage: %s -w <wsize> -c <csize> [-C command]\n" + " %s --help\n" " %s --version\n", cmd, cmd, cmd); +} + +void +print_help (char *cmd) +{ + print_revision ("check_vsz", "$Revision$"); + printf + ("Copyright (c) 2000 Karl DeBisschop <kdebiss@alum.mit.edu>\n\n" + "This plugin checks the image size of a running program and returns an\n" + "error if the number is above either of the thresholds given.\n\n"); + print_usage (cmd); + printf + ("\nOptions:\n" + " -h, --help\n" + " Print detailed help\n" + " -V, --version\n" + " Print version numbers and license information\n" + " -w, --warning=INTEGER\n" + " Program image size necessary to cause a WARNING state\n" + " -c, --critical=INTEGER\n" + " Program image size necessary to cause a CRITICAL state\n" + " -C, --command=STRING\n" " Program to search for [optional]\n"); +} diff --git a/plugins/common.h.in b/plugins/common.h.in new file mode 100644 index 00000000..9cb4bcbb --- /dev/null +++ b/plugins/common.h.in @@ -0,0 +1,159 @@ +/****************************************************************************** + * + * Nagios plugins common include file + * + * License: GPL + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) + * + * Last Modified: 11-05-1999 + * + * Description: + * + * This file contains common include files and defines used in many of + * the plugins. + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include <stdio.h> /* obligatory includes */ +#include <stdlib.h> +#include <errno.h> + +#include "config.h" + +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif + +/* #ifdef HAVE_GETOPT_H */ +#include <getopt.h> +/* #endif */ + +#include <ctype.h> + + +/* + * + * Missing Functions + * + */ + +#ifndef HAVE_STRTOL +# define strtol(a,b,c) atol((a)) +#endif + +#ifndef HAVE_STRTOUL +# define strtoul(a,b,c) (unsigned long)atol((a)) +#endif + +/* + * + * Standard Values + * + */ + +#define OK 0 +#define ERROR -1 + +#define TRUE 1 +#define FALSE 0 + +#define STATE_CRITICAL 2 /* service state return codes */ +#define STATE_WARNING 1 +#define STATE_OK 0 +#define STATE_UNKNOWN -1 +#define STATE_DEPENDENT -2 + +#define DEFAULT_SOCKET_TIMEOUT 10 /* timeout after 10 seconds */ + +#define MAX_INPUT_BUFFER 1024 /* max size of most buffers we use */ + +#define MAX_HOST_ADDRESS_LENGTH 256 /* max size of a host address */ + + +#ifndef HAVE_SNPRINTF +/* +int snprintf (char *str, size_t n, const char *fmt, ...); +int snprintf (char *str, size_t n, const char *fmt, ...) +{ + char *buf; + int i; + int j=0; + va_list ap; + int d; + char c, *p, *s; + + if((buf=malloc(n))==NULL){ + puts("could not malloc snprintf buffer\n"); + exit(-1); + } + va_start(ap,fmt); + i=strlen(fmt); + while((jj=index(&fmt[j],'%'))){ + j+=jj+1; + switch fmt[j] + { + case 's': + s = va_arg(ap, char *); + i+=strlen(s); + break; + case 'd': + d = va_arg(ap, int); + i++; + if (d<0) i++; + while((d=d/10)>0) i++; + break; + case 'c': + c = va_arg(ap, char); + i++; + break; + } + } + va_end(ap); + vsprintf(buf,fmt,ap); + strcpy(str,buf[1:n-1]); + exit(result); +} +*/ +#endif diff --git a/plugins/getopt.c b/plugins/getopt.c new file mode 100644 index 00000000..364a1459 --- /dev/null +++ b/plugins/getopt.c @@ -0,0 +1,724 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#if !defined (__STDC__) || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include <stdlib.h> +#endif /* GNU C library. */ + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +#ifdef HAVE_LIBINTL_H +# include <libintl.h> +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} +ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include <string.h> +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#if !defined (__STDC__) || !__STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (optstring) + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0) { + optstring = _getopt_initialize (optstring); + optind = 1; /* Don't scan ARGV[0], the program name. */ + } + + if (nextchar == NULL || *nextchar == '\0') { + /* Advance to the next ARGV-element. */ + + if (ordering == PERMUTE) { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only + && (argv[optind][2] + || !my_index (optstring, argv[optind][1]))))) { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) { + if (nameend - nextchar == strlen (p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) { + option_index = indfound; + optind++; + if (*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else { + if (opterr) + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) { + if (optind < argc) + optarg = argv[optind++]; + else { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) { + if (opterr) { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') { + if (opterr) { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); + } + optopt = c; + return '?'; + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) { + if (opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, (int *) 0, 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/plugins/getopt1.c b/plugins/getopt1.c new file mode 100644 index 00000000..bbac373b --- /dev/null +++ b/plugins/getopt1.c @@ -0,0 +1,176 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "getopt.h" + +#if !defined (__STDC__) || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#else +char *getenv (); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +#include <stdio.h> + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/plugins/netutils.c b/plugins/netutils.c new file mode 100644 index 00000000..e5d35281 --- /dev/null +++ b/plugins/netutils.c @@ -0,0 +1,431 @@ +/**************************************************************************** +* +* Nagios plugins network utilities +* +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Description: +* +* This file contains commons functions used in many of the plugins. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +****************************************************************************/ + +#include "config.h" +#include "common.h" +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +extern int socket_timeout; +RETSIGTYPE socket_timeout_alarm_handler (int); + +int process_tcp_request2 (char *, int, char *, char *, int); +int process_tcp_request (char *, int, char *, char *, int); +int process_udp_request (char *, int, char *, char *, int); +int process_request (char *, int, char *, char *, char *, int); + +int my_tcp_connect (char *, int, int *); +int my_udp_connect (char *, int, int *); +int my_connect (char *, int, int *, char *); + +int my_inet_aton (register const char *, struct in_addr *); + +/* handles socket timeouts */ +void +socket_timeout_alarm_handler (int sig) +{ + + printf ("Socket timeout after %d seconds\n", socket_timeout); + + exit (STATE_CRITICAL); +} + + +/* connects to a host on a specified TCP port, sends a string, + and gets a response */ +int +process_tcp_request (char *server_address, + int server_port, + char *send_buffer, char *recv_buffer, int recv_size) +{ + int result; + char proto[4] = "tcp"; + + result = process_request (server_address, + server_port, + proto, send_buffer, recv_buffer, recv_size); + + return result; +} + + +/* connects to a host on a specified UDP port, sends a string, and gets a + response */ +int +process_udp_request (char *server_address, + int server_port, + char *send_buffer, char *recv_buffer, int recv_size) +{ + int result; + char proto[4] = "udp"; + + result = process_request (server_address, + server_port, + proto, send_buffer, recv_buffer, recv_size); + + return result; +} + + + +/* connects to a host on a specified tcp port, sends a string, and gets a + response. loops on select-recv until timeout or eof to get all of a + multi-packet answer */ +int +process_tcp_request2 (char *server_address, + int server_port, + char *send_buffer, char *recv_buffer, int recv_size) +{ + + int result; + int send_result; + int recv_result; + int sd; + struct timeval tv; + fd_set readfds; + int recv_length = 0; + + result = my_connect (server_address, server_port, &sd, "tcp"); + if (result != STATE_OK) + return STATE_CRITICAL; + + send_result = send (sd, send_buffer, strlen (send_buffer), 0); + if (send_result != strlen (send_buffer)) { + printf ("send() failed\n"); + result = STATE_WARNING; + } + + while (1) { + /* wait up to the number of seconds for socket timeout + minus one for data from the host */ + tv.tv_sec = socket_timeout - 1; + tv.tv_usec = 0; + FD_ZERO (&readfds); + FD_SET (sd, &readfds); + select (sd + 1, &readfds, NULL, NULL, &tv); + + /* make sure some data has arrived */ + if (!FD_ISSET (sd, &readfds)) { /* it hasn't */ + if (!recv_length) { + strcpy (recv_buffer, ""); + printf ("No data was recieved from host!\n"); + result = STATE_WARNING; + } + else { /* this one failed, but previous ones worked */ + recv_buffer[recv_length] = 0; + } + break; + } + else { /* it has */ + recv_result = + recv (sd, recv_buffer + recv_length, recv_size - recv_length - 1, 0); + if (recv_result == -1) { /* recv failed, bail out */ + strcpy (recv_buffer + recv_length, ""); + result = STATE_WARNING; + break; + } + else if (recv_result == 0) { /* end of file ? */ + recv_buffer[recv_length] = 0; + break; + } + else { /* we got data! */ + recv_length += recv_result; + if (recv_length >= recv_size - 1) { /* buffer full, we're done */ + recv_buffer[recv_size - 1] = 0; + break; + } + } + } /* end if(!FD_ISSET(sd,&readfds)) */ + } /* end while(1) */ + + close (sd); + return result; +} + +/* connects to a host on a specified port, sends a string, and gets a + response */ +int +process_request (char *server_address, + int server_port, + char *proto, + char *send_buffer, char *recv_buffer, int recv_size) +{ + int result; + int send_result; + int recv_result; + int sd; + struct timeval tv; + fd_set readfds; + + result = STATE_OK; + + result = my_connect (server_address, server_port, &sd, proto); + if (result != STATE_OK) + return STATE_CRITICAL; + + send_result = send (sd, send_buffer, strlen (send_buffer), 0); + if (send_result != strlen (send_buffer)) { + printf ("send() failed\n"); + result = STATE_WARNING; + } + + /* wait up to the number of seconds for socket timeout minus one + for data from the host */ + tv.tv_sec = socket_timeout - 1; + tv.tv_usec = 0; + FD_ZERO (&readfds); + FD_SET (sd, &readfds); + select (sd + 1, &readfds, NULL, NULL, &tv); + + /* make sure some data has arrived */ + if (!FD_ISSET (sd, &readfds)) { + strcpy (recv_buffer, ""); + printf ("No data was recieved from host!\n"); + result = STATE_WARNING; + } + + else { + recv_result = recv (sd, recv_buffer, recv_size - 1, 0); + if (recv_result == -1) { + strcpy (recv_buffer, ""); + if (!strcmp (proto, "tcp")) + printf ("recv() failed\n"); + result = STATE_WARNING; + } + else + recv_buffer[recv_result] = 0; + + /* terminate returned string */ + recv_buffer[recv_size - 1] = 0; + } + + close (sd); + + return result; +} + + +/* opens a connection to a remote host/tcp port */ +int +my_tcp_connect (char *host_name, int port, int *sd) +{ + int result; + char proto[4] = "tcp"; + + result = my_connect (host_name, port, sd, proto); + + return result; +} + + +/* opens a connection to a remote host/udp port */ +int +my_udp_connect (char *host_name, int port, int *sd) +{ + int result; + char proto[4] = "udp"; + + result = my_connect (host_name, port, sd, proto); + + return result; +} + + +/* opens a tcp or udp connection to a remote host */ +int +my_connect (char *host_name, int port, int *sd, char *proto) +{ + struct sockaddr_in servaddr; + struct hostent *hp; + struct protoent *ptrp; + int result; + + bzero ((char *) &servaddr, sizeof (servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons (port); + + /* try to bypass using a DNS lookup if this is just an IP address */ + if (!my_inet_aton (host_name, &servaddr.sin_addr)) { + + /* else do a DNS lookup */ + hp = gethostbyname ((const char *) host_name); + if (hp == NULL) { + printf ("Invalid host name '%s'\n", host_name); + return STATE_UNKNOWN; + } + + memcpy (&servaddr.sin_addr, hp->h_addr, hp->h_length); + } + + /* map transport protocol name to protocol number */ + if ((ptrp = getprotobyname (proto)) == NULL) { + printf ("Cannot map \"%s\" to protocol number\n", proto); + return STATE_UNKNOWN; + } + + /* create a socket */ + *sd = + socket (PF_INET, (!strcmp (proto, "udp")) ? SOCK_DGRAM : SOCK_STREAM, + ptrp->p_proto); + if (*sd < 0) { + printf ("Socket creation failed\n"); + return STATE_UNKNOWN; + } + + /* open a connection */ + result = connect (*sd, (struct sockaddr *) &servaddr, sizeof (servaddr)); + if (result < 0) { + switch (errno) { + case ECONNREFUSED: + printf ("Connection refused by host\n"); + break; + case ETIMEDOUT: + printf ("Timeout while attempting connection\n"); + break; + case ENETUNREACH: + printf ("Network is unreachable\n"); + break; + default: + printf ("Connection refused or timed out\n"); + } + + return STATE_CRITICAL; + } + + return STATE_OK; +} + + + +/* This code was taken from Fyodor's nmap utility, which was originally + taken from the GLIBC 2.0.6 libraries because Solaris doesn't contain + the inet_aton() funtion. */ +int +my_inet_aton (register const char *cp, struct in_addr *addr) +{ + register unsigned int val; /* changed from u_long --david */ + register int base, n; + register char c; + u_int parts[4]; + register u_int *pp = parts; + + c = *cp; + + for (;;) { + + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit ((int) c)) + return (0); + val = 0; + base = 10; + + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + + for (;;) { + if (isascii ((int) c) && isdigit ((int) c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } + else if (base == 16 && isascii ((int) c) && isxdigit ((int) c)) { + val = (val << 4) | (c + 10 - (islower ((int) c) ? 'a' : 'A')); + c = *++cp; + } + else + break; + } + + if (c == '.') { + + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } + else + break; + } + + /* Check for trailing characters */ + if (c != '\0' && (!isascii ((int) c) || !isspace ((int) c))) + return (0); + + /* Concoct the address according to the number of parts specified */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + + if (addr) + addr->s_addr = htonl (val); + + return (1); +} diff --git a/plugins/netutils.h.in b/plugins/netutils.h.in new file mode 100644 index 00000000..be4ae241 --- /dev/null +++ b/plugins/netutils.h.in @@ -0,0 +1,63 @@ +/****************************************************************************** +* +* Nagios plugins net utilities include file +* +* License: GPL +* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) +* +* Last Modified: $Date$ +* +* Description: +* +* This file contains common include files and function definitions +* used in many of the plugins. +* +* License Information: +* +* 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., 675 Mass Ave, Cambridge, MA 02139, USA. +* +******************************************************************************/ + +#undef STDC_HEADERS +#undef HAVE_STRINGS_H +#undef HAVE_STRING_H + +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +void socket_timeout_alarm_handler (int); + +int process_tcp_request2 (char *address, int port, char *sbuffer, + char *rbuffer, int rsize); +int process_tcp_request (char *address, int port, char *sbuffer, + char *rbuffer, int rsize); +int process_udp_request (char *address, int port, char *sbuffer, + char *rbuffer, int rsize); +int process_request (char *address, int port, char *proto, char *sbuffer, + char *rbuffer, int rsize); + +int my_tcp_connect (char *address, int port, int *sd); +int my_udp_connect (char *address, int port, int *sd); +int my_connect (char *address, int port, int *sd, char *proto); + +int my_inet_aton (register const char *cp, struct in_addr *addr); + +#ifndef DEFAULT_SOCKET_TIMEOUT +#include "config.h" +#include "common.h" +#endif +int socket_timeout = DEFAULT_SOCKET_TIMEOUT; diff --git a/plugins/popen.c b/plugins/popen.c new file mode 100644 index 00000000..cde3c764 --- /dev/null +++ b/plugins/popen.c @@ -0,0 +1,314 @@ +/****************************************************************************** + * popen.c + * + * A safe alternative to popen + * + * Provides spopen and spclose + +FILE * spopen(const char *); +int spclose(FILE *); + + * + * Code taken with liitle modification from "Advanced Programming for the Unix + * Environment" by W. Richard Stevens + * + * This is considered safe in that no shell is spawned, and the environment and + * path passed to the exec'd program are esstially empty. (popen create a shell + * and passes the environment to it). + * + ******************************************************************************/ + +#include <config.h> +#include <common.h> + +/* extern so plugin has pid to kill exec'd process on timeouts */ +extern int timeout_interval; +extern pid_t *childpid; +extern int *child_stderr_array; +extern FILE *child_process; + +FILE *spopen (const char *); +int spclose (FILE *); +RETSIGTYPE popen_timeout_alarm_handler (int); + +#include <stdarg.h> /* ANSI C header file */ +#include <fcntl.h> + +#include <limits.h> +#include <sys/resource.h> + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif + +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +/* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ +#if defined(SIG_IGN) && !defined(SIG_ERR) +#define SIG_ERR ((Sigfunc *)-1) +#endif + +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) +int open_max (void); /* {Prog openmax} */ +void err_sys (const char *, ...); +char *rtrim (char *, const char *); + +/*int *childerr = NULL;*//* ptr to array allocated at run-time */ +/*extern pid_t *childpid = NULL; *//* ptr to array allocated at run-time */ +static int maxfd; /* from our open_max(), {Prog openmax} */ + +FILE * +spopen (const char *cmdstring) +{ + char *environ[] = { NULL }; + char *cmd = NULL; + char **argv = NULL; + char *str; + int argc; + + int i = 0, pfd[2], pfderr[2]; + pid_t pid; + +#ifdef RLIMIT_CORE + /* do not leave core files */ + struct rlimit limit; + getrlimit (RLIMIT_CORE, &limit); + limit.rlim_cur = 0; + setrlimit (RLIMIT_CORE, &limit); +#endif + + /* if no command was passed, return with no error */ + if (cmdstring == NULL) + return (NULL); + + /* make copy of command string so strtok() doesn't silently modify it */ + /* (the calling program may want to access it later) */ + cmd = malloc (strlen (cmdstring) + 1); + if (cmd == NULL) + return NULL; + strcpy (cmd, cmdstring); + + /* This is not a shell, so we don't handle "???" */ + if (strstr (cmdstring, "\"")) + return NULL; + + /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ + if (strstr (cmdstring, " ' ") || strstr (cmdstring, "'''")) + return NULL; + + /* there cannot be more args than characters */ + argc = strlen (cmdstring) + 1; /* add 1 for NULL termination */ + argv = malloc (sizeof(char*)*argc); + if (argv == NULL) { + printf ("Could not malloc argv array in popen()\n"); + return NULL; + } + + /* loop to get arguments to command */ + while (cmd) { + str = cmd; + str += strspn (str, " \t\r\n"); /* trim any leading whitespace */ + + if (i >= argc - 2) { + printf ("You've got a big problem buddy! You need more args!!!\n"); + return (NULL); + } + + if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */ + str++; + if (!strstr (str, "'")) + return NULL; /* balanced? */ + cmd = 1 + strstr (str, "'"); + str[strcspn (str, "'")] = 0; + } + else { + if (strpbrk (str, " \t\r\n")) { + cmd = 1 + strpbrk (str, " \t\r\n"); + str[strcspn (str, " \t\r\n")] = 0; + } + else { + cmd = NULL; + } + } + + if (cmd && strlen (cmd) == strspn (cmd, " \t\r\n")) + cmd = NULL; + + argv[i++] = str; + + } + argv[i] = NULL; + + if (childpid == NULL) { /* first time through */ + maxfd = open_max (); /* allocate zeroed out array for child pids */ + if ((childpid = calloc (maxfd, sizeof (pid_t))) == NULL) + return (NULL); + } + + if (child_stderr_array == NULL) { /* first time through */ + maxfd = open_max (); /* allocate zeroed out array for child pids */ + if ((child_stderr_array = calloc (maxfd, sizeof (int))) == NULL) + return (NULL); + } + + if (pipe (pfd) < 0) + return (NULL); /* errno set by pipe() */ + + if (pipe (pfderr) < 0) + return (NULL); /* errno set by pipe() */ + + if ((pid = fork ()) < 0) + return (NULL); /* errno set by fork() */ + else if (pid == 0) { /* child */ + close (pfd[0]); + if (pfd[1] != STDOUT_FILENO) { + dup2 (pfd[1], STDOUT_FILENO); + close (pfd[1]); + } + close (pfderr[0]); + if (pfderr[1] != STDERR_FILENO) { + dup2 (pfderr[1], STDERR_FILENO); + close (pfderr[1]); + } + /* close all descriptors in childpid[] */ + for (i = 0; i < maxfd; i++) + if (childpid[i] > 0) + close (i); + + execve (argv[0], argv, environ); + _exit (0); + } + + close (pfd[1]); /* parent */ + if ((child_process = fdopen (pfd[0], "r")) == NULL) + return (NULL); + close (pfderr[1]); + + childpid[fileno (child_process)] = pid; /* remember child pid for this fd */ + child_stderr_array[fileno (child_process)] = pfderr[0]; /* remember STDERR */ + return (child_process); +} + +int +spclose (FILE * fp) +{ + int fd, stat; + pid_t pid; + + if (childpid == NULL) + return (-1); /* popen() has never been called */ + + fd = fileno (fp); + if ((pid = childpid[fd]) == 0) + return (-1); /* fp wasn't opened by popen() */ + + childpid[fd] = 0; + if (fclose (fp) == EOF) + return (-1); + + while (waitpid (pid, &stat, 0) < 0) + if (errno != EINTR) + return (-1); /* error other than EINTR from waitpid() */ + + if (WIFEXITED (stat)) + return (WEXITSTATUS (stat)); /* return child's termination status */ + + return (STATE_UNKNOWN); +} + +#ifdef OPEN_MAX +static int openmax = OPEN_MAX; +#else +static int openmax = 0; +#endif + +#define OPEN_MAX_GUESS 256 /* if OPEN_MAX is indeterminate */ + /* no guarantee this is adequate */ + +void +popen_timeout_alarm_handler (int signo) +{ + if (signo == SIGALRM) { + kill (childpid[fileno (child_process)], SIGKILL); + printf ("CRITICAL - Plugin timed out after %d seconds\n", + timeout_interval); + exit (STATE_CRITICAL); + } +} + +int +open_max (void) +{ + if (openmax == 0) { /* first time through */ + errno = 0; + if ((openmax = sysconf (_SC_OPEN_MAX)) < 0) { + if (errno == 0) + openmax = OPEN_MAX_GUESS; /* it's indeterminate */ + else + err_sys ("sysconf error for _SC_OPEN_MAX"); + } + } + return (openmax); +} + + +static void err_doit (int, const char *, va_list); + +char *pname = NULL; /* caller can set this from argv[0] */ + +/* Fatal error related to a system call. + * Print a message and terminate. */ + +void +err_sys (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + err_doit (1, fmt, ap); + va_end (ap); + exit (1); +} + +/* Print a message and return to caller. + * Caller specifies "errnoflag". */ + +#define MAXLINE 2048 +static void +err_doit (int errnoflag, const char *fmt, va_list ap) +{ + int errno_save; + char buf[MAXLINE]; + + errno_save = errno; /* value caller might want printed */ + vsprintf (buf, fmt, ap); + if (errnoflag) + sprintf (buf + strlen (buf), ": %s", strerror (errno_save)); + strcat (buf, "\n"); + fflush (stdout); /* in case stdout and stderr are the same */ + fputs (buf, stderr); + fflush (NULL); /* flushes all stdio output streams */ + return; +} + +char * +rtrim (char *str, const char *tok) +{ + int i = 0; + + while (str != NULL) { + if (*(str + i) == *tok) { + sprintf (str + i, "%s", "\0"); + return str; + } + i++; + } + return str; +} diff --git a/plugins/popen.h.in b/plugins/popen.h.in new file mode 100644 index 00000000..adae2ecf --- /dev/null +++ b/plugins/popen.h.in @@ -0,0 +1,9 @@ +FILE *spopen (const char *); +int spclose (FILE *); +RETSIGTYPE popen_timeout_alarm_handler (int); + +int timeout_interval; +pid_t *childpid; +int *child_stderr_array; +FILE *child_process; +FILE *child_stderr; diff --git a/plugins/snprintf.c b/plugins/snprintf.c new file mode 100644 index 00000000..1474b639 --- /dev/null +++ b/plugins/snprintf.c @@ -0,0 +1,377 @@ +/* + * Copyright (c) 1983, 1995, 1996 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Some changes made by bbraun@synack.net for use with xinetd */ + +#if !defined(HAVE_SNPRINTF) + +/* Extracted from sendmail 8.8.5 */ +#ifndef lint +static char sccsid[] = "@(#)$Id$ excerpted from conf.c 8.333 (Berkeley) 1/21/97"; +#endif /* not lint */ +# ifdef __STDC__ +#include <stdio.h> +#include <stdlib.h> + +#ifndef __P +#define __P(p) p +#endif + +#include <stdarg.h> +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap, f) +#define VA_END va_end(ap) + +#else + +#include <sys/types.h> +#include <stdio.h> + +#ifndef __P +#define __P(p) () +#endif + +#include <varargs.h> +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap) +#define VA_END va_end(ap) + +#endif +/* +** SNPRINTF, VSNPRINT -- counted versions of printf +** +** These versions have been grabbed off the net. They have been +** cleaned up to compile properly and support for .precision and +** %lx has been added. +*/ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + **************************************************************/ + +/*static char _id[] = "$Id$";*/ +static void dopr(); +static char *end; +#ifndef _SCO_DS +/* VARARGS3 */ +int +# ifdef __STDC__ +snprintf(char *str, size_t count, const char *fmt, ...) +# else +snprintf(str, count, fmt, va_alist) + char *str; + size_t count; + char *fmt; + va_dcl +#endif +{ + int len; + VA_LOCAL_DECL + + VA_START(fmt); + len = vsnprintf(str, count, fmt, ap); + VA_END; + return len; +} +#endif + +# ifndef luna2 +int +# ifdef __STDC__ +vsnprintf(char *str, size_t count, const char *fmt, va_list args) +#else +vsnprintf(str, count, fmt, args) + char *str; + int count; + char *fmt; + va_list args; +#endif +{ + str[0] = 0; + end = str + count - 1; + dopr( str, fmt, args ); + if (count > 0) + end[0] = 0; + return strlen(str); +} + +/* + * dopr(): poor man's version of doprintf + */ + +static void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth)); +static void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad)); +static void dostr __P(( char * , int )); +static char *output; +static void dopr_outch __P(( int c )); + +static void +# ifdef __STDC__ +dopr(char * buffer, const char * format, va_list args ) +#else +dopr( buffer, format, args ) + char *buffer; + char *format; + va_list args; +#endif +{ + int ch; + long value; + int longflag = 0; + int pointflag = 0; + int maxwidth = 0; + char *strvalue; + int ljust; + int len; + int zpad; + + output = buffer; + while( (ch = *format++) ){ + switch( ch ){ + case '%': + ljust = len = zpad = maxwidth = 0; + longflag = pointflag = 0; + nextch: + ch = *format++; + switch( ch ){ + case 0: + dostr( "**end of format**" , 0); + return; + case '-': ljust = 1; goto nextch; + case '0': /* set zero padding if len not set */ + if(len==0 && !pointflag) zpad = '0'; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + if (pointflag) + maxwidth = maxwidth*10 + ch - '0'; + else + len = len*10 + ch - '0'; + goto nextch; + case '*': + if (pointflag) + maxwidth = va_arg( args, int ); + else + len = va_arg( args, int ); + goto nextch; + case '.': pointflag = 1; goto nextch; + case 'l': longflag = 1; goto nextch; + case 'u': case 'U': + /*fmtnum(value,base,dosign,ljust,len,zpad) */ + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 10,0, ljust, len, zpad ); break; + case 'o': case 'O': + /*fmtnum(value,base,dosign,ljust,len,zpad) */ + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 8,0, ljust, len, zpad ); break; + case 'd': case 'D': + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 10,1, ljust, len, zpad ); break; + case 'x': + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value, 16,0, ljust, len, zpad ); break; + case 'X': + if( longflag ){ + value = va_arg( args, long ); + } else { + value = va_arg( args, int ); + } + fmtnum( value,-16,0, ljust, len, zpad ); break; + case 's': + strvalue = va_arg( args, char *); + if (maxwidth > 0 || !pointflag) { + if (pointflag && len > maxwidth) + len = maxwidth; /* Adjust padding */ + fmtstr( strvalue,ljust,len,zpad, maxwidth); + } + break; + case 'c': + ch = va_arg( args, int ); + dopr_outch( ch ); break; + case '%': dopr_outch( ch ); continue; + default: + dostr( "???????" , 0); + } + break; + default: + dopr_outch( ch ); + break; + } + } + *output = 0; +} + +static void +fmtstr( value, ljust, len, zpad, maxwidth ) + char *value; + int ljust, len, zpad, maxwidth; +{ + int padlen, strlen; /* amount to pad */ + + if( value == 0 ){ + value = "<NULL>"; + } + for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */ + if (strlen > maxwidth && maxwidth) + strlen = maxwidth; + padlen = len - strlen; + if( padlen < 0 ) padlen = 0; + if( ljust ) padlen = -padlen; + while( padlen > 0 ) { + dopr_outch( ' ' ); + --padlen; + } + dostr( value, maxwidth ); + while( padlen < 0 ) { + dopr_outch( ' ' ); + ++padlen; + } +} + +static void +fmtnum( value, base, dosign, ljust, len, zpad ) + long value; + int base, dosign, ljust, len, zpad; +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int padlen = 0; /* amount to pad */ + int caps = 0; + + /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", + value, base, dosign, ljust, len, zpad )); */ + uvalue = value; + if( dosign ){ + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + } + if( base < 0 ){ + caps = 1; + base = -base; + } + do{ + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + }while(uvalue); + convert[place] = 0; + padlen = len - place; + if( padlen < 0 ) padlen = 0; + if( ljust ) padlen = -padlen; + /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", + convert,place,signvalue,padlen)); */ + if( zpad && padlen > 0 ){ + if( signvalue ){ + dopr_outch( signvalue ); + --padlen; + signvalue = 0; + } + while( padlen > 0 ){ + dopr_outch( zpad ); + --padlen; + } + } + while( padlen > 0 ) { + dopr_outch( ' ' ); + --padlen; + } + if( signvalue ) dopr_outch( signvalue ); + while( place > 0 ) dopr_outch( convert[--place] ); + while( padlen < 0 ){ + dopr_outch( ' ' ); + ++padlen; + } +} + +static void +dostr( str , cut) + char *str; + int cut; +{ + if (cut) { + while(*str && cut-- > 0) dopr_outch(*str++); + } else { + while(*str) dopr_outch(*str++); + } +} + +static void +dopr_outch( c ) + int c; +{ +#if 0 + if( iscntrl(c) && c != '\n' && c != '\t' ){ + c = '@' + (c & 0x1F); + if( end == 0 || output < end ) + *output++ = '^'; + } +#endif + if( end == 0 || output < end ) + *output++ = c; +} + +# endif /* !luna2 */ + +#endif /* HAVE_SNPRINTF */ diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t new file mode 100644 index 00000000..f1e436dc --- /dev/null +++ b/plugins/t/check_disk.t @@ -0,0 +1,31 @@ +use strict; +use Test; +use vars qw($tests); + +BEGIN {$tests = 6; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_disk 100 100 /"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^(Disk ok - +[\.0-9]+|DISK OK - )/'; + +$cmd = "./check_disk -w 0 -c 0 /"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^(Disk ok - +[\.0-9]+|DISK OK - )/'; + +$cmd = "./check_disk 0 0 /"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^(Only +[\.0-9]+|DISK CRITICAL - )/'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t new file mode 100644 index 00000000..a85e2e76 --- /dev/null +++ b/plugins/t/check_dns.t @@ -0,0 +1,29 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +#`nslookup localhost > /dev/null 2>&1` || exit(77); + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_dns 127.0.0.1 -to 5"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/DNS ok - +[\.0-9]+ seconds response time, Address\(es\) is\/are /'; + +$cmd = "./check_dns $Cache::nullhost -to 1"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_fping.t b/plugins/t/check_fping.t new file mode 100644 index 00000000..629ee35f --- /dev/null +++ b/plugins/t/check_fping.t @@ -0,0 +1,37 @@ +#! /usr/bin/perl -w +# $Id$ + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +exit(0) unless (-x "./check_fping"); + +#`fping 127.0.0.1 > /dev/null 2>&1` || exit(77); + +my $null = ''; +my $cmd; +my $str; +my $t; +my $stat; + + +$cmd = "./check_fping 127.0.0.1"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^FPING OK - 127.0.0.1/'; + +$cmd = "./check_fping $Cache::nullhost"; +$str = `$cmd`; +if ($?>>8 == 1 or $?>>8 == 2) { + $stat = 2; +} +$t += ok $stat,2; +print "Test was: $cmd\n" if (($?>>8) < 1); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_ftp.t b/plugins/t/check_ftp.t new file mode 100644 index 00000000..c3f74d92 --- /dev/null +++ b/plugins/t/check_ftp.t @@ -0,0 +1,32 @@ +#! /usr/bin/perl -w + +#use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_ftp $Cache::hostname -wt 300 -ct 600"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/FTP ok - [0-9]+ second response time/'; + +#$cmd = "./check_ftp $Cache::noserver -wt 0 -ct 0"; +#$str = `$cmd`; +#$t += ok $?>>8,2; +#print "Test was: $cmd\n" unless ($?); + +$cmd = "./check_ftp $Cache::nullhost -wt 0 -ct 0 -to 1"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_hpjd.t b/plugins/t/check_hpjd.t new file mode 100644 index 00000000..b4e198d2 --- /dev/null +++ b/plugins/t/check_hpjd.t @@ -0,0 +1,32 @@ +#! /usr/bin/perl -w + +use strict; +use Helper; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 4; plan tests => $tests} + +exit(0) unless (-x "./check_hpjd"); + +my $null = ''; +my $cmd; +my $str; +my $t; +my $printer = get_option("hpjd_printer","HP Jet-Direct card address"); + +$cmd = "./check_hpjd $printer"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^Printer ok - /'; + +$cmd = "./check_hpjd $Cache::noserver"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/Timeout: No response from /'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t new file mode 100644 index 00000000..2782fcd5 --- /dev/null +++ b/plugins/t/check_http.t @@ -0,0 +1,22 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $str; +my $t; + +$str = `./check_http $Cache::hostname -wt 300 -ct 600`; +$t += ok $?>>8,0; +$t += ok $str, '/HTTP\/1.1 [0-9]{3} (OK|Found) - [0-9]+ second response time/'; + +$str = `./check_http $Cache::nullhost -wt 1 -ct 2`; +$t += ok $?>>8,2; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_imap.t b/plugins/t/check_imap.t new file mode 100644 index 00000000..47494e59 --- /dev/null +++ b/plugins/t/check_imap.t @@ -0,0 +1,34 @@ +#! /usr/bin/perl -w + +#use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_imap $Cache::mailhost"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +$cmd = "./check_imap -H $Cache::mailhost -p 143 -w 9 -c 9 -t 10 -e '* OK'"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + + +# Reverse compatibility +$cmd = "./check_imap $Cache::mailhost -p 143 -wt 9 -ct 9 -to 10 -e '* OK'"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); + diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t new file mode 100644 index 00000000..ac14620f --- /dev/null +++ b/plugins/t/check_load.t @@ -0,0 +1,27 @@ +#! /usr/bin/perl -w + +use strict; +use Test; +use vars qw($tests); + +BEGIN {$tests = 4; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_load 100 100 100 100 100 100"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^load average: +[\.0-9]+, +[\.0-9]+, +[\.0-9]+$/'; + +$cmd = "./check_load 0 0 0 0 0 0"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^load average: +[\.0-9]+, +[\.0-9]+, +[\.0-9]+ CRITICAL$/'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_mysql.t b/plugins/t/check_mysql.t new file mode 100644 index 00000000..ae2a0087 --- /dev/null +++ b/plugins/t/check_mysql.t @@ -0,0 +1,23 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 1; plan tests => $tests} + +exit(0) unless (-x "./check_mysql"); + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_mysql -H 127.0.0.1 -P 3306"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_ping.t b/plugins/t/check_ping.t new file mode 100644 index 00000000..97bc660e --- /dev/null +++ b/plugins/t/check_ping.t @@ -0,0 +1,33 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 5; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_ping 127.0.0.1 100 100 1000 1000 -p 1"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/PING (ok|OK) - Packet loss = +[0-9]{1,2}\%, +RTA = [\.0-9]+ ms/'; + +$cmd = "./check_ping 127.0.0.1 0 0 0 0 -p 1"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/Packet loss = +[0-9]{1,2}\%, +RTA = [\.0-9]+ ms/'; + +$cmd = "./check_ping $Cache::nullhost 0 0 0 0 -p 1 -to 1"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_pop.t b/plugins/t/check_pop.t new file mode 100644 index 00000000..60b5a4ef --- /dev/null +++ b/plugins/t/check_pop.t @@ -0,0 +1,31 @@ +#! /usr/bin/perl -w + +#use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_pop $Cache::mailhost"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +$cmd = "./check_pop -H $Cache::mailhost -p 110 -w 9 -c 9 -t 10 -e '+OK'"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +$cmd = "./check_pop $Cache::mailhost -p 110 -wt 9 -ct 9 -to 10 -e '+OK'"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_procs.t b/plugins/t/check_procs.t new file mode 100644 index 00000000..9c2330f9 --- /dev/null +++ b/plugins/t/check_procs.t @@ -0,0 +1,51 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 10; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +# Reverse Compatibility +$cmd = "./check_procs 100000 100000"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^OK - [0-9]+ processes running$/'; + +# Reverse Compatibility +$cmd = "./check_procs 100000 100000 Z"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^OK - [0-9]+ processes running with /'; + +# Reverse Compatibility +$cmd = "./check_procs 0 10000000"; +$str = `$cmd`; +$t += ok $?>>8,1; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^WARNING - [0-9]+ processes running$/'; + +# Reverse Compatibility +$cmd = "./check_procs 0 0"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^CRITICAL - [0-9]+ processes running$/'; + +# Reverse Compatibility +$cmd = "./check_procs 0 0 S"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^CRITICAL - [0-9]+ processes running with /'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_smtp.t b/plugins/t/check_smtp.t new file mode 100644 index 00000000..2a82b877 --- /dev/null +++ b/plugins/t/check_smtp.t @@ -0,0 +1,31 @@ +#! /usr/bin/perl -w + +#use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_smtp $Cache::mailhost"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +$cmd = "./check_smtp -H $Cache::mailhost -p 25 -t 1 -w 9 -c 9 -t 10 -e 220"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +$cmd = "./check_smtp -H $Cache::mailhost -p 25 -wt 9 -ct 9 -to 10 -e 220"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_snmp.t b/plugins/t/check_snmp.t new file mode 100644 index 00000000..162b0b9b --- /dev/null +++ b/plugins/t/check_snmp.t @@ -0,0 +1,52 @@ +#! /usr/bin/perl -w + +use strict; +use Helper; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 8; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; +my $community=get_option("snmp_community","SNMP community name"); + +exit(0) unless (-x "./check_snmp"); + +$cmd = "./check_snmp -H 127.0.0.1 -C $community -o system.sysUpTime.0 -w 1: -c 1:"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +chomp $str; +$t += ok $str, '/^SNMP OK - \d+/'; + +$cmd = "./check_snmp -H 127.0.0.1 -C $community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +chomp $str; +$t += ok $str, '/^SNMP OK - 1\s*$/'; + +$cmd = "./check_snmp -H 127.0.0.1 -C $community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1:"; +$str = `$cmd`; +$t += ok $?>>8,1; +print "Test was: $cmd\n" unless ($?); +chomp $str; +$t += ok $str, '/^SNMP WARNING - \*1\*\s*$/'; + +$cmd = "./check_snmp -H 127.0.0.1 -C $community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +chomp $str; +$t += ok $str, '/^SNMP CRITICAL - \*1\*\s*$/'; + +#host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 = 1 +#enterprises.ucdavis.memory.memAvailSwap.0 +#./check_snmp 127.0.0.1 -C staff -o enterprises.ucdavis.diskTable.dskEntry.dskAvail.1,enterprises.ucdavis.diskTable.dskEntry.dskPercent.1 -w 100000: -c 50000: -l Space on root -u 'bytes free (','% used)' + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_swap.t b/plugins/t/check_swap.t new file mode 100644 index 00000000..5b702f00 --- /dev/null +++ b/plugins/t/check_swap.t @@ -0,0 +1,34 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 6; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_swap 100 100"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^Swap ok - Swap used\: +[0-9]{1,2}\% \([0-9]+ bytes out of [0-9]+\)$/'; + +$cmd = "./check_swap 0 0"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^CRITICAL - Swap used\: +[0-9]{1,2}\% \([0-9]+ bytes out of [0-9]+\)$/'; + +$cmd = "./check_swap 100 100 1000000000 1000000000"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^CRITICAL - Swap used\: +[0-9]{1,2}\% \([0-9]+ bytes out of [0-9]+\)$/'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_tcp.t b/plugins/t/check_tcp.t new file mode 100644 index 00000000..1abec769 --- /dev/null +++ b/plugins/t/check_tcp.t @@ -0,0 +1,27 @@ +#! /usr/bin/perl -w + +#use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_tcp $Cache::hostname -p 80 -wt 300 -ct 600"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "$cmd\n" if ($?); +$t += ok $str, '/^TCP OK - [0-9]+ second response time on port 80/'; + +$cmd = "./check_tcp $Cache::nullhost -p 81 -wt 0 -ct 0 -to 1"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "$cmd\n" unless ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_time.t b/plugins/t/check_time.t new file mode 100644 index 00000000..4d8c5c2b --- /dev/null +++ b/plugins/t/check_time.t @@ -0,0 +1,52 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Helper; +use Test; +use vars qw($tests); + +BEGIN {$tests = 6; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; +my $udp_hostname=get_option("udp_hostname","UDP host name"); + +# standard mode + +$cmd = "./check_time -H $udp_hostname -w 999999,59 -c 999999,59 -t 60"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^TIME OK - [0-9]+ second time difference$/'; + +$cmd = "./check_time -H $udp_hostname -w 999999 -W 59 -c 999999 -C 59 -t 60"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^TIME OK - [0-9]+ second time difference$/'; + +# reverse compatibility mode + +$cmd = "./check_time $udp_hostname -wt 59 -ct 59 -cd 999999 -wd 999999 -to 60"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^TIME OK - [0-9]+ second time difference$/'; + +# failure mode + +#$cmd = "./check_time -H $Cache::nullhost -t 1"; +#$str = `$cmd`; +#$t += ok $?>>8,255; +#print "Test was: $cmd\n" unless ($?); + +#$cmd = "./check_time -H $Cache::noserver -t 1"; +#$str = `$cmd`; +#$t += ok $?>>8,255; +#print "$cmd\n" unless ($?); + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_udp.t b/plugins/t/check_udp.t new file mode 100644 index 00000000..abbf5e49 --- /dev/null +++ b/plugins/t/check_udp.t @@ -0,0 +1,24 @@ +#! /usr/bin/perl -w + +#use strict; +use Cache; +use Helper; +use Test; +use vars qw($tests); + +BEGIN {$tests = 3; plan tests => $tests} + +my $null = ''; +my $str; +my $t; +my $hostname=get_option("udp_hostname","UDP host name"); + +$str = `./check_udp $hostname -p 37 -wt 300 -ct 600`; +$t += ok $?>>8,0; +$t += ok $str, '/^Connection accepted on port 37 - [0-9]+ second response time$/'; + +$str = `./check_udp $Cache::nullhost -p 80 -wt 0 -ct 0 -to 1`; +$t += ok $?>>8,2; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_users.t b/plugins/t/check_users.t new file mode 100644 index 00000000..593f1737 --- /dev/null +++ b/plugins/t/check_users.t @@ -0,0 +1,28 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 4; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_users 1000 1000"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^USERS OK - +[0-9]+ users currently logged in$/'; + +$cmd = "./check_users 0 0"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^USERS CRITICAL - [0-9]+ +users currently logged in$/'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/t/check_vsz.t b/plugins/t/check_vsz.t new file mode 100644 index 00000000..95972619 --- /dev/null +++ b/plugins/t/check_vsz.t @@ -0,0 +1,28 @@ +#! /usr/bin/perl -w + +use strict; +use Cache; +use Test; +use vars qw($tests); + +BEGIN {$tests = 4; plan tests => $tests} + +my $null = ''; +my $cmd; +my $str; +my $t; + +$cmd = "./check_vsz 100000 1000000 init"; +$str = `$cmd`; +$t += ok $?>>8,0; +print "Test was: $cmd\n" if ($?); +$t += ok $str, '/^ok \(all VSZ\<[0-9]+\)/'; + +$cmd = "./check_vsz 0 0"; +$str = `$cmd`; +$t += ok $?>>8,2; +print "Test was: $cmd\n" unless ($?); +$t += ok $str, '/^CRITICAL \(VSZ\>[0-9]+\)/'; + +exit(0) if defined($Test::Harness::VERSION); +exit($tests - $t); diff --git a/plugins/tests/check_disk b/plugins/tests/check_disk new file mode 100644 index 00000000..c4323e0b --- /dev/null +++ b/plugins/tests/check_disk @@ -0,0 +1,9 @@ +check_disk + +[normal] +100 100 / +^Disk ok - +[\.0-9]+ + +[critical] +0 0 / +^Only +[\.0-9]+ diff --git a/plugins/tests/check_dns b/plugins/tests/check_dns new file mode 100644 index 00000000..2e9b9a09 --- /dev/null +++ b/plugins/tests/check_dns @@ -0,0 +1,9 @@ +check_dns + +[normal] +127.0.0.1 +DNS ok - +[\.0-9]+ seconds response time, Address\(es\) is\/are 127\.0\.0\.1 + +[critical] +$nullhost +DNS (problem - Probably a non-existent host/domain|CRITICAL - Non-existent host/domain|CRITICAL - Connection timed out after [0-9]+ seconds) diff --git a/plugins/tests/check_ftp b/plugins/tests/check_ftp new file mode 100644 index 00000000..4266ebdc --- /dev/null +++ b/plugins/tests/check_ftp @@ -0,0 +1,9 @@ +check_ftp + +[normal] +$hostname -wt 300 -ct 600 +FTP ok - [0-9]+ second response time + +[critical] +$noserver -wt 0 -ct 0 +(Invalid FTP response received from host|Connection refused by host) diff --git a/plugins/tests/check_hpjd b/plugins/tests/check_hpjd new file mode 100644 index 00000000..df35996f --- /dev/null +++ b/plugins/tests/check_hpjd @@ -0,0 +1,9 @@ +check_hpjd + +[normal] +$printer +^Printer ok - + +[critical] +$noserver +Timeout: No response from ns diff --git a/plugins/tests/check_http b/plugins/tests/check_http new file mode 100644 index 00000000..e09f6ff7 --- /dev/null +++ b/plugins/tests/check_http @@ -0,0 +1,9 @@ +check_http + +[normal] +www.infoplease.com -wt 300 -ct 600 +HTTP/1.1 200 OK - [0-9]+ second response time + +[critical] +$nullhost -wt 1 -ct 2 +(Connection refused by host|Network is unreachable|Connection refused or timed out|Socket timeout after [0-9]+ seconds)$ diff --git a/plugins/tests/check_load b/plugins/tests/check_load new file mode 100644 index 00000000..5e4be3a4 --- /dev/null +++ b/plugins/tests/check_load @@ -0,0 +1,9 @@ +check_load + +[normal] +100 100 100 100 100 100 +^load average: +[\.0-9]+, +[\.0-9]+, +[\.0-9]+$ + +[critical] +0 0 0 0 0 0 +^load average: +[\.0-9]+, +[\.0-9]+, +[\.0-9]+ CRITICAL$ diff --git a/plugins/tests/check_ping b/plugins/tests/check_ping new file mode 100644 index 00000000..115cbaa3 --- /dev/null +++ b/plugins/tests/check_ping @@ -0,0 +1,13 @@ +check_ping + +[normal] +127.0.0.1 100 100 1000 1000 -p 1 +PING ok - Packet loss = +[0-9]{1,2}\%, +RTA = [\.0-9]+ ms + +[critical] +127.0.0.1 0 0 0 0 -p 1 +Packet loss = +[0-9]{1,2}\%, +RTA = [\.0-9]+ ms + +[critical] +$nullhost 0 0 0 0 -p 1 -to 1 +CRITICAL - Plugin timed out after 1 seconds diff --git a/plugins/tests/check_procs b/plugins/tests/check_procs new file mode 100644 index 00000000..f7c65222 --- /dev/null +++ b/plugins/tests/check_procs @@ -0,0 +1,23 @@ +check_procs + +# this is a comment + +[normal] +100000 100000 +^OK - [0-9]+ processes running$ + +[normal] +100000 100000 Z +^OK - [0-9]+ processes with Z status$ + +[warning] +0 10000000 +^WARNING - [0-9]+ processes running$ + +[critical] +0 0 +^CRITICAL - [0-9]+ processes running$ + +[critical] +0 0 S +^CRITICAL - [0-9]+ processes with S status$ diff --git a/plugins/tests/check_swap b/plugins/tests/check_swap new file mode 100644 index 00000000..b6cbb42f --- /dev/null +++ b/plugins/tests/check_swap @@ -0,0 +1,13 @@ +check_swap + +[normal] +100 100 +^Swap ok - Swap used\: +[0-9]{1,2}\% \([0-9]+ bytes out of [0-9]+\)$ + +[critical] +0 0 +^CRITICAL - Swap used\: +[0-9]{1,2}\% \([0-9]+ bytes out of [0-9]+\)$ + +[critical] +100 100 1000000000 10000000000 +^CRITICAL - Swap used\: +[0-9]{1,2}\% \([0-9]+ bytes out of [0-9]+\)$ diff --git a/plugins/tests/check_users b/plugins/tests/check_users new file mode 100644 index 00000000..5a7959a5 --- /dev/null +++ b/plugins/tests/check_users @@ -0,0 +1,9 @@ +check_users + +[normal] +1000 1000 +^Users ok - +[0-9]+ users logged in$ + +[critical] +0 0 +^[0-9]+ +users currently logged in$ diff --git a/plugins/tests/check_vsz b/plugins/tests/check_vsz new file mode 100644 index 00000000..4fdec936 --- /dev/null +++ b/plugins/tests/check_vsz @@ -0,0 +1,9 @@ +check_vsz + +[normal] +100000 1000000 init +^ok \(all VSZ\<[0-9]+\) + +[critical] +0 0 +^CRITICAL \(VSZ\>[0-9]+\) diff --git a/plugins/urlize.c b/plugins/urlize.c new file mode 100644 index 00000000..83c37dac --- /dev/null +++ b/plugins/urlize.c @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * urlize.c + * + * Program: plugin wrapper for Nagios + * License: GPL + * Copyright (c) 2000 Karl DeBisschop (kdebiss@alum.mit.edu) + * + * Last Modified: $Date$ + * 2000-06-01 Karl DeBisschop <karl@debisschop.net> + * Written based of concept in urlize.pl + * + * Usage: urlize <url> <plugin> <arg1> ... <argN> + * + * Description: + * + * This plugin wraps the text output of another command (plugin) in HTML + * <A> tags, thus displaying the plugin output in as a clickable link in + * the Nagios status screen. The return status is the same as the plugin + * invoked by urlize + * + * License Information: + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "common.h" +#include "utils.h" +#include "popen.h" + +void print_usage (char *); +void print_help (char *); + +int +main (int argc, char **argv) +{ + int i = 0, found = 0, result = STATE_UNKNOWN; + char command_line[MAX_INPUT_BUFFER] = ""; + char input_buffer[MAX_INPUT_BUFFER]; + + if (argc < 2) { + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + + if (!strcmp (argv[1], "-h") || !strcmp (argv[1], "--help")) { + print_help (argv[0]); + exit (STATE_OK); + } + + if (!strcmp (argv[1], "-V") || !strcmp (argv[1], "--version")) { + print_revision (my_basename (argv[0]), "$Revision$"); + exit (STATE_OK); + } + + if (argc < 2) { + print_usage (my_basename (argv[0])); + exit (STATE_UNKNOWN); + } + + sprintf (command_line, "%s", argv[2]); + for (i = 3; i < argc; i++) { + sprintf (command_line, "%s %s", command_line, argv[i]); + } + + child_process = spopen (command_line); + if (child_process == NULL) { + printf ("Could not open pipe: %s\n", command_line); + exit (STATE_UNKNOWN); + } + + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); + if (child_stderr == NULL) { + printf ("Could not open stderr for %s\n", command_line); + } + + printf ("<A href=\"%s\">", argv[1]); + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + found++; + if (index (input_buffer, '\n')) { + input_buffer[strcspn (input_buffer, "\n")] = 0; + printf ("%s", input_buffer); + } + else { + printf ("%s", input_buffer); + } + } + + if (!found) { + printf ("%s problem - No data recieved from host\nCMD: %s\n", argv[0], + command_line); + exit (STATE_UNKNOWN); + } + + /* close the pipe */ + result = spclose (child_process); + + /* WARNING if output found on stderr */ + if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = max (result, STATE_WARNING); + + /* close stderr */ + (void) fclose (child_stderr); + + printf ("</A>\n"); + return result; +} + +void +print_usage (char *cmd) +{ + printf ("Usage:\n %s <url> <plugin> <arg1> ... <argN>\n", + my_basename (cmd)); +} + +void +print_help (char *cmd) +{ + print_revision ("urlize", "$Revision$"); + printf + ("Copyright (c) 2000 Karl DeBisschop (kdebiss@alum.mit.edu)\n\n" + "\nThis plugin wraps the text output of another command (plugin) in HTML\n" + "<A> tags, thus displaying the plugin output in as a clickable link in\n" + "the Nagios status screen. The return status is the same as the invoked\n" + "plugin.\n\n"); + print_usage (cmd); + exit (STATE_OK); +} diff --git a/plugins/utils.c b/plugins/utils.c new file mode 100644 index 00000000..49e4d3d7 --- /dev/null +++ b/plugins/utils.c @@ -0,0 +1,610 @@ +/***************************************************************************** + * + * utils.c + * + * Library of useful functions for plugins + * + * Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net) + * License: GPL + * + * $Revision$ + * $Date$ + ****************************************************************************/ + +#include "config.h" +#include "common.h" +#include "version.h" +#include <stdarg.h> +#include <limits.h> + +extern int timeout_interval; + +char *my_basename (char *); +void support (void); +char *clean_revstring (const char *); +void print_revision (char *, const char *); +void terminate (int, const char *fmt, ...); +RETSIGTYPE timeout_alarm_handler (int); + +int is_host (char *); +int is_dotted_quad (char *); +int is_hostname (char *); + +int is_integer (char *); +int is_intpos (char *); +int is_intneg (char *); +int is_intnonneg (char *); +int is_intpercent (char *); + +int is_numeric (char *); +int is_positive (char *); +int is_negative (char *); +int is_nonnegative (char *); +int is_percentage (char *); + +int is_option (char *str); + +void strip (char *); +char *strscpy (char *dest, const char *src); +char *strscat (char *dest, const char *src); +char *strnl (char *str); +char *ssprintf (char *str, const char *fmt, ...); +char *strpcpy (char *dest, const char *src, const char *str); +char *strpcat (char *dest, const char *src, const char *str); + +#define LABELLEN 63 +#define STRLEN 64 +#define TXTBLK 128 + +#define max(a,b) ((a)>(b))?(a):(b) + +char * +my_basename (char *path) +{ + if (!strstr (path, "/")) + return path; + else + return 1 + strrchr (path, '/'); +} + + +void +support (void) +{ + printf + ("Send email to nagios-users@lists.sourceforge.net if you have questions\n" + "regarding use of this software. To submit patches or suggest improvements,\n" + "send email to nagiosplug-devel@lists.sourceforge.net\n"); +} + + +char * +clean_revstring (const char *revstring) +{ + char plugin_revision[STRLEN]; + if (sscanf (revstring,"$Revision: %[0-9.]",plugin_revision) == 1) + return strscpy (NULL, plugin_revision); + else + return strscpy (NULL, "N/A"); +} + +void +print_revision (char *command_name, const char *revision_string) +{ + char plugin_revision[STRLEN]; + + if (sscanf (revision_string, "$Revision: %[0-9.]", plugin_revision) != 1) + strncpy (plugin_revision, "N/A", STRLEN); + printf ("%s (nagios-plugins %s) %s\n", + my_basename (command_name), VERSION, plugin_revision); + printf + ("The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n" + "copies of the plugins under the terms of the GNU General Public License.\n" + "For more information about these matters, see the file named COPYING.\n"); + +} + + +void +terminate (int result, const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); + exit (result); +} + +void +timeout_alarm_handler (int signo) +{ + if (signo == SIGALRM) { + printf ("CRITICAL - Plugin timed out after %d seconds\n", + timeout_interval); + exit (STATE_CRITICAL); + } +} + +int +is_host (char *address) +{ + if (is_dotted_quad (address) || is_hostname (address)) + return (TRUE); + return (FALSE); +} + +int +is_dotted_quad (char *address) +{ + int o1, o2, o3, o4; + char c[1]; + + if (sscanf (address, "%d.%d.%d.%d%c", &o1, &o2, &o3, &o4, c) != 4) + return FALSE; + else if (o1 > 255 || o2 > 255 || o3 > 255 || o4 > 255) + return FALSE; + else if (o1 < 0 || o2 < 0 || o3 < 0 || o4 < 0) + return FALSE; + else + return TRUE; +} + +/* from RFC-1035 + * + * The labels must follow the rules for ARPANET host names. They must + * start with a letter, end with a letter or digit, and have as interior + * characters only letters, digits, and hyphen. There are also some + * restrictions on the length. Labels must be 63 characters or less. */ + +int +is_hostname (char *s1) +{ + if (strlen (s1) > 63) + return FALSE; + if (strcspn + (s1, + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789-.") != + 0) return FALSE; + if (strspn (s1, "0123456789-.") == 1) + return FALSE; + while ((s1 = index (s1, '.'))) { + s1++; + if (strspn (s1, "0123456789-.") == 1) { + printf ("%s\n", s1); + return FALSE; + } + } + return TRUE; +} + +int +is_numeric (char *number) +{ + char tmp[1]; + float x; + if (sscanf (number, "%f%c", &x, tmp) == 1) + return (TRUE); + return (FALSE); +} + +int +is_positive (char *number) +{ + if (is_numeric (number) && atof (number) > 0.0) + return (TRUE); + return (FALSE); +} + +int +is_negative (char *number) +{ + if (is_numeric (number) && atof (number) < 0.0) + return (TRUE); + return (FALSE); +} + +int +is_nonnegative (char *number) +{ + if (is_numeric (number) && atof (number) >= 0.0) + return (TRUE); + return (FALSE); +} + +int +is_percentage (char *number) +{ + int x; + if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100) + return (TRUE); + return (FALSE); +} + +int +is_integer (char *number) +{ + long int n; + + if (strspn (number, "-0123456789 ") != strlen (number)) + return (FALSE); + + n = strtol (number, NULL, 10); + if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX) + return (TRUE); + return (FALSE); +} + +int +is_intpos (char *number) +{ + if (is_integer (number) && atoi (number) > 0) + return (TRUE); + return (FALSE); +} + +int +is_intneg (char *number) +{ + if (is_integer (number) && atoi (number) < 0) + return (TRUE); + return (FALSE); +} + +int +is_intnonneg (char *number) +{ + if (is_integer (number) && atoi (number) >= 0) + return (TRUE); + return (FALSE); +} + +int +is_intpercent (char *number) +{ + int i; + if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100) + return (TRUE); + return (FALSE); +} + +int +is_option (char *str) +{ + if (strspn (str, "-") == 1 || strspn (str, "-") == 2) + return TRUE; + return FALSE; +} + + + + + +void +strip (char *buffer) +{ + size_t x; + int i; + + for (x = strlen (buffer); x >= 1; x--) { + i = x - 1; + if (buffer[i] == ' ' || + buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t') + buffer[i] = '\0'; + else + break; + } + return; +} + + + + + +/****************************************************************************** + * + * Copies one string to another + * + * Given a pointer destination string, which may or may not already + * hold some text, and a source string with additional text (possibly + * NULL or empty), returns a pointer to a a copy of the source + * string. Uses realloc to free memory held by the dest argument if + * new storage space is required, and any previously existing data in + * the destination string is lost. + * + * Example: + * + * char *str=NULL; + * str = strscpy("This is a line of text with no trailing newline"); + * + *****************************************************************************/ + +char * +strscpy (char *dest, const char *src) +{ + size_t len; + + if (src == NULL) + return dest; + + len = strlen (src) + 1; + if (dest == NULL) + dest = malloc (len); + else if (strlen (dest) < len) + dest = realloc (dest, len); + if (dest == NULL) + terminate (STATE_UNKNOWN, "failed realloc in strscpy\n"); + + strncpy (dest, src, len); + + return dest; +} + + + + + +/****************************************************************************** + * + * Concatenates one string to the end of another + * + * Given a pointer destination string, which may or may not already + * hold some text, and a source string with additional text (possibly + * NULL or empty), returns a pointer to a string that is the first + * string with the second concatenated to it. Uses realloc to free + * memory held by the dest argument if new storage space is required. + * + * Example: + * + * char *str=NULL; + * str = strscpy("This is a line of text with no trailing newline"); + * str = strscat(str,"\n"); + * + *****************************************************************************/ + +char * +strscat (char *dest, const char *src) +{ + size_t len, l2; + + if (src) + l2 = strlen (src); + else + return dest; + + if (dest) + len = strlen (dest); + else + len = 0; + + dest = realloc (dest, len + l2 + 1); + if (dest == NULL) + terminate (STATE_UNKNOWN, "failed malloc in strscat\n"); + + strncpy (dest + len, src, l2); + dest[len + l2] = '\0'; + + return dest; +} + + + + + +/****************************************************************************** + * + * Returns a pointer to the next line of a multiline string buffer + * + * Given a pointer string, find the text following the next sequence + * of \r and \n characters. This has the effect of skipping blank + * lines as well + * + * Example: + * + * Given text as follows: + * + * ============================== + * This + * is + * a + * + * multiline string buffer + * ============================== + * + * int i=0; + * char *str=NULL; + * char *ptr=NULL; + * str = strscpy(str,"This\nis\r\na\n\nmultiline string buffer\n"); + * ptr = str; + * while (ptr) { + * printf("%d %s",i++,firstword(ptr)); + * ptr = strnl(ptr); + * } + * + * Produces the following: + * + * 1 This + * 2 is + * 3 a + * 4 multiline + * + * NOTE: The 'firstword()' function is conceptual only and does not + * exist in this package. + * + * NOTE: Although the second 'ptr' variable is not strictly needed in + * this example, it is good practice with these utilities. Once + * the * pointer is advance in this manner, it may no longer be + * handled with * realloc(). So at the end of the code fragment + * above, * strscpy(str,"foo") work perfectly fine, but + * strscpy(ptr,"foo") will * cause the the program to crash with + * a segmentation fault. + * + *****************************************************************************/ + +char * +strnl (char *str) +{ + size_t len; + if (str == NULL) + return NULL; + str = strpbrk (str, "\r\n"); + if (str == NULL) + return NULL; + len = strspn (str, "\r\n"); + if (str[len] == '\0') + return NULL; + str += len; + if (strlen (str) == 0) + return NULL; + return str; +} + + + + + +/****************************************************************************** + * + * Does a formatted print to a string variable + * + * Given a pointer destination string, which may or may not already + * hold some text, and a source string with additional text (possibly + * NULL or empty), returns a pointer to a string that cntains the + * results of the specified formatted print + * + * Example: + * + * char *str=NULL; + * str = ssprintf(str,"%d %s",1,"string"); + * + *****************************************************************************/ + +char * +ssprintf (char *ptr, const char *fmt, ...) +{ + va_list ap; + int nchars; + size_t size; + char *str = NULL; + + if (str == NULL) { + str = malloc (TXTBLK); + if (str == NULL) + terminate (STATE_UNKNOWN, "malloc failed in ssprintf"); + size = TXTBLK; + } + else + size = max (strlen (str), TXTBLK); + + va_start (ap, fmt); + + while (1) { + + nchars = vsnprintf (str, size, fmt, ap); + + if (nchars > -1) + if (nchars < (int) size) { + va_end (ap); + str[nchars] = '\0'; + if (ptr) + free (ptr); + return str; + } + else { + size = (size_t) (nchars + 1); + } + + else + size *= 2; + + str = realloc (str, size); + + if (str == NULL) + terminate (STATE_UNKNOWN, "realloc failed in ssprintf"); + } + +} + + + + + +/****************************************************************************** + * + * Like strscpy, except only the portion of the source string up to + * the provided delimiter is copied. + * + * Example: + * + * str = strpcpy(str,"This is a line of text with no trailing newline","x"); + * printf("%s\n",str); + * + * Produces: + * + *This is a line of te + * + *****************************************************************************/ + +char * +strpcpy (char *dest, const char *src, const char *str) +{ + size_t len; + + if (src) + len = strcspn (src, str); + else + return NULL; + + if (dest == NULL || strlen (dest) < len) + dest = realloc (dest, len + 1); + if (dest == NULL) + terminate (STATE_UNKNOWN, "failed realloc in strpcpy\n"); + + strncpy (dest, src, len); + dest[len] = '\0'; + + return dest; +} + + + + + +/****************************************************************************** + * + * Like strscat, except only the portion of the source string up to + * the provided delimiter is copied. + * + * str = strpcpy(str,"This is a line of text with no trailing newline","x"); + * str = strpcat(str,"This is a line of text with no trailing newline","x"); + * printf("%s\n",str); + * + *This is a line of texThis is a line of tex + * + *****************************************************************************/ + +char * +strpcat (char *dest, const char *src, const char *str) +{ + size_t len, l2; + + if (dest) + len = strlen (dest); + else + len = 0; + + if (src) { + l2 = strcspn (src, str); + } + else { + return dest; + } + + dest = realloc (dest, len + l2 + 1); + if (dest == NULL) + terminate (STATE_UNKNOWN, "failed malloc in strscat\n"); + + strncpy (dest + len, src, l2); + dest[len + l2] = '\0'; + + return dest; +} diff --git a/plugins/utils.h.in b/plugins/utils.h.in new file mode 100644 index 00000000..a21d63d6 --- /dev/null +++ b/plugins/utils.h.in @@ -0,0 +1,92 @@ +/* header file for nagios plugins uitls.c */ + +/* this file should be included in all plugins */ + +/* The purpose of this package is to provide safer alternantives to C +functions that might otherwise be vulnerable to hacking. This +currently includes a standard suite of validation routines to be sure +that an string argument acually converts to its intended type and a +suite of string handling routine that do their own memory management +in order to resist overflow attacks. In addition, a few functions are +provided to standardize version and error reporting accross the entire +suite of plugins. */ + +/* Standardize version information, termination */ + +char *my_basename (char *); +void support (void); +char *clean_revstring (const char *revstring); +void print_revision (char *, const char *); +void terminate (int result, char *msg, ...); +extern RETSIGTYPE timeout_alarm_handler (int); + +/* Handle timeouts */ + +time_t start_time, end_time; +int timeout_interval = DEFAULT_SOCKET_TIMEOUT; + +/* Test input types */ + +int is_host (char *); +int is_dotted_quad (char *); +int is_hostname (char *); + +int is_integer (char *); +int is_intpos (char *); +int is_intneg (char *); +int is_intnonneg (char *); +int is_intpercent (char *); + +int is_numeric (char *); +int is_positive (char *); +int is_negative (char *); +int is_nonnegative (char *); +int is_percentage (char *); + +int is_option (char *); + +/* Handle strings safely */ + +void strip (char *buffer); +char *strscpy (char *dest, char *src); +char *strscat (char *dest, char *src); +char *strnl (char *str); +char *ssprintf (char *str, const char *fmt, ...); +char *strpcpy (char *dest, const char *src, const char *str); +char *strpcat (char *dest, const char *src, const char *str); + +#define max(a,b) ((a)>(b))?(a):(b) + +#define usage(msg) {\ + printf(msg);\ + print_usage();\ +exit(STATE_UNKNOWN);\ +} + +#define usage2(msg,arg) {\ + printf("%s: %s - %s\n",PROGNAME,msg,arg);\ + print_usage();\ + exit(STATE_UNKNOWN);\ +} + +#define state_text(a) \ +(a)==0?"OK":\ +(a)==1?"WARNING":\ +(a)==2?"CRITICAL":\ +(a)==-2?"DEPENDENT":\ +"UNKNOWN" + +/* The idea here is that, although not every plugin will use all of these, + most will or should. Therefore, for consistency, these very common + options should have only these meanings throughout the overall suite */ + +#define STD_OPTS "Vvht:c:w:H:F:" +#define STD_OPTS_LONG \ +{"version",no_argument,0,'V'},\ +{"verbose",no_argument,0,'v'},\ +{"help",no_argument,0,'h'},\ +{"timeout",required_argument,0,'t'},\ +{"critical",required_argument,0,'c'},\ +{"warning",required_argument,0,'w'},\ +{"hostname",required_argument,0,'H'},\ +{"file",required_argument,0,'F'} diff --git a/plugins/version.h.in b/plugins/version.h.in new file mode 100644 index 00000000..e41aaee0 --- /dev/null +++ b/plugins/version.h.in @@ -0,0 +1,2 @@ +#define PACKAGE_VERSION "1.3.0-alpha1" +#define CVS_DATE "$Date$" @@ -0,0 +1,22 @@ +#!/bin/sh + +rpm --showrc | grep macrofiles | sed 's/$/:\.\/rpmmacros/' > rpmrc +echo %_sourcedir $PWD/SOURCES > rpmmacros +echo %_rpmdir $PWD/RPMS >> rpmmacros +echo %_srcrpmdir $PWD/SRPMS >> rpmmacros +echo >> rpmmacros + +if test -f $HOME/.rpmrc; then + mv $HOME/.rpmrc $HOME/.rpmrcsave + cat $HOME/.rpmrcsave ./rpmrc > $HOME/.rpmrc +else + cat ./rpmrc > $HOME/.rpmrc +fi + +rpm $@ + +if test -f $HOME/.rpmrcsave; then + mv $HOME/.rpmrcsave $HOME/.rpmrc +else + rm $HOME/.rpmrc +fi diff --git a/subst.in b/subst.in new file mode 100644 index 00000000..092efc83 --- /dev/null +++ b/subst.in @@ -0,0 +1,4 @@ +#! /bin/sed + +s|\${exec_prefix}|@exec_prefix@|; +s|\${prefix}|@prefix@|; diff --git a/subst.sh b/subst.sh new file mode 100755 index 00000000..25606d30 --- /dev/null +++ b/subst.sh @@ -0,0 +1,16 @@ +#! /bin/sh + +if [ -x /bin/mktemp ]; then + TEMP=`/bin/mktemp $1.$$.XXXXXX` || exit 1 +else + TEMP=$1.$$.`date +"%S"` + umask 177 + touch $TEMP +fi + +sed -f subst $1 > $TEMP + +chmod +x $TEMP +touch -r $1 $TEMP +cp -p $TEMP $1 +rm $TEMP diff --git a/test.pl.in b/test.pl.in new file mode 100755 index 00000000..0b895a31 --- /dev/null +++ b/test.pl.in @@ -0,0 +1,87 @@ +#!/usr/bin/perl -w +use strict; + +my $file = '../Cache'; +unless (-f "$file.pm") { + open(CACHE,">$file.pm") or die "Cannot open cache"; + print CACHE "package Cache; +require Exporter; +\@ISA=qw(Exporter); +\@EXPORT=qw(); +1; +"; + close CACHE; +} + +use Helper; +my ($tstdir,$spath,$hostname,$mailhost,$noserver,$nullhost,$quickcheck); + +use Getopt::Long; +GetOptions + ("tstdir:s"=>\$tstdir, + "spath:s"=>\$spath, + "hostname:s"=>\$hostname, + "mailhost:s"=>\$mailhost, + "noserver:s"=>\$noserver, + "nullhost:s"=>\$nullhost, + "quickcheck"=>\$quickcheck); + +$spath = "." unless ($spath); + +unless ($quickcheck) { + + $hostname = get_option("hostname","host for FTP/HTTP/UDP tests") unless ($hostname); + $mailhost = get_option("mailhost","host for SMTP/IMAP/POP tests") unless ($mailhost); + $noserver = get_option("noserver","host that rejects above services") unless ($noserver); + # This machine should not be locatable from your network. Use IP + # private addresses like 10.x.x.x and pick one that does not exist + # on your LAN/WAN + $nullhost = get_option("nullhost","nonexistent IP address (e.g., 10.0.0.0)") unless ($nullhost); +} + +my @dots; +if (@ARGV) { + @dots = @ARGV; +} else { + unless ($tstdir) { + if (-d './t') { + $tstdir = './t'; + } else { + $tstdir = $ENV{PWD}; + $tstdir = `/bin/pwd` unless defined($tstdir); + chomp $tstdir; + if (defined($tstdir)) { + $tstdir =~ s|^(.*)/([^/]+)/?$|$1/$2|; + if (-d "../../$2/t") { + $tstdir = "../../$2/t"; + } elsif (-d "$tstdir/t") { + $tstdir = "$tstdir/t"; + } + } else { + die "Could not get PWD from environment\n"; + } + } + } + $tstdir = './t' unless ($tstdir); + opendir(DIR, $tstdir) || die "can't opendir $tstdir: $!"; + while ($file = readdir(DIR)) { + push @dots, "$tstdir/$file" if ($file =~ m/^[^\.]+\.t$/); + } + closedir DIR; +} +my $prog; +my $test; +my @progs; +foreach $test (@dots) { + $prog=`basename $test .t`; + chomp $prog; + if ( -e "$prog" ){ + push @progs, "$test"; + }else{ + print "No binary found for $prog\n"; + } +} + +use Test::Harness; +#$Test::Harness::verbose=1; +runtests(@progs); diff --git a/tools/setup b/tools/setup new file mode 100755 index 00000000..8d65f4a8 --- /dev/null +++ b/tools/setup @@ -0,0 +1,5 @@ +#! /bin/sh +autoconf +autoheader +automake +chmod +x debian/rules
\ No newline at end of file diff --git a/tools/tango b/tools/tango new file mode 100755 index 00000000..7f418d73 --- /dev/null +++ b/tools/tango @@ -0,0 +1,218 @@ +#!/usr/bin/perl + +use strict; +#use vars qw(\$version \$help \$verbose \$lang \@includes \%ents); +use Getopt::Long; + +sub print_revision ($$); +sub print_usage ($$); +sub print_help ($$); +sub slurp ($$$@); + +my $PROGNAME = "tango"; +my $REVISION = '$Revision$ '; +$REVISION =~ s/^\$Revision: //; +$REVISION =~ s/ \$ $//; + +my $PACKAGE = 'Nagios Plugins'; +my $RELEASE = '1.3'; +my $WARRANTY = "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\ncopies of the plugins under the terms of the GNU General Public License.\nFor more information about these matters, see the file named COPYING.\n"; + +my $version = undef; +my $help = undef; +my $verbose = undef; +my $lang = undef; +my $follow = undef; +my @INCLUDE = undef; + +Getopt::Long::Configure('bundling'); +GetOptions + ("V" => \$version, "version" => \$version, + "h" => \$help, "help" => \$help, + "v" => \$verbose, "verbose" => \$verbose, + "f" => \$follow, "follow!" => \$follow, + "l=s" => \$lang, "language=s" => \$lang, + "I=s" => \@INCLUDE); + +if ($help) { + print_help ($PROGNAME,$REVISION); + exit 0; +} + +if ($version) { + print_revision ($PROGNAME,$REVISION); + exit 0; +} + +if (!defined($lang)) { + print_usage ($PROGNAME,$REVISION); + exit 1; +} + +my $t; +my @files; +my $file; +my $key; +my $ent; +my $cmd; +my $dir; + +# first step is to get a set of defines in effect +# we do this with gcc preprocessor +# +# first, assemble the command +my $cmd = "/usr/bin/gcc -E -dM"; +foreach $dir (@INCLUDE) { + $cmd .= " -I $dir" if ($dir) ; +} + +# add the file(s) to process +while ($file = shift) { + push @files, $file; + $cmd .= " $file"; +} + +# then execute the command, storing defines in %main::ents +open T, "$cmd |"; +while (<T>) { + next if (m|\#define\s+[^\s\(]+\(|); + if (m|\#define\s+(\S+)\s+(\"?)(.*?)\2$|) { + $key = $1; + $ent = $3; + $ent =~ s|\\n\\n|</para>\n\n<para>|msg; + $ent =~ s|\\n|\n|msg; + $main::ents{$key} = $ent; + } +} + +# then we slurp the file to fetch the XML +my $xml = ""; +foreach $file (@files) { + $xml .= slurp ($lang, $follow, $file, @INCLUDE); +} + +# finally substitute the defines as XML entities +foreach $key (keys %main::ents) { + $xml =~ s/\&$key\;/$main::ents{$key}/msg; +} + +# and print the result +print $xml; + +exit 0; + +sub print_revision ($$) { + my $PROGNAME = shift; + my $REVISION = shift; + print "$PROGNAME ($PACKAGE $RELEASE) $REVISION\n"; + print "$WARRANTY"; +} + +sub print_usage ($$) { + my $PROGNAME = shift; + my $REVISION = shift; + print qq"\n$PROGNAME -l <language> [options] file [...]\n" +} + +sub print_help ($$) { + my $PROGNAME = shift; + my $REVISION = shift; + print_usage ($PROGNAME, $REVISION); + print qq" +Options: + -l, --language=STRING + Currently supported languages are C and perl +"; +} + +sub slurp ($$$@) { + no strict 'refs'; + my ($lang, $follow, $file, @INCLUDE) = @_; + my $xml = ""; + my $block; + my $dir = ""; + my $ostat; + my $descriptor = 'T' . int(rand 100000000); + + if ($file !~ m|^[\.\/\\]|) { + foreach $dir (@INCLUDE) { + if ($ostat = open $descriptor, "<$dir/$file") { + push @main::includes, $file; + last; + } + } + } else { + $ostat = open $descriptor, "<$file"; + push @main::includes, $file if $ostat; + } + return "" unless $ostat; + + if ($lang eq 'C') { + while (<$descriptor>) { + $block = $_; + if ($follow && m|^\s*\#\s*include\s+[<"]([^\">]+)[">]|) { + $xml .= slurp ($lang, $follow, $1, @INCLUDE) unless (in (@main::includes, $1)); + } + if ($block =~ m|(\S+)\s+(\S+)\s*(\([^\)]*\));|) { + $main::ents{"PROTO_$2"} = "$1 $2 $3"; + } + if ($block =~ m|//|) { # C++ style one-line comment + if (m|//\@\@-(.*)-\@\@|) { + $xml .= $1; + } + } + if ($block =~ m|/\*|) { # normal C comments + while ($block !~ m|/\*(.*)\*/|ms) { + $block .= <$descriptor>; + } + if ($block =~ m|\@\@-(.*)-\@\@|ms) { + $xml .= $1; + } elsif ($block =~ m|\@s*-(.*)\s*-\@|ms) { + $key = $1; + while ($block !~ m|\*/\s*([^\;]+);|ms) { + $block .= <$descriptor>; + } + if ($block =~ m|\*/\s*([^\;]+);|ms) { + $main::ents{$key} = $1; + } + } + } + } + } + close $descriptor; + return $xml; +} + +sub in () { + my $el = pop; + foreach $key (@_) { + return 1 if ($key eq $el); + } + return 0; +} + +sub CommentStart ($) { + my $lang = shift; + if ($lang eq 'C') { + return '/*'; + } elsif ($lang == 'perl') { + return '#'; + } else { + return undef; + } +} + +# if ($_ =~ m/^\s*\#\s*define\s+([-_a-zA-Z0-9]+)\s+(.*)\s*$/) { +# $key = $1; +# $main::ents{$key} = "$2"; +# while (($main::ents{$key} =~ s/\\\s*$//s) && ($block = <$descriptor>)) { +# $main::ents{$key} .= $block; +# } +# $main::ents{$key} =~ s/"(.*)"$/$1/s; +# $main::ents{$key} =~ s/\s+\/[\/\*].*$//s; +# } + +### Local Variables: ;;; +### tab-width: 2 ;;; +### perl-indent-level: 2 ;;; +### End: ;;; |