Merge branch 'master' into fix/check_ssh-variable-stuff

This commit is contained in:
Lorenz Kästle 2024-10-31 15:27:01 +01:00
commit fa15fdcf5d
81 changed files with 15126 additions and 16862 deletions

11
.clang-format Normal file
View file

@ -0,0 +1,11 @@
UseTab: ForContinuationAndIndentation
IndentWidth: 4
TabWidth: 4
AllowShortIfStatementsOnASingleLine: false
BreakBeforeBraces: Attach
AlignConsecutiveMacros: true
ColumnLimit: 140
IndentPPDirectives: AfterHash
SortIncludes: Never
AllowShortEnumsOnASingleLine: false
BinPackArguments: true

26
.github/mock.sh vendored
View file

@ -2,6 +2,8 @@
set -x
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
BASE_PATH="/src"
@ -18,7 +20,11 @@ SPEC_FILE="${SPEC_DIR}monitoring-plugins.spec"
cd ${BASE_PATH}
dnf -y --setopt="tsflags=nodocs" update && \
if [ ${distro_id} != "fedora" ]; then dnf -y --setopt="tsflags=nodocs" install epel-release; else platform_id="$(echo ${platform_id} | sed s/^f/fc/)"; fi && \
if [ "${distro_id}" != "fedora" ]; then
dnf -y --setopt="tsflags=nodocs" install epel-release;
else
platform_id="$(echo "${platform_id}" | sed s/^f/fc/)";
fi && \
case ${distro_id} in
ol)
case ${platform_id} in
@ -32,19 +38,27 @@ dnf -y --setopt="tsflags=nodocs" update && \
;;
esac
dnf -y --setopt="tsflags=nodocs" install mock rpm-build git-core && \
usermod -a -G mock $(whoami)
usermod -a -G mock "$(whoami)"
SRC_RPM="monitoring-plugins-*-1.${platform_id}.src.rpm"
if command -v git > /dev/null 2>&1; then
git config --global --add safe.directory ${BASE_PATH}
SHA="$(git rev-parse HEAD)"
sed "s/^%global commit.*/%global commit ${SHA}/" ${SPEC_FILE} > ${SPEC_DIR}monitoring-plugins-git.spec
sed -i "s/^%global fromgit.*/%global fromgit 1/" ${SPEC_DIR}monitoring-plugins-git.spec
SPEC_FILE="${SPEC_DIR}monitoring-plugins-git.spec"
SRC_RPM="monitoring-plugins-*git.$(echo ${SHA:0:7})*.${platform_id}.src.rpm"
SRC_RPM="monitoring-plugins-*git.${SHA:0:7}*.${platform_id}.src.rpm"
fi
mkdir -p "${SRCRPM_DIR}" "${RPM_DIR}"
#rpmbuild --undefine=_disable_source_fetch --define "_sourcedir ${SOURCE_DIR}" -ba ${SPEC_FILE}
dnf -y --setopt="tsflags=nodocs" install rpmdevtools && spectool -g -C ${SOURCE_DIR} ${SPEC_FILE} && \
mock --dnf --clean --spec ${SPEC_FILE} --sources=${SOURCE_DIR} --result=${SRCRPM_DIR} --build || { cat ${SRCRPM_DIR}/{root,build}.log; exit 1; }
mock --dnf --clean --sources=${SOURCE_DIR} --result=${RPM_DIR} --rebuild ${SRCRPM_DIR}/${SRC_RPM} || { cat ${RPM_DIR}/{root,build}.log; exit 1; }
dnf -y --setopt="tsflags=nodocs" install rpmdevtools && \
spectool -g -C ${SOURCE_DIR} ${SPEC_FILE} && \
{ mock --dnf --clean --spec ${SPEC_FILE} --sources=${SOURCE_DIR} --result=${SRCRPM_DIR} --build || \
{ cat ${SRCRPM_DIR}/{root,build}.log; exit 1; } }
mock --dnf --clean --sources=${SOURCE_DIR} --result=${RPM_DIR} --rebuild "${SRCRPM_DIR}"/${SRC_RPM} || \
{ cat ${RPM_DIR}/{root,build}.log; exit 1; }
ls -la ${SOURCE_DIR} ${SRCRPM_DIR} ${RPM_DIR}

View file

@ -1,7 +1,7 @@
#!/bin/bash
set -x
set -e
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
@ -127,5 +127,5 @@ sed "/NP_HOST_TLS_CERT/s/.*/'NP_HOST_TLS_CERT' => '$(hostname)',/" -i /src/.gith
# create some test files to lower inodes
for i in $(seq 10); do
touch /media/ramdisk2/test.$1
touch /media/ramdisk2/test.$i
done

78
.github/workflows/test-next.yml vendored Normal file
View file

@ -0,0 +1,78 @@
---
name: Tests Debian:Testing and Fedora:Rawhide
on:
workflow_dispatch: {}
push:
branches-ignore:
- '*'
schedule:
# Run every week on Monday at 9:00 AM (UTC)
- cron: '0 9 * * 1'
jobs:
full-test:
name: Running unit and integrationt tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
distro:
- 'debian:testing'
include:
- distro: 'debian:testing'
prepare: .github/prepare_debian.sh
steps:
- name: Git clone repository
uses: actions/checkout@v4
- name: Run the tests on ${{ matrix.distro }}
run: |
docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol
docker run \
-e NPTEST_ACCEPTDEFAULT=1 \
-e NPTEST_CACHE="/src/.github/NPTest.cache" \
-w /src -v ${PWD}:/src \
--tmpfs /media/ramdisk1 \
-v /var/run/utmp:/var/run/utmp \
--mount source=tmp-vol,destination=/src,target=/media/ramdisk2 \
${{ matrix.distro }} \
/bin/sh -c '${{ matrix.prepare }} && \
tools/setup && \
./configure --enable-libtap --with-ipv6=no && \
make && \
make test && \
make dist && \
tar zxf monitoring-plugins-*.tar.gz && \
cd monitoring-plugins-*/ && \
./configure && \
make'
docker container prune -f
docker volume prune -f
build-test:
name: Running rpm build test on ${{ matrix.distro }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- {"distro": "fedora:rawhide", "build": ".github/mock.sh"}
steps:
- name: Git clone repository
uses: actions/checkout@v4
- name: Run the tests on ${{ matrix.distro }}
run: |
docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol
docker run \
--privileged=true \
-e NPTEST_ACCEPTDEFAULT=1 \
-e NPTEST_CACHE="/src/.github/NPTest.cache" \
-w /src -v ${PWD}:/src \
--tmpfs /media/ramdisk1 \
-v /var/run/utmp:/var/run/utmp \
--mount source=tmp-vol,destination=/src,target=/media/ramdisk2 \
${{ matrix.distro }} \
/bin/sh -c '${{ matrix.build }} && \
ls -la'
docker container prune -f
docker volume prune -f

View file

@ -54,7 +54,6 @@ jobs:
matrix:
include:
- {"distro": "fedora:latest", "build": ".github/mock.sh"}
- {"distro": "fedora:rawhide", "build": ".github/mock.sh"}
- {"distro": "rockylinux:8", "build": ".github/mock.sh"}
- {"distro": "almalinux:9", "build": ".github/mock.sh"}
# - {"distro": "oraclelinux:9", "build": ".github/mock.sh"}

35
CODING
View file

@ -7,33 +7,20 @@ readability in a wide range of environments.
1. C Language Programming
All code should comply with the requirements of the Free Software
All code should comply with most of 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
https://www.gnu.org/prep/standards/standards.html ).
We also follow most of the FSF guidelines, with the huge and explicit
exception of the style guidelines.
Developers may suggest deviations from the FSF
style recommendations, which will be considered by open discussion on
the Monitoring Plugins devel mailing list. Any such deviations will
apply to the entire code base to ensure consistency.
Currently, the exceptions to FSF recommendations 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).
the Monitoring Plugins devel mailing list or the Github Pull Request.
Any such deviations should be
applied to the entire code base to ensure consistency.
The style guideline is the following:
Whatever clang-format does with the configuration file available (.clang-format)
Apart from that, code should naturally be readable and easy to understand.
2. Perl Language Programming

View file

@ -14,15 +14,8 @@
<pubdate>2013</pubdate>
<title>Monitoring Plugins Development Guidelines</title>
<revhistory>
<revision>
<revnumber>1796</revnumber>
<date>2007-09-24 14:51:07 -0400 (Mon, 24 Sep 2007)</date>
</revision>
</revhistory>
<copyright>
<year>2000 - 2013</year>
<year>2000 - 2024</year>
<holder>Monitoring Plugins Development Team</holder>
</copyright>
@ -34,7 +27,7 @@
the plugin developers and encourage the standardization of the
different kind of plugins: C, shell, perl, python, etc.</para>
<para>Monitoring Plugins Development Guidelines Copyright (C) 2000-2013
<para>Monitoring Plugins Development Guidelines Copyright (C) 2000-2024
(Monitoring Plugins Team)</para>
<para>Permission is granted to make and distribute verbatim
@ -383,13 +376,6 @@
<para>It is up to third party programs to convert the Monitoring Plugins
performance data into graphs.</para>
</section>
<section><title>Translations</title>
<para>If possible, use translation tools for all output to respect the user's language
settings. See <xref linkend="translationsdevelopers"> for guidelines
for the core plugins.
</para>
</section>
</section>
<section id="SysCmdAuxFiles"><title>System Commands and Auxiliary Files</title>
@ -727,19 +713,18 @@ setup the tests. Run "make test" to run all the tests.
</section>
<section id="CodingGuidelines"><title>Coding guidelines</title>
<para>See <ulink url="http://www.gnu.org/prep/standards_toc.html">GNU
Coding standards</ulink> for general guidelines.</para>
Coding standards</ulink> for general guidelines.
Some parts of the guidelines (namely and explicitly the coding style)
are not seen as best practice by us.</para>
<section><title>C coding</title>
<para>Variables should be declared at the beginning of code blocks and
not inline because of portability with older compilers.</para>
<para>You should use the type "bool" and its values
"true" and "false" instead of the "int" type for booleans.
</para>
</section>
<section><title>Crediting sources</title>
<para>If you have copied a routine from another source, make sure the licence
<para>If you have copied a routine from another source, make sure the license
from your source allows this. Add a comment referencing the ACKNOWLEDGEMENTS
file, where you can put more detail about the source.</para>
<para>For contributed code, do not add any named credits in the source code
@ -756,32 +741,6 @@ setup the tests. Run "make test" to run all the tests.
<para>All commits will be written to a ChangeLog at release time.
</para>
</section>
<section id="translationsdevelopers"><title>Translations for developers</title>
<para>To make the job easier for translators, please follow these guidelines:</para>
<orderedlist>
<listitem><para>
Before creating new strings, check the po/monitoring-plugins.pot file to
see if a similar string
already exists
</para></listitem>
<listitem><para>
For help texts, break into individual options so that these can be reused
between plugins
</para></listitem>
<listitem><para>Try to avoid linefeeds unless you are working on a block of text</para></listitem>
<listitem><para>Short help is not translated</para></listitem>
<listitem><para>Long help has options in English language, but text translated</para></listitem>
<listitem><para>"Copyright" kept in English</para></listitem>
<listitem><para>Copyright holder names kept in original text</para></listitem>
<listitem><para>Debugging output does not need to be translated</para></listitem>
</orderedlist>
</section>
<section><title>Translations for translators</title>
<para>To create an up to date list of translatable strings, run: tools/gen_locale.sh</para>
</section>
</section>
<section id="SubmittingChanges"><title>Submission of new plugins and patches</title>

View file

@ -1,24 +1,24 @@
/*****************************************************************************
*
* Monitoring Plugins extra_opts library
*
* License: GPL
* Copyright (c) 2007 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
*
* Monitoring Plugins extra_opts library
*
* License: GPL
* Copyright (c) 2007 - 2024 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
#include "common.h"
#include "utils_base.h"
@ -26,110 +26,115 @@
#include "extra_opts.h"
/* FIXME: copied from utils.h; we should move a bunch of libs! */
bool is_option2 (char *str)
{
bool is_option2(char *str) {
if (!str)
return false;
else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
else if (strspn(str, "-") == 1 || strspn(str, "-") == 2)
return true;
else
return false;
}
/* this is the externally visible function used by plugins */
char **np_extra_opts(int *argc, char **argv, const char *plugin_name){
np_arg_list *extra_args=NULL, *ea1=NULL, *ea_tmp=NULL;
char **argv_new=NULL;
char *argptr=NULL;
int i, j, optfound, argc_new, ea_num=*argc;
char **np_extra_opts(int *argc, char **argv, const char *plugin_name) {
np_arg_list *extra_args = NULL, *ea1 = NULL, *ea_tmp = NULL;
char **argv_new = NULL;
char *argptr = NULL;
int i, j, optfound, argc_new, ea_num = *argc;
if(*argc<2) {
if (*argc < 2) {
/* No arguments provided */
return argv;
}
for(i=1; i<*argc; i++){
argptr=NULL;
optfound=0;
for (i = 1; i < *argc; i++) {
argptr = NULL;
optfound = 0;
/* Do we have an extra-opts parameter? */
if(strncmp(argv[i], "--extra-opts=", 13)==0){
if (strncmp(argv[i], "--extra-opts=", 13) == 0) {
/* It is a single argument with value */
argptr=argv[i]+13;
argptr = argv[i] + 13;
/* Delete the extra opts argument */
for(j=i;j<*argc;j++) argv[j]=argv[j+1];
for (j = i; j < *argc; j++)
argv[j] = argv[j + 1];
i--;
*argc-=1;
}else if(strcmp(argv[i], "--extra-opts")==0){
if((i+1<*argc)&&!is_option2(argv[i+1])){
*argc -= 1;
} else if (strcmp(argv[i], "--extra-opts") == 0) {
if ((i + 1 < *argc) && !is_option2(argv[i + 1])) {
/* It is a argument with separate value */
argptr=argv[i+1];
argptr = argv[i + 1];
/* Delete the extra-opts argument/value */
for(j=i;j<*argc-1;j++) argv[j]=argv[j+2];
i-=2;
*argc-=2;
for (j = i; j < *argc - 1; j++)
argv[j] = argv[j + 2];
i -= 2;
*argc -= 2;
ea_num--;
}else{
} else {
/* It has no value */
optfound=1;
optfound = 1;
/* Delete the extra opts argument */
for(j=i;j<*argc;j++) argv[j]=argv[j+1];
for (j = i; j < *argc; j++)
argv[j] = argv[j + 1];
i--;
*argc-=1;
*argc -= 1;
}
}
/* If we found extra-opts, expand them and store them for later*/
if(argptr||optfound){
if (argptr || optfound) {
/* Process ini section, returning a linked list of arguments */
ea1=np_get_defaults(argptr, plugin_name);
if(ea1==NULL) {
ea1 = np_get_defaults(argptr, plugin_name);
if (ea1 == NULL) {
/* no extra args (empty section)? */
ea_num--;
continue;
}
/* append the list to extra_args */
if(extra_args==NULL){
extra_args=ea1;
while((ea1 = ea1->next)) ea_num++;
}else{
ea_tmp=extra_args;
while(ea_tmp->next) {
ea_tmp=ea_tmp->next;
if (extra_args == NULL) {
extra_args = ea1;
while ((ea1 = ea1->next))
ea_num++;
} else {
ea_tmp = extra_args;
while (ea_tmp->next) {
ea_tmp = ea_tmp->next;
}
ea_tmp->next=ea1;
while((ea1 = ea1->next)) ea_num++;
ea_tmp->next = ea1;
while ((ea1 = ea1->next))
ea_num++;
}
ea1=ea_tmp=NULL;
ea1 = ea_tmp = NULL;
}
} /* lather, rince, repeat */
if(ea_num==*argc && extra_args==NULL){
if (ea_num == *argc && extra_args == NULL) {
/* No extra-opts */
return argv;
}
/* done processing arguments. now create a new argv array... */
argv_new=(char**)malloc((ea_num+1)*sizeof(char**));
if(argv_new==NULL) die(STATE_UNKNOWN, _("malloc() failed!\n"));
argv_new = (char **)malloc((ea_num + 1) * sizeof(char **));
if (argv_new == NULL)
die(STATE_UNKNOWN, _("malloc() failed!\n"));
/* starting with program name */
argv_new[0]=argv[0];
argc_new=1;
argv_new[0] = argv[0];
argc_new = 1;
/* then parsed ini opts (frying them up in the same run) */
while(extra_args){
argv_new[argc_new++]=extra_args->arg;
ea1=extra_args;
extra_args=extra_args->next;
while (extra_args) {
argv_new[argc_new++] = extra_args->arg;
ea1 = extra_args;
extra_args = extra_args->next;
free(ea1);
}
/* finally the rest of the argv array */
for (i=1; i<*argc; i++) argv_new[argc_new++]=argv[i];
*argc=argc_new;
for (i = 1; i < *argc; i++)
argv_new[argc_new++] = argv[i];
*argc = argc_new;
/* and terminate. */
argv_new[argc_new]=NULL;
argv_new[argc_new] = NULL;
return argv_new;
}

View file

@ -20,4 +20,3 @@
char **np_extra_opts(int *argc, char **argv, const char *plugin_name);
#endif /* _EXTRA_OPTS_H_ */

View file

@ -1,7 +1,27 @@
/*****************************************************************************
*
* License: GPL
* Copyright (c) 2024 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
#include "./maxfd.h"
#include <errno.h>
long mp_open_max (void) {
long mp_open_max(void) {
long maxfd = 0L;
/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
* If that fails and the macro isn't defined, we fall back to an educated
@ -10,17 +30,17 @@ long mp_open_max (void) {
#ifdef _SC_OPEN_MAX
errno = 0;
if ((maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
if ((maxfd = sysconf(_SC_OPEN_MAX)) < 0) {
if (errno == 0)
maxfd = DEFAULT_MAXFD; /* it's indeterminate */
maxfd = DEFAULT_MAXFD; /* it's indeterminate */
else
die (STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n"));
die(STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n"));
}
#elif defined(OPEN_MAX)
return OPEN_MAX
#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
return DEFAULT_MAXFD;
#endif
return(maxfd);
return (maxfd);
}

View file

@ -1,9 +1,9 @@
#ifndef _MAXFD_
#define _MAXFD_
#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
#define MAXFD_LIMIT 8192 /* upper limit of open files */
#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
#define MAXFD_LIMIT 8192 /* upper limit of open files */
long mp_open_max (void);
long mp_open_max(void);
#endif // _MAXFD_

View file

@ -1,25 +1,25 @@
/*****************************************************************************
*
* Monitoring Plugins parse_ini library
*
* License: GPL
* Copyright (c) 2007 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring Plugins parse_ini library
*
* License: GPL
* Copyright (c) 2007 - 2024 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "idpriv.h"
@ -40,31 +40,20 @@ typedef struct {
char *stanza;
} np_ini_info;
static char *default_ini_file_names[] = {
"monitoring-plugins.ini",
"plugins.ini",
"nagios-plugins.ini",
NULL
};
static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", "nagios-plugins.ini", NULL};
static char *default_ini_path_names[] = {
"/usr/local/etc/monitoring-plugins/monitoring-plugins.ini",
"/usr/local/etc/monitoring-plugins.ini",
"/etc/monitoring-plugins/monitoring-plugins.ini",
"/etc/monitoring-plugins.ini",
"/usr/local/etc/monitoring-plugins/monitoring-plugins.ini", "/usr/local/etc/monitoring-plugins.ini",
"/etc/monitoring-plugins/monitoring-plugins.ini", "/etc/monitoring-plugins.ini",
/* deprecated path names (for backward compatibility): */
"/etc/nagios/plugins.ini",
"/usr/local/nagios/etc/plugins.ini",
"/usr/local/etc/nagios/plugins.ini",
"/etc/opt/nagios/plugins.ini",
"/etc/nagios-plugins.ini",
"/usr/local/etc/nagios-plugins.ini",
"/etc/opt/nagios-plugins.ini",
NULL
};
"/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini", "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini",
"/etc/nagios-plugins.ini", "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL};
/* eat all characters from a FILE pointer until n is encountered */
#define GOBBLE_TO(f, c, n) do { (c)=fgetc((f)); } while((c)!=EOF && (c)!=(n))
#define GOBBLE_TO(f, c, n) \
do { \
(c) = fgetc((f)); \
} while ((c) != EOF && (c) != (n))
/* internal function that returns the constructed defaults options */
static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts);
@ -81,9 +70,7 @@ static char *default_file_in_path(void);
* [stanza][@filename]
* into its separate parts.
*/
static void
parse_locator(const char *locator, const char *def_stanza, np_ini_info *i)
{
static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i) {
size_t locator_len = 0, stanza_len = 0;
/* if locator is NULL we'll use default values */
@ -96,7 +83,7 @@ parse_locator(const char *locator, const char *def_stanza, np_ini_info *i)
i->stanza = malloc(sizeof(char) * (stanza_len + 1));
strncpy(i->stanza, locator, stanza_len);
i->stanza[stanza_len] = '\0';
} else {/* otherwise we use the default stanza */
} else { /* otherwise we use the default stanza */
i->stanza = strdup(def_stanza);
}
@ -105,7 +92,7 @@ parse_locator(const char *locator, const char *def_stanza, np_ini_info *i)
/* check whether there's an @file part */
if (stanza_len == locator_len) {
i->file = default_file();
i->file = default_file();
i->file_string_on_heap = false;
} else {
i->file = strdup(&(locator[stanza_len + 1]));
@ -113,35 +100,28 @@ parse_locator(const char *locator, const char *def_stanza, np_ini_info *i)
}
if (i->file == NULL || i->file[0] == '\0')
die(STATE_UNKNOWN,
_("Cannot find config file in any standard location.\n"));
die(STATE_UNKNOWN, _("Cannot find config file in any standard location.\n"));
}
/*
* This is the externally visible function used by extra_opts.
*/
np_arg_list *
np_get_defaults(const char *locator, const char *default_section)
{
np_arg_list *np_get_defaults(const char *locator, const char *default_section) {
FILE *inifile = NULL;
np_arg_list *defaults = NULL;
np_ini_info i;
int is_suid_plugin = mp_suid();
if (is_suid_plugin && idpriv_temp_drop() == -1)
die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"),
strerror(errno));
die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno));
parse_locator(locator, default_section, &i);
inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r");
if (inifile == NULL)
die(STATE_UNKNOWN, _("Can't read config file: %s\n"),
strerror(errno));
die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno));
if (!read_defaults(inifile, i.stanza, &defaults))
die(STATE_UNKNOWN,
_("Invalid section '%s' in config file '%s'\n"), i.stanza,
i.file);
die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file);
if (i.file_string_on_heap) {
free(i.file);
@ -151,8 +131,7 @@ np_get_defaults(const char *locator, const char *default_section)
fclose(inifile);
free(i.stanza);
if (is_suid_plugin && idpriv_temp_restore() == -1)
die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"),
strerror(errno));
die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno));
return defaults;
}
@ -164,13 +143,15 @@ np_get_defaults(const char *locator, const char *default_section)
* be extra careful about user-supplied input (i.e. avoiding possible
* format string vulnerabilities, etc).
*/
static int
read_defaults(FILE *f, const char *stanza, np_arg_list **opts)
{
static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) {
int c = 0;
bool status = false;
size_t i, stanza_len;
enum { NOSTANZA, WRONGSTANZA, RIGHTSTANZA } stanzastate = NOSTANZA;
enum {
NOSTANZA,
WRONGSTANZA,
RIGHTSTANZA
} stanzastate = NOSTANZA;
stanza_len = strlen(stanza);
@ -217,8 +198,7 @@ read_defaults(FILE *f, const char *stanza, np_arg_list **opts)
* we're dealing with a config error
*/
case NOSTANZA:
die(STATE_UNKNOWN, "%s\n",
_("Config file error"));
die(STATE_UNKNOWN, "%s\n", _("Config file error"));
/* we're in a stanza, but for a different plugin */
case WRONGSTANZA:
GOBBLE_TO(f, c, '\n');
@ -227,8 +207,7 @@ read_defaults(FILE *f, const char *stanza, np_arg_list **opts)
case RIGHTSTANZA:
ungetc(c, f);
if (add_option(f, opts)) {
die(STATE_UNKNOWN, "%s\n",
_("Config file error"));
die(STATE_UNKNOWN, "%s\n", _("Config file error"));
}
status = true;
break;
@ -246,9 +225,7 @@ read_defaults(FILE *f, const char *stanza, np_arg_list **opts)
* --option[=value]
* appending it to the linked list optbuf.
*/
static int
add_option(FILE *f, np_arg_list **optlst)
{
static int add_option(FILE *f, np_arg_list **optlst) {
np_arg_list *opttmp = *optlst, *optnew;
char *linebuf = NULL, *lineend = NULL, *optptr = NULL, *optend = NULL;
char *eqptr = NULL, *valptr = NULL, *valend = NULL;
@ -295,8 +272,7 @@ add_option(FILE *f, np_arg_list **optlst)
if (optptr == eqptr)
die(STATE_UNKNOWN, "%s\n", _("Config file error"));
/* continue from '=' to start of value or EOL */
for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr);
valptr++)
for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++)
continue;
/* continue to the end of value */
for (valend = valptr; valend < lineend; valend++)
@ -365,13 +341,10 @@ add_option(FILE *f, np_arg_list **optlst)
return 0;
}
static char *
default_file(void)
{
char *ini_file;
static char *default_file(void) {
char *ini_file;
if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL ||
(ini_file = default_file_in_path()) != NULL) {
if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL || (ini_file = default_file_in_path()) != NULL) {
return ini_file;
}
@ -383,9 +356,7 @@ default_file(void)
return NULL;
}
static char *
default_file_in_path(void)
{
static char *default_file_in_path(void) {
char *config_path, **file;
char *dir, *ini_file, *tokens;

View file

@ -19,4 +19,3 @@ typedef struct np_arg_el {
np_arg_list *np_get_defaults(const char *locator, const char *default_section);
#endif /* _PARSE_INI_H_ */

View file

@ -1,29 +1,27 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "gl/base64.h"
#include "tap.h"
int
main (int argc, char **argv)
{
#if 0 /* The current base64 function doesn't work on 8bit data */
int main(int argc, char **argv) {
#if 0 /* The current base64 function doesn't work on 8bit data */
char random[1024] = {
0x8b,0xb0,0xc4,0xe2,0xfc,0x22,0x9f,0x0d,0x85,0xe7,0x2c,0xaa,0x39,0xa1,0x46,0x88,
0x50,0xe6,0x34,0x37,0x0b,0x45,0x4b,0xb8,0xb2,0x86,0x7a,0x3e,0x7f,0x0c,0x40,0x18,
@ -182,168 +180,124 @@ main (int argc, char **argv)
#endif
char random[1024] = {
0x0b,0x30,0x44,0x62,0x7c,0x22,0x1f,0x0d,0x05,0x67,0x2c,0x2a,0x39,0x21,0x46,0x08,
0x50,0x66,0x34,0x37,0x0b,0x45,0x4b,0x38,0x32,0x06,0x7a,0x3e,0x7f,0x0c,0x40,0x18,
0x6b,0x2d,0x60,0x4c,0x60,0x0c,0x23,0x43,0x3b,0x3e,0x1b,0x16,0x04,0x46,0x58,0x3f,
0x40,0x6a,0x11,0x05,0x63,0x71,0x14,0x35,0x47,0x79,0x13,0x6f,0x6b,0x27,0x18,0x5b,
0x48,0x27,0x3e,0x6f,0x15,0x33,0x4f,0x3e,0x5e,0x51,0x73,0x68,0x25,0x0f,0x06,0x5b,
0x7c,0x72,0x75,0x3e,0x3f,0x1b,0x5c,0x6d,0x6a,0x39,0x7c,0x63,0x63,0x60,0x6c,0x7a,
0x33,0x76,0x52,0x13,0x25,0x33,0x7d,0x65,0x23,0x27,0x11,0x06,0x06,0x47,0x71,0x1e,
0x14,0x74,0x63,0x70,0x2d,0x15,0x27,0x18,0x51,0x06,0x05,0x33,0x11,0x2c,0x6b,0x00,
0x2d,0x77,0x20,0x48,0x0d,0x73,0x51,0x45,0x25,0x7f,0x7f,0x35,0x26,0x2e,0x26,0x53,
0x24,0x68,0x1e,0x0e,0x58,0x3a,0x59,0x50,0x56,0x37,0x5f,0x66,0x01,0x4c,0x5a,0x64,
0x32,0x50,0x7b,0x6a,0x20,0x72,0x2b,0x1d,0x7e,0x43,0x7b,0x61,0x42,0x0b,0x61,0x73,
0x24,0x79,0x3a,0x6b,0x4a,0x79,0x6e,0x09,0x0f,0x27,0x2d,0x0c,0x5e,0x32,0x4b,0x0d,
0x79,0x46,0x39,0x21,0x0a,0x26,0x5f,0x3a,0x00,0x26,0x3f,0x13,0x2e,0x7e,0x50,0x2b,
0x67,0x46,0x72,0x3f,0x3b,0x01,0x46,0x1b,0x0b,0x35,0x49,0x39,0x19,0x70,0x3d,0x02,
0x41,0x0e,0x38,0x05,0x76,0x65,0x4f,0x31,0x6c,0x5e,0x17,0x04,0x15,0x36,0x26,0x64,
0x34,0x14,0x17,0x7c,0x0e,0x0b,0x5b,0x55,0x53,0x6b,0x00,0x42,0x41,0x4f,0x02,0x5c,
0x13,0x0a,0x2c,0x2c,0x3e,0x10,0x14,0x33,0x45,0x7c,0x7a,0x5a,0x31,0x61,0x39,0x08,
0x22,0x6a,0x1e,0x0f,0x6f,0x1b,0x6c,0x13,0x5e,0x79,0x20,0x79,0x50,0x62,0x06,0x2c,
0x76,0x17,0x04,0x2b,0x2a,0x75,0x1f,0x0c,0x37,0x4e,0x0f,0x7b,0x2d,0x34,0x75,0x60,
0x31,0x74,0x2e,0x0a,0x4a,0x11,0x6c,0x49,0x25,0x01,0x3a,0x3d,0x22,0x1e,0x6d,0x18,
0x51,0x78,0x2d,0x62,0x31,0x4c,0x50,0x40,0x17,0x4b,0x6f,0x22,0x00,0x7f,0x61,0x2a,
0x34,0x3e,0x00,0x5f,0x2f,0x5f,0x2f,0x14,0x2a,0x55,0x27,0x1f,0x46,0x1f,0x12,0x46,
0x5e,0x1e,0x0c,0x7c,0x38,0x01,0x61,0x64,0x76,0x22,0x6e,0x08,0x20,0x38,0x4f,0x73,
0x72,0x55,0x12,0x42,0x19,0x50,0x61,0x43,0x77,0x7d,0x41,0x2e,0x35,0x4f,0x3d,0x31,
0x28,0x58,0x67,0x1b,0x03,0x51,0x20,0x32,0x1c,0x08,0x6e,0x37,0x75,0x37,0x44,0x4f,
0x68,0x19,0x07,0x64,0x14,0x28,0x25,0x2b,0x69,0x35,0x18,0x27,0x26,0x14,0x13,0x70,
0x42,0x19,0x12,0x75,0x3e,0x02,0x5d,0x7c,0x13,0x1f,0x16,0x53,0x3b,0x74,0x48,0x3c,
0x5e,0x39,0x6c,0x1c,0x1c,0x74,0x39,0x1f,0x00,0x1b,0x06,0x0a,0x68,0x3b,0x52,0x4f,
0x1e,0x6e,0x3c,0x35,0x0c,0x38,0x0e,0x0b,0x3b,0x1a,0x76,0x23,0x29,0x53,0x1e,0x5f,
0x41,0x0c,0x4b,0x0a,0x65,0x28,0x78,0x67,0x48,0x59,0x26,0x6d,0x31,0x76,0x23,0x70,
0x61,0x64,0x3b,0x38,0x79,0x66,0x74,0x53,0x2c,0x64,0x64,0x54,0x03,0x54,0x65,0x44,
0x4c,0x18,0x4f,0x48,0x20,0x4f,0x72,0x10,0x3f,0x0c,0x52,0x2d,0x03,0x14,0x03,0x51,
0x42,0x10,0x77,0x6a,0x34,0x06,0x32,0x03,0x72,0x14,0x7c,0x08,0x5d,0x52,0x1a,0x62,
0x7c,0x3e,0x30,0x7e,0x5f,0x7f,0x54,0x0f,0x44,0x49,0x5d,0x5e,0x10,0x6a,0x06,0x2b,
0x06,0x53,0x10,0x39,0x37,0x32,0x4a,0x4e,0x3d,0x2b,0x65,0x38,0x39,0x07,0x72,0x54,
0x64,0x4d,0x56,0x6a,0x03,0x22,0x70,0x7b,0x5f,0x60,0x0b,0x2a,0x0b,0x6b,0x10,0x64,
0x14,0x05,0x22,0x00,0x73,0x40,0x23,0x5b,0x51,0x1f,0x2b,0x1a,0x5d,0x69,0x7a,0x46,
0x0c,0x5f,0x32,0x4b,0x4a,0x28,0x52,0x79,0x5b,0x12,0x42,0x18,0x00,0x5d,0x27,0x31,
0x53,0x3c,0x4c,0x36,0x4e,0x38,0x3f,0x72,0x03,0x71,0x02,0x5b,0x36,0x59,0x7f,0x75,
0x6e,0x08,0x54,0x0d,0x34,0x1c,0x34,0x57,0x5d,0x69,0x48,0x00,0x3b,0x05,0x07,0x6e,
0x27,0x65,0x6e,0x40,0x3d,0x3a,0x4f,0x72,0x5d,0x39,0x16,0x0f,0x63,0x12,0x12,0x15,
0x3a,0x70,0x0d,0x57,0x18,0x0d,0x5e,0x3d,0x22,0x68,0x68,0x7c,0x6d,0x4f,0x0c,0x7b,
0x09,0x2d,0x4a,0x73,0x20,0x47,0x07,0x57,0x75,0x5d,0x53,0x70,0x34,0x21,0x40,0x57,
0x51,0x5e,0x49,0x44,0x00,0x54,0x27,0x04,0x68,0x7e,0x59,0x56,0x58,0x74,0x14,0x3c,
0x16,0x33,0x41,0x16,0x4b,0x2f,0x49,0x37,0x0a,0x54,0x08,0x08,0x1f,0x39,0x67,0x76,
0x28,0x28,0x07,0x1d,0x61,0x47,0x51,0x4d,0x75,0x26,0x52,0x47,0x47,0x0c,0x57,0x58,
0x74,0x3e,0x62,0x6c,0x58,0x3a,0x44,0x1e,0x16,0x2e,0x21,0x1c,0x73,0x45,0x67,0x74,
0x4f,0x33,0x66,0x0e,0x74,0x66,0x26,0x1f,0x2e,0x38,0x44,0x40,0x7e,0x2a,0x50,0x52,
0x5e,0x43,0x01,0x7a,0x38,0x49,0x3c,0x55,0x4d,0x5a,0x44,0x08,0x26,0x59,0x4d,0x45,
0x0b,0x48,0x0a,0x33,0x5e,0x4a,0x4d,0x75,0x16,0x17,0x63,0x46,0x01,0x2a,0x55,0x7b,
0x0f,0x02,0x73,0x6a,0x4b,0x7f,0x75,0x65,0x3c,0x4c,0x33,0x39,0x6c,0x74,0x05,0x60,
0x0f,0x7f,0x2d,0x41,0x4d,0x4d,0x46,0x71,0x09,0x6f,0x4f,0x60,0x15,0x0f,0x46,0x73,
0x63,0x4c,0x5e,0x74,0x30,0x0d,0x28,0x43,0x08,0x72,0x32,0x04,0x2e,0x31,0x29,0x27,
0x44,0x6d,0x13,0x17,0x48,0x0f,0x49,0x52,0x10,0x13,0x7f,0x17,0x16,0x62,0x79,0x35,
0x78,0x3e,0x01,0x7c,0x2e,0x0f,0x76,0x3e,0x5e,0x53,0x6c,0x5b,0x5f,0x7c,0x19,0x41,
0x02,0x2f,0x17,0x64,0x41,0x75,0x10,0x04,0x47,0x7c,0x3d,0x4b,0x52,0x00,0x10,0x5d,
0x51,0x4e,0x7a,0x27,0x25,0x55,0x40,0x12,0x35,0x60,0x05,0x1b,0x34,0x2d,0x04,0x7a,
0x6a,0x69,0x02,0x79,0x03,0x3a,0x2f,0x06,0x0a,0x79,0x7b,0x12,0x5d,0x7c,0x52,0x29,
0x47,0x58,0x12,0x73,0x3f,0x27,0x56,0x05,0x0c,0x48,0x32,0x58,0x6b,0x57,0x5c,0x03,
0x64,0x56,0x11,0x52,0x7a,0x30,0x36,0x29,0x17,0x3b,0x68,0x7a,0x7c,0x05,0x6b,0x6b,
0x13,0x6a,0x24,0x5c,0x68,0x42,0x18,0x32,0x03,0x73,0x6e,0x04,0x21,0x2e,0x01,0x04,
0x63,0x7d,0x44,0x41,0x12,0x31,0x0b,0x15,0x1f,0x70,0x00,0x2e,0x66,0x14,0x3c,0x7f,
0x2b,0x00,0x1f,0x0c,0x28,0x59,0x0a,0x16,0x49,0x5a,0x5c,0x64,0x65,0x4b,0x11,0x29,
0x15,0x36,0x5a,0x65,0x19,0x4f,0x60,0x23,0x3a,0x3a,0x13,0x25,0x02,0x78,0x4c,0x54
};
char b64_known[1369] = {
0x43,0x7a,0x42,0x45,0x59,0x6e,0x77,0x69,0x48,0x77,0x30,0x46,0x5a,0x79,0x77,0x71,
0x4f,0x53,0x46,0x47,0x43,0x46,0x42,0x6d,0x4e,0x44,0x63,0x4c,0x52,0x55,0x73,0x34,
0x4d,0x67,0x5a,0x36,0x50,0x6e,0x38,0x4d,0x51,0x42,0x68,0x72,0x4c,0x57,0x42,0x4d,
0x59,0x41,0x77,0x6a,0x51,0x7a,0x73,0x2b,0x47,0x78,0x59,0x45,0x52,0x6c,0x67,0x2f,
0x51,0x47,0x6f,0x52,0x42,0x57,0x4e,0x78,0x46,0x44,0x56,0x48,0x65,0x52,0x4e,0x76,
0x61,0x79,0x63,0x59,0x57,0x30,0x67,0x6e,0x50,0x6d,0x38,0x56,0x4d,0x30,0x38,0x2b,
0x58,0x6c,0x46,0x7a,0x61,0x43,0x55,0x50,0x42,0x6c,0x74,0x38,0x63,0x6e,0x55,0x2b,
0x50,0x78,0x74,0x63,0x62,0x57,0x6f,0x35,0x66,0x47,0x4e,0x6a,0x59,0x47,0x78,0x36,
0x4d,0x33,0x5a,0x53,0x45,0x79,0x55,0x7a,0x66,0x57,0x55,0x6a,0x4a,0x78,0x45,0x47,
0x42,0x6b,0x64,0x78,0x48,0x68,0x52,0x30,0x59,0x33,0x41,0x74,0x46,0x53,0x63,0x59,
0x55,0x51,0x59,0x46,0x4d,0x78,0x45,0x73,0x61,0x77,0x41,0x74,0x64,0x79,0x42,0x49,
0x44,0x58,0x4e,0x52,0x52,0x53,0x56,0x2f,0x66,0x7a,0x55,0x6d,0x4c,0x69,0x5a,0x54,
0x4a,0x47,0x67,0x65,0x44,0x6c,0x67,0x36,0x57,0x56,0x42,0x57,0x4e,0x31,0x39,0x6d,
0x41,0x55,0x78,0x61,0x5a,0x44,0x4a,0x51,0x65,0x32,0x6f,0x67,0x63,0x69,0x73,0x64,
0x66,0x6b,0x4e,0x37,0x59,0x55,0x49,0x4c,0x59,0x58,0x4d,0x6b,0x65,0x54,0x70,0x72,
0x53,0x6e,0x6c,0x75,0x43,0x51,0x38,0x6e,0x4c,0x51,0x78,0x65,0x4d,0x6b,0x73,0x4e,
0x65,0x55,0x59,0x35,0x49,0x51,0x6f,0x6d,0x58,0x7a,0x6f,0x41,0x4a,0x6a,0x38,0x54,
0x4c,0x6e,0x35,0x51,0x4b,0x32,0x64,0x47,0x63,0x6a,0x38,0x37,0x41,0x55,0x59,0x62,
0x43,0x7a,0x56,0x4a,0x4f,0x52,0x6c,0x77,0x50,0x51,0x4a,0x42,0x44,0x6a,0x67,0x46,
0x64,0x6d,0x56,0x50,0x4d,0x57,0x78,0x65,0x46,0x77,0x51,0x56,0x4e,0x69,0x5a,0x6b,
0x4e,0x42,0x51,0x58,0x66,0x41,0x34,0x4c,0x57,0x31,0x56,0x54,0x61,0x77,0x42,0x43,
0x51,0x55,0x38,0x43,0x58,0x42,0x4d,0x4b,0x4c,0x43,0x77,0x2b,0x45,0x42,0x51,0x7a,
0x52,0x58,0x78,0x36,0x57,0x6a,0x46,0x68,0x4f,0x51,0x67,0x69,0x61,0x68,0x34,0x50,
0x62,0x78,0x74,0x73,0x45,0x31,0x35,0x35,0x49,0x48,0x6c,0x51,0x59,0x67,0x59,0x73,
0x64,0x68,0x63,0x45,0x4b,0x79,0x70,0x31,0x48,0x77,0x77,0x33,0x54,0x67,0x39,0x37,
0x4c,0x54,0x52,0x31,0x59,0x44,0x46,0x30,0x4c,0x67,0x70,0x4b,0x45,0x57,0x78,0x4a,
0x4a,0x51,0x45,0x36,0x50,0x53,0x49,0x65,0x62,0x52,0x68,0x52,0x65,0x43,0x31,0x69,
0x4d,0x55,0x78,0x51,0x51,0x42,0x64,0x4c,0x62,0x79,0x49,0x41,0x66,0x32,0x45,0x71,
0x4e,0x44,0x34,0x41,0x58,0x79,0x39,0x66,0x4c,0x78,0x51,0x71,0x56,0x53,0x63,0x66,
0x52,0x68,0x38,0x53,0x52,0x6c,0x34,0x65,0x44,0x48,0x77,0x34,0x41,0x57,0x46,0x6b,
0x64,0x69,0x4a,0x75,0x43,0x43,0x41,0x34,0x54,0x33,0x4e,0x79,0x56,0x52,0x4a,0x43,
0x47,0x56,0x42,0x68,0x51,0x33,0x64,0x39,0x51,0x53,0x34,0x31,0x54,0x7a,0x30,0x78,
0x4b,0x46,0x68,0x6e,0x47,0x77,0x4e,0x52,0x49,0x44,0x49,0x63,0x43,0x47,0x34,0x33,
0x64,0x54,0x64,0x45,0x54,0x32,0x67,0x5a,0x42,0x32,0x51,0x55,0x4b,0x43,0x55,0x72,
0x61,0x54,0x55,0x59,0x4a,0x79,0x59,0x55,0x45,0x33,0x42,0x43,0x47,0x52,0x4a,0x31,
0x50,0x67,0x4a,0x64,0x66,0x42,0x4d,0x66,0x46,0x6c,0x4d,0x37,0x64,0x45,0x67,0x38,
0x58,0x6a,0x6c,0x73,0x48,0x42,0x78,0x30,0x4f,0x52,0x38,0x41,0x47,0x77,0x59,0x4b,
0x61,0x44,0x74,0x53,0x54,0x78,0x35,0x75,0x50,0x44,0x55,0x4d,0x4f,0x41,0x34,0x4c,
0x4f,0x78,0x70,0x32,0x49,0x79,0x6c,0x54,0x48,0x6c,0x39,0x42,0x44,0x45,0x73,0x4b,
0x5a,0x53,0x68,0x34,0x5a,0x30,0x68,0x5a,0x4a,0x6d,0x30,0x78,0x64,0x69,0x4e,0x77,
0x59,0x57,0x51,0x37,0x4f,0x48,0x6c,0x6d,0x64,0x46,0x4d,0x73,0x5a,0x47,0x52,0x55,
0x41,0x31,0x52,0x6c,0x52,0x45,0x77,0x59,0x54,0x30,0x67,0x67,0x54,0x33,0x49,0x51,
0x50,0x77,0x78,0x53,0x4c,0x51,0x4d,0x55,0x41,0x31,0x46,0x43,0x45,0x48,0x64,0x71,
0x4e,0x41,0x59,0x79,0x41,0x33,0x49,0x55,0x66,0x41,0x68,0x64,0x55,0x68,0x70,0x69,
0x66,0x44,0x34,0x77,0x66,0x6c,0x39,0x2f,0x56,0x41,0x39,0x45,0x53,0x56,0x31,0x65,
0x45,0x47,0x6f,0x47,0x4b,0x77,0x5a,0x54,0x45,0x44,0x6b,0x33,0x4d,0x6b,0x70,0x4f,
0x50,0x53,0x74,0x6c,0x4f,0x44,0x6b,0x48,0x63,0x6c,0x52,0x6b,0x54,0x56,0x5a,0x71,
0x41,0x79,0x4a,0x77,0x65,0x31,0x39,0x67,0x43,0x79,0x6f,0x4c,0x61,0x78,0x42,0x6b,
0x46,0x41,0x55,0x69,0x41,0x48,0x4e,0x41,0x49,0x31,0x74,0x52,0x48,0x79,0x73,0x61,
0x58,0x57,0x6c,0x36,0x52,0x67,0x78,0x66,0x4d,0x6b,0x74,0x4b,0x4b,0x46,0x4a,0x35,
0x57,0x78,0x4a,0x43,0x47,0x41,0x42,0x64,0x4a,0x7a,0x46,0x54,0x50,0x45,0x77,0x32,
0x54,0x6a,0x67,0x2f,0x63,0x67,0x4e,0x78,0x41,0x6c,0x73,0x32,0x57,0x58,0x39,0x31,
0x62,0x67,0x68,0x55,0x44,0x54,0x51,0x63,0x4e,0x46,0x64,0x64,0x61,0x55,0x67,0x41,
0x4f,0x77,0x55,0x48,0x62,0x69,0x64,0x6c,0x62,0x6b,0x41,0x39,0x4f,0x6b,0x39,0x79,
0x58,0x54,0x6b,0x57,0x44,0x32,0x4d,0x53,0x45,0x68,0x55,0x36,0x63,0x41,0x31,0x58,
0x47,0x41,0x31,0x65,0x50,0x53,0x4a,0x6f,0x61,0x48,0x78,0x74,0x54,0x77,0x78,0x37,
0x43,0x53,0x31,0x4b,0x63,0x79,0x42,0x48,0x42,0x31,0x64,0x31,0x58,0x56,0x4e,0x77,
0x4e,0x43,0x46,0x41,0x56,0x31,0x46,0x65,0x53,0x55,0x51,0x41,0x56,0x43,0x63,0x45,
0x61,0x48,0x35,0x5a,0x56,0x6c,0x68,0x30,0x46,0x44,0x77,0x57,0x4d,0x30,0x45,0x57,
0x53,0x79,0x39,0x4a,0x4e,0x77,0x70,0x55,0x43,0x41,0x67,0x66,0x4f,0x57,0x64,0x32,
0x4b,0x43,0x67,0x48,0x48,0x57,0x46,0x48,0x55,0x55,0x31,0x31,0x4a,0x6c,0x4a,0x48,
0x52,0x77,0x78,0x58,0x57,0x48,0x51,0x2b,0x59,0x6d,0x78,0x59,0x4f,0x6b,0x51,0x65,
0x46,0x69,0x34,0x68,0x48,0x48,0x4e,0x46,0x5a,0x33,0x52,0x50,0x4d,0x32,0x59,0x4f,
0x64,0x47,0x59,0x6d,0x48,0x79,0x34,0x34,0x52,0x45,0x42,0x2b,0x4b,0x6c,0x42,0x53,
0x58,0x6b,0x4d,0x42,0x65,0x6a,0x68,0x4a,0x50,0x46,0x56,0x4e,0x57,0x6b,0x51,0x49,
0x4a,0x6c,0x6c,0x4e,0x52,0x51,0x74,0x49,0x43,0x6a,0x4e,0x65,0x53,0x6b,0x31,0x31,
0x46,0x68,0x64,0x6a,0x52,0x67,0x45,0x71,0x56,0x58,0x73,0x50,0x41,0x6e,0x4e,0x71,
0x53,0x33,0x39,0x31,0x5a,0x54,0x78,0x4d,0x4d,0x7a,0x6c,0x73,0x64,0x41,0x56,0x67,
0x44,0x33,0x38,0x74,0x51,0x55,0x31,0x4e,0x52,0x6e,0x45,0x4a,0x62,0x30,0x39,0x67,
0x46,0x51,0x39,0x47,0x63,0x32,0x4e,0x4d,0x58,0x6e,0x51,0x77,0x44,0x53,0x68,0x44,
0x43,0x48,0x49,0x79,0x42,0x43,0x34,0x78,0x4b,0x53,0x64,0x45,0x62,0x52,0x4d,0x58,
0x53,0x41,0x39,0x4a,0x55,0x68,0x41,0x54,0x66,0x78,0x63,0x57,0x59,0x6e,0x6b,0x31,
0x65,0x44,0x34,0x42,0x66,0x43,0x34,0x50,0x64,0x6a,0x35,0x65,0x55,0x32,0x78,0x62,
0x58,0x33,0x77,0x5a,0x51,0x51,0x49,0x76,0x46,0x32,0x52,0x42,0x64,0x52,0x41,0x45,
0x52,0x33,0x77,0x39,0x53,0x31,0x49,0x41,0x45,0x46,0x31,0x52,0x54,0x6e,0x6f,0x6e,
0x4a,0x56,0x56,0x41,0x45,0x6a,0x56,0x67,0x42,0x52,0x73,0x30,0x4c,0x51,0x52,0x36,
0x61,0x6d,0x6b,0x43,0x65,0x51,0x4d,0x36,0x4c,0x77,0x59,0x4b,0x65,0x58,0x73,0x53,
0x58,0x58,0x78,0x53,0x4b,0x55,0x64,0x59,0x45,0x6e,0x4d,0x2f,0x4a,0x31,0x59,0x46,
0x44,0x45,0x67,0x79,0x57,0x47,0x74,0x58,0x58,0x41,0x4e,0x6b,0x56,0x68,0x46,0x53,
0x65,0x6a,0x41,0x32,0x4b,0x52,0x63,0x37,0x61,0x48,0x70,0x38,0x42,0x57,0x74,0x72,
0x45,0x32,0x6f,0x6b,0x58,0x47,0x68,0x43,0x47,0x44,0x49,0x44,0x63,0x32,0x34,0x45,
0x49,0x53,0x34,0x42,0x42,0x47,0x4e,0x39,0x52,0x45,0x45,0x53,0x4d,0x51,0x73,0x56,
0x48,0x33,0x41,0x41,0x4c,0x6d,0x59,0x55,0x50,0x48,0x38,0x72,0x41,0x42,0x38,0x4d,
0x4b,0x46,0x6b,0x4b,0x46,0x6b,0x6c,0x61,0x58,0x47,0x52,0x6c,0x53,0x78,0x45,0x70,
0x46,0x54,0x5a,0x61,0x5a,0x52,0x6c,0x50,0x59,0x43,0x4d,0x36,0x4f,0x68,0x4d,0x6c,
0x41,0x6e,0x68,0x4d,0x56,0x41,0x3d,0x3d,0x00
};
0x0b, 0x30, 0x44, 0x62, 0x7c, 0x22, 0x1f, 0x0d, 0x05, 0x67, 0x2c, 0x2a, 0x39, 0x21, 0x46, 0x08, 0x50, 0x66, 0x34, 0x37, 0x0b, 0x45,
0x4b, 0x38, 0x32, 0x06, 0x7a, 0x3e, 0x7f, 0x0c, 0x40, 0x18, 0x6b, 0x2d, 0x60, 0x4c, 0x60, 0x0c, 0x23, 0x43, 0x3b, 0x3e, 0x1b, 0x16,
0x04, 0x46, 0x58, 0x3f, 0x40, 0x6a, 0x11, 0x05, 0x63, 0x71, 0x14, 0x35, 0x47, 0x79, 0x13, 0x6f, 0x6b, 0x27, 0x18, 0x5b, 0x48, 0x27,
0x3e, 0x6f, 0x15, 0x33, 0x4f, 0x3e, 0x5e, 0x51, 0x73, 0x68, 0x25, 0x0f, 0x06, 0x5b, 0x7c, 0x72, 0x75, 0x3e, 0x3f, 0x1b, 0x5c, 0x6d,
0x6a, 0x39, 0x7c, 0x63, 0x63, 0x60, 0x6c, 0x7a, 0x33, 0x76, 0x52, 0x13, 0x25, 0x33, 0x7d, 0x65, 0x23, 0x27, 0x11, 0x06, 0x06, 0x47,
0x71, 0x1e, 0x14, 0x74, 0x63, 0x70, 0x2d, 0x15, 0x27, 0x18, 0x51, 0x06, 0x05, 0x33, 0x11, 0x2c, 0x6b, 0x00, 0x2d, 0x77, 0x20, 0x48,
0x0d, 0x73, 0x51, 0x45, 0x25, 0x7f, 0x7f, 0x35, 0x26, 0x2e, 0x26, 0x53, 0x24, 0x68, 0x1e, 0x0e, 0x58, 0x3a, 0x59, 0x50, 0x56, 0x37,
0x5f, 0x66, 0x01, 0x4c, 0x5a, 0x64, 0x32, 0x50, 0x7b, 0x6a, 0x20, 0x72, 0x2b, 0x1d, 0x7e, 0x43, 0x7b, 0x61, 0x42, 0x0b, 0x61, 0x73,
0x24, 0x79, 0x3a, 0x6b, 0x4a, 0x79, 0x6e, 0x09, 0x0f, 0x27, 0x2d, 0x0c, 0x5e, 0x32, 0x4b, 0x0d, 0x79, 0x46, 0x39, 0x21, 0x0a, 0x26,
0x5f, 0x3a, 0x00, 0x26, 0x3f, 0x13, 0x2e, 0x7e, 0x50, 0x2b, 0x67, 0x46, 0x72, 0x3f, 0x3b, 0x01, 0x46, 0x1b, 0x0b, 0x35, 0x49, 0x39,
0x19, 0x70, 0x3d, 0x02, 0x41, 0x0e, 0x38, 0x05, 0x76, 0x65, 0x4f, 0x31, 0x6c, 0x5e, 0x17, 0x04, 0x15, 0x36, 0x26, 0x64, 0x34, 0x14,
0x17, 0x7c, 0x0e, 0x0b, 0x5b, 0x55, 0x53, 0x6b, 0x00, 0x42, 0x41, 0x4f, 0x02, 0x5c, 0x13, 0x0a, 0x2c, 0x2c, 0x3e, 0x10, 0x14, 0x33,
0x45, 0x7c, 0x7a, 0x5a, 0x31, 0x61, 0x39, 0x08, 0x22, 0x6a, 0x1e, 0x0f, 0x6f, 0x1b, 0x6c, 0x13, 0x5e, 0x79, 0x20, 0x79, 0x50, 0x62,
0x06, 0x2c, 0x76, 0x17, 0x04, 0x2b, 0x2a, 0x75, 0x1f, 0x0c, 0x37, 0x4e, 0x0f, 0x7b, 0x2d, 0x34, 0x75, 0x60, 0x31, 0x74, 0x2e, 0x0a,
0x4a, 0x11, 0x6c, 0x49, 0x25, 0x01, 0x3a, 0x3d, 0x22, 0x1e, 0x6d, 0x18, 0x51, 0x78, 0x2d, 0x62, 0x31, 0x4c, 0x50, 0x40, 0x17, 0x4b,
0x6f, 0x22, 0x00, 0x7f, 0x61, 0x2a, 0x34, 0x3e, 0x00, 0x5f, 0x2f, 0x5f, 0x2f, 0x14, 0x2a, 0x55, 0x27, 0x1f, 0x46, 0x1f, 0x12, 0x46,
0x5e, 0x1e, 0x0c, 0x7c, 0x38, 0x01, 0x61, 0x64, 0x76, 0x22, 0x6e, 0x08, 0x20, 0x38, 0x4f, 0x73, 0x72, 0x55, 0x12, 0x42, 0x19, 0x50,
0x61, 0x43, 0x77, 0x7d, 0x41, 0x2e, 0x35, 0x4f, 0x3d, 0x31, 0x28, 0x58, 0x67, 0x1b, 0x03, 0x51, 0x20, 0x32, 0x1c, 0x08, 0x6e, 0x37,
0x75, 0x37, 0x44, 0x4f, 0x68, 0x19, 0x07, 0x64, 0x14, 0x28, 0x25, 0x2b, 0x69, 0x35, 0x18, 0x27, 0x26, 0x14, 0x13, 0x70, 0x42, 0x19,
0x12, 0x75, 0x3e, 0x02, 0x5d, 0x7c, 0x13, 0x1f, 0x16, 0x53, 0x3b, 0x74, 0x48, 0x3c, 0x5e, 0x39, 0x6c, 0x1c, 0x1c, 0x74, 0x39, 0x1f,
0x00, 0x1b, 0x06, 0x0a, 0x68, 0x3b, 0x52, 0x4f, 0x1e, 0x6e, 0x3c, 0x35, 0x0c, 0x38, 0x0e, 0x0b, 0x3b, 0x1a, 0x76, 0x23, 0x29, 0x53,
0x1e, 0x5f, 0x41, 0x0c, 0x4b, 0x0a, 0x65, 0x28, 0x78, 0x67, 0x48, 0x59, 0x26, 0x6d, 0x31, 0x76, 0x23, 0x70, 0x61, 0x64, 0x3b, 0x38,
0x79, 0x66, 0x74, 0x53, 0x2c, 0x64, 0x64, 0x54, 0x03, 0x54, 0x65, 0x44, 0x4c, 0x18, 0x4f, 0x48, 0x20, 0x4f, 0x72, 0x10, 0x3f, 0x0c,
0x52, 0x2d, 0x03, 0x14, 0x03, 0x51, 0x42, 0x10, 0x77, 0x6a, 0x34, 0x06, 0x32, 0x03, 0x72, 0x14, 0x7c, 0x08, 0x5d, 0x52, 0x1a, 0x62,
0x7c, 0x3e, 0x30, 0x7e, 0x5f, 0x7f, 0x54, 0x0f, 0x44, 0x49, 0x5d, 0x5e, 0x10, 0x6a, 0x06, 0x2b, 0x06, 0x53, 0x10, 0x39, 0x37, 0x32,
0x4a, 0x4e, 0x3d, 0x2b, 0x65, 0x38, 0x39, 0x07, 0x72, 0x54, 0x64, 0x4d, 0x56, 0x6a, 0x03, 0x22, 0x70, 0x7b, 0x5f, 0x60, 0x0b, 0x2a,
0x0b, 0x6b, 0x10, 0x64, 0x14, 0x05, 0x22, 0x00, 0x73, 0x40, 0x23, 0x5b, 0x51, 0x1f, 0x2b, 0x1a, 0x5d, 0x69, 0x7a, 0x46, 0x0c, 0x5f,
0x32, 0x4b, 0x4a, 0x28, 0x52, 0x79, 0x5b, 0x12, 0x42, 0x18, 0x00, 0x5d, 0x27, 0x31, 0x53, 0x3c, 0x4c, 0x36, 0x4e, 0x38, 0x3f, 0x72,
0x03, 0x71, 0x02, 0x5b, 0x36, 0x59, 0x7f, 0x75, 0x6e, 0x08, 0x54, 0x0d, 0x34, 0x1c, 0x34, 0x57, 0x5d, 0x69, 0x48, 0x00, 0x3b, 0x05,
0x07, 0x6e, 0x27, 0x65, 0x6e, 0x40, 0x3d, 0x3a, 0x4f, 0x72, 0x5d, 0x39, 0x16, 0x0f, 0x63, 0x12, 0x12, 0x15, 0x3a, 0x70, 0x0d, 0x57,
0x18, 0x0d, 0x5e, 0x3d, 0x22, 0x68, 0x68, 0x7c, 0x6d, 0x4f, 0x0c, 0x7b, 0x09, 0x2d, 0x4a, 0x73, 0x20, 0x47, 0x07, 0x57, 0x75, 0x5d,
0x53, 0x70, 0x34, 0x21, 0x40, 0x57, 0x51, 0x5e, 0x49, 0x44, 0x00, 0x54, 0x27, 0x04, 0x68, 0x7e, 0x59, 0x56, 0x58, 0x74, 0x14, 0x3c,
0x16, 0x33, 0x41, 0x16, 0x4b, 0x2f, 0x49, 0x37, 0x0a, 0x54, 0x08, 0x08, 0x1f, 0x39, 0x67, 0x76, 0x28, 0x28, 0x07, 0x1d, 0x61, 0x47,
0x51, 0x4d, 0x75, 0x26, 0x52, 0x47, 0x47, 0x0c, 0x57, 0x58, 0x74, 0x3e, 0x62, 0x6c, 0x58, 0x3a, 0x44, 0x1e, 0x16, 0x2e, 0x21, 0x1c,
0x73, 0x45, 0x67, 0x74, 0x4f, 0x33, 0x66, 0x0e, 0x74, 0x66, 0x26, 0x1f, 0x2e, 0x38, 0x44, 0x40, 0x7e, 0x2a, 0x50, 0x52, 0x5e, 0x43,
0x01, 0x7a, 0x38, 0x49, 0x3c, 0x55, 0x4d, 0x5a, 0x44, 0x08, 0x26, 0x59, 0x4d, 0x45, 0x0b, 0x48, 0x0a, 0x33, 0x5e, 0x4a, 0x4d, 0x75,
0x16, 0x17, 0x63, 0x46, 0x01, 0x2a, 0x55, 0x7b, 0x0f, 0x02, 0x73, 0x6a, 0x4b, 0x7f, 0x75, 0x65, 0x3c, 0x4c, 0x33, 0x39, 0x6c, 0x74,
0x05, 0x60, 0x0f, 0x7f, 0x2d, 0x41, 0x4d, 0x4d, 0x46, 0x71, 0x09, 0x6f, 0x4f, 0x60, 0x15, 0x0f, 0x46, 0x73, 0x63, 0x4c, 0x5e, 0x74,
0x30, 0x0d, 0x28, 0x43, 0x08, 0x72, 0x32, 0x04, 0x2e, 0x31, 0x29, 0x27, 0x44, 0x6d, 0x13, 0x17, 0x48, 0x0f, 0x49, 0x52, 0x10, 0x13,
0x7f, 0x17, 0x16, 0x62, 0x79, 0x35, 0x78, 0x3e, 0x01, 0x7c, 0x2e, 0x0f, 0x76, 0x3e, 0x5e, 0x53, 0x6c, 0x5b, 0x5f, 0x7c, 0x19, 0x41,
0x02, 0x2f, 0x17, 0x64, 0x41, 0x75, 0x10, 0x04, 0x47, 0x7c, 0x3d, 0x4b, 0x52, 0x00, 0x10, 0x5d, 0x51, 0x4e, 0x7a, 0x27, 0x25, 0x55,
0x40, 0x12, 0x35, 0x60, 0x05, 0x1b, 0x34, 0x2d, 0x04, 0x7a, 0x6a, 0x69, 0x02, 0x79, 0x03, 0x3a, 0x2f, 0x06, 0x0a, 0x79, 0x7b, 0x12,
0x5d, 0x7c, 0x52, 0x29, 0x47, 0x58, 0x12, 0x73, 0x3f, 0x27, 0x56, 0x05, 0x0c, 0x48, 0x32, 0x58, 0x6b, 0x57, 0x5c, 0x03, 0x64, 0x56,
0x11, 0x52, 0x7a, 0x30, 0x36, 0x29, 0x17, 0x3b, 0x68, 0x7a, 0x7c, 0x05, 0x6b, 0x6b, 0x13, 0x6a, 0x24, 0x5c, 0x68, 0x42, 0x18, 0x32,
0x03, 0x73, 0x6e, 0x04, 0x21, 0x2e, 0x01, 0x04, 0x63, 0x7d, 0x44, 0x41, 0x12, 0x31, 0x0b, 0x15, 0x1f, 0x70, 0x00, 0x2e, 0x66, 0x14,
0x3c, 0x7f, 0x2b, 0x00, 0x1f, 0x0c, 0x28, 0x59, 0x0a, 0x16, 0x49, 0x5a, 0x5c, 0x64, 0x65, 0x4b, 0x11, 0x29, 0x15, 0x36, 0x5a, 0x65,
0x19, 0x4f, 0x60, 0x23, 0x3a, 0x3a, 0x13, 0x25, 0x02, 0x78, 0x4c, 0x54};
char b64_known[1369] = {
0x43, 0x7a, 0x42, 0x45, 0x59, 0x6e, 0x77, 0x69, 0x48, 0x77, 0x30, 0x46, 0x5a, 0x79, 0x77, 0x71, 0x4f, 0x53, 0x46, 0x47, 0x43, 0x46,
0x42, 0x6d, 0x4e, 0x44, 0x63, 0x4c, 0x52, 0x55, 0x73, 0x34, 0x4d, 0x67, 0x5a, 0x36, 0x50, 0x6e, 0x38, 0x4d, 0x51, 0x42, 0x68, 0x72,
0x4c, 0x57, 0x42, 0x4d, 0x59, 0x41, 0x77, 0x6a, 0x51, 0x7a, 0x73, 0x2b, 0x47, 0x78, 0x59, 0x45, 0x52, 0x6c, 0x67, 0x2f, 0x51, 0x47,
0x6f, 0x52, 0x42, 0x57, 0x4e, 0x78, 0x46, 0x44, 0x56, 0x48, 0x65, 0x52, 0x4e, 0x76, 0x61, 0x79, 0x63, 0x59, 0x57, 0x30, 0x67, 0x6e,
0x50, 0x6d, 0x38, 0x56, 0x4d, 0x30, 0x38, 0x2b, 0x58, 0x6c, 0x46, 0x7a, 0x61, 0x43, 0x55, 0x50, 0x42, 0x6c, 0x74, 0x38, 0x63, 0x6e,
0x55, 0x2b, 0x50, 0x78, 0x74, 0x63, 0x62, 0x57, 0x6f, 0x35, 0x66, 0x47, 0x4e, 0x6a, 0x59, 0x47, 0x78, 0x36, 0x4d, 0x33, 0x5a, 0x53,
0x45, 0x79, 0x55, 0x7a, 0x66, 0x57, 0x55, 0x6a, 0x4a, 0x78, 0x45, 0x47, 0x42, 0x6b, 0x64, 0x78, 0x48, 0x68, 0x52, 0x30, 0x59, 0x33,
0x41, 0x74, 0x46, 0x53, 0x63, 0x59, 0x55, 0x51, 0x59, 0x46, 0x4d, 0x78, 0x45, 0x73, 0x61, 0x77, 0x41, 0x74, 0x64, 0x79, 0x42, 0x49,
0x44, 0x58, 0x4e, 0x52, 0x52, 0x53, 0x56, 0x2f, 0x66, 0x7a, 0x55, 0x6d, 0x4c, 0x69, 0x5a, 0x54, 0x4a, 0x47, 0x67, 0x65, 0x44, 0x6c,
0x67, 0x36, 0x57, 0x56, 0x42, 0x57, 0x4e, 0x31, 0x39, 0x6d, 0x41, 0x55, 0x78, 0x61, 0x5a, 0x44, 0x4a, 0x51, 0x65, 0x32, 0x6f, 0x67,
0x63, 0x69, 0x73, 0x64, 0x66, 0x6b, 0x4e, 0x37, 0x59, 0x55, 0x49, 0x4c, 0x59, 0x58, 0x4d, 0x6b, 0x65, 0x54, 0x70, 0x72, 0x53, 0x6e,
0x6c, 0x75, 0x43, 0x51, 0x38, 0x6e, 0x4c, 0x51, 0x78, 0x65, 0x4d, 0x6b, 0x73, 0x4e, 0x65, 0x55, 0x59, 0x35, 0x49, 0x51, 0x6f, 0x6d,
0x58, 0x7a, 0x6f, 0x41, 0x4a, 0x6a, 0x38, 0x54, 0x4c, 0x6e, 0x35, 0x51, 0x4b, 0x32, 0x64, 0x47, 0x63, 0x6a, 0x38, 0x37, 0x41, 0x55,
0x59, 0x62, 0x43, 0x7a, 0x56, 0x4a, 0x4f, 0x52, 0x6c, 0x77, 0x50, 0x51, 0x4a, 0x42, 0x44, 0x6a, 0x67, 0x46, 0x64, 0x6d, 0x56, 0x50,
0x4d, 0x57, 0x78, 0x65, 0x46, 0x77, 0x51, 0x56, 0x4e, 0x69, 0x5a, 0x6b, 0x4e, 0x42, 0x51, 0x58, 0x66, 0x41, 0x34, 0x4c, 0x57, 0x31,
0x56, 0x54, 0x61, 0x77, 0x42, 0x43, 0x51, 0x55, 0x38, 0x43, 0x58, 0x42, 0x4d, 0x4b, 0x4c, 0x43, 0x77, 0x2b, 0x45, 0x42, 0x51, 0x7a,
0x52, 0x58, 0x78, 0x36, 0x57, 0x6a, 0x46, 0x68, 0x4f, 0x51, 0x67, 0x69, 0x61, 0x68, 0x34, 0x50, 0x62, 0x78, 0x74, 0x73, 0x45, 0x31,
0x35, 0x35, 0x49, 0x48, 0x6c, 0x51, 0x59, 0x67, 0x59, 0x73, 0x64, 0x68, 0x63, 0x45, 0x4b, 0x79, 0x70, 0x31, 0x48, 0x77, 0x77, 0x33,
0x54, 0x67, 0x39, 0x37, 0x4c, 0x54, 0x52, 0x31, 0x59, 0x44, 0x46, 0x30, 0x4c, 0x67, 0x70, 0x4b, 0x45, 0x57, 0x78, 0x4a, 0x4a, 0x51,
0x45, 0x36, 0x50, 0x53, 0x49, 0x65, 0x62, 0x52, 0x68, 0x52, 0x65, 0x43, 0x31, 0x69, 0x4d, 0x55, 0x78, 0x51, 0x51, 0x42, 0x64, 0x4c,
0x62, 0x79, 0x49, 0x41, 0x66, 0x32, 0x45, 0x71, 0x4e, 0x44, 0x34, 0x41, 0x58, 0x79, 0x39, 0x66, 0x4c, 0x78, 0x51, 0x71, 0x56, 0x53,
0x63, 0x66, 0x52, 0x68, 0x38, 0x53, 0x52, 0x6c, 0x34, 0x65, 0x44, 0x48, 0x77, 0x34, 0x41, 0x57, 0x46, 0x6b, 0x64, 0x69, 0x4a, 0x75,
0x43, 0x43, 0x41, 0x34, 0x54, 0x33, 0x4e, 0x79, 0x56, 0x52, 0x4a, 0x43, 0x47, 0x56, 0x42, 0x68, 0x51, 0x33, 0x64, 0x39, 0x51, 0x53,
0x34, 0x31, 0x54, 0x7a, 0x30, 0x78, 0x4b, 0x46, 0x68, 0x6e, 0x47, 0x77, 0x4e, 0x52, 0x49, 0x44, 0x49, 0x63, 0x43, 0x47, 0x34, 0x33,
0x64, 0x54, 0x64, 0x45, 0x54, 0x32, 0x67, 0x5a, 0x42, 0x32, 0x51, 0x55, 0x4b, 0x43, 0x55, 0x72, 0x61, 0x54, 0x55, 0x59, 0x4a, 0x79,
0x59, 0x55, 0x45, 0x33, 0x42, 0x43, 0x47, 0x52, 0x4a, 0x31, 0x50, 0x67, 0x4a, 0x64, 0x66, 0x42, 0x4d, 0x66, 0x46, 0x6c, 0x4d, 0x37,
0x64, 0x45, 0x67, 0x38, 0x58, 0x6a, 0x6c, 0x73, 0x48, 0x42, 0x78, 0x30, 0x4f, 0x52, 0x38, 0x41, 0x47, 0x77, 0x59, 0x4b, 0x61, 0x44,
0x74, 0x53, 0x54, 0x78, 0x35, 0x75, 0x50, 0x44, 0x55, 0x4d, 0x4f, 0x41, 0x34, 0x4c, 0x4f, 0x78, 0x70, 0x32, 0x49, 0x79, 0x6c, 0x54,
0x48, 0x6c, 0x39, 0x42, 0x44, 0x45, 0x73, 0x4b, 0x5a, 0x53, 0x68, 0x34, 0x5a, 0x30, 0x68, 0x5a, 0x4a, 0x6d, 0x30, 0x78, 0x64, 0x69,
0x4e, 0x77, 0x59, 0x57, 0x51, 0x37, 0x4f, 0x48, 0x6c, 0x6d, 0x64, 0x46, 0x4d, 0x73, 0x5a, 0x47, 0x52, 0x55, 0x41, 0x31, 0x52, 0x6c,
0x52, 0x45, 0x77, 0x59, 0x54, 0x30, 0x67, 0x67, 0x54, 0x33, 0x49, 0x51, 0x50, 0x77, 0x78, 0x53, 0x4c, 0x51, 0x4d, 0x55, 0x41, 0x31,
0x46, 0x43, 0x45, 0x48, 0x64, 0x71, 0x4e, 0x41, 0x59, 0x79, 0x41, 0x33, 0x49, 0x55, 0x66, 0x41, 0x68, 0x64, 0x55, 0x68, 0x70, 0x69,
0x66, 0x44, 0x34, 0x77, 0x66, 0x6c, 0x39, 0x2f, 0x56, 0x41, 0x39, 0x45, 0x53, 0x56, 0x31, 0x65, 0x45, 0x47, 0x6f, 0x47, 0x4b, 0x77,
0x5a, 0x54, 0x45, 0x44, 0x6b, 0x33, 0x4d, 0x6b, 0x70, 0x4f, 0x50, 0x53, 0x74, 0x6c, 0x4f, 0x44, 0x6b, 0x48, 0x63, 0x6c, 0x52, 0x6b,
0x54, 0x56, 0x5a, 0x71, 0x41, 0x79, 0x4a, 0x77, 0x65, 0x31, 0x39, 0x67, 0x43, 0x79, 0x6f, 0x4c, 0x61, 0x78, 0x42, 0x6b, 0x46, 0x41,
0x55, 0x69, 0x41, 0x48, 0x4e, 0x41, 0x49, 0x31, 0x74, 0x52, 0x48, 0x79, 0x73, 0x61, 0x58, 0x57, 0x6c, 0x36, 0x52, 0x67, 0x78, 0x66,
0x4d, 0x6b, 0x74, 0x4b, 0x4b, 0x46, 0x4a, 0x35, 0x57, 0x78, 0x4a, 0x43, 0x47, 0x41, 0x42, 0x64, 0x4a, 0x7a, 0x46, 0x54, 0x50, 0x45,
0x77, 0x32, 0x54, 0x6a, 0x67, 0x2f, 0x63, 0x67, 0x4e, 0x78, 0x41, 0x6c, 0x73, 0x32, 0x57, 0x58, 0x39, 0x31, 0x62, 0x67, 0x68, 0x55,
0x44, 0x54, 0x51, 0x63, 0x4e, 0x46, 0x64, 0x64, 0x61, 0x55, 0x67, 0x41, 0x4f, 0x77, 0x55, 0x48, 0x62, 0x69, 0x64, 0x6c, 0x62, 0x6b,
0x41, 0x39, 0x4f, 0x6b, 0x39, 0x79, 0x58, 0x54, 0x6b, 0x57, 0x44, 0x32, 0x4d, 0x53, 0x45, 0x68, 0x55, 0x36, 0x63, 0x41, 0x31, 0x58,
0x47, 0x41, 0x31, 0x65, 0x50, 0x53, 0x4a, 0x6f, 0x61, 0x48, 0x78, 0x74, 0x54, 0x77, 0x78, 0x37, 0x43, 0x53, 0x31, 0x4b, 0x63, 0x79,
0x42, 0x48, 0x42, 0x31, 0x64, 0x31, 0x58, 0x56, 0x4e, 0x77, 0x4e, 0x43, 0x46, 0x41, 0x56, 0x31, 0x46, 0x65, 0x53, 0x55, 0x51, 0x41,
0x56, 0x43, 0x63, 0x45, 0x61, 0x48, 0x35, 0x5a, 0x56, 0x6c, 0x68, 0x30, 0x46, 0x44, 0x77, 0x57, 0x4d, 0x30, 0x45, 0x57, 0x53, 0x79,
0x39, 0x4a, 0x4e, 0x77, 0x70, 0x55, 0x43, 0x41, 0x67, 0x66, 0x4f, 0x57, 0x64, 0x32, 0x4b, 0x43, 0x67, 0x48, 0x48, 0x57, 0x46, 0x48,
0x55, 0x55, 0x31, 0x31, 0x4a, 0x6c, 0x4a, 0x48, 0x52, 0x77, 0x78, 0x58, 0x57, 0x48, 0x51, 0x2b, 0x59, 0x6d, 0x78, 0x59, 0x4f, 0x6b,
0x51, 0x65, 0x46, 0x69, 0x34, 0x68, 0x48, 0x48, 0x4e, 0x46, 0x5a, 0x33, 0x52, 0x50, 0x4d, 0x32, 0x59, 0x4f, 0x64, 0x47, 0x59, 0x6d,
0x48, 0x79, 0x34, 0x34, 0x52, 0x45, 0x42, 0x2b, 0x4b, 0x6c, 0x42, 0x53, 0x58, 0x6b, 0x4d, 0x42, 0x65, 0x6a, 0x68, 0x4a, 0x50, 0x46,
0x56, 0x4e, 0x57, 0x6b, 0x51, 0x49, 0x4a, 0x6c, 0x6c, 0x4e, 0x52, 0x51, 0x74, 0x49, 0x43, 0x6a, 0x4e, 0x65, 0x53, 0x6b, 0x31, 0x31,
0x46, 0x68, 0x64, 0x6a, 0x52, 0x67, 0x45, 0x71, 0x56, 0x58, 0x73, 0x50, 0x41, 0x6e, 0x4e, 0x71, 0x53, 0x33, 0x39, 0x31, 0x5a, 0x54,
0x78, 0x4d, 0x4d, 0x7a, 0x6c, 0x73, 0x64, 0x41, 0x56, 0x67, 0x44, 0x33, 0x38, 0x74, 0x51, 0x55, 0x31, 0x4e, 0x52, 0x6e, 0x45, 0x4a,
0x62, 0x30, 0x39, 0x67, 0x46, 0x51, 0x39, 0x47, 0x63, 0x32, 0x4e, 0x4d, 0x58, 0x6e, 0x51, 0x77, 0x44, 0x53, 0x68, 0x44, 0x43, 0x48,
0x49, 0x79, 0x42, 0x43, 0x34, 0x78, 0x4b, 0x53, 0x64, 0x45, 0x62, 0x52, 0x4d, 0x58, 0x53, 0x41, 0x39, 0x4a, 0x55, 0x68, 0x41, 0x54,
0x66, 0x78, 0x63, 0x57, 0x59, 0x6e, 0x6b, 0x31, 0x65, 0x44, 0x34, 0x42, 0x66, 0x43, 0x34, 0x50, 0x64, 0x6a, 0x35, 0x65, 0x55, 0x32,
0x78, 0x62, 0x58, 0x33, 0x77, 0x5a, 0x51, 0x51, 0x49, 0x76, 0x46, 0x32, 0x52, 0x42, 0x64, 0x52, 0x41, 0x45, 0x52, 0x33, 0x77, 0x39,
0x53, 0x31, 0x49, 0x41, 0x45, 0x46, 0x31, 0x52, 0x54, 0x6e, 0x6f, 0x6e, 0x4a, 0x56, 0x56, 0x41, 0x45, 0x6a, 0x56, 0x67, 0x42, 0x52,
0x73, 0x30, 0x4c, 0x51, 0x52, 0x36, 0x61, 0x6d, 0x6b, 0x43, 0x65, 0x51, 0x4d, 0x36, 0x4c, 0x77, 0x59, 0x4b, 0x65, 0x58, 0x73, 0x53,
0x58, 0x58, 0x78, 0x53, 0x4b, 0x55, 0x64, 0x59, 0x45, 0x6e, 0x4d, 0x2f, 0x4a, 0x31, 0x59, 0x46, 0x44, 0x45, 0x67, 0x79, 0x57, 0x47,
0x74, 0x58, 0x58, 0x41, 0x4e, 0x6b, 0x56, 0x68, 0x46, 0x53, 0x65, 0x6a, 0x41, 0x32, 0x4b, 0x52, 0x63, 0x37, 0x61, 0x48, 0x70, 0x38,
0x42, 0x57, 0x74, 0x72, 0x45, 0x32, 0x6f, 0x6b, 0x58, 0x47, 0x68, 0x43, 0x47, 0x44, 0x49, 0x44, 0x63, 0x32, 0x34, 0x45, 0x49, 0x53,
0x34, 0x42, 0x42, 0x47, 0x4e, 0x39, 0x52, 0x45, 0x45, 0x53, 0x4d, 0x51, 0x73, 0x56, 0x48, 0x33, 0x41, 0x41, 0x4c, 0x6d, 0x59, 0x55,
0x50, 0x48, 0x38, 0x72, 0x41, 0x42, 0x38, 0x4d, 0x4b, 0x46, 0x6b, 0x4b, 0x46, 0x6b, 0x6c, 0x61, 0x58, 0x47, 0x52, 0x6c, 0x53, 0x78,
0x45, 0x70, 0x46, 0x54, 0x5a, 0x61, 0x5a, 0x52, 0x6c, 0x50, 0x59, 0x43, 0x4d, 0x36, 0x4f, 0x68, 0x4d, 0x6c, 0x41, 0x6e, 0x68, 0x4d,
0x56, 0x41, 0x3d, 0x3d, 0x00};
char *b64_test;
plan_tests(1);
base64_encode_alloc (random, 1024, &b64_test);
base64_encode_alloc(random, 1024, &b64_test);
ok(strcmp(b64_known, b64_test) == 0,
"Test matching a base64 encoded 1024 bytes random string");
ok(strcmp(b64_known, b64_test) == 0, "Test matching a base64 encoded 1024 bytes random string");
return exit_status();
}

View file

@ -1,20 +1,20 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_cmd.h"
@ -22,27 +22,23 @@
#include "tap.h"
#define COMMAND_LINE 1024
#define UNSET 65530
#define UNSET 65530
char *
get_command (char *const *line)
{
char *get_command(char *const *line) {
char *cmd;
int i = 0;
asprintf (&cmd, " %s", line[i++]);
asprintf(&cmd, " %s", line[i++]);
while (line[i] != NULL) {
asprintf (&cmd, "%s %s", cmd, line[i]);
asprintf(&cmd, "%s %s", cmd, line[i]);
i++;
}
return cmd;
}
int
main (int argc, char **argv)
{
char **command_line = malloc (sizeof (char *) * COMMAND_LINE);
int main(int argc, char **argv) {
char **command_line = malloc(sizeof(char *) * COMMAND_LINE);
char *command = NULL;
char *perl;
output chld_out, chld_err;
@ -51,183 +47,154 @@ main (int argc, char **argv)
plan_tests(51);
diag ("Running plain echo command, set one");
diag("Running plain echo command, set one");
/* ensure everything is empty before we begin */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
ok (chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok (chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok (result == UNSET, "(initialised) Checking exit code is reset");
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
ok(chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok(chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok(result == UNSET, "(initialised) Checking exit code is reset");
command_line[0] = strdup ("/bin/echo");
command_line[1] = strdup ("this");
command_line[2] = strdup ("is");
command_line[3] = strdup ("test");
command_line[4] = strdup ("one");
command_line[0] = strdup("/bin/echo");
command_line[1] = strdup("this");
command_line[2] = strdup("is");
command_line[3] = strdup("test");
command_line[4] = strdup("one");
command = get_command (command_line);
command = get_command(command_line);
result = cmd_run_array (command_line, &chld_out, &chld_err, 0);
ok (chld_out.lines == 1,
"(array) Check for expected number of stdout lines");
ok (chld_err.lines == 0,
"(array) Check for expected number of stderr lines");
ok (strcmp (chld_out.line[0], "this is test one") == 0,
"(array) Check for expected stdout output");
ok (result == 0, "(array) Checking exit code");
result = cmd_run_array(command_line, &chld_out, &chld_err, 0);
ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines");
ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines");
ok(strcmp(chld_out.line[0], "this is test one") == 0, "(array) Check for expected stdout output");
ok(result == 0, "(array) Checking exit code");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
ok (chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok (chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok (result == UNSET, "(initialised) Checking exit code is reset");
ok(chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok(chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok(result == UNSET, "(initialised) Checking exit code is reset");
result = cmd_run (command, &chld_out, &chld_err, 0);
result = cmd_run(command, &chld_out, &chld_err, 0);
ok (chld_out.lines == 1,
"(string) Check for expected number of stdout lines");
ok (chld_err.lines == 0,
"(string) Check for expected number of stderr lines");
ok (strcmp (chld_out.line[0], "this is test one") == 0,
"(string) Check for expected stdout output");
ok (result == 0, "(string) Checking exit code");
ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines");
ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines");
ok(strcmp(chld_out.line[0], "this is test one") == 0, "(string) Check for expected stdout output");
ok(result == 0, "(string) Checking exit code");
diag ("Running plain echo command, set two");
diag("Running plain echo command, set two");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
ok (chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok (chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok (result == UNSET, "(initialised) Checking exit code is reset");
ok(chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok(chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok(result == UNSET, "(initialised) Checking exit code is reset");
command_line[0] = strdup ("/bin/echo");
command_line[1] = strdup ("this is test two");
command_line[0] = strdup("/bin/echo");
command_line[1] = strdup("this is test two");
command_line[2] = NULL;
command_line[3] = NULL;
command_line[4] = NULL;
result = cmd_run_array (command_line, &chld_out, &chld_err, 0);
ok (chld_out.lines == 1,
"(array) Check for expected number of stdout lines");
ok (chld_err.lines == 0,
"(array) Check for expected number of stderr lines");
ok (strcmp (chld_out.line[0], "this is test two") == 0,
"(array) Check for expected stdout output");
ok (result == 0, "(array) Checking exit code");
result = cmd_run_array(command_line, &chld_out, &chld_err, 0);
ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines");
ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines");
ok(strcmp(chld_out.line[0], "this is test two") == 0, "(array) Check for expected stdout output");
ok(result == 0, "(array) Checking exit code");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
ok (chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok (chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok (result == UNSET, "(initialised) Checking exit code is reset");
ok(chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok(chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok(result == UNSET, "(initialised) Checking exit code is reset");
result = cmd_run (command, &chld_out, &chld_err, 0);
ok (chld_out.lines == 1,
"(string) Check for expected number of stdout lines");
ok (chld_err.lines == 0,
"(string) Check for expected number of stderr lines");
ok (strcmp (chld_out.line[0], "this is test one") == 0,
"(string) Check for expected stdout output");
ok (result == 0, "(string) Checking exit code");
result = cmd_run(command, &chld_out, &chld_err, 0);
ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines");
ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines");
ok(strcmp(chld_out.line[0], "this is test one") == 0, "(string) Check for expected stdout output");
ok(result == 0, "(string) Checking exit code");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
ok (chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok (chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok (result == UNSET, "(initialised) Checking exit code is reset");
ok(chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok(chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok(result == UNSET, "(initialised) Checking exit code is reset");
/* Pass linefeeds via parameters through - those should be evaluated by echo to give multi line output */
command_line[0] = strdup("/bin/echo");
command_line[1] = strdup("this is a test via echo\nline two\nit's line 3");
command_line[2] = strdup("and (note space between '3' and 'and') $$ will not get evaluated");
result = cmd_run_array (command_line, &chld_out, &chld_err, 0);
ok (chld_out.lines == 3,
"(array) Check for expected number of stdout lines");
ok (chld_err.lines == 0,
"(array) Check for expected number of stderr lines");
ok (strcmp (chld_out.line[0], "this is a test via echo") == 0,
"(array) Check line 1 for expected stdout output");
ok (strcmp (chld_out.line[1], "line two") == 0,
"(array) Check line 2 for expected stdout output");
ok (strcmp (chld_out.line[2], "it's line 3 and (note space between '3' and 'and') $$ will not get evaluated") == 0,
"(array) Check line 3 for expected stdout output");
ok (result == 0, "(array) Checking exit code");
result = cmd_run_array(command_line, &chld_out, &chld_err, 0);
ok(chld_out.lines == 3, "(array) Check for expected number of stdout lines");
ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines");
ok(strcmp(chld_out.line[0], "this is a test via echo") == 0, "(array) Check line 1 for expected stdout output");
ok(strcmp(chld_out.line[1], "line two") == 0, "(array) Check line 2 for expected stdout output");
ok(strcmp(chld_out.line[2], "it's line 3 and (note space between '3' and 'and') $$ will not get evaluated") == 0,
"(array) Check line 3 for expected stdout output");
ok(result == 0, "(array) Checking exit code");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
ok (chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok (chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok (result == UNSET, "(initialised) Checking exit code is reset");
ok(chld_out.lines == 0, "(initialised) Checking stdout is reset");
ok(chld_err.lines == 0, "(initialised) Checking stderr is reset");
ok(result == UNSET, "(initialised) Checking exit code is reset");
command = (char *)malloc(COMMAND_LINE);
strcpy(command, "/bin/echo3456 non-existent command");
result = cmd_run (command, &chld_out, &chld_err, 0);
ok (chld_out.lines == 0,
"Non existent command, so no output");
ok (chld_err.lines == 0,
"No stderr either");
ok (result == 3, "Get return code 3 (?) for non-existent command");
result = cmd_run(command, &chld_out, &chld_err, 0);
ok(chld_out.lines == 0, "Non existent command, so no output");
ok(chld_err.lines == 0, "No stderr either");
ok(result == 3, "Get return code 3 (?) for non-existent command");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
command = (char *)malloc(COMMAND_LINE);
strcpy(command, "/bin/sh non-existent-file");
result = cmd_run (command, &chld_out, &chld_err, 0);
ok (chld_out.lines == 0,
"/bin/sh returns no stdout when file is missing...");
ok (chld_err.lines == 1,
"...but does give an error line");
ok (strstr(chld_err.line[0],"non-existent-file") != NULL, "And missing filename is in error message");
ok (result != 0, "Get non-zero return code from /bin/sh");
result = cmd_run(command, &chld_out, &chld_err, 0);
ok(chld_out.lines == 0, "/bin/sh returns no stdout when file is missing...");
ok(chld_err.lines == 1, "...but does give an error line");
ok(strstr(chld_err.line[0], "non-existent-file") != NULL, "And missing filename is in error message");
ok(result != 0, "Get non-zero return code from /bin/sh");
/* ensure everything is empty again */
result = UNSET;
command = (char *)malloc(COMMAND_LINE);
strcpy(command, "/bin/sh -c 'exit 7'");
result = cmd_run (command, NULL, NULL, 0);
ok (result == 7, "Get return code 7 from /bin/sh");
strcpy(command, "/bin/sh -c 'exit 7'");
result = cmd_run(command, NULL, NULL, 0);
ok(result == 7, "Get return code 7 from /bin/sh");
/* ensure everything is empty again */
memset (&chld_out, 0, sizeof (output));
memset (&chld_err, 0, sizeof (output));
memset(&chld_out, 0, sizeof(output));
memset(&chld_err, 0, sizeof(output));
result = UNSET;
command = (char *)malloc(COMMAND_LINE);
strcpy(command, "/bin/non-existent-command");
result = cmd_run (command, &chld_out, &chld_err, 0);
result = cmd_run(command, &chld_out, &chld_err, 0);
ok (chld_out.lines == 0,
"/bin/non-existent-command returns no stdout...");
ok (chld_err.lines == 0,
"...and no stderr output either");
ok (result == 3, "Get return code 3 = UNKNOWN when command does not exist");
ok(chld_out.lines == 0, "/bin/non-existent-command returns no stdout...");
ok(chld_err.lines == 0, "...and no stderr output either");
ok(result == 3, "Get return code 3 = UNKNOWN when command does not exist");
return exit_status ();
return exit_status();
}

View file

@ -1,36 +1,31 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_disk.h"
#include "tap.h"
#include "regex.h"
void np_test_mount_entry_regex (struct mount_entry *dummy_mount_list,
char *regstr, int cflags, int expect,
char *desc);
void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc);
int
main (int argc, char **argv)
{
struct name_list *exclude_filesystem=NULL;
struct name_list *exclude_fstype=NULL;
int main(int argc, char **argv) {
struct name_list *exclude_filesystem = NULL;
struct name_list *exclude_fstype = NULL;
struct name_list *dummy_mountlist = NULL;
struct name_list *temp_name;
struct parameter_list *paths = NULL;
@ -44,19 +39,19 @@ main (int argc, char **argv)
plan_tests(33);
ok( np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list");
ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list");
np_add_name(&exclude_filesystem, "/var/log");
ok( np_find_name(exclude_filesystem, "/var/log") == true, "is in list now");
ok( np_find_name(exclude_filesystem, "/home") == false, "/home not in list");
ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now");
ok(np_find_name(exclude_filesystem, "/home") == false, "/home not in list");
np_add_name(&exclude_filesystem, "/home");
ok( np_find_name(exclude_filesystem, "/home") == true, "is in list now");
ok( np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list");
ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now");
ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list");
ok( np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list");
ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list");
np_add_name(&exclude_fstype, "iso9660");
ok( np_find_name(exclude_fstype, "iso9660") == true, "is in list now");
ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now");
ok( np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables");
ok(np_find_name(exclude_filesystem, "iso9660") == false, "Make sure no clashing in variables");
/*
for (temp_name = exclude_filesystem; temp_name; temp_name = temp_name->next) {
@ -64,55 +59,35 @@ main (int argc, char **argv)
}
*/
me = (struct mount_entry *) malloc(sizeof *me);
me = (struct mount_entry *)malloc(sizeof *me);
me->me_devname = strdup("/dev/c0t0d0s0");
me->me_mountdir = strdup("/");
*mtail = me;
mtail = &me->me_next;
me = (struct mount_entry *) malloc(sizeof *me);
me = (struct mount_entry *)malloc(sizeof *me);
me->me_devname = strdup("/dev/c1t0d1s0");
me->me_mountdir = strdup("/var");
*mtail = me;
mtail = &me->me_next;
me = (struct mount_entry *) malloc(sizeof *me);
me = (struct mount_entry *)malloc(sizeof *me);
me->me_devname = strdup("/dev/c2t0d0s0");
me->me_mountdir = strdup("/home");
*mtail = me;
mtail = &me->me_next;
np_test_mount_entry_regex(dummy_mount_list, strdup("/"),
cflags, 3, strdup("a"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"),
cflags, 3,strdup("regex on dev names:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"),
cflags, 0,
strdup("regex on non existent dev/path:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"),
cflags | REG_ICASE,0,
strdup("regi on non existent dev/path:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"),
cflags, 3,
strdup("partial devname regex match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"),
cflags, 1,
strdup("partial devname regex match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"),
cflags | REG_ICASE, 1,
strdup("partial devname regi match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("home"),
cflags, 1,
strdup("partial pathname regex match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"),
cflags | REG_ICASE, 1,
strdup("partial pathname regi match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"),
cflags, 2,
strdup("grouped regex pathname match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"),
cflags | REG_ICASE, 2,
strdup("grouped regi pathname match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:"));
np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:"));
np_add_parameter(&paths, "/home/groups");
np_add_parameter(&paths, "/var");
@ -124,20 +99,20 @@ main (int argc, char **argv)
for (p = paths; p; p = p->name_next) {
struct mount_entry *temp_me;
temp_me = p->best_match;
if (! strcmp(p->name, "/home/groups")) {
ok( temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home");
} else if (! strcmp(p->name, "/var")) {
ok( temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var");
} else if (! strcmp(p->name, "/tmp")) {
ok( temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /");
} else if (! strcmp(p->name, "/home/tonvoon")) {
ok( temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home");
} else if (! strcmp(p->name, "/dev/c2t0d0s0")) {
ok( temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0");
if (!strcmp(p->name, "/home/groups")) {
ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home");
} else if (!strcmp(p->name, "/var")) {
ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var");
} else if (!strcmp(p->name, "/tmp")) {
ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /");
} else if (!strcmp(p->name, "/home/tonvoon")) {
ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home");
} else if (!strcmp(p->name, "/dev/c2t0d0s0")) {
ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0");
}
}
paths = NULL; /* Bad boy - should free, but this is a test suite */
paths = NULL; /* Bad boy - should free, but this is a test suite */
np_add_parameter(&paths, "/home/groups");
np_add_parameter(&paths, "/var");
np_add_parameter(&paths, "/tmp");
@ -146,31 +121,31 @@ main (int argc, char **argv)
np_set_best_match(paths, dummy_mount_list, true);
for (p = paths; p; p = p->name_next) {
if (! strcmp(p->name, "/home/groups")) {
ok( ! p->best_match , "/home/groups correctly not found");
} else if (! strcmp(p->name, "/var")) {
ok( p->best_match, "/var found");
} else if (! strcmp(p->name, "/tmp")) {
ok(! p->best_match, "/tmp correctly not found");
} else if (! strcmp(p->name, "/home/tonvoon")) {
ok(! p->best_match, "/home/tonvoon not found");
} else if (! strcmp(p->name, "/home")) {
ok( p->best_match, "/home found");
if (!strcmp(p->name, "/home/groups")) {
ok(!p->best_match, "/home/groups correctly not found");
} else if (!strcmp(p->name, "/var")) {
ok(p->best_match, "/var found");
} else if (!strcmp(p->name, "/tmp")) {
ok(!p->best_match, "/tmp correctly not found");
} else if (!strcmp(p->name, "/home/tonvoon")) {
ok(!p->best_match, "/home/tonvoon not found");
} else if (!strcmp(p->name, "/home")) {
ok(p->best_match, "/home found");
}
}
/* test deleting first element in paths */
paths = np_del_parameter(paths, NULL);
for (p = paths; p; p = p->name_next) {
if (! strcmp(p->name, "/home/groups"))
if (!strcmp(p->name, "/home/groups"))
found = 1;
}
ok(found == 0, "first element successfully deleted");
found = 0;
p=paths;
p = paths;
while (p) {
if (! strcmp(p->name, "/tmp"))
if (!strcmp(p->name, "/tmp"))
p = np_del_parameter(p, prev);
else {
prev = p;
@ -179,7 +154,7 @@ main (int argc, char **argv)
}
for (p = paths; p; p = p->name_next) {
if (! strcmp(p->name, "/tmp"))
if (!strcmp(p->name, "/tmp"))
found = 1;
if (p->name_next)
prev = p;
@ -190,7 +165,7 @@ main (int argc, char **argv)
p = np_del_parameter(last, prev);
for (p = paths; p; p = p->name_next) {
if (! strcmp(p->name, "/home"))
if (!strcmp(p->name, "/home"))
found = 1;
last = p;
count++;
@ -198,27 +173,20 @@ main (int argc, char **argv)
ok(found == 0, "last (/home) element successfully deleted");
ok(count == 2, "two elements remaining");
return exit_status();
}
void
np_test_mount_entry_regex (struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc)
{
void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) {
int matches = 0;
regex_t re;
struct mount_entry *me;
if (regcomp(&re,regstr, cflags) == 0) {
for (me = dummy_mount_list; me; me= me->me_next) {
if(np_regex_match_mount_entry(me,&re))
if (regcomp(&re, regstr, cflags) == 0) {
for (me = dummy_mount_list; me; me = me->me_next) {
if (np_regex_match_mount_entry(me, &re))
matches++;
}
ok( matches == expect,
"%s '%s' matched %i/3 entries. ok: %i/3",
desc, regstr, expect, matches);
ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches);
} else
ok ( false, "regex '%s' not compilable", regstr);
ok(false, "regex '%s' not compilable", regstr);
}

BIN
lib/tests/test_generic_output Executable file

Binary file not shown.

View file

@ -1,20 +1,20 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_base.h"
@ -29,81 +29,93 @@ void my_free(char *string) {
}
}
char*
list2str(np_arg_list *optlst)
{
char *optstr=NULL;
char *list2str(np_arg_list *optlst) {
char *optstr = NULL;
np_arg_list *optltmp;
/* Put everything as a space-separated string */
asprintf(&optstr, "");
while (optlst) {
asprintf(&optstr, "%s%s ", optstr, optlst->arg);
optltmp=optlst;
optlst=optlst->next;
optltmp = optlst;
optlst = optlst->next;
free(optltmp);
}
/* Strip last whitespace */
if (strlen(optstr)>1) optstr[strlen(optstr)-1]='\0';
if (strlen(optstr) > 1)
optstr[strlen(optstr) - 1] = '\0';
return optstr;
}
int
main (int argc, char **argv)
{
char *optstr=NULL;
int main(int argc, char **argv) {
char *optstr = NULL;
plan_tests(12);
optstr=list2str(np_get_defaults("section@./config-tiny.ini", "check_disk"));
ok( !strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "config-tiny.ini's section as expected");
optstr = list2str(np_get_defaults("section@./config-tiny.ini", "check_disk"));
ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "config-tiny.ini's section as expected");
my_free(optstr);
optstr=list2str(np_get_defaults("@./config-tiny.ini", "section"));
ok( !strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "Used default section name, without specific");
optstr = list2str(np_get_defaults("@./config-tiny.ini", "section"));
ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "Used default section name, without specific");
my_free(optstr);
optstr=list2str(np_get_defaults("Section Two@./config-tiny.ini", "check_disk"));
ok( !strcmp(optstr, "--something else=blah --remove=whitespace"), "config-tiny.ini's Section Two as expected");
optstr = list2str(np_get_defaults("Section Two@./config-tiny.ini", "check_disk"));
ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), "config-tiny.ini's Section Two as expected");
my_free(optstr);
optstr=list2str(np_get_defaults("/path/to/file.txt@./config-tiny.ini", "check_disk"));
ok( !strcmp(optstr, "--this=that"), "config-tiny.ini's filename as section name");
optstr = list2str(np_get_defaults("/path/to/file.txt@./config-tiny.ini", "check_disk"));
ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's filename as section name");
my_free(optstr);
optstr=list2str(np_get_defaults("section2@./config-tiny.ini", "check_disk"));
ok( !strcmp(optstr, "--this=that"), "config-tiny.ini's section2 with whitespace before section name");
optstr = list2str(np_get_defaults("section2@./config-tiny.ini", "check_disk"));
ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's section2 with whitespace before section name");
my_free(optstr);
optstr=list2str(np_get_defaults("section3@./config-tiny.ini", "check_disk"));
ok( !strcmp(optstr, "--this=that"), "config-tiny.ini's section3 with whitespace after section name");
optstr = list2str(np_get_defaults("section3@./config-tiny.ini", "check_disk"));
ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's section3 with whitespace after section name");
my_free(optstr);
optstr=list2str(np_get_defaults("check_mysql@./plugin.ini", "check_disk"));
ok( !strcmp(optstr, "--username=operator --password=secret"), "plugin.ini's check_mysql as expected");
optstr = list2str(np_get_defaults("check_mysql@./plugin.ini", "check_disk"));
ok(!strcmp(optstr, "--username=operator --password=secret"), "plugin.ini's check_mysql as expected");
my_free(optstr);
optstr=list2str(np_get_defaults("check_mysql2@./plugin.ini", "check_disk"));
ok( !strcmp(optstr, "-u=admin -p=secret"), "plugin.ini's check_mysql2 as expected");
optstr = list2str(np_get_defaults("check_mysql2@./plugin.ini", "check_disk"));
ok(!strcmp(optstr, "-u=admin -p=secret"), "plugin.ini's check_mysql2 as expected");
my_free(optstr);
optstr=list2str(np_get_defaults("check space_and_flags@./plugin.ini", "check_disk"));
ok( !strcmp(optstr, "--foo=bar -a -b --bar"), "plugin.ini space in stanza and flag arguments");
optstr = list2str(np_get_defaults("check space_and_flags@./plugin.ini", "check_disk"));
ok(!strcmp(optstr, "--foo=bar -a -b --bar"), "plugin.ini space in stanza and flag arguments");
my_free(optstr);
optstr=list2str(np_get_defaults("Section Two@./config-dos.ini", "check_disk"));
ok( !strcmp(optstr, "--something else=blah --remove=whitespace"), "config-dos.ini's Section Two as expected");
optstr = list2str(np_get_defaults("Section Two@./config-dos.ini", "check_disk"));
ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), "config-dos.ini's Section Two as expected");
my_free(optstr);
optstr=list2str(np_get_defaults("section_twice@./plugin.ini", "check_disk"));
ok( !strcmp(optstr, "--foo=bar --bar=foo"), "plugin.ini's section_twice defined twice in the file");
optstr = list2str(np_get_defaults("section_twice@./plugin.ini", "check_disk"));
ok(!strcmp(optstr, "--foo=bar --bar=foo"), "plugin.ini's section_twice defined twice in the file");
my_free(optstr);
optstr=list2str(np_get_defaults("tcp_long_lines@plugins.ini", "check_tcp"));
ok( !strcmp(optstr, "--escape --send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda --expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda --jail"), "Long options");
optstr = list2str(np_get_defaults("tcp_long_lines@plugins.ini", "check_tcp"));
ok(!strcmp(optstr, "--escape --send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar "
"BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda "
"yadda yadda Foo bar BAZ yadda yadda yadda Foo "
"bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ "
"yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda --expect=Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ "
"yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo "
"bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda "
"yadda yadda Foo bar BAZ yadda yadda yadda Foo "
"bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ "
"yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo "
"bar BAZ yadda yadda yadda --jail"),
"Long options");
my_free(optstr);
return exit_status();
}

View file

@ -1,26 +1,24 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "parse_ini.h"
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
/*
* This is for testing arguments expected to die.
@ -30,4 +28,3 @@ main (int argc, char **argv)
return 0;
}

View file

@ -1,19 +1,19 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
#include "common.h"
#include "utils_base.h"
@ -40,23 +40,24 @@ void my_free(int *argc, char **newargv, char **argv) {
#else
void my_free(int *argc, char **newargv, char **argv) {
/* Free stuff (and print while we're at it) */
int i, freeflag=1;
printf (" Arg(%i): ", *argc+1);
printf ("'%s' ", newargv[0]);
for (i=1; i<*argc; i++) {
printf ("'%s' ", newargv[i]);
int i, freeflag = 1;
printf(" Arg(%i): ", *argc + 1);
printf("'%s' ", newargv[0]);
for (i = 1; i < *argc; i++) {
printf("'%s' ", newargv[i]);
/* Stop freeing when we get to the start of the original array */
if (freeflag) {
if (newargv[i] == argv[1])
freeflag=0;
freeflag = 0;
else
free(newargv[i]);
}
}
printf ("\n");
printf("\n");
/* Free only if it's a different array */
if (newargv != argv) free(newargv);
*argc=0;
if (newargv != argv)
free(newargv);
*argc = 0;
}
#endif
@ -67,9 +68,10 @@ int array_diff(int i1, char **a1, int i2, char **a2) {
printf(" Argument count doesn't match!\n");
return 0;
}
for (i=0; i<=i1; i++) {
if (a1[i]==NULL && a2[i]==NULL) continue;
if (a1[i]==NULL || a2[i]==NULL) {
for (i = 0; i <= i1; i++) {
if (a1[i] == NULL && a2[i] == NULL)
continue;
if (a1[i] == NULL || a2[i] == NULL) {
printf(" Argument # %i null in one array!\n", i);
return 0;
}
@ -81,59 +83,58 @@ int array_diff(int i1, char **a1, int i2, char **a2) {
return 1;
}
int
main (int argc, char **argv)
{
char **argv_new=NULL;
int main(int argc, char **argv) {
char **argv_new = NULL;
int i, argc_test;
plan_tests(5);
{
char *argv_test[] = {"prog_name", (char *) NULL};
argc_test=1;
char *argv_known[] = {"prog_name", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", (char *)NULL};
argc_test = 1;
char *argv_known[] = {"prog_name", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 1, argv_known), "No opts, returns correct argv/argc");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "arg1", "--arg2=val1", "--arg3", "val2", (char *) NULL};
argc_test=5;
char *argv_known[] = {"prog_name", "arg1", "--arg2=val1", "--arg3", "val2", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "arg1", "--arg2=val1", "--arg3", "val2", (char *)NULL};
argc_test = 5;
char *argv_known[] = {"prog_name", "arg1", "--arg2=val1", "--arg3", "val2", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 5, argv_known), "No extra opts, verbatim copy of argv");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "--extra-opts=@./config-opts.ini", (char *) NULL};
argc_test=2;
char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "--extra-opts=@./config-opts.ini", (char *)NULL};
argc_test = 2;
char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts using default section");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", "sect2@./config-opts.ini", (char *) NULL};
argc_test=4;
char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", "sect2@./config-opts.ini", (char *)NULL};
argc_test = 4;
char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts specified twice");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "--arg1=val1", "--extra-opts=@./config-opts.ini", "--extra-opts", "sect1@./config-opts.ini", "--arg2", (char *) NULL};
argc_test=6;
char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", "--one=two", "--arg1=val1", "--arg2", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "--arg1=val1", "--extra-opts=@./config-opts.ini", "--extra-opts", "sect1@./config-opts.ini",
"--arg2", (char *)NULL};
argc_test = 6;
char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", "--one=two",
"--arg1=val1", "--arg2", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 7, argv_known), "twice extra opts using two sections");
my_free(&argc_test, argv_new, argv_test);
}
return exit_status();
}

View file

@ -1,19 +1,19 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
#include "common.h"
#include "utils_base.h"
@ -23,23 +23,24 @@
void my_free(int *argc, char **newargv, char **argv) {
/* Free stuff (and print while we're at it) */
int i, freeflag=1;
printf (" Arg(%i): ", *argc+1);
printf ("'%s' ", newargv[0]);
for (i=1; i<*argc; i++) {
printf ("'%s' ", newargv[i]);
int i, freeflag = 1;
printf(" Arg(%i): ", *argc + 1);
printf("'%s' ", newargv[0]);
for (i = 1; i < *argc; i++) {
printf("'%s' ", newargv[i]);
/* Stop freeing when we get to the start of the original array */
if (freeflag) {
if (newargv[i] == argv[1])
freeflag=0;
freeflag = 0;
else
free(newargv[i]);
}
}
printf ("\n");
printf("\n");
/* Free only if it's a different array */
if (newargv != argv) free(newargv);
*argc=0;
if (newargv != argv)
free(newargv);
*argc = 0;
}
int array_diff(int i1, char **a1, int i2, char **a2) {
@ -49,9 +50,10 @@ int array_diff(int i1, char **a1, int i2, char **a2) {
printf(" Argument count doesn't match!\n");
return 0;
}
for (i=0; i<=i1; i++) {
if (a1[i]==NULL && a2[i]==NULL) continue;
if (a1[i]==NULL || a2[i]==NULL) {
for (i = 0; i <= i1; i++) {
if (a1[i] == NULL && a2[i] == NULL)
continue;
if (a1[i] == NULL || a2[i] == NULL) {
printf(" Argument # %i null in one array!\n", i);
return 0;
}
@ -63,59 +65,77 @@ int array_diff(int i1, char **a1, int i2, char **a2) {
return 1;
}
int
main (int argc, char **argv)
{
char **argv_new=NULL;
int main(int argc, char **argv) {
char **argv_new = NULL;
int i, argc_test;
plan_tests(5);
{
char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "--arg3", "val2", (char *) NULL};
argc_test=5;
char *argv_known[] = {"prog_name", "--foo=bar", "arg1", "--arg3", "val2", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "--arg3", "val2", (char *)NULL};
argc_test = 5;
char *argv_known[] = {"prog_name", "--foo=bar", "arg1", "--arg3", "val2", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 5, argv_known), "Default section 1");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "--extra-opts", (char *) NULL};
argc_test=2;
char *argv_known[] = {"prog_name", "--foo=bar", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "--extra-opts", (char *)NULL};
argc_test = 2;
char *argv_known[] = {"prog_name", "--foo=bar", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 2, argv_known), "Default section 2");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "arg1", "--extra-opts=section1", "--arg3", "val2", (char *) NULL};
argc_test=5;
char *argv_known[] = {"prog_name", "--foobar=baz", "arg1", "--arg3", "val2", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "arg1", "--extra-opts=section1", "--arg3", "val2", (char *)NULL};
argc_test = 5;
char *argv_known[] = {"prog_name", "--foobar=baz", "arg1", "--arg3", "val2", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 5, argv_known), "Default section 3");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "-arg3", "val2", (char *) NULL};
argc_test=5;
char *argv_known[] = {"prog_name", "--foo=bar", "arg1", "-arg3", "val2", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "-arg3", "val2", (char *)NULL};
argc_test = 5;
char *argv_known[] = {"prog_name", "--foo=bar", "arg1", "-arg3", "val2", (char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_disk");
ok(array_diff(argc_test, argv_new, 5, argv_known), "Default section 4");
my_free(&argc_test, argv_new, argv_test);
}
{
char *argv_test[] = {"check_tcp", "--extra-opts", "--extra-opts=tcp_long_lines", (char *) NULL};
argc_test=3;
char *argv_known[] = {"check_tcp", "--timeout=10", "--escape", "--send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda", "--expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda", "--jail", (char *) NULL};
argv_new=np_extra_opts(&argc_test, argv_test, "check_tcp");
char *argv_test[] = {"check_tcp", "--extra-opts", "--extra-opts=tcp_long_lines", (char *)NULL};
argc_test = 3;
char *argv_known[] = {
"check_tcp",
"--timeout=10",
"--escape",
"--send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda "
"yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ "
"yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda "
"yadda yadda Foo bar "
"BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda",
"--expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ yadda "
"yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda "
"yadda Foo bar BAZ "
"yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda "
"yadda yadda Foo bar "
"BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ "
"yadda yadda yadda Foo "
"bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda",
"--jail",
(char *)NULL};
argv_new = np_extra_opts(&argc_test, argv_test, "check_tcp");
ok(array_diff(argc_test, argv_new, 6, argv_known), "Long lines test");
my_free(&argc_test, argv_new, argv_test);
}
return exit_status();
}

View file

@ -1,31 +1,28 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*****************************************************************************/
#include "extra_opts.h"
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
/*
* This is for testing arguments expected to die.
*/
argv=np_extra_opts(&argc, argv, argv[0]);
argv = np_extra_opts(&argc, argv, argv[0]);
return 0;
}

View file

@ -1,34 +1,32 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_tcp.h"
#include "tap.h"
int
main(void)
{
int main(void) {
char **server_expect;
int server_expect_count = 3;
plan_tests(9);
server_expect = malloc(sizeof(char*) * server_expect_count);
server_expect = malloc(sizeof(char *) * server_expect_count);
server_expect[0] = strdup("AA");
server_expect[1] = strdup("bb");
@ -42,17 +40,13 @@ main(void)
"Test matching any string at the beginning (substring match)");
ok(np_expect_match("XX bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE,
"Test with strings not matching at the beginning");
ok(np_expect_match("XX CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE,
"Test matching any string");
ok(np_expect_match("XX", server_expect, server_expect_count, 0) == NP_MATCH_RETRY,
"Test not matching any string");
ok(np_expect_match("XX CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE, "Test matching any string");
ok(np_expect_match("XX", server_expect, server_expect_count, 0) == NP_MATCH_RETRY, "Test not matching any string");
ok(np_expect_match("XX AA bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_SUCCESS,
"Test matching all strings");
ok(np_expect_match("XX bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY,
"Test not matching all strings");
ok(np_expect_match("XX bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY, "Test not matching all strings");
ok(np_expect_match("XX XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY,
"Test not matching any string (testing all)");
return exit_status();
}

View file

@ -1,20 +1,20 @@
/*****************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_base.h"
@ -27,331 +27,323 @@
#include "utils_base.c"
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
char state_path[1024];
range *range;
double temp;
range *range;
double temp;
thresholds *thresholds = NULL;
int i, rc;
char *temp_string;
int i, rc;
char *temp_string;
state_key *temp_state_key = NULL;
state_data *temp_state_data;
time_t current_time;
time_t current_time;
plan_tests(185);
ok( this_monitoring_plugin==NULL, "monitoring_plugin not initialised");
ok(this_monitoring_plugin == NULL, "monitoring_plugin not initialised");
np_init( "check_test", argc, argv );
np_init("check_test", argc, argv);
ok( this_monitoring_plugin!=NULL, "monitoring_plugin now initialised");
ok( !strcmp(this_monitoring_plugin->plugin_name, "check_test"), "plugin name initialised" );
ok(this_monitoring_plugin != NULL, "monitoring_plugin now initialised");
ok(!strcmp(this_monitoring_plugin->plugin_name, "check_test"), "plugin name initialised");
ok( this_monitoring_plugin->argc==argc, "Argc set" );
ok( this_monitoring_plugin->argv==argv, "Argv set" );
ok(this_monitoring_plugin->argc == argc, "Argc set");
ok(this_monitoring_plugin->argv == argv, "Argv set");
np_set_args(0,0);
np_set_args(0, 0);
ok( this_monitoring_plugin->argc==0, "argc changed" );
ok( this_monitoring_plugin->argv==0, "argv changed" );
ok(this_monitoring_plugin->argc == 0, "argc changed");
ok(this_monitoring_plugin->argv == 0, "argv changed");
np_set_args(argc, argv);
range = parse_range_string("6");
ok( range != NULL, "'6' is valid range");
ok( range->start == 0, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 6, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok(range != NULL, "'6' is valid range");
ok(range->start == 0, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 6, "End correct");
ok(range->end_infinity == false, "Not using infinity");
free(range);
range = parse_range_string("1:12%%");
ok( range != NULL, "'1:12%%' is valid - percentages are ignored");
ok( range->start == 1, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 12, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok(range != NULL, "'1:12%%' is valid - percentages are ignored");
ok(range->start == 1, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 12, "End correct");
ok(range->end_infinity == false, "Not using infinity");
free(range);
range = parse_range_string("-7:23");
ok( range != NULL, "'-7:23' is valid range");
ok( range->start == -7, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 23, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok(range != NULL, "'-7:23' is valid range");
ok(range->start == -7, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 23, "End correct");
ok(range->end_infinity == false, "Not using infinity");
free(range);
range = parse_range_string(":5.75");
ok( range != NULL, "':5.75' is valid range");
ok( range->start == 0, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 5.75, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok(range != NULL, "':5.75' is valid range");
ok(range->start == 0, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 5.75, "End correct");
ok(range->end_infinity == false, "Not using infinity");
free(range);
range = parse_range_string("~:-95.99");
ok( range != NULL, "~:-95.99' is valid range");
ok( range->start_infinity == true, "Using negative infinity");
ok( range->end == -95.99, "End correct (with rounding errors)");
ok( range->end_infinity == false, "Not using infinity");
ok(range != NULL, "~:-95.99' is valid range");
ok(range->start_infinity == true, "Using negative infinity");
ok(range->end == -95.99, "End correct (with rounding errors)");
ok(range->end_infinity == false, "Not using infinity");
free(range);
range = parse_range_string("12345678901234567890:");
temp = atof("12345678901234567890"); /* Can't just use this because number too large */
ok( range != NULL, "'12345678901234567890:' is valid range");
ok( range->start == temp, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end_infinity == true, "Using infinity");
temp = atof("12345678901234567890"); /* Can't just use this because number too large */
ok(range != NULL, "'12345678901234567890:' is valid range");
ok(range->start == temp, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end_infinity == true, "Using infinity");
/* Cannot do a "-1" on temp, as it appears to be same value */
ok( check_range(temp/1.1, range) == true, "12345678901234567890/1.1 - alert");
ok( check_range(temp, range) == false, "12345678901234567890 - no alert");
ok( check_range(temp*2, range) == false, "12345678901234567890*2 - no alert");
ok(check_range(temp / 1.1, range) == true, "12345678901234567890/1.1 - alert");
ok(check_range(temp, range) == false, "12345678901234567890 - no alert");
ok(check_range(temp * 2, range) == false, "12345678901234567890*2 - no alert");
free(range);
range = parse_range_string("~:0");
ok( range != NULL, "'~:0' is valid range");
ok( range->start_infinity == true, "Using negative infinity");
ok( range->end == 0, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok( range->alert_on == OUTSIDE, "Will alert on outside of this range");
ok( check_range(0.5, range) == true, "0.5 - alert");
ok( check_range(-10, range) == false, "-10 - no alert");
ok( check_range(0, range) == false, "0 - no alert");
ok(range != NULL, "'~:0' is valid range");
ok(range->start_infinity == true, "Using negative infinity");
ok(range->end == 0, "End correct");
ok(range->end_infinity == false, "Not using infinity");
ok(range->alert_on == OUTSIDE, "Will alert on outside of this range");
ok(check_range(0.5, range) == true, "0.5 - alert");
ok(check_range(-10, range) == false, "-10 - no alert");
ok(check_range(0, range) == false, "0 - no alert");
free(range);
range = parse_range_string("@0:657.8210567");
ok( range != 0, "@0:657.8210567' is a valid range");
ok( range->start == 0, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 657.8210567, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok( range->alert_on == INSIDE, "Will alert on inside of this range" );
ok( check_range(32.88, range) == true, "32.88 - alert");
ok( check_range(-2, range) == false, "-2 - no alert");
ok( check_range(657.8210567, range) == true, "657.8210567 - alert");
ok( check_range(0, range) == true, "0 - alert");
ok(range != 0, "@0:657.8210567' is a valid range");
ok(range->start == 0, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 657.8210567, "End correct");
ok(range->end_infinity == false, "Not using infinity");
ok(range->alert_on == INSIDE, "Will alert on inside of this range");
ok(check_range(32.88, range) == true, "32.88 - alert");
ok(check_range(-2, range) == false, "-2 - no alert");
ok(check_range(657.8210567, range) == true, "657.8210567 - alert");
ok(check_range(0, range) == true, "0 - alert");
free(range);
range = parse_range_string("@1:1");
ok( range != NULL, "'@1:1' is a valid range");
ok( range->start == 1, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 1, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok( range->alert_on == INSIDE, "Will alert on inside of this range" );
ok( check_range(0.5, range) == false, "0.5 - no alert");
ok( check_range(1, range) == true, "1 - alert");
ok( check_range(5.2, range) == false, "5.2 - no alert");
ok(range != NULL, "'@1:1' is a valid range");
ok(range->start == 1, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 1, "End correct");
ok(range->end_infinity == false, "Not using infinity");
ok(range->alert_on == INSIDE, "Will alert on inside of this range");
ok(check_range(0.5, range) == false, "0.5 - no alert");
ok(check_range(1, range) == true, "1 - alert");
ok(check_range(5.2, range) == false, "5.2 - no alert");
free(range);
range = parse_range_string("1:1");
ok( range != NULL, "'1:1' is a valid range");
ok( range->start == 1, "Start correct");
ok( range->start_infinity == false, "Not using negative infinity");
ok( range->end == 1, "End correct");
ok( range->end_infinity == false, "Not using infinity");
ok( check_range(0.5, range) == true, "0.5 - alert");
ok( check_range(1, range) == false, "1 - no alert");
ok( check_range(5.2, range) == true, "5.2 - alert");
ok(range != NULL, "'1:1' is a valid range");
ok(range->start == 1, "Start correct");
ok(range->start_infinity == false, "Not using negative infinity");
ok(range->end == 1, "End correct");
ok(range->end_infinity == false, "Not using infinity");
ok(check_range(0.5, range) == true, "0.5 - alert");
ok(check_range(1, range) == false, "1 - no alert");
ok(check_range(5.2, range) == true, "5.2 - alert");
free(range);
range = parse_range_string("2:1");
ok( range == NULL, "'2:1' rejected");
ok(range == NULL, "'2:1' rejected");
rc = _set_thresholds(&thresholds, NULL, NULL);
ok( rc == 0, "Thresholds (NULL, NULL) set");
ok( thresholds->warning == NULL, "Warning not set");
ok( thresholds->critical == NULL, "Critical not set");
ok(rc == 0, "Thresholds (NULL, NULL) set");
ok(thresholds->warning == NULL, "Warning not set");
ok(thresholds->critical == NULL, "Critical not set");
rc = _set_thresholds(&thresholds, NULL, "80");
ok( rc == 0, "Thresholds (NULL, '80') set");
ok( thresholds->warning == NULL, "Warning not set");
ok( thresholds->critical->end == 80, "Critical set correctly");
ok(rc == 0, "Thresholds (NULL, '80') set");
ok(thresholds->warning == NULL, "Warning not set");
ok(thresholds->critical->end == 80, "Critical set correctly");
rc = _set_thresholds(&thresholds, "5:33", NULL);
ok( rc == 0, "Thresholds ('5:33', NULL) set");
ok( thresholds->warning->start == 5, "Warning start set");
ok( thresholds->warning->end == 33, "Warning end set");
ok( thresholds->critical == NULL, "Critical not set");
ok(rc == 0, "Thresholds ('5:33', NULL) set");
ok(thresholds->warning->start == 5, "Warning start set");
ok(thresholds->warning->end == 33, "Warning end set");
ok(thresholds->critical == NULL, "Critical not set");
rc = _set_thresholds(&thresholds, "30", "60");
ok( rc == 0, "Thresholds ('30', '60') set");
ok( thresholds->warning->end == 30, "Warning set correctly");
ok( thresholds->critical->end == 60, "Critical set correctly");
ok( get_status(15.3, thresholds) == STATE_OK, "15.3 - ok");
ok( get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning");
ok( get_status(69, thresholds) == STATE_CRITICAL, "69 - critical");
ok(rc == 0, "Thresholds ('30', '60') set");
ok(thresholds->warning->end == 30, "Warning set correctly");
ok(thresholds->critical->end == 60, "Critical set correctly");
ok(get_status(15.3, thresholds) == STATE_OK, "15.3 - ok");
ok(get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning");
ok(get_status(69, thresholds) == STATE_CRITICAL, "69 - critical");
rc = _set_thresholds(&thresholds, "-10:-2", "-30:20");
ok( rc == 0, "Thresholds ('-30:20', '-10:-2') set");
ok( thresholds->warning->start == -10, "Warning start set correctly");
ok( thresholds->warning->end == -2, "Warning end set correctly");
ok( thresholds->critical->start == -30, "Critical start set correctly");
ok( thresholds->critical->end == 20, "Critical end set correctly");
ok( get_status(-31, thresholds) == STATE_CRITICAL, "-31 - critical");
ok( get_status(-29, thresholds) == STATE_WARNING, "-29 - warning");
ok( get_status(-11, thresholds) == STATE_WARNING, "-11 - warning");
ok( get_status(-10, thresholds) == STATE_OK, "-10 - ok");
ok( get_status(-2, thresholds) == STATE_OK, "-2 - ok");
ok( get_status(-1, thresholds) == STATE_WARNING, "-1 - warning");
ok( get_status(19, thresholds) == STATE_WARNING, "19 - warning");
ok( get_status(21, thresholds) == STATE_CRITICAL, "21 - critical");
ok(rc == 0, "Thresholds ('-30:20', '-10:-2') set");
ok(thresholds->warning->start == -10, "Warning start set correctly");
ok(thresholds->warning->end == -2, "Warning end set correctly");
ok(thresholds->critical->start == -30, "Critical start set correctly");
ok(thresholds->critical->end == 20, "Critical end set correctly");
ok(get_status(-31, thresholds) == STATE_CRITICAL, "-31 - critical");
ok(get_status(-29, thresholds) == STATE_WARNING, "-29 - warning");
ok(get_status(-11, thresholds) == STATE_WARNING, "-11 - warning");
ok(get_status(-10, thresholds) == STATE_OK, "-10 - ok");
ok(get_status(-2, thresholds) == STATE_OK, "-2 - ok");
ok(get_status(-1, thresholds) == STATE_WARNING, "-1 - warning");
ok(get_status(19, thresholds) == STATE_WARNING, "19 - warning");
ok(get_status(21, thresholds) == STATE_CRITICAL, "21 - critical");
char *test;
test = np_escaped_string("bob\\n");
ok( strcmp(test, "bob\n") == 0, "bob\\n ok");
ok(strcmp(test, "bob\n") == 0, "bob\\n ok");
free(test);
test = np_escaped_string("rhuba\\rb");
ok( strcmp(test, "rhuba\rb") == 0, "rhuba\\rb okay");
ok(strcmp(test, "rhuba\rb") == 0, "rhuba\\rb okay");
free(test);
test = np_escaped_string("ba\\nge\\r");
ok( strcmp(test, "ba\nge\r") == 0, "ba\\nge\\r okay");
ok(strcmp(test, "ba\nge\r") == 0, "ba\\nge\\r okay");
free(test);
test = np_escaped_string("\\rabbi\\t");
ok( strcmp(test, "\rabbi\t") == 0, "\\rabbi\\t okay");
ok(strcmp(test, "\rabbi\t") == 0, "\\rabbi\\t okay");
free(test);
test = np_escaped_string("and\\\\or");
ok( strcmp(test, "and\\or") == 0, "and\\\\or okay");
ok(strcmp(test, "and\\or") == 0, "and\\\\or okay");
free(test);
test = np_escaped_string("bo\\gus");
ok( strcmp(test, "bogus") == 0, "bo\\gus okay");
ok(strcmp(test, "bogus") == 0, "bo\\gus okay");
free(test);
test = np_escaped_string("everything");
ok( strcmp(test, "everything") == 0, "everything okay");
ok(strcmp(test, "everything") == 0, "everything okay");
/* np_extract_ntpvar tests (23) */
test=np_extract_ntpvar("foo=bar, bar=foo, foobar=barfoo\n", "foo");
test = np_extract_ntpvar("foo=bar, bar=foo, foobar=barfoo\n", "foo");
ok(test && !strcmp(test, "bar"), "1st test as expected");
free(test);
test=np_extract_ntpvar("foo=bar,bar=foo,foobar=barfoo\n", "bar");
test = np_extract_ntpvar("foo=bar,bar=foo,foobar=barfoo\n", "bar");
ok(test && !strcmp(test, "foo"), "2nd test as expected");
free(test);
test=np_extract_ntpvar("foo=bar, bar=foo, foobar=barfoo\n", "foobar");
test = np_extract_ntpvar("foo=bar, bar=foo, foobar=barfoo\n", "foobar");
ok(test && !strcmp(test, "barfoo"), "3rd test as expected");
free(test);
test=np_extract_ntpvar("foo=bar\n", "foo");
test = np_extract_ntpvar("foo=bar\n", "foo");
ok(test && !strcmp(test, "bar"), "Single test as expected");
free(test);
test=np_extract_ntpvar("foo=bar, bar=foo, foobar=barfooi\n", "abcd");
test = np_extract_ntpvar("foo=bar, bar=foo, foobar=barfooi\n", "abcd");
ok(!test, "Key not found 1");
test=np_extract_ntpvar("foo=bar\n", "abcd");
test = np_extract_ntpvar("foo=bar\n", "abcd");
ok(!test, "Key not found 2");
test=np_extract_ntpvar("foo=bar=foobar", "foo");
test = np_extract_ntpvar("foo=bar=foobar", "foo");
ok(test && !strcmp(test, "bar=foobar"), "Strange string 1");
free(test);
test=np_extract_ntpvar("foo", "foo");
test = np_extract_ntpvar("foo", "foo");
ok(!test, "Malformed string 1");
test=np_extract_ntpvar("foo,", "foo");
test = np_extract_ntpvar("foo,", "foo");
ok(!test, "Malformed string 2");
test=np_extract_ntpvar("foo=", "foo");
test = np_extract_ntpvar("foo=", "foo");
ok(!test, "Malformed string 3");
test=np_extract_ntpvar("foo=,bar=foo", "foo");
test = np_extract_ntpvar("foo=,bar=foo", "foo");
ok(!test, "Malformed string 4");
test=np_extract_ntpvar(",foo", "foo");
test = np_extract_ntpvar(",foo", "foo");
ok(!test, "Malformed string 5");
test=np_extract_ntpvar("=foo", "foo");
test = np_extract_ntpvar("=foo", "foo");
ok(!test, "Malformed string 6");
test=np_extract_ntpvar("=foo,", "foo");
test = np_extract_ntpvar("=foo,", "foo");
ok(!test, "Malformed string 7");
test=np_extract_ntpvar(",,,", "foo");
test = np_extract_ntpvar(",,,", "foo");
ok(!test, "Malformed string 8");
test=np_extract_ntpvar("===", "foo");
test = np_extract_ntpvar("===", "foo");
ok(!test, "Malformed string 9");
test=np_extract_ntpvar(",=,=,", "foo");
test = np_extract_ntpvar(",=,=,", "foo");
ok(!test, "Malformed string 10");
test=np_extract_ntpvar("=,=,=", "foo");
test = np_extract_ntpvar("=,=,=", "foo");
ok(!test, "Malformed string 11");
test=np_extract_ntpvar(" foo=bar ,\n bar=foo\n , foobar=barfoo \n ", "foo");
test = np_extract_ntpvar(" foo=bar ,\n bar=foo\n , foobar=barfoo \n ", "foo");
ok(test && !strcmp(test, "bar"), "Random spaces and newlines 1");
free(test);
test=np_extract_ntpvar(" foo=bar ,\n bar=foo\n , foobar=barfoo \n ", "bar");
test = np_extract_ntpvar(" foo=bar ,\n bar=foo\n , foobar=barfoo \n ", "bar");
ok(test && !strcmp(test, "foo"), "Random spaces and newlines 2");
free(test);
test=np_extract_ntpvar(" foo=bar ,\n bar=foo\n , foobar=barfoo \n ", "foobar");
test = np_extract_ntpvar(" foo=bar ,\n bar=foo\n , foobar=barfoo \n ", "foobar");
ok(test && !strcmp(test, "barfoo"), "Random spaces and newlines 3");
free(test);
test=np_extract_ntpvar(" foo=bar ,\n bar\n \n= \n foo\n , foobar=barfoo \n ", "bar");
test = np_extract_ntpvar(" foo=bar ,\n bar\n \n= \n foo\n , foobar=barfoo \n ", "bar");
ok(test && !strcmp(test, "foo"), "Random spaces and newlines 4");
free(test);
test=np_extract_ntpvar("", "foo");
test = np_extract_ntpvar("", "foo");
ok(!test, "Empty string return NULL");
/* This is the result of running ./test_utils */
temp_string = (char *) _np_state_generate_key();
ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got hash with exe and no parameters" ) ||
diag( "You are probably running in wrong directory. Must run as ./test_utils" );
temp_string = (char *)_np_state_generate_key();
ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got hash with exe and no parameters") ||
diag("You are probably running in wrong directory. Must run as ./test_utils");
this_monitoring_plugin->argc=4;
this_monitoring_plugin->argc = 4;
this_monitoring_plugin->argv[0] = "./test_utils";
this_monitoring_plugin->argv[1] = "here";
this_monitoring_plugin->argv[2] = "--and";
this_monitoring_plugin->argv[3] = "now";
temp_string = (char *) _np_state_generate_key();
ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"), "Got based on expected argv" );
temp_string = (char *)_np_state_generate_key();
ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"), "Got based on expected argv");
unsetenv("MP_STATE_PATH");
temp_string = (char *) _np_state_calculate_location_prefix();
ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory" );
temp_string = (char *)_np_state_calculate_location_prefix();
ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory");
setenv("MP_STATE_PATH", "", 1);
temp_string = (char *) _np_state_calculate_location_prefix();
ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string" );
temp_string = (char *)_np_state_calculate_location_prefix();
ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string");
setenv("MP_STATE_PATH", "/usr/local/nagios/var", 1);
temp_string = (char *) _np_state_calculate_location_prefix();
ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory" );
temp_string = (char *)_np_state_calculate_location_prefix();
ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory");
ok(temp_state_key == NULL, "temp_state_key initially empty");
ok(temp_state_key==NULL, "temp_state_key initially empty");
this_monitoring_plugin->argc=1;
this_monitoring_plugin->argc = 1;
this_monitoring_plugin->argv[0] = "./test_utils";
np_enable_state(NULL, 51);
temp_state_key = this_monitoring_plugin->state;
ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
ok( !strcmp(temp_state_key->name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got generated filename" );
ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name");
ok(!strcmp(temp_state_key->name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got generated filename");
np_enable_state("allowedchars_in_keyname", 77);
temp_state_key = this_monitoring_plugin->state;
sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname", (unsigned long)geteuid());
ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
ok( !strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars" );
ok( !strcmp(temp_state_key->_filename, state_path), "Got internal filename" );
ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name");
ok(!strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars");
ok(!strcmp(temp_state_key->_filename, state_path), "Got internal filename");
/* Don't do this test just yet. Will die */
/*
@ -363,73 +355,65 @@ main (int argc, char **argv)
np_enable_state("funnykeyname", 54);
temp_state_key = this_monitoring_plugin->state;
sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname", (unsigned long)geteuid());
ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
ok( !strcmp(temp_state_key->name, "funnykeyname"), "Got key name" );
ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name");
ok(!strcmp(temp_state_key->name, "funnykeyname"), "Got key name");
ok( !strcmp(temp_state_key->_filename, state_path), "Got internal filename" );
ok( temp_state_key->data_version==54, "Version set" );
ok(!strcmp(temp_state_key->_filename, state_path), "Got internal filename");
ok(temp_state_key->data_version == 54, "Version set");
temp_state_data = np_state_read();
ok( temp_state_data==NULL, "Got no state data as file does not exist" );
ok(temp_state_data == NULL, "Got no state data as file does not exist");
/*
temp_fp = fopen("var/statefile", "r");
if (temp_fp==NULL)
printf("Error opening. errno=%d\n", errno);
printf("temp_fp=%s\n", temp_fp);
ok( _np_state_read_file(temp_fp) == true, "Can read state file" );
fclose(temp_fp);
*/
/*
temp_fp = fopen("var/statefile", "r");
if (temp_fp==NULL)
printf("Error opening. errno=%d\n", errno);
printf("temp_fp=%s\n", temp_fp);
ok( _np_state_read_file(temp_fp) == true, "Can read state file" );
fclose(temp_fp);
*/
temp_state_key->_filename="var/statefile";
temp_state_key->_filename = "var/statefile";
temp_state_data = np_state_read();
ok( this_monitoring_plugin->state->state_data!=NULL, "Got state data now" ) || diag("Are you running in right directory? Will get coredump next if not");
ok( this_monitoring_plugin->state->state_data->time==1234567890, "Got time" );
ok( !strcmp((char *)this_monitoring_plugin->state->state_data->data, "String to read"), "Data as expected" );
ok(this_monitoring_plugin->state->state_data != NULL, "Got state data now") ||
diag("Are you running in right directory? Will get coredump next if not");
ok(this_monitoring_plugin->state->state_data->time == 1234567890, "Got time");
ok(!strcmp((char *)this_monitoring_plugin->state->state_data->data, "String to read"), "Data as expected");
temp_state_key->data_version=53;
temp_state_key->data_version = 53;
temp_state_data = np_state_read();
ok( temp_state_data==NULL, "Older data version gives NULL" );
temp_state_key->data_version=54;
ok(temp_state_data == NULL, "Older data version gives NULL");
temp_state_key->data_version = 54;
temp_state_key->_filename="var/nonexistent";
temp_state_key->_filename = "var/nonexistent";
temp_state_data = np_state_read();
ok( temp_state_data==NULL, "Missing file gives NULL" );
ok( this_monitoring_plugin->state->state_data==NULL, "No state information" );
ok(temp_state_data == NULL, "Missing file gives NULL");
ok(this_monitoring_plugin->state->state_data == NULL, "No state information");
temp_state_key->_filename="var/oldformat";
temp_state_key->_filename = "var/oldformat";
temp_state_data = np_state_read();
ok( temp_state_data==NULL, "Old file format gives NULL" );
ok(temp_state_data == NULL, "Old file format gives NULL");
temp_state_key->_filename="var/baddate";
temp_state_key->_filename = "var/baddate";
temp_state_data = np_state_read();
ok( temp_state_data==NULL, "Bad date gives NULL" );
ok(temp_state_data == NULL, "Bad date gives NULL");
temp_state_key->_filename="var/missingdataline";
temp_state_key->_filename = "var/missingdataline";
temp_state_data = np_state_read();
ok( temp_state_data==NULL, "Missing data line gives NULL" );
ok(temp_state_data == NULL, "Missing data line gives NULL");
unlink("var/generated");
temp_state_key->_filename="var/generated";
current_time=1234567890;
temp_state_key->_filename = "var/generated";
current_time = 1234567890;
np_state_write_string(current_time, "String to read");
ok(system("cmp var/generated var/statefile")==0, "Generated file same as expected");
ok(system("cmp var/generated var/statefile") == 0, "Generated file same as expected");
unlink("var/generated_directory/statefile");
unlink("var/generated_directory");
temp_state_key->_filename="var/generated_directory/statefile";
current_time=1234567890;
temp_state_key->_filename = "var/generated_directory/statefile";
current_time = 1234567890;
np_state_write_string(current_time, "String to read");
ok(system("cmp var/generated_directory/statefile var/statefile")==0, "Have created directory");
ok(system("cmp var/generated_directory/statefile var/statefile") == 0, "Have created directory");
/* This test to check cannot write to dir - can't automate yet */
/*
@ -438,15 +422,13 @@ main (int argc, char **argv)
np_state_write_string(current_time, "String to read");
*/
temp_state_key->_filename="var/generated";
temp_state_key->_filename = "var/generated";
time(&current_time);
np_state_write_string(0, "String to read");
temp_state_data = np_state_read();
/* Check time is set to current_time */
ok(system("cmp var/generated var/statefile > /dev/null")!=0, "Generated file should be different this time");
ok(this_monitoring_plugin->state->state_data->time-current_time<=1, "Has time generated from current time");
ok(system("cmp var/generated var/statefile > /dev/null") != 0, "Generated file should be different this time");
ok(this_monitoring_plugin->state->state_data->time - current_time <= 1, "Has time generated from current time");
/* Don't know how to automatically test this. Need to be able to redefine die and catch the error */
/*
@ -454,23 +436,16 @@ main (int argc, char **argv)
np_state_write_string(0, "Bad file");
*/
np_cleanup();
ok(this_monitoring_plugin==NULL, "Free'd this_monitoring_plugin");
ok(this_monitoring_plugin == NULL, "Free'd this_monitoring_plugin");
ok(mp_suid() == false, "Test aren't suid");
/* base states with random case */
char *states[] = {
"Ok",
"wArnINg",
"cRiTIcaL",
"UnKNoWN",
NULL
};
char *states[] = {"Ok", "wArnINg", "cRiTIcaL", "UnKNoWN", NULL};
for (i=0; states[i]!=NULL; i++) {
for (i = 0; states[i] != NULL; i++) {
/* out of the random case states, create the lower and upper versions + numeric string one */
char *statelower = strdup(states[i]);
char *stateupper = strdup(states[i]);
@ -488,23 +463,23 @@ main (int argc, char **argv)
char testname[64] = "Translate state string: ";
int tlen = strlen(testname);
strcpy(testname+tlen, states[i]);
ok(i==mp_translate_state(states[i]), testname);
strcpy(testname + tlen, states[i]);
ok(i == mp_translate_state(states[i]), testname);
strcpy(testname+tlen, statelower);
ok(i==mp_translate_state(statelower), testname);
strcpy(testname + tlen, statelower);
ok(i == mp_translate_state(statelower), testname);
strcpy(testname+tlen, stateupper);
ok(i==mp_translate_state(stateupper), testname);
strcpy(testname + tlen, stateupper);
ok(i == mp_translate_state(stateupper), testname);
strcpy(testname+tlen, statenum);
ok(i==mp_translate_state(statenum), testname);
strcpy(testname + tlen, statenum);
ok(i == mp_translate_state(statenum), testname);
}
ok(ERROR==mp_translate_state("warningfewgw"), "Translate state string with garbage");
ok(ERROR==mp_translate_state("00"), "Translate state string: bad numeric string 1");
ok(ERROR==mp_translate_state("01"), "Translate state string: bad numeric string 2");
ok(ERROR==mp_translate_state("10"), "Translate state string: bad numeric string 3");
ok(ERROR==mp_translate_state(""), "Translate state string: empty string");
ok(ERROR == mp_translate_state("warningfewgw"), "Translate state string with garbage");
ok(ERROR == mp_translate_state("00"), "Translate state string: bad numeric string 1");
ok(ERROR == mp_translate_state("01"), "Translate state string: bad numeric string 2");
ok(ERROR == mp_translate_state("10"), "Translate state string: bad numeric string 3");
ok(ERROR == mp_translate_state(""), "Translate state string: empty string");
return exit_status();
}

View file

@ -1,28 +1,28 @@
/*****************************************************************************
*
* utils_base.c
*
* License: GPL
* Copyright (c) 2006 Monitoring Plugins Development Team
*
* Library of useful functions for plugins
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* utils_base.c
*
* License: GPL
* Copyright (c) 2006 - 2024 Monitoring Plugins Development Team
*
* Library of useful functions for plugins
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "../plugins/common.h"
#include <stdarg.h>
@ -33,43 +33,47 @@
#include <unistd.h>
#include <sys/types.h>
#define np_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } }
#define np_free(ptr) \
{ \
if (ptr) { \
free(ptr); \
ptr = NULL; \
} \
}
monitoring_plugin *this_monitoring_plugin=NULL;
monitoring_plugin *this_monitoring_plugin = NULL;
int timeout_state = STATE_CRITICAL;
unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT;
bool _np_state_read_file(FILE *);
void np_init( char *plugin_name, int argc, char **argv ) {
if (this_monitoring_plugin==NULL) {
void np_init(char *plugin_name, int argc, char **argv) {
if (this_monitoring_plugin == NULL) {
this_monitoring_plugin = calloc(1, sizeof(monitoring_plugin));
if (this_monitoring_plugin==NULL) {
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
if (this_monitoring_plugin == NULL) {
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
}
this_monitoring_plugin->plugin_name = strdup(plugin_name);
if (this_monitoring_plugin->plugin_name==NULL)
if (this_monitoring_plugin->plugin_name == NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
this_monitoring_plugin->argc = argc;
this_monitoring_plugin->argv = argv;
}
}
void np_set_args( int argc, char **argv ) {
if (this_monitoring_plugin==NULL)
void np_set_args(int argc, char **argv) {
if (this_monitoring_plugin == NULL)
die(STATE_UNKNOWN, _("This requires np_init to be called"));
this_monitoring_plugin->argc = argc;
this_monitoring_plugin->argv = argv;
}
void np_cleanup() {
if (this_monitoring_plugin!=NULL) {
if(this_monitoring_plugin->state!=NULL) {
if(this_monitoring_plugin->state->state_data) {
if (this_monitoring_plugin != NULL) {
if (this_monitoring_plugin->state != NULL) {
if (this_monitoring_plugin->state->state_data) {
np_free(this_monitoring_plugin->state->state_data->data);
np_free(this_monitoring_plugin->state->state_data);
}
@ -79,48 +83,43 @@ void np_cleanup() {
np_free(this_monitoring_plugin->plugin_name);
np_free(this_monitoring_plugin);
}
this_monitoring_plugin=NULL;
this_monitoring_plugin = NULL;
}
/* Hidden function to get a pointer to this_monitoring_plugin for testing */
void _get_monitoring_plugin( monitoring_plugin **pointer ){
*pointer = this_monitoring_plugin;
}
void _get_monitoring_plugin(monitoring_plugin **pointer) { *pointer = this_monitoring_plugin; }
void
die (int result, const char *fmt, ...)
{
if(fmt!=NULL) {
void die(int result, const char *fmt, ...) {
if (fmt != NULL) {
va_list ap;
va_start (ap, fmt);
vprintf (fmt, ap);
va_end (ap);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
if(this_monitoring_plugin!=NULL) {
if (this_monitoring_plugin != NULL) {
np_cleanup();
}
exit (result);
exit(result);
}
void set_range_start (range *this, double value) {
void set_range_start(range *this, double value) {
this->start = value;
this->start_infinity = false;
}
void set_range_end (range *this, double value) {
void set_range_end(range *this, double value) {
this->end = value;
this->end_infinity = false;
}
range
*parse_range_string (char *str) {
range *parse_range_string(char *str) {
range *temp_range;
double start;
double end;
char *end_str;
temp_range = (range *) calloc(1, sizeof(range));
temp_range = (range *)calloc(1, sizeof(range));
/* Set defaults */
temp_range->start = 0;
@ -140,10 +139,10 @@ range
if (str[0] == '~') {
temp_range->start_infinity = true;
} else {
start = strtod(str, NULL); /* Will stop at the ':' */
start = strtod(str, NULL); /* Will stop at the ':' */
set_range_start(temp_range, start);
}
end_str++; /* Move past the ':' */
end_str++; /* Move past the ':' */
} else {
end_str = str;
}
@ -152,9 +151,7 @@ range
set_range_end(temp_range, end);
}
if (temp_range->start_infinity == true ||
temp_range->end_infinity == true ||
temp_range->start <= temp_range->end) {
if (temp_range->start_infinity == true || temp_range->end_infinity == true || temp_range->start <= temp_range->end) {
return temp_range;
}
free(temp_range);
@ -162,14 +159,11 @@ range
}
/* returns 0 if okay, otherwise 1 */
int
_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
{
int _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) {
thresholds *temp_thresholds = NULL;
if ((temp_thresholds = calloc(1, sizeof(thresholds))) == NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
temp_thresholds->warning = NULL;
temp_thresholds->critical = NULL;
@ -190,9 +184,7 @@ _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_st
return 0;
}
void
set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
{
void set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) {
switch (_set_thresholds(my_thresholds, warn_string, critical_string)) {
case 0:
return;
@ -206,7 +198,7 @@ set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_str
void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
printf("%s - ", threshold_name);
if (! my_threshold) {
if (!my_threshold) {
printf("Threshold not set");
} else {
if (my_threshold->warning) {
@ -224,8 +216,7 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
}
/* Returns true if alert should be raised based on the range */
bool check_range(double value, range *my_range)
{
bool check_range(double value, range *my_range) {
bool no = false;
bool yes = true;
@ -258,9 +249,7 @@ bool check_range(double value, range *my_range)
}
/* Returns status */
int
get_status(double value, thresholds *my_thresholds)
{
int get_status(double value, thresholds *my_thresholds) {
if (my_thresholds->critical != NULL) {
if (check_range(value, my_thresholds->critical) == true) {
return STATE_CRITICAL;
@ -274,27 +263,27 @@ get_status(double value, thresholds *my_thresholds)
return STATE_OK;
}
char *np_escaped_string (const char *string) {
char *np_escaped_string(const char *string) {
char *data;
int i, j=0;
int i, j = 0;
data = strdup(string);
for (i=0; data[i]; i++) {
for (i = 0; data[i]; i++) {
if (data[i] == '\\') {
switch(data[++i]) {
case 'n':
data[j++] = '\n';
break;
case 'r':
data[j++] = '\r';
break;
case 't':
data[j++] = '\t';
break;
case '\\':
data[j++] = '\\';
break;
default:
data[j++] = data[i];
switch (data[++i]) {
case 'n':
data[j++] = '\n';
break;
case 'r':
data[j++] = '\r';
break;
case 't':
data[j++] = '\t';
break;
case '\\':
data[j++] = '\\';
break;
default:
data[j++] = data[i];
}
} else {
data[j++] = data[i];
@ -313,33 +302,38 @@ int np_check_if_root(void) { return (geteuid() == 0); }
* data strings.
*/
char *np_extract_value(const char *varlist, const char *name, char sep) {
char *tmp=NULL, *value=NULL;
char *tmp = NULL, *value = NULL;
int i;
while (1) {
/* Strip any leading space */
for (; isspace(varlist[0]); varlist++);
for (; isspace(varlist[0]); varlist++)
;
if (strncmp(name, varlist, strlen(name)) == 0) {
varlist += strlen(name);
/* strip trailing spaces */
for (; isspace(varlist[0]); varlist++);
for (; isspace(varlist[0]); varlist++)
;
if (varlist[0] == '=') {
/* We matched the key, go past the = sign */
varlist++;
/* strip leading spaces */
for (; isspace(varlist[0]); varlist++);
for (; isspace(varlist[0]); varlist++)
;
if ((tmp = index(varlist, sep))) {
/* Value is delimited by a comma */
if (tmp-varlist == 0) continue;
value = (char *)calloc(1, tmp-varlist+1);
strncpy(value, varlist, tmp-varlist);
value[tmp-varlist] = '\0';
if (tmp - varlist == 0)
continue;
value = (char *)calloc(1, tmp - varlist + 1);
strncpy(value, varlist, tmp - varlist);
value[tmp - varlist] = '\0';
} else {
/* Value is delimited by a \0 */
if (strlen(varlist) == 0) continue;
if (strlen(varlist) == 0)
continue;
value = (char *)calloc(1, strlen(varlist) + 1);
strncpy(value, varlist, strlen(varlist));
value[strlen(varlist)] = '\0';
@ -357,14 +351,14 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
}
/* Clean-up trailing spaces/newlines */
if (value) for (i=strlen(value)-1; isspace(value[i]); i--) value[i] = '\0';
if (value)
for (i = strlen(value) - 1; isspace(value[i]); i--)
value[i] = '\0';
return value;
}
const char *
state_text (int result)
{
const char *state_text(int result) {
switch (result) {
case STATE_OK:
return "OK";
@ -383,14 +377,14 @@ state_text (int result)
* Read a string representing a state (ok, warning... or numeric: 0, 1) and
* return the corresponding STATE_ value or ERROR)
*/
int mp_translate_state (char *state_text) {
if (!strcasecmp(state_text,"OK") || !strcmp(state_text,"0"))
int mp_translate_state(char *state_text) {
if (!strcasecmp(state_text, "OK") || !strcmp(state_text, "0"))
return STATE_OK;
if (!strcasecmp(state_text,"WARNING") || !strcmp(state_text,"1"))
if (!strcasecmp(state_text, "WARNING") || !strcmp(state_text, "1"))
return STATE_WARNING;
if (!strcasecmp(state_text,"CRITICAL") || !strcmp(state_text,"2"))
if (!strcasecmp(state_text, "CRITICAL") || !strcmp(state_text, "2"))
return STATE_CRITICAL;
if (!strcasecmp(state_text,"UNKNOWN") || !strcmp(state_text,"3"))
if (!strcasecmp(state_text, "UNKNOWN") || !strcmp(state_text, "3"))
return STATE_UNKNOWN;
return ERROR;
}
@ -404,7 +398,7 @@ char *_np_state_generate_key() {
int i;
char **argv = this_monitoring_plugin->argv;
char keyname[41];
char *p=NULL;
char *p = NULL;
unsigned char result[256];
@ -418,7 +412,7 @@ char *_np_state_generate_key() {
EVP_DigestInit(ctx, EVP_sha256());
for(i=0; i<this_monitoring_plugin->argc; i++) {
for (i = 0; i < this_monitoring_plugin->argc; i++) {
EVP_DigestUpdate(ctx, argv[i], strlen(argv[i]));
}
@ -427,28 +421,28 @@ char *_np_state_generate_key() {
struct sha256_ctx ctx;
for(i=0; i<this_monitoring_plugin->argc; i++) {
for (i = 0; i < this_monitoring_plugin->argc; i++) {
sha256_process_bytes(argv[i], strlen(argv[i]), &ctx);
}
sha256_finish_ctx(&ctx, result);
#endif // FOUNDOPENSSL
for (i=0; i<20; ++i) {
sprintf(&keyname[2*i], "%02x", result[i]);
for (i = 0; i < 20; ++i) {
sprintf(&keyname[2 * i], "%02x", result[i]);
}
keyname[40]='\0';
keyname[40] = '\0';
p = strdup(keyname);
if(p==NULL) {
if (p == NULL) {
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
}
return p;
}
void _cleanup_state_data() {
if (this_monitoring_plugin->state->state_data!=NULL) {
if (this_monitoring_plugin->state->state_data != NULL) {
np_free(this_monitoring_plugin->state->state_data->data);
np_free(this_monitoring_plugin->state->state_data);
}
@ -459,18 +453,18 @@ void _cleanup_state_data() {
* envvar NAGIOS_PLUGIN_STATE_DIRECTORY
* statically compiled shared state directory
*/
char* _np_state_calculate_location_prefix(){
char *_np_state_calculate_location_prefix() {
char *env_dir;
/* Do not allow passing MP_STATE_PATH in setuid plugins
* for security reasons */
if (!mp_suid()) {
env_dir = getenv("MP_STATE_PATH");
if(env_dir && env_dir[0] != '\0')
if (env_dir && env_dir[0] != '\0')
return env_dir;
/* This is the former ENV, for backward-compatibility */
env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
if(env_dir && env_dir[0] != '\0')
if (env_dir && env_dir[0] != '\0')
return env_dir;
}
@ -486,46 +480,43 @@ void np_enable_state(char *keyname, int expected_data_version) {
state_key *this_state = NULL;
char *temp_filename = NULL;
char *temp_keyname = NULL;
char *p=NULL;
char *p = NULL;
int ret;
if(this_monitoring_plugin==NULL)
if (this_monitoring_plugin == NULL)
die(STATE_UNKNOWN, _("This requires np_init to be called"));
this_state = (state_key *) calloc(1, sizeof(state_key));
if(this_state==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
this_state = (state_key *)calloc(1, sizeof(state_key));
if (this_state == NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
if(keyname==NULL) {
if (keyname == NULL) {
temp_keyname = _np_state_generate_key();
} else {
temp_keyname = strdup(keyname);
if(temp_keyname==NULL)
if (temp_keyname == NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
}
/* Die if invalid characters used for keyname */
p = temp_keyname;
while(*p!='\0') {
if(! (isalnum(*p) || *p == '_')) {
while (*p != '\0') {
if (!(isalnum(*p) || *p == '_')) {
die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'"));
}
p++;
}
this_state->name=temp_keyname;
this_state->plugin_name=this_monitoring_plugin->plugin_name;
this_state->data_version=expected_data_version;
this_state->state_data=NULL;
this_state->name = temp_keyname;
this_state->plugin_name = this_monitoring_plugin->plugin_name;
this_state->data_version = expected_data_version;
this_state->state_data = NULL;
/* Calculate filename */
ret = asprintf(&temp_filename, "%s/%lu/%s/%s",
_np_state_calculate_location_prefix(), (unsigned long)geteuid(),
this_monitoring_plugin->plugin_name, this_state->name);
ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), (unsigned long)geteuid(),
this_monitoring_plugin->plugin_name, this_state->name);
if (ret < 0)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
this_state->_filename=temp_filename;
this_state->_filename = temp_filename;
this_monitoring_plugin->state = this_state;
}
@ -538,23 +529,22 @@ void np_enable_state(char *keyname, int expected_data_version) {
* if exceptional error.
*/
state_data *np_state_read() {
state_data *this_state_data=NULL;
state_data *this_state_data = NULL;
FILE *statefile;
bool rc = false;
if(this_monitoring_plugin==NULL)
if (this_monitoring_plugin == NULL)
die(STATE_UNKNOWN, _("This requires np_init to be called"));
/* Open file. If this fails, no previous state found */
statefile = fopen( this_monitoring_plugin->state->_filename, "r" );
if(statefile!=NULL) {
statefile = fopen(this_monitoring_plugin->state->_filename, "r");
if (statefile != NULL) {
this_state_data = (state_data *) calloc(1, sizeof(state_data));
if(this_state_data==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
this_state_data = (state_data *)calloc(1, sizeof(state_data));
if (this_state_data == NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
this_state_data->data=NULL;
this_state_data->data = NULL;
this_monitoring_plugin->state->state_data = this_state_data;
rc = _np_state_read_file(statefile);
@ -562,7 +552,7 @@ state_data *np_state_read() {
fclose(statefile);
}
if(!rc) {
if (!rc) {
_cleanup_state_data();
}
@ -577,60 +567,65 @@ bool _np_state_read_file(FILE *f) {
size_t pos;
char *line;
int i;
int failure=0;
int failure = 0;
time_t current_time, data_time;
enum { STATE_FILE_VERSION, STATE_DATA_VERSION, STATE_DATA_TIME, STATE_DATA_TEXT, STATE_DATA_END } expected=STATE_FILE_VERSION;
enum {
STATE_FILE_VERSION,
STATE_DATA_VERSION,
STATE_DATA_TIME,
STATE_DATA_TEXT,
STATE_DATA_END
} expected = STATE_FILE_VERSION;
time(&current_time);
/* Note: This introduces a limit of 1024 bytes in the string data */
line = (char *) calloc(1, 1024);
if(line==NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
line = (char *)calloc(1, 1024);
if (line == NULL)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
while(!failure && (fgets(line,1024,f))!=NULL){
pos=strlen(line);
if(line[pos-1]=='\n') {
line[pos-1]='\0';
while (!failure && (fgets(line, 1024, f)) != NULL) {
pos = strlen(line);
if (line[pos - 1] == '\n') {
line[pos - 1] = '\0';
}
if(line[0] == '#') continue;
if (line[0] == '#')
continue;
switch(expected) {
case STATE_FILE_VERSION:
i=atoi(line);
if(i!=NP_STATE_FORMAT_VERSION)
failure++;
else
expected=STATE_DATA_VERSION;
break;
case STATE_DATA_VERSION:
i=atoi(line);
if(i != this_monitoring_plugin->state->data_version)
failure++;
else
expected=STATE_DATA_TIME;
break;
case STATE_DATA_TIME:
/* If time > now, error */
data_time=strtoul(line,NULL,10);
if(data_time > current_time)
failure++;
else {
this_monitoring_plugin->state->state_data->time = data_time;
expected=STATE_DATA_TEXT;
}
break;
case STATE_DATA_TEXT:
this_monitoring_plugin->state->state_data->data = strdup(line);
if(this_monitoring_plugin->state->state_data->data==NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
expected=STATE_DATA_END;
status=true;
break;
case STATE_DATA_END:
;
switch (expected) {
case STATE_FILE_VERSION:
i = atoi(line);
if (i != NP_STATE_FORMAT_VERSION)
failure++;
else
expected = STATE_DATA_VERSION;
break;
case STATE_DATA_VERSION:
i = atoi(line);
if (i != this_monitoring_plugin->state->data_version)
failure++;
else
expected = STATE_DATA_TIME;
break;
case STATE_DATA_TIME:
/* If time > now, error */
data_time = strtoul(line, NULL, 10);
if (data_time > current_time)
failure++;
else {
this_monitoring_plugin->state->state_data->time = data_time;
expected = STATE_DATA_TEXT;
}
break;
case STATE_DATA_TEXT:
this_monitoring_plugin->state->state_data->data = strdup(line);
if (this_monitoring_plugin->state->state_data->data == NULL)
die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
expected = STATE_DATA_END;
status = true;
break;
case STATE_DATA_END:;
}
}
@ -647,77 +642,75 @@ bool _np_state_read_file(FILE *f) {
*/
void np_state_write_string(time_t data_time, char *data_string) {
FILE *fp;
char *temp_file=NULL;
int fd=0, result=0;
char *temp_file = NULL;
int fd = 0, result = 0;
time_t current_time;
char *directories=NULL;
char *p=NULL;
char *directories = NULL;
char *p = NULL;
if(data_time==0)
if (data_time == 0)
time(&current_time);
else
current_time=data_time;
current_time = data_time;
/* If file doesn't currently exist, create directories */
if(access(this_monitoring_plugin->state->_filename,F_OK)!=0) {
if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) {
result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename);
if(result < 0)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
if (result < 0)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
for(p=directories+1; *p; p++) {
if(*p=='/') {
*p='\0';
if((access(directories,F_OK)!=0) && (mkdir(directories, S_IRWXU)!=0)) {
for (p = directories + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) {
/* Can't free this! Otherwise error message is wrong! */
/* np_free(directories); */
die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories);
}
*p='/';
*p = '/';
}
}
np_free(directories);
}
result = asprintf(&temp_file,"%s.XXXXXX",this_monitoring_plugin->state->_filename);
if(result < 0)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename);
if (result < 0)
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
if((fd=mkstemp(temp_file))==-1) {
if ((fd = mkstemp(temp_file)) == -1) {
np_free(temp_file);
die(STATE_UNKNOWN, _("Cannot create temporary filename"));
}
fp=(FILE *)fdopen(fd,"w");
if(fp==NULL) {
fp = (FILE *)fdopen(fd, "w");
if (fp == NULL) {
close(fd);
unlink(temp_file);
np_free(temp_file);
die(STATE_UNKNOWN, _("Unable to open temporary state file"));
}
fprintf(fp,"# NP State file\n");
fprintf(fp,"%d\n",NP_STATE_FORMAT_VERSION);
fprintf(fp,"%d\n",this_monitoring_plugin->state->data_version);
fprintf(fp,"%lu\n",current_time);
fprintf(fp,"%s\n",data_string);
fprintf(fp, "# NP State file\n");
fprintf(fp, "%d\n", NP_STATE_FORMAT_VERSION);
fprintf(fp, "%d\n", this_monitoring_plugin->state->data_version);
fprintf(fp, "%lu\n", current_time);
fprintf(fp, "%s\n", data_string);
fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP);
fflush(fp);
result=fclose(fp);
result = fclose(fp);
fsync(fd);
if(result!=0) {
if (result != 0) {
unlink(temp_file);
np_free(temp_file);
die(STATE_UNKNOWN, _("Error writing temp file"));
}
if(rename(temp_file, this_monitoring_plugin->state->_filename)!=0) {
if (rename(temp_file, this_monitoring_plugin->state->_filename) != 0) {
unlink(temp_file);
np_free(temp_file);
die(STATE_UNKNOWN, _("Cannot rename state temp file"));

View file

@ -3,7 +3,7 @@
/* Header file for Monitoring Plugins utils_base.c */
#ifndef USE_OPENSSL
# include "sha256.h"
# include "sha256.h"
#endif
/* This file holds header information for thresholds - use this in preference to
@ -20,44 +20,43 @@
#define INSIDE 1
typedef struct range_struct {
double start;
double start;
bool start_infinity;
double end;
int end_infinity;
int alert_on; /* OUTSIDE (default) or INSIDE */
char* text; /* original unparsed text input */
} range;
double end;
int end_infinity;
int alert_on; /* OUTSIDE (default) or INSIDE */
char *text; /* original unparsed text input */
} range;
typedef struct thresholds_struct {
range *warning;
range *critical;
} thresholds;
range *warning;
range *critical;
} thresholds;
#define NP_STATE_FORMAT_VERSION 1
typedef struct state_data_struct {
time_t time;
void *data;
int length; /* Of binary data */
} state_data;
time_t time;
void *data;
int length; /* Of binary data */
} state_data;
typedef struct state_key_struct {
char *name;
char *plugin_name;
int data_version;
char *_filename;
char *name;
char *plugin_name;
int data_version;
char *_filename;
state_data *state_data;
} state_key;
} state_key;
typedef struct np_struct {
char *plugin_name;
char *plugin_name;
state_key *state;
int argc;
char **argv;
} monitoring_plugin;
int argc;
char **argv;
} monitoring_plugin;
range *parse_range_string (char *);
range *parse_range_string(char *);
int _set_thresholds(thresholds **, char *, char *);
void set_thresholds(thresholds **, char *, char *);
void print_thresholds(const char *, thresholds *);
@ -71,13 +70,13 @@ extern unsigned int timeout_interval;
/* All possible characters in a threshold range */
#define NP_THRESHOLDS_CHARS "-0123456789.:@~"
char *np_escaped_string (const char *);
char *np_escaped_string(const char *);
void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3)));
void die(int, const char *, ...) __attribute__((noreturn, format(printf, 2, 3)));
/* Return codes for _set_thresholds */
#define NP_RANGE_UNPARSEABLE 1
#define NP_WARN_WITHIN_CRIT 2
#define NP_WARN_WITHIN_CRIT 2
/* a simple check to see if we're running as root.
* returns zero on failure, nonzero on success */
@ -93,7 +92,7 @@ int np_check_if_root(void);
* This function can be used to parse NTP control packet data and performance
* data strings.
*/
char *np_extract_value(const char*, const char*, char);
char *np_extract_value(const char *, const char *, char);
/*
* Same as np_extract_value with separator suitable for NTP control packet
@ -105,7 +104,7 @@ char *np_extract_value(const char*, const char*, char);
* Read a string representing a state (ok, warning... or numeric: 0, 1) and
* return the corresponding NP_STATE or ERROR)
*/
int mp_translate_state (char *);
int mp_translate_state(char *);
void np_enable_state(char *, int);
state_data *np_state_read();
@ -114,6 +113,6 @@ void np_state_write_string(time_t, char *);
void np_init(char *, int argc, char **argv);
void np_set_args(int argc, char **argv);
void np_cleanup();
const char *state_text (int);
const char *state_text(int);
#endif /* _UTILS_BASE_ */

View file

@ -1,40 +1,40 @@
/*****************************************************************************
*
* Monitoring run command utilities
*
* License: GPL
* Copyright (c) 2005-2006 Monitoring Plugins Development Team
*
* Description :
*
* A simple interface to executing programs from other programs, using an
* optimized and safe popen()-like implementation. It is considered safe
* in that no shell needs to be spawned and the environment passed to the
* execve()'d program is essentially empty.
*
* The code in this file is a derivative of popen.c which in turn was taken
* from "Advanced Programming for the Unix Environment" by W. Richard Stevens.
*
* Care has been taken to make sure the functions are async-safe. The one
* function which isn't is cmd_init() which it doesn't make sense to
* call twice anyway, so the api as a whole should be considered async-safe.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring run command utilities
*
* License: GPL
* Copyright (c) 2005-2024 Monitoring Plugins Development Team
*
* Description :
*
* A simple interface to executing programs from other programs, using an
* optimized and safe popen()-like implementation. It is considered safe
* in that no shell needs to be spawned and the environment passed to the
* execve()'d program is essentially empty.
*
* The code in this file is a derivative of popen.c which in turn was taken
* from "Advanced Programming for the Unix Environment" by W. Richard Stevens.
*
* Care has been taken to make sure the functions are async-safe. The one
* function which isn't is cmd_init() which it doesn't make sense to
* call twice anyway, so the api as a whole should be considered async-safe.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#define NAGIOSPLUG_API_C 1
@ -59,7 +59,7 @@ static pid_t *_cmd_pids = NULL;
#include <fcntl.h>
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# include <sys/wait.h>
#endif
/* used in _cmd_open to pass the environment to commands */
@ -67,57 +67,48 @@ extern char **environ;
/** macros **/
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
# 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)
# define SIG_ERR ((Sigfunc *)-1)
#endif
/** prototypes **/
static int _cmd_open (char *const *, int *, int *)
__attribute__ ((__nonnull__ (1, 2, 3)));
static int _cmd_open(char *const *, int *, int *) __attribute__((__nonnull__(1, 2, 3)));
static int _cmd_fetch_output (int, output *, int)
__attribute__ ((__nonnull__ (2)));
static int _cmd_fetch_output(int, output *, int) __attribute__((__nonnull__(2)));
static int _cmd_close (int);
static int _cmd_close(int);
/* prototype imported from utils.h */
extern void die (int, const char *, ...)
__attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
extern void die(int, const char *, ...) __attribute__((__noreturn__, __format__(__printf__, 2, 3)));
/* this function is NOT async-safe. It is exported so multithreaded
* plugins (or other apps) can call it prior to running any commands
* through this api and thus achieve async-safeness throughout the api */
void
cmd_init (void)
{
void cmd_init(void) {
long maxfd = mp_open_max();
/* if maxfd is unnaturally high, we force it to a lower value
* ( e.g. on SunOS, when ulimit is set to unlimited: 2147483647 this would cause
* a segfault when following calloc is called ... ) */
if ( maxfd > MAXFD_LIMIT ) {
if (maxfd > MAXFD_LIMIT) {
maxfd = MAXFD_LIMIT;
}
if (!_cmd_pids)
_cmd_pids = calloc (maxfd, sizeof (pid_t));
_cmd_pids = calloc(maxfd, sizeof(pid_t));
}
/* Start running a command, array style */
static int
_cmd_open (char *const *argv, int *pfd, int *pfderr)
{
static int _cmd_open(char *const *argv, int *pfd, int *pfderr) {
pid_t pid;
#ifdef RLIMIT_CORE
struct rlimit limit;
@ -130,26 +121,26 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
setenv("LC_ALL", "C", 1);
if (pipe (pfd) < 0 || pipe (pfderr) < 0 || (pid = fork ()) < 0)
return -1; /* errno set by the failing function */
if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0)
return -1; /* errno set by the failing function */
/* child runs exceve() and _exit. */
if (pid == 0) {
#ifdef RLIMIT_CORE
#ifdef RLIMIT_CORE
/* the program we execve shouldn't leave core files */
getrlimit (RLIMIT_CORE, &limit);
getrlimit(RLIMIT_CORE, &limit);
limit.rlim_cur = 0;
setrlimit (RLIMIT_CORE, &limit);
setrlimit(RLIMIT_CORE, &limit);
#endif
close (pfd[0]);
close(pfd[0]);
if (pfd[1] != STDOUT_FILENO) {
dup2 (pfd[1], STDOUT_FILENO);
close (pfd[1]);
dup2(pfd[1], STDOUT_FILENO);
close(pfd[1]);
}
close (pfderr[0]);
close(pfderr[0]);
if (pfderr[1] != STDERR_FILENO) {
dup2 (pfderr[1], STDERR_FILENO);
close (pfderr[1]);
dup2(pfderr[1], STDERR_FILENO);
close(pfderr[1]);
}
/* close all descriptors in _cmd_pids[]
@ -158,16 +149,16 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
long maxfd = mp_open_max();
for (i = 0; i < maxfd; i++)
if (_cmd_pids[i] > 0)
close (i);
close(i);
execve (argv[0], argv, environ);
_exit (STATE_UNKNOWN);
execve(argv[0], argv, environ);
_exit(STATE_UNKNOWN);
}
/* parent picks up execution here */
/* close children descriptors in our address space */
close (pfd[1]);
close (pfderr[1]);
close(pfd[1]);
close(pfderr[1]);
/* tag our file's entry in the pid-list and return it */
_cmd_pids[pfd[0]] = pid;
@ -175,9 +166,7 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
return pfd[0];
}
static int
_cmd_close (int fd)
{
static int _cmd_close(int fd) {
int status;
pid_t pid;
@ -187,40 +176,37 @@ _cmd_close (int fd)
return -1;
_cmd_pids[fd] = 0;
if (close (fd) == -1)
if (close(fd) == -1)
return -1;
/* EINTR is ok (sort of), everything else is bad */
while (waitpid (pid, &status, 0) < 0)
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
return -1;
/* return child's termination status */
return (WIFEXITED (status)) ? WEXITSTATUS (status) : -1;
return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1;
}
static int
_cmd_fetch_output (int fd, output * op, int flags)
{
static int _cmd_fetch_output(int fd, output *op, int flags) {
size_t len = 0, i = 0, lineno = 0;
size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */
size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */
char *buf = NULL;
int ret;
char tmpbuf[4096];
op->buf = NULL;
op->buflen = 0;
while ((ret = read (fd, tmpbuf, sizeof (tmpbuf))) > 0) {
len = (size_t) ret;
op->buf = realloc (op->buf, op->buflen + len + 1);
memcpy (op->buf + op->buflen, tmpbuf, len);
while ((ret = read(fd, tmpbuf, sizeof(tmpbuf))) > 0) {
len = (size_t)ret;
op->buf = realloc(op->buf, op->buflen + len + 1);
memcpy(op->buf + op->buflen, tmpbuf, len);
op->buflen += len;
i++;
}
if (ret < 0) {
printf ("read() returned %d: %s\n", ret, strerror (errno));
printf("read() returned %d: %s\n", ret, strerror(errno));
return ret;
}
@ -231,10 +217,9 @@ _cmd_fetch_output (int fd, output * op, int flags)
/* and some may want both */
if (flags & CMD_NO_ASSOC) {
buf = malloc (op->buflen);
memcpy (buf, op->buf, op->buflen);
}
else
buf = malloc(op->buflen);
memcpy(buf, op->buf, op->buflen);
} else
buf = op->buf;
op->line = NULL;
@ -248,8 +233,8 @@ _cmd_fetch_output (int fd, output * op, int flags)
ary_size = op->buflen >> --rsf;
} while (!ary_size);
op->line = realloc (op->line, ary_size * sizeof (char *));
op->lens = realloc (op->lens, ary_size * sizeof (size_t));
op->line = realloc(op->line, ary_size * sizeof(char *));
op->lens = realloc(op->lens, ary_size * sizeof(size_t));
}
/* set the pointer to the string */
@ -261,7 +246,7 @@ _cmd_fetch_output (int fd, output * op, int flags)
buf[i] = '\0';
/* calculate the string length using pointer difference */
op->lens[lineno] = (size_t) & buf[i] - (size_t) op->line[lineno];
op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno];
lineno++;
i++;
@ -270,10 +255,7 @@ _cmd_fetch_output (int fd, output * op, int flags)
return lineno;
}
int
cmd_run (const char *cmdstring, output * out, output * err, int flags)
{
int cmd_run(const char *cmdstring, output *out, output *err, int flags) {
int i = 0, argc;
size_t cmdlen;
char **argv = NULL;
@ -285,120 +267,114 @@ cmd_run (const char *cmdstring, output * out, output * err, int flags)
/* initialize the structs */
if (out)
memset (out, 0, sizeof (output));
memset(out, 0, sizeof(output));
if (err)
memset (err, 0, sizeof (output));
memset(err, 0, sizeof(output));
/* make copy of command string so strtok() doesn't silently modify it */
/* (the calling program may want to access it later) */
cmdlen = strlen (cmdstring);
if ((cmd = malloc (cmdlen + 1)) == NULL)
cmdlen = strlen(cmdstring);
if ((cmd = malloc(cmdlen + 1)) == NULL)
return -1;
memcpy (cmd, cmdstring, cmdlen);
memcpy(cmd, cmdstring, cmdlen);
cmd[cmdlen] = '\0';
/* This is not a shell, so we don't handle "???" */
if (strstr (cmdstring, "\"")) return -1;
if (strstr(cmdstring, "\""))
return -1;
/* allow single quotes, but only if non-whitesapce doesn't occur on both sides */
if (strstr (cmdstring, " ' ") || strstr (cmdstring, "'''"))
if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''"))
return -1;
/* each arg must be whitespace-separated, so args can be a maximum
* of (len / 2) + 1. We add 1 extra to the mix for NULL termination */
argc = (cmdlen >> 1) + 2;
argv = calloc (sizeof (char *), argc);
argv = calloc(sizeof(char *), argc);
if (argv == NULL) {
printf ("%s\n", _("Could not malloc argv array in popen()"));
printf("%s\n", _("Could not malloc argv array in popen()"));
return -1;
}
/* get command arguments (stupidly, but fairly quickly) */
while (cmd) {
str = cmd;
str += strspn (str, " \t\r\n"); /* trim any leading whitespace */
str += strspn(str, " \t\r\n"); /* trim any leading whitespace */
if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */
if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */
str++;
if (!strstr (str, "'"))
return -1; /* 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 {
if (!strstr(str, "'"))
return -1; /* 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"))
if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n"))
cmd = NULL;
argv[i++] = str;
}
return cmd_run_array (argv, out, err, flags);
return cmd_run_array(argv, out, err, flags);
}
int
cmd_run_array (char *const *argv, output * out, output * err, int flags)
{
int cmd_run_array(char *const *argv, output *out, output *err, int flags) {
int fd, pfd_out[2], pfd_err[2];
/* initialize the structs */
if (out)
memset (out, 0, sizeof (output));
memset(out, 0, sizeof(output));
if (err)
memset (err, 0, sizeof (output));
memset(err, 0, sizeof(output));
if ((fd = _cmd_open (argv, pfd_out, pfd_err)) == -1)
die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]);
if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1)
die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]);
if (out)
out->lines = _cmd_fetch_output (pfd_out[0], out, flags);
out->lines = _cmd_fetch_output(pfd_out[0], out, flags);
if (err)
err->lines = _cmd_fetch_output (pfd_err[0], err, flags);
err->lines = _cmd_fetch_output(pfd_err[0], err, flags);
return _cmd_close (fd);
return _cmd_close(fd);
}
int
cmd_file_read ( char *filename, output *out, int flags)
{
int cmd_file_read(char *filename, output *out, int flags) {
int fd;
if(out)
memset (out, 0, sizeof(output));
if (out)
memset(out, 0, sizeof(output));
if ((fd = open(filename, O_RDONLY)) == -1) {
die( STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno) );
die(STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno));
}
if(out)
out->lines = _cmd_fetch_output (fd, out, flags);
if (out)
out->lines = _cmd_fetch_output(fd, out, flags);
if (close(fd) == -1)
die( STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno) );
die(STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno));
return 0;
}
void
timeout_alarm_handler (int signo)
{
void timeout_alarm_handler(int signo) {
if (signo == SIGALRM) {
printf (_("%s - Plugin timed out after %d seconds\n"),
state_text(timeout_state), timeout_interval);
printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state), timeout_interval);
long maxfd = mp_open_max();
if(_cmd_pids) for(long int i = 0; i < maxfd; i++) {
if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL);
}
if (_cmd_pids)
for (long int i = 0; i < maxfd; i++) {
if (_cmd_pids[i] != 0)
kill(_cmd_pids[i], SIGKILL);
}
exit (timeout_state);
exit(timeout_state);
}
}

View file

@ -4,12 +4,10 @@
/*
* Header file for Monitoring Plugins utils_cmd.c
*
*
*/
/** types **/
struct output
{
struct output {
char *buf; /* output buffer */
size_t buflen; /* output buffer content length */
char **line; /* array of lines (points to buf) */
@ -20,20 +18,18 @@ struct output
typedef struct output output;
/** prototypes **/
int cmd_run (const char *, output *, output *, int);
int cmd_run_array (char *const *, output *, output *, int);
int cmd_file_read (char *, output *, int);
int cmd_run(const char *, output *, output *, int);
int cmd_run_array(char *const *, output *, output *, int);
int cmd_file_read(char *, output *, int);
/* only multi-threaded plugins need to bother with this */
void cmd_init (void);
void cmd_init(void);
#define CMD_INIT cmd_init()
/* possible flags for cmd_run()'s fourth argument */
#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */
#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */
void timeout_alarm_handler (int);
#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */
#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */
void timeout_alarm_handler(int);
#endif /* _UTILS_CMD_ */

View file

@ -1,44 +1,42 @@
/*****************************************************************************
*
* Library for check_disk
*
* License: GPL
* Copyright (c) 1999-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains utilities for check_disk. These are tested by libtap
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Library for check_disk
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains utilities for check_disk. These are tested by libtap
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_disk.h"
#include "gl/fsusage.h"
#include <string.h>
void
np_add_name (struct name_list **list, const char *name)
{
struct name_list *new_entry;
new_entry = (struct name_list *) malloc (sizeof *new_entry);
new_entry->name = (char *) name;
new_entry->next = *list;
*list = new_entry;
void np_add_name(struct name_list **list, const char *name) {
struct name_list *new_entry;
new_entry = (struct name_list *)malloc(sizeof *new_entry);
new_entry->name = (char *)name;
new_entry->next = *list;
*list = new_entry;
}
/* @brief Initialises a new regex at the begin of list via regcomp(3)
@ -50,17 +48,14 @@ np_add_name (struct name_list **list, const char *name)
* @param regex the string containing the regex which should be inserted into the list
* @param clags the cflags parameter for regcomp(3)
*/
int
np_add_regex (struct regex_list **list, const char *regex, int cflags)
{
struct regex_list *new_entry = (struct regex_list *) malloc (sizeof *new_entry);
int np_add_regex(struct regex_list **list, const char *regex, int cflags) {
struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry);
if (new_entry == NULL) {
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
strerror(errno));
die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
}
int regcomp_result = regcomp(&new_entry->regex, regex, cflags);
int regcomp_result = regcomp(&new_entry->regex, regex, cflags);
if (!regcomp_result) {
// regcomp succeeded
@ -74,197 +69,187 @@ np_add_regex (struct regex_list **list, const char *regex, int cflags)
return regcomp_result;
}
}
/* Initialises a new parameter at the end of list */
struct parameter_list *
np_add_parameter(struct parameter_list **list, const char *name)
{
struct parameter_list *current = *list;
struct parameter_list *new_path;
new_path = (struct parameter_list *) malloc (sizeof *new_path);
new_path->name = (char *) malloc(strlen(name) + 1);
new_path->best_match = NULL;
new_path->name_next = NULL;
new_path->name_prev = NULL;
new_path->freespace_bytes = NULL;
new_path->freespace_units = NULL;
new_path->freespace_percent = NULL;
new_path->usedspace_bytes = NULL;
new_path->usedspace_units = NULL;
new_path->usedspace_percent = NULL;
new_path->usedinodes_percent = NULL;
new_path->freeinodes_percent = NULL;
new_path->group = NULL;
new_path->dfree_pct = -1;
new_path->dused_pct = -1;
new_path->total = 0;
new_path->available = 0;
new_path->available_to_root = 0;
new_path->used = 0;
new_path->dused_units = 0;
new_path->dfree_units = 0;
new_path->dtotal_units = 0;
new_path->inodes_total = 0;
new_path->inodes_free = 0;
new_path->inodes_free_to_root = 0;
new_path->inodes_used = 0;
new_path->dused_inodes_percent = 0;
new_path->dfree_inodes_percent = 0;
struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) {
struct parameter_list *current = *list;
struct parameter_list *new_path;
new_path = (struct parameter_list *)malloc(sizeof *new_path);
new_path->name = (char *)malloc(strlen(name) + 1);
new_path->best_match = NULL;
new_path->name_next = NULL;
new_path->name_prev = NULL;
new_path->freespace_bytes = NULL;
new_path->freespace_units = NULL;
new_path->freespace_percent = NULL;
new_path->usedspace_bytes = NULL;
new_path->usedspace_units = NULL;
new_path->usedspace_percent = NULL;
new_path->usedinodes_percent = NULL;
new_path->freeinodes_percent = NULL;
new_path->group = NULL;
new_path->dfree_pct = -1;
new_path->dused_pct = -1;
new_path->total = 0;
new_path->available = 0;
new_path->available_to_root = 0;
new_path->used = 0;
new_path->dused_units = 0;
new_path->dfree_units = 0;
new_path->dtotal_units = 0;
new_path->inodes_total = 0;
new_path->inodes_free = 0;
new_path->inodes_free_to_root = 0;
new_path->inodes_used = 0;
new_path->dused_inodes_percent = 0;
new_path->dfree_inodes_percent = 0;
strcpy(new_path->name, name);
strcpy(new_path->name, name);
if (current == NULL) {
*list = new_path;
new_path->name_prev = NULL;
} else {
while (current->name_next) {
current = current->name_next;
}
current->name_next = new_path;
new_path->name_prev = current;
}
return new_path;
if (current == NULL) {
*list = new_path;
new_path->name_prev = NULL;
} else {
while (current->name_next) {
current = current->name_next;
}
current->name_next = new_path;
new_path->name_prev = current;
}
return new_path;
}
/* Delete a given parameter from list and return pointer to next element*/
struct parameter_list *
np_del_parameter(struct parameter_list *item, struct parameter_list *prev)
{
if (item == NULL) {
return NULL;
}
struct parameter_list *next;
struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) {
if (item == NULL) {
return NULL;
}
struct parameter_list *next;
if (item->name_next)
next = item->name_next;
else
next = NULL;
if (item->name_next)
next = item->name_next;
else
next = NULL;
if (next)
next->name_prev = prev;
if (next)
next->name_prev = prev;
if (prev)
prev->name_next = next;
if (prev)
prev->name_next = next;
if (item->name) {
free(item->name);
}
free(item);
if (item->name) {
free(item->name);
}
free(item);
return next;
return next;
}
/* returns a pointer to the struct found in the list */
struct parameter_list *
np_find_parameter(struct parameter_list *list, const char *name)
{
struct parameter_list *temp_list;
for (temp_list = list; temp_list; temp_list = temp_list->name_next) {
if (! strcmp(temp_list->name, name))
return temp_list;
}
struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) {
struct parameter_list *temp_list;
for (temp_list = list; temp_list; temp_list = temp_list->name_next) {
if (!strcmp(temp_list->name, name))
return temp_list;
}
return NULL;
return NULL;
}
void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) {
struct parameter_list *d;
for (d = desired; d; d= d->name_next) {
if (! d->best_match) {
struct mount_entry *me;
size_t name_len = strlen(d->name);
size_t best_match_len = 0;
struct mount_entry *best_match = NULL;
struct fs_usage fsp;
struct parameter_list *d;
for (d = desired; d; d = d->name_next) {
if (!d->best_match) {
struct mount_entry *me;
size_t name_len = strlen(d->name);
size_t best_match_len = 0;
struct mount_entry *best_match = NULL;
struct fs_usage fsp;
/* set best match if path name exactly matches a mounted device name */
for (me = mount_list; me; me = me->me_next) {
if (strcmp(me->me_devname, d->name)==0) {
if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) {
best_match = me;
}
}
}
/* set best match if path name exactly matches a mounted device name */
for (me = mount_list; me; me = me->me_next) {
if (strcmp(me->me_devname, d->name) == 0) {
if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) {
best_match = me;
}
}
}
/* set best match by directory name if no match was found by devname */
if (! best_match) {
for (me = mount_list; me; me = me->me_next) {
size_t len = strlen (me->me_mountdir);
if ((!exact && (best_match_len <= len && len <= name_len &&
(len == 1 || strncmp (me->me_mountdir, d->name, len) == 0)))
|| (exact && strcmp(me->me_mountdir, d->name)==0))
{
if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) {
best_match = me;
best_match_len = len;
}
}
}
}
/* set best match by directory name if no match was found by devname */
if (!best_match) {
for (me = mount_list; me; me = me->me_next) {
size_t len = strlen(me->me_mountdir);
if ((!exact &&
(best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) ||
(exact && strcmp(me->me_mountdir, d->name) == 0)) {
if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) {
best_match = me;
best_match_len = len;
}
}
}
}
if (best_match) {
d->best_match = best_match;
} else {
d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */
}
}
}
if (best_match) {
d->best_match = best_match;
} else {
d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */
}
}
}
}
/* Returns true if name is in list */
bool np_find_name (struct name_list *list, const char *name) {
const struct name_list *n;
bool np_find_name(struct name_list *list, const char *name) {
const struct name_list *n;
if (list == NULL || name == NULL) {
return false;
}
for (n = list; n; n = n->next) {
if (!strcmp(name, n->name)) {
return true;
}
}
return false;
if (list == NULL || name == NULL) {
return false;
}
for (n = list; n; n = n->next) {
if (!strcmp(name, n->name)) {
return true;
}
}
return false;
}
/* Returns true if name is in list */
bool np_find_regmatch (struct regex_list *list, const char *name) {
int len;
regmatch_t m;
bool np_find_regmatch(struct regex_list *list, const char *name) {
int len;
regmatch_t m;
if (name == NULL) {
return false;
}
if (name == NULL) {
return false;
}
len = strlen(name);
len = strlen(name);
for (; list; list = list->next) {
/* Emulate a full match as if surrounded with ^( )$
by checking whether the match spans the whole name */
if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) {
return true;
}
}
for (; list; list = list->next) {
/* Emulate a full match as if surrounded with ^( )$
by checking whether the match spans the whole name */
if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) {
return true;
}
}
return false;
return false;
}
bool np_seen_name(struct name_list *list, const char *name) {
const struct name_list *s;
for (s = list; s; s=s->next) {
if (!strcmp(s->name, name)) {
return true;
}
}
return false;
}
bool np_regex_match_mount_entry (struct mount_entry* me, regex_t* re) {
if (regexec(re, me->me_devname, (size_t) 0, NULL, 0) == 0 ||
regexec(re, me->me_mountdir, (size_t) 0, NULL, 0) == 0 ) {
return true;
}
const struct name_list *s;
for (s = list; s; s = s->next) {
if (!strcmp(s->name, name)) {
return true;
}
}
return false;
}
bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) {
if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) {
return true;
}
return false;
}

View file

@ -4,49 +4,45 @@
#include "utils_base.h"
#include "regex.h"
struct name_list
{
char *name;
struct name_list *next;
struct name_list {
char *name;
struct name_list *next;
};
struct regex_list
{
regex_t regex;
struct regex_list *next;
struct regex_list {
regex_t regex;
struct regex_list *next;
};
struct parameter_list
{
char *name;
thresholds *freespace_bytes;
thresholds *freespace_units;
thresholds *freespace_percent;
thresholds *usedspace_bytes;
thresholds *usedspace_units;
thresholds *usedspace_percent;
thresholds *usedinodes_percent;
thresholds *freeinodes_percent;
char *group;
struct mount_entry *best_match;
struct parameter_list *name_next;
struct parameter_list *name_prev;
uintmax_t total, available, available_to_root, used,
inodes_free, inodes_free_to_root, inodes_used, inodes_total;
double dfree_pct, dused_pct;
uint64_t dused_units, dfree_units, dtotal_units;
double dused_inodes_percent, dfree_inodes_percent;
struct parameter_list {
char *name;
thresholds *freespace_bytes;
thresholds *freespace_units;
thresholds *freespace_percent;
thresholds *usedspace_bytes;
thresholds *usedspace_units;
thresholds *usedspace_percent;
thresholds *usedinodes_percent;
thresholds *freeinodes_percent;
char *group;
struct mount_entry *best_match;
struct parameter_list *name_next;
struct parameter_list *name_prev;
uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total;
double dfree_pct, dused_pct;
uint64_t dused_units, dfree_units, dtotal_units;
double dused_inodes_percent, dfree_inodes_percent;
};
void np_add_name (struct name_list **list, const char *name);
bool np_find_name (struct name_list *list, const char *name);
bool np_seen_name (struct name_list *list, const char *name);
int np_add_regex (struct regex_list **list, const char *regex, int cflags);
bool np_find_regmatch (struct regex_list *list, const char *name);
void np_add_name(struct name_list **list, const char *name);
bool np_find_name(struct name_list *list, const char *name);
bool np_seen_name(struct name_list *list, const char *name);
int np_add_regex(struct regex_list **list, const char *regex, int cflags);
bool np_find_regmatch(struct regex_list *list, const char *name);
struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name);
struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name);
struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev);
int search_parameter_list (struct parameter_list *list, const char *name);
int search_parameter_list(struct parameter_list *list, const char *name);
void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact);
bool np_regex_match_mount_entry (struct mount_entry* me, regex_t* re);
bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re);

View file

@ -1,51 +1,46 @@
/*****************************************************************************
*
* Library for check_tcp
*
* License: GPL
* Copyright (c) 1999-2013 Monitoring Plugins Development Team
*
* Description:
*
* This file contains utilities for check_tcp. These are tested by libtap
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Library for check_tcp
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains utilities for check_tcp. These are tested by libtap
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils_tcp.h"
#define VERBOSE(message) \
do { \
if (flags & NP_MATCH_VERBOSE) \
puts(message); \
#define VERBOSE(message) \
do { \
if (flags & NP_MATCH_VERBOSE) \
puts(message); \
} while (0)
enum np_match_result
np_expect_match(char *status, char **server_expect, int expect_count, int flags)
{
enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, int flags) {
int i, match = 0, partial = 0;
for (i = 0; i < expect_count; i++) {
if (flags & NP_MATCH_VERBOSE)
printf("looking for [%s] %s [%s]\n", server_expect[i],
(flags & NP_MATCH_EXACT) ?
"in beginning of" : "anywhere in",
status);
printf("looking for [%s] %s [%s]\n", server_expect[i], (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status);
if (flags & NP_MATCH_EXACT) {
if (strncmp(status, server_expect[i], strlen(server_expect[i])) == 0) {
@ -58,15 +53,14 @@ np_expect_match(char *status, char **server_expect, int expect_count, int flags)
continue;
}
} else if (strstr(status, server_expect[i]) != NULL) {
VERBOSE("found it");
match++;
continue;
VERBOSE("found it");
match++;
continue;
}
VERBOSE("couldn't find it");
}
if ((flags & NP_MATCH_ALL && match == expect_count) ||
(!(flags & NP_MATCH_ALL) && match >= 1))
if ((flags & NP_MATCH_ALL && match == expect_count) || (!(flags & NP_MATCH_ALL) && match >= 1))
return NP_MATCH_SUCCESS;
else if (partial > 0 || !(flags & NP_MATCH_EXACT))
return NP_MATCH_RETRY;

View file

@ -1,8 +1,8 @@
/* Header file for utils_tcp */
#define NP_MATCH_ALL 0x1
#define NP_MATCH_EXACT 0x2
#define NP_MATCH_VERBOSE 0x4
#define NP_MATCH_ALL 0x1
#define NP_MATCH_EXACT 0x2
#define NP_MATCH_VERBOSE 0x4
/*
* The NP_MATCH_RETRY state indicates that matching might succeed if
@ -16,7 +16,4 @@ enum np_match_result {
NP_MATCH_RETRY
};
enum np_match_result np_expect_match(char *status,
char **server_expect,
int server_expect_count,
int flags);
enum np_match_result np_expect_match(char *status, char **server_expect, int server_expect_count, int flags);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -97,11 +97,12 @@ my $opt_V ;
my $opt_u;
my $opt_n;
my $opt_x ;
my $opt_d;
my %excluded ;
my %unused_names ;
my @unused_ports ;
my %session_opts;
my @exclude_descriptions;
@ -134,6 +135,7 @@ if (!defined($session)) {
}
push(@snmpoids,$snmpLocIfDescr);
push(@snmpoids,$snmpIfOperStatus);
push(@snmpoids,$snmpIfAdminStatus);
push(@snmpoids,$snmpIfDescr);
@ -180,18 +182,28 @@ foreach $key (keys %ifStatus) {
if ($ifStatus{$key}{$snmpIfAdminStatus} == 1 ) {
#check only if interface is not excluded
if (!defined $unused_names{$ifStatus{$key}{$snmpIfDescr}} ) {
# check only if interface type is not listed in %excluded
if (!defined $excluded{$ifStatus{$key}{$snmpIfType}} ) {
if ($ifStatus{$key}{$snmpIfOperStatus} == 1 ) { $ifup++ ; }
if ($ifStatus{$key}{$snmpIfOperStatus} == 2 ) {
$ifdown++ ;
if (defined $ifXTable) {
$ifmessage .= sprintf("%s: down -> %s<BR>\n", $ifStatus{$key}{$snmpIfName}, $ifStatus{$key}{$snmpIfAlias});
}else{
$ifmessage .= sprintf("%s: down <BR>\n",$ifStatus{$key}{$snmpIfDescr});
}
#check only if interface is not excluded (by description)
#counter for matching descriptions
my $match_descr = 0;
foreach my $description (@exclude_descriptions) {
if ($ifStatus{$key}{$snmpLocIfDescr} =~ /^$description/) { $match_descr = 1; }
}
if ($match_descr == 0) {
# check only if interface type is not listed in %excluded
if (!defined $excluded{$ifStatus{$key}{$snmpIfType}} ) {
if ($ifStatus{$key}{$snmpIfOperStatus} == 1 ) { $ifup++ ; }
if ($ifStatus{$key}{$snmpIfOperStatus} == 2 ) {
$ifdown++ ;
if (defined $ifXTable) {
$ifmessage .= sprintf("%s: down -> %s<BR>\n", $ifStatus{$key}{$snmpIfName}, $ifStatus{$key}{$snmpIfAlias});
}else{
$ifmessage .= sprintf("%s: down <BR>\n",$ifStatus{$key}{$snmpIfDescr});
}
}
if ($ifStatus{$key}{$snmpIfOperStatus} == 5 ) { $ifdormant++ ;}
} else {
$ifexclude++;
}
if ($ifStatus{$key}{$snmpIfOperStatus} == 5 ) { $ifdormant++ ;}
} else {
$ifexclude++;
}
@ -264,6 +276,9 @@ sub print_help() {
printf " the descriptive name. Do not use if you don't know what this is. \n";
printf " -x (--exclude) A comma separated list of ifType values that should be excluded \n";
printf " from the report (default for an empty list is PPP(23).\n";
printf " -d (--exclude_ports_by_description) A comma separated list of LocIfDescr values that should be excluded \n";
printf " from the report (default is an empty exclusion list). Done using regexp '/^arg/', ex:\n";
printf " '-d connect,test' will match with descriptions like 'testing phase' but not 'in testing'.\n";
printf " -n (--unused_ports_by_name) A comma separated list of ifDescr values that should be excluded \n";
printf " from the report (default is an empty exclusion list).\n";
printf " -u (--unused_ports) A comma separated list of ifIndex values that should be excluded \n";
@ -306,6 +321,7 @@ sub process_arguments() {
"I" => \$ifXTable, "ifmib" => \$ifXTable,
"x:s" => \$opt_x, "exclude:s" => \$opt_x,
"u=s" => \$opt_u, "unused_ports=s" => \$opt_u,
"d=s" => \$opt_d, "exclude_ports_by_description=s" => \$opt_d,
"n=s" => \$opt_n, "unused_ports_by_name=s" => \$opt_n,
"M=i" => \$maxmsgsize, "maxmsgsize=i" => \$maxmsgsize,
"t=i" => \$timeout, "timeout=i" => \$timeout,
@ -414,6 +430,11 @@ sub process_arguments() {
}
}
# Exclude interfaces by descriptions
if (defined $opt_d) {
@exclude_descriptions = split(/,/,$opt_d);
}
# Excluded interface descriptors
if (defined $opt_n) {
my @unused = split(/,/,$opt_n);

View file

@ -3,7 +3,7 @@
* Monitoring check_apt plugin
*
* License: GPL
* Copyright (c) 2006-2008 Monitoring Plugins Development Team
* Copyright (c) 2006-2024 Monitoring Plugins Development Team
*
* Original author: Sean Finney
*
@ -30,7 +30,7 @@
*****************************************************************************/
const char *progname = "check_apt";
const char *copyright = "2006-2008";
const char *copyright = "2006-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"

View file

@ -1,33 +1,33 @@
/*****************************************************************************
*
* Monitoring check_by_ssh plugin
*
* License: GPL
* Copyright (c) 2000-2008 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_by_ssh plugin
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_by_ssh plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_by_ssh plugin
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_by_ssh";
const char *copyright = "2000-2008";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -36,82 +36,80 @@ const char *email = "devel@monitoring-plugins.org";
#include "utils_cmd.h"
#ifndef NP_MAXARGS
#define NP_MAXARGS 1024
# define NP_MAXARGS 1024
#endif
int process_arguments (int, char **);
int validate_arguments (void);
void comm_append (const char *);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int validate_arguments(void);
static void comm_append(const char * /*str*/);
static void print_help(void);
void print_usage(void);
unsigned int commands = 0;
unsigned int services = 0;
int skip_stdout = 0;
int skip_stderr = 0;
int warn_on_stderr = 0;
bool unknown_timeout = false;
char *remotecmd = NULL;
char **commargv = NULL;
int commargc = 0;
char *hostname = NULL;
char *outputfile = NULL;
char *host_shortname = NULL;
char **service;
bool passive = false;
bool verbose = false;
static unsigned int commands = 0;
static unsigned int services = 0;
static int skip_stdout = 0;
static int skip_stderr = 0;
static int warn_on_stderr = 0;
static bool unknown_timeout = false;
static char *remotecmd = NULL;
static char **commargv = NULL;
static int commargc = 0;
static char *hostname = NULL;
static char *outputfile = NULL;
static char *host_shortname = NULL;
static char **service;
static bool passive = false;
static bool verbose = false;
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
char *status_text;
int cresult;
int result = STATE_UNKNOWN;
time_t local_time;
FILE *fp = NULL;
output chld_out, chld_err;
FILE *file_pointer = NULL;
output chld_out;
output chld_err;
remotecmd = "";
comm_append(SSH_COMMAND);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
/* process arguments */
if (process_arguments (argc, argv) == ERROR)
if (process_arguments(argc, argv) == ERROR)
usage_va(_("Could not parse arguments"));
/* Set signal handling and alarm timeout */
if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
usage_va(_("Cannot catch SIGALRM"));
}
alarm (timeout_interval);
alarm(timeout_interval);
/* run the command */
if (verbose) {
printf ("Command: %s\n", commargv[0]);
printf("Command: %s\n", commargv[0]);
for (int i = 1; i < commargc; i++)
printf ("Argument %i: %s\n", i, commargv[i]);
printf("Argument %i: %s\n", i, commargv[i]);
}
result = cmd_run_array (commargv, &chld_out, &chld_err, 0);
result = cmd_run_array(commargv, &chld_out, &chld_err, 0);
/* SSH returns 255 if connection attempt fails; include the first line of error output */
if (result == 255 && unknown_timeout) {
printf (_("SSH connection failed: %s\n"),
chld_err.lines > 0 ? chld_err.line[0] : "(no error output)");
printf(_("SSH connection failed: %s\n"), chld_err.lines > 0 ? chld_err.line[0] : "(no error output)");
return STATE_UNKNOWN;
}
if (verbose) {
for(size_t i = 0; i < chld_out.lines; i++)
for (size_t i = 0; i < chld_out.lines; i++)
printf("stdout: %s\n", chld_out.line[i]);
for(size_t i = 0; i < chld_err.lines; i++)
for (size_t i = 0; i < chld_err.lines; i++)
printf("stderr: %s\n", chld_err.line[i]);
}
@ -121,155 +119,144 @@ main (int argc, char **argv)
skip_stderr = chld_err.lines;
/* UNKNOWN or worse if (non-skipped) output found on stderr */
if(chld_err.lines > (size_t)skip_stderr) {
printf (_("Remote command execution failed: %s\n"),
chld_err.line[skip_stderr]);
if ( warn_on_stderr )
if (chld_err.lines > (size_t)skip_stderr) {
printf(_("Remote command execution failed: %s\n"), chld_err.line[skip_stderr]);
if (warn_on_stderr)
return max_state_alt(result, STATE_WARNING);
else
return max_state_alt(result, STATE_UNKNOWN);
return max_state_alt(result, STATE_UNKNOWN);
}
/* this is simple if we're not supposed to be passive.
* Wrap up quickly and keep the tricks below */
if(!passive) {
if (!passive) {
if (chld_out.lines > (size_t)skip_stdout)
for (size_t i = skip_stdout; i < chld_out.lines; i++)
puts (chld_out.line[i]);
puts(chld_out.line[i]);
else
printf (_("%s - check_by_ssh: Remote command '%s' returned status %d\n"),
state_text(result), remotecmd, result);
return result; /* return error status from remote command */
printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), remotecmd, result);
return result; /* return error status from remote command */
}
/*
* Passive mode
*/
/* process output */
if (!(fp = fopen (outputfile, "a"))) {
printf (_("SSH WARNING: could not open %s\n"), outputfile);
exit (STATE_UNKNOWN);
if (!(file_pointer = fopen(outputfile, "a"))) {
printf(_("SSH WARNING: could not open %s\n"), outputfile);
exit(STATE_UNKNOWN);
}
local_time = time (NULL);
local_time = time(NULL);
commands = 0;
for(size_t i = skip_stdout; i < chld_out.lines; i++) {
for (size_t i = skip_stdout; i < chld_out.lines; i++) {
status_text = chld_out.line[i++];
if (i == chld_out.lines || strstr (chld_out.line[i], "STATUS CODE: ") == NULL)
die (STATE_UNKNOWN, _("%s: Error parsing output\n"), progname);
if (i == chld_out.lines || strstr(chld_out.line[i], "STATUS CODE: ") == NULL)
die(STATE_UNKNOWN, _("%s: Error parsing output\n"), progname);
if (service[commands] && status_text
&& sscanf (chld_out.line[i], "STATUS CODE: %d", &cresult) == 1)
{
fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
(int) local_time, host_shortname, service[commands++],
cresult, status_text);
if (service[commands] && status_text && sscanf(chld_out.line[i], "STATUS CODE: %d", &cresult) == 1) {
fprintf(file_pointer, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, host_shortname, service[commands++],
cresult, status_text);
}
}
/* Multiple commands and passive checking should always return OK */
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int process_arguments(int argc, char **argv) {
int c;
char *p1, *p2;
char *p1;
char *p2;
int option = 0;
static struct option longopts[] = {
{"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'},
{"unknown-timeout", no_argument, 0, 'U'},
{"host", required_argument, 0, 'H'}, /* backward compatibility */
{"hostname", 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'},
{"skip", optional_argument, 0, 'S'}, /* backwards compatibility */
{"skip-stdout", optional_argument, 0, 'S'},
{"skip-stderr", optional_argument, 0, 'E'},
{"warn-on-stderr", no_argument, 0, 'W'},
{"proto1", no_argument, 0, '1'},
{"proto2", no_argument, 0, '2'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"ssh-option", required_argument, 0, 'o'},
{"quiet", no_argument, 0, 'q'},
{"configfile", optional_argument, 0, 'F'},
{0, 0, 0, 0}
};
static struct option longopts[] = {{"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'},
{"unknown-timeout", no_argument, 0, 'U'},
{"host", required_argument, 0, 'H'}, /* backward compatibility */
{"hostname", 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'},
{"skip", optional_argument, 0, 'S'}, /* backwards compatibility */
{"skip-stdout", optional_argument, 0, 'S'},
{"skip-stderr", optional_argument, 0, 'E'},
{"warn-on-stderr", no_argument, 0, 'W'},
{"proto1", no_argument, 0, '1'},
{"proto2", no_argument, 0, '2'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"ssh-option", required_argument, 0, 'o'},
{"quiet", no_argument, 0, 'q'},
{"configfile", optional_argument, 0, 'F'},
{0, 0, 0, 0}};
if (argc < 2)
return ERROR;
for (c = 1; c < argc; c++)
if (strcmp ("-to", argv[c]) == 0)
strcpy (argv[c], "-t");
if (strcmp("-to", argv[c]) == 0)
strcpy(argv[c], "-t");
while (1) {
c = getopt_long (argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts,
&option);
c = getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option);
if (c == -1 || c == EOF)
break;
switch (c) {
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'v': /* help */
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'v': /* help */
verbose = true;
break;
case 't': /* timeout period */
if (!is_integer (optarg))
case 't': /* timeout period */
if (!is_integer(optarg))
usage_va(_("Timeout interval must be a positive integer"));
else
timeout_interval = atoi (optarg);
timeout_interval = atoi(optarg);
break;
case 'U':
unknown_timeout = true;
break;
case 'H': /* host */
case 'H': /* host */
hostname = optarg;
break;
case 'p': /* port number */
if (!is_integer (optarg))
if (!is_integer(optarg))
usage_va(_("Port must be a positive integer"));
comm_append("-p");
comm_append(optarg);
break;
case 'O': /* output file */
case 'O': /* output file */
outputfile = optarg;
passive = true;
break;
case 's': /* description of service to check */
case 's': /* description of service to check */
p1 = optarg;
service = realloc (service, (++services) * sizeof(char *));
while ((p2 = index (p1, ':'))) {
service = realloc(service, (++services) * sizeof(char *));
while ((p2 = index(p1, ':'))) {
*p2 = '\0';
service[services - 1] = p1;
service = realloc (service, (++services) * sizeof(char *));
service = realloc(service, (++services) * sizeof(char *));
p1 = p2 + 1;
}
service[services - 1] = p1;
break;
case 'n': /* short name of host in the monitoring configuration */
case 'n': /* short name of host in the monitoring configuration */
host_shortname = optarg;
break;
@ -277,67 +264,67 @@ process_arguments (int argc, char **argv)
comm_append("-l");
comm_append(optarg);
break;
case 'l': /* login name */
case 'l': /* login name */
comm_append("-l");
comm_append(optarg);
break;
case 'i': /* identity */
case 'i': /* identity */
comm_append("-i");
comm_append(optarg);
break;
case '1': /* Pass these switches directly to ssh */
case '1': /* Pass these switches directly to ssh */
comm_append("-1");
break;
case '2': /* 1 to force version 1, 2 to force version 2 */
case '2': /* 1 to force version 1, 2 to force version 2 */
comm_append("-2");
break;
case '4': /* -4 for IPv4 */
case '4': /* -4 for IPv4 */
comm_append("-4");
break;
case '6': /* -6 for IPv6 */
case '6': /* -6 for IPv6 */
comm_append("-6");
break;
case 'f': /* fork to background */
case 'f': /* fork to background */
comm_append("-f");
break;
case 'C': /* Command for remote machine */
case 'C': /* Command for remote machine */
commands++;
if (commands > 1)
xasprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
xasprintf (&remotecmd, "%s%s", remotecmd, optarg);
xasprintf(&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
xasprintf(&remotecmd, "%s%s", remotecmd, optarg);
break;
case 'S': /* skip n (or all) lines on stdout */
case 'S': /* skip n (or all) lines on stdout */
if (optarg == NULL)
skip_stdout = -1; /* skip all output on stdout */
else if (!is_integer (optarg))
else if (!is_integer(optarg))
usage_va(_("skip-stdout argument must be an integer"));
else
skip_stdout = atoi (optarg);
skip_stdout = atoi(optarg);
break;
case 'E': /* skip n (or all) lines on stderr */
case 'E': /* skip n (or all) lines on stderr */
if (optarg == NULL)
skip_stderr = -1; /* skip all output on stderr */
else if (!is_integer (optarg))
else if (!is_integer(optarg))
usage_va(_("skip-stderr argument must be an integer"));
else
skip_stderr = atoi (optarg);
skip_stderr = atoi(optarg);
break;
case 'W': /* exit with warning if there is an output on stderr */
case 'W': /* exit with warning if there is an output on stderr */
warn_on_stderr = 1;
break;
case 'o': /* Extra options for the ssh command */
case 'o': /* Extra options for the ssh command */
comm_append("-o");
comm_append(optarg);
break;
case 'q': /* Tell the ssh command to be quiet */
case 'q': /* Tell the ssh command to be quiet */
comm_append("-q");
break;
case 'F': /* ssh configfile */
case 'F': /* ssh configfile */
comm_append("-F");
comm_append(optarg);
break;
default: /* help */
default: /* help */
usage5();
}
}
@ -345,7 +332,7 @@ process_arguments (int argc, char **argv)
c = optind;
if (hostname == NULL) {
if (c <= argc) {
die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname);
die(STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname);
}
hostname = argv[c++];
}
@ -353,143 +340,130 @@ process_arguments (int argc, char **argv)
if (strlen(remotecmd) == 0) {
for (; c < argc; c++)
if (strlen(remotecmd) > 0)
xasprintf (&remotecmd, "%s %s", remotecmd, argv[c]);
xasprintf(&remotecmd, "%s %s", remotecmd, argv[c]);
else
xasprintf (&remotecmd, "%s", argv[c]);
xasprintf(&remotecmd, "%s", argv[c]);
}
if (commands > 1 || passive)
xasprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
xasprintf(&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
if (remotecmd == NULL || strlen (remotecmd) <= 1)
if (remotecmd == NULL || strlen(remotecmd) <= 1)
usage_va(_("No remotecmd"));
comm_append(hostname);
comm_append(remotecmd);
return validate_arguments ();
return validate_arguments();
}
void
comm_append (const char *str)
{
void comm_append(const char *str) {
if (++commargc > NP_MAXARGS)
die(STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, NP_MAXARGS);
if ((commargv = (char **)realloc(commargv, (commargc+1) * sizeof(char *))) == NULL)
if ((commargv = (char **)realloc(commargv, (commargc + 1) * sizeof(char *))) == NULL)
die(STATE_UNKNOWN, _("Can not (re)allocate 'commargv' buffer\n"));
commargv[commargc-1] = strdup(str);
commargv[commargc - 1] = strdup(str);
commargv[commargc] = NULL;
}
int
validate_arguments (void)
{
int validate_arguments(void) {
if (remotecmd == NULL || hostname == NULL)
return ERROR;
if (passive && commands != services)
die (STATE_UNKNOWN, _("%s: In passive mode, you must provide a service name for each command.\n"), progname);
die(STATE_UNKNOWN, _("%s: In passive mode, you must provide a service name for each command.\n"), progname);
if (passive && host_shortname == NULL)
die (STATE_UNKNOWN, _("%s: In passive mode, you must provide the host short name from the monitoring configs.\n"), progname);
die(STATE_UNKNOWN, _("%s: In passive mode, you must provide the host short name from the monitoring configs.\n"), progname);
return OK;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("Copyright (c) 1999 Karl DeBisschop <kdebisschop@users.sourceforge.net>\n");
printf(COPYRIGHT, copyright, email);
printf ("Copyright (c) 1999 Karl DeBisschop <kdebisschop@users.sourceforge.net>\n");
printf (COPYRIGHT, copyright, email);
printf(_("This plugin uses SSH to execute commands on a remote host"));
printf (_("This plugin uses SSH to execute commands on a remote host"));
printf("\n\n");
printf ("\n\n");
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf (UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_EXTRA_OPTS);
printf(UT_HOST_PORT, 'p', "none");
printf (UT_HOST_PORT, 'p', "none");
printf(UT_IPv46);
printf (UT_IPv46);
printf (" %s\n", "-1, --proto1");
printf (" %s\n", _("tell ssh to use Protocol 1 [optional]"));
printf (" %s\n", "-2, --proto2");
printf (" %s\n", _("tell ssh to use Protocol 2 [optional]"));
printf (" %s\n", "-S, --skip-stdout[=n]");
printf (" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]"));
printf (" %s\n", "-E, --skip-stderr[=n]");
printf (" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]"));
printf (" %s\n", "-W, --warn-on-stderr]");
printf (" %s\n", _("Exit with an warning, if there is an output on STDERR"));
printf (" %s\n", "-f");
printf (" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed"));
printf (" %s\n","-C, --command='COMMAND STRING'");
printf (" %s\n", _("command to execute on the remote machine"));
printf (" %s\n","-l, --logname=USERNAME");
printf (" %s\n", _("SSH user name on remote host [optional]"));
printf (" %s\n","-i, --identity=KEYFILE");
printf (" %s\n", _("identity of an authorized key [optional]"));
printf (" %s\n","-O, --output=FILE");
printf (" %s\n", _("external command file for monitoring [optional]"));
printf (" %s\n","-s, --services=LIST");
printf (" %s\n", _("list of monitoring service names, separated by ':' [optional]"));
printf (" %s\n","-n, --name=NAME");
printf (" %s\n", _("short name of host in the monitoring configuration [optional]"));
printf (" %s\n","-o, --ssh-option=OPTION");
printf (" %s\n", _("Call ssh with '-o OPTION' (may be used multiple times) [optional]"));
printf (" %s\n","-F, --configfile");
printf (" %s\n", _("Tell ssh to use this configfile [optional]"));
printf (" %s\n","-q, --quiet");
printf (" %s\n", _("Tell ssh to suppress warning and diagnostic messages [optional]"));
printf (UT_WARN_CRIT);
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (" %s\n","-U, --unknown-timeout");
printf (" %s\n", _("Make connection problems return UNKNOWN instead of CRITICAL"));
printf (UT_VERBOSE);
printf(" %s\n", "-1, --proto1");
printf(" %s\n", _("tell ssh to use Protocol 1 [optional]"));
printf(" %s\n", "-2, --proto2");
printf(" %s\n", _("tell ssh to use Protocol 2 [optional]"));
printf(" %s\n", "-S, --skip-stdout[=n]");
printf(" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]"));
printf(" %s\n", "-E, --skip-stderr[=n]");
printf(" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]"));
printf(" %s\n", "-W, --warn-on-stderr]");
printf(" %s\n", _("Exit with an warning, if there is an output on STDERR"));
printf(" %s\n", "-f");
printf(" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed"));
printf(" %s\n", "-C, --command='COMMAND STRING'");
printf(" %s\n", _("command to execute on the remote machine"));
printf(" %s\n", "-l, --logname=USERNAME");
printf(" %s\n", _("SSH user name on remote host [optional]"));
printf(" %s\n", "-i, --identity=KEYFILE");
printf(" %s\n", _("identity of an authorized key [optional]"));
printf(" %s\n", "-O, --output=FILE");
printf(" %s\n", _("external command file for monitoring [optional]"));
printf(" %s\n", "-s, --services=LIST");
printf(" %s\n", _("list of monitoring service names, separated by ':' [optional]"));
printf(" %s\n", "-n, --name=NAME");
printf(" %s\n", _("short name of host in the monitoring configuration [optional]"));
printf(" %s\n", "-o, --ssh-option=OPTION");
printf(" %s\n", _("Call ssh with '-o OPTION' (may be used multiple times) [optional]"));
printf(" %s\n", "-F, --configfile");
printf(" %s\n", _("Tell ssh to use this configfile [optional]"));
printf(" %s\n", "-q, --quiet");
printf(" %s\n", _("Tell ssh to suppress warning and diagnostic messages [optional]"));
printf(UT_WARN_CRIT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(" %s\n", "-U, --unknown-timeout");
printf(" %s\n", _("Make connection problems return UNKNOWN instead of CRITICAL"));
printf(UT_VERBOSE);
printf("\n");
printf (" %s\n", _("The most common mode of use is to refer to a local identity file with"));
printf (" %s\n", _("the '-i' option. In this mode, the identity pair should have a null"));
printf (" %s\n", _("passphrase and the public key should be listed in the authorized_keys"));
printf (" %s\n", _("file of the remote host. Usually the key will be restricted to running"));
printf (" %s\n", _("only one command on the remote server. If the remote SSH server tracks"));
printf (" %s\n", _("invocation arguments, the one remote program may be an agent that can"));
printf (" %s\n", _("execute additional commands as proxy"));
printf("\n");
printf (" %s\n", _("To use passive mode, provide multiple '-C' options, and provide"));
printf (" %s\n", _("all of -O, -s, and -n options (servicelist order must match '-C'options)"));
printf ("\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "$ check_by_ssh -H localhost -n lh -s c1:c2:c3 -C uptime -C uptime -C uptime -O /tmp/foo");
printf (" %s\n", "$ cat /tmp/foo");
printf (" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c1;0; up 2 days");
printf (" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c2;0; up 2 days");
printf (" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c3;0; up 2 days");
printf(" %s\n", _("The most common mode of use is to refer to a local identity file with"));
printf(" %s\n", _("the '-i' option. In this mode, the identity pair should have a null"));
printf(" %s\n", _("passphrase and the public key should be listed in the authorized_keys"));
printf(" %s\n", _("file of the remote host. Usually the key will be restricted to running"));
printf(" %s\n", _("only one command on the remote server. If the remote SSH server tracks"));
printf(" %s\n", _("invocation arguments, the one remote program may be an agent that can"));
printf(" %s\n", _("execute additional commands as proxy"));
printf("\n");
printf(" %s\n", _("To use passive mode, provide multiple '-C' options, and provide"));
printf(" %s\n", _("all of -O, -s, and -n options (servicelist order must match '-C'options)"));
printf("\n");
printf("%s\n", _("Examples:"));
printf(" %s\n", "$ check_by_ssh -H localhost -n lh -s c1:c2:c3 -C uptime -C uptime -C uptime -O /tmp/foo");
printf(" %s\n", "$ cat /tmp/foo");
printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c1;0; up 2 days");
printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c2;0; up 2 days");
printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c3;0; up 2 days");
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s -H <host> -C <command> [-fqvU] [-1|-2] [-4|-6]\n"
" [-S [lines]] [-E [lines]] [-W] [-t timeout] [-i identity]\n"
" [-l user] [-n name] [-s servicelist] [-O outputfile]\n"
" [-p port] [-o ssh-option] [-F configfile]\n",
progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s -H <host> -C <command> [-fqvU] [-1|-2] [-4|-6]\n"
" [-S [lines]] [-E [lines]] [-W] [-t timeout] [-i identity]\n"
" [-l user] [-n name] [-s servicelist] [-O outputfile]\n"
" [-p port] [-o ssh-option] [-F configfile]\n",
progname);
}

View file

@ -1,92 +1,92 @@
/*****************************************************************************
*
* check_cluster.c - Host and Service Cluster Plugin for Monitoring
*
* License: GPL
* Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)
* Copyright (c) 2007 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* check_cluster.c - Host and Service Cluster Plugin for Monitoring
*
* License: GPL
* Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)
* Copyright (c) 2007-2024 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_cluster";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
#include "utils_base.h"
#define CHECK_SERVICES 1
#define CHECK_HOSTS 2
enum {
CHECK_SERVICES = 1,
CHECK_HOSTS = 2
};
void print_help (void);
void print_usage (void);
static void print_help(void);
void print_usage(void);
int total_services_ok=0;
int total_services_warning=0;
int total_services_unknown=0;
int total_services_critical=0;
static int total_services_ok = 0;
static int total_services_warning = 0;
static int total_services_unknown = 0;
static int total_services_critical = 0;
int total_hosts_up=0;
int total_hosts_down=0;
int total_hosts_unreachable=0;
static int total_hosts_up = 0;
static int total_hosts_down = 0;
static int total_hosts_unreachable = 0;
char *warn_threshold;
char *crit_threshold;
static char *warn_threshold;
static char *crit_threshold;
int check_type=CHECK_SERVICES;
static int check_type = CHECK_SERVICES;
char *data_vals=NULL;
char *label=NULL;
static char *data_vals = NULL;
static char *label = NULL;
int verbose=0;
static int verbose = 0;
int process_arguments(int,char **);
static int process_arguments(int /*argc*/, char ** /*argv*/);
int main(int argc, char **argv){
int main(int argc, char **argv) {
char *ptr;
int data_val;
int return_code=STATE_OK;
int return_code = STATE_OK;
thresholds *thresholds = NULL;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts(&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if(process_arguments(argc,argv)==ERROR)
if (process_arguments(argc, argv) == ERROR)
usage(_("Could not parse arguments"));
/* Initialize the thresholds */
set_thresholds(&thresholds, warn_threshold, crit_threshold);
if(verbose)
if (verbose)
print_thresholds("check_cluster", thresholds);
/* check the data values */
for(ptr=strtok(data_vals,",");ptr!=NULL;ptr=strtok(NULL,",")){
for (ptr = strtok(data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) {
data_val=atoi(ptr);
data_val = atoi(ptr);
if(check_type==CHECK_SERVICES){
switch(data_val){
if (check_type == CHECK_SERVICES) {
switch (data_val) {
case 0:
total_services_ok++;
break;
@ -101,10 +101,9 @@ int main(int argc, char **argv){
break;
default:
break;
}
}
else{
switch(data_val){
}
} else {
switch (data_val) {
case 0:
total_hosts_up++;
break;
@ -116,67 +115,54 @@ int main(int argc, char **argv){
break;
default:
break;
}
}
}
}
}
}
/* return the status of the cluster */
if(check_type==CHECK_SERVICES){
return_code=get_status(total_services_warning+total_services_unknown+total_services_critical, thresholds);
printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n",
state_text(return_code), (label==NULL)?"Service cluster":label,
total_services_ok,total_services_warning,
total_services_unknown,total_services_critical);
}
else{
return_code=get_status(total_hosts_down+total_hosts_unreachable, thresholds);
printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n",
state_text(return_code), (label==NULL)?"Host cluster":label,
total_hosts_up,total_hosts_down,total_hosts_unreachable);
if (check_type == CHECK_SERVICES) {
return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, thresholds);
printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n", state_text(return_code),
(label == NULL) ? "Service cluster" : label, total_services_ok, total_services_warning, total_services_unknown,
total_services_critical);
} else {
return_code = get_status(total_hosts_down + total_hosts_unreachable, thresholds);
printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code), (label == NULL) ? "Host cluster" : label,
total_hosts_up, total_hosts_down, total_hosts_unreachable);
}
return return_code;
}
int process_arguments(int argc, char **argv){
int process_arguments(int argc, char **argv) {
int c;
char *ptr;
int option=0;
static struct option longopts[]={
{"data", required_argument,0,'d'},
{"warning", required_argument,0,'w'},
{"critical", required_argument,0,'c'},
{"label", required_argument,0,'l'},
{"host", no_argument, 0,'h'},
{"service", no_argument, 0,'s'},
{"verbose", no_argument, 0,'v'},
{"version", no_argument, 0,'V'},
{"help", no_argument, 0,'H'},
{0,0,0,0}
};
int option = 0;
static struct option longopts[] = {{"data", required_argument, 0, 'd'}, {"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'}, {"label", required_argument, 0, 'l'},
{"host", no_argument, 0, 'h'}, {"service", no_argument, 0, 's'},
{"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'H'}, {0, 0, 0, 0}};
/* no options were supplied */
if(argc<2)
if (argc < 2)
return ERROR;
while(1){
while (1) {
c=getopt_long(argc,argv,"hHsvVw:c:d:l:",longopts,&option);
c = getopt_long(argc, argv, "hHsvVw:c:d:l:", longopts, &option);
if(c==-1 || c==EOF || c==1)
if (c == -1 || c == EOF || c == 1)
break;
switch(c){
switch (c) {
case 'h': /* host cluster */
check_type=CHECK_HOSTS;
check_type = CHECK_HOSTS;
break;
case 's': /* service cluster */
check_type=CHECK_SERVICES;
check_type = CHECK_SERVICES;
break;
case 'w': /* warning threshold */
@ -188,20 +174,20 @@ int process_arguments(int argc, char **argv){
break;
case 'd': /* data values */
data_vals=(char *)strdup(optarg);
data_vals = (char *)strdup(optarg);
/* validate data */
for (ptr=data_vals;ptr!=NULL;ptr+=2){
if (ptr[0]<'0' || ptr[0]>'3')
for (ptr = data_vals; ptr != NULL; ptr += 2) {
if (ptr[0] < '0' || ptr[0] > '3')
return ERROR;
if (ptr[1]=='\0')
if (ptr[1] == '\0')
break;
if (ptr[1]!=',')
if (ptr[1] != ',')
return ERROR;
}
break;
case 'l': /* text label */
label=(char *)strdup(optarg);
label = (char *)strdup(optarg);
break;
case 'v': /* verbose */
@ -209,8 +195,8 @@ int process_arguments(int argc, char **argv){
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
break;
case 'H': /* help */
@ -221,20 +207,18 @@ int process_arguments(int argc, char **argv){
default:
return ERROR;
break;
}
}
}
if(data_vals==NULL)
if (data_vals == NULL)
return ERROR;
return OK;
}
void
print_help(void)
{
void print_help(void) {
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)\n");
printf("Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org)\n");
printf(COPYRIGHT, copyright, email);
printf(_("Host/Service Cluster Plugin for Monitoring"));
@ -245,21 +229,21 @@ print_help(void)
printf("\n");
printf("%s\n", _("Options:"));
printf(UT_EXTRA_OPTS);
printf (" %s\n", "-s, --service");
printf (" %s\n", _("Check service cluster status"));
printf (" %s\n", "-h, --host");
printf (" %s\n", _("Check host cluster status"));
printf (" %s\n", "-l, --label=STRING");
printf (" %s\n", _("Optional prepended text output (i.e. \"Host cluster\")"));
printf (" %s\n", "-w, --warning=THRESHOLD");
printf (" %s\n", _("Specifies the range of hosts or services in cluster that must be in a"));
printf (" %s\n", _("non-OK state in order to return a WARNING status level"));
printf (" %s\n", "-c, --critical=THRESHOLD");
printf (" %s\n", _("Specifies the range of hosts or services in cluster that must be in a"));
printf (" %s\n", _("non-OK state in order to return a CRITICAL status level"));
printf (" %s\n", "-d, --data=LIST");
printf (" %s\n", _("The status codes of the hosts or services in the cluster, separated by"));
printf (" %s\n", _("commas"));
printf(" %s\n", "-s, --service");
printf(" %s\n", _("Check service cluster status"));
printf(" %s\n", "-h, --host");
printf(" %s\n", _("Check host cluster status"));
printf(" %s\n", "-l, --label=STRING");
printf(" %s\n", _("Optional prepended text output (i.e. \"Host cluster\")"));
printf(" %s\n", "-w, --warning=THRESHOLD");
printf(" %s\n", _("Specifies the range of hosts or services in cluster that must be in a"));
printf(" %s\n", _("non-OK state in order to return a WARNING status level"));
printf(" %s\n", "-c, --critical=THRESHOLD");
printf(" %s\n", _("Specifies the range of hosts or services in cluster that must be in a"));
printf(" %s\n", _("non-OK state in order to return a CRITICAL status level"));
printf(" %s\n", "-d, --data=LIST");
printf(" %s\n", _("The status codes of the hosts or services in the cluster, separated by"));
printf(" %s\n", _("commas"));
printf(UT_VERBOSE);
@ -267,23 +251,18 @@ print_help(void)
printf("%s\n", _("Notes:"));
printf(UT_THRESHOLDS_NOTES);
printf ("\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:");
printf (" %s\n", _("Will alert critical if there are 3 or more service data points in a non-OK") );
printf (" %s\n", _("state.") );
printf("\n");
printf("%s\n", _("Examples:"));
printf(" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:");
printf(" %s\n", _("Will alert critical if there are 3 or more service data points in a non-OK"));
printf(" %s\n", _("state."));
printf(UT_SUPPORT);
}
void
print_usage(void)
{
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s (-s | -h) -d val1[,val2,...,valn] [-l label]\n", progname);
printf("[-w threshold] [-c threshold] [-v] [--help]\n");
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,30 +1,30 @@
/*****************************************************************************
*
* Monitoring check_dig plugin
*
* License: GPL
* Copyright (c) 2002-2008 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_dig plugin
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_dig plugin
*
* License: GPL
* Copyright (c) 2002-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_dig plugin
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
/* Hackers note:
* There are typecasts to (char *) from _("foo bar") in this file.
@ -33,7 +33,7 @@
* because on some architectures those strings are in non-writable memory */
const char *progname = "check_dig";
const char *copyright = "2002-2008";
const char *copyright = "2002-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -41,340 +41,312 @@ const char *email = "devel@monitoring-plugins.org";
#include "utils.h"
#include "runcmd.h"
int process_arguments (int, char **);
int validate_arguments (void);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int validate_arguments(void);
static void print_help(void);
void print_usage(void);
#define UNDEFINED 0
#define DEFAULT_PORT 53
#define UNDEFINED 0
#define DEFAULT_PORT 53
#define DEFAULT_TRIES 2
char *query_address = NULL;
char *record_type = "A";
char *expected_address = NULL;
char *dns_server = NULL;
char *dig_args = "";
char *query_transport = "";
bool verbose = false;
int server_port = DEFAULT_PORT;
int number_tries = DEFAULT_TRIES;
double warning_interval = UNDEFINED;
double critical_interval = UNDEFINED;
struct timeval tv;
static char *query_address = NULL;
static char *record_type = "A";
static char *expected_address = NULL;
static char *dns_server = NULL;
static char *dig_args = "";
static char *query_transport = "";
static bool verbose = false;
static int server_port = DEFAULT_PORT;
static int number_tries = DEFAULT_TRIES;
static double warning_interval = UNDEFINED;
static double critical_interval = UNDEFINED;
static struct timeval tv;
int
main (int argc, char **argv)
{
char *command_line;
output chld_out, chld_err;
char *msg = NULL;
size_t i;
char *t;
long microsec;
double elapsed_time;
int result = STATE_UNKNOWN;
int timeout_interval_dig;
int main(int argc, char **argv) {
char *command_line;
output chld_out;
output chld_err;
char *msg = NULL;
size_t i;
char *t;
long microsec;
double elapsed_time;
int result = STATE_UNKNOWN;
int timeout_interval_dig;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Set signal handling and alarm */
if (signal (SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR)
usage_va(_("Cannot catch SIGALRM"));
/* Set signal handling and alarm */
if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR)
usage_va(_("Cannot catch SIGALRM"));
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
/* Parse extra opts if any */
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage_va(_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage_va(_("Could not parse arguments"));
/* dig applies the timeout to each try, so we need to work around this */
timeout_interval_dig = timeout_interval / number_tries + number_tries;
/* dig applies the timeout to each try, so we need to work around this */
timeout_interval_dig = timeout_interval / number_tries + number_tries;
/* get the command to run */
xasprintf (&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d",
PATH_TO_DIG, dig_args, query_transport, server_port, dns_server, query_address, record_type, number_tries, timeout_interval_dig);
/* get the command to run */
xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, dig_args, query_transport, server_port, dns_server,
query_address, record_type, number_tries, timeout_interval_dig);
alarm (timeout_interval);
gettimeofday (&tv, NULL);
alarm(timeout_interval);
gettimeofday(&tv, NULL);
if (verbose) {
printf ("%s\n", command_line);
if(expected_address != NULL) {
printf (_("Looking for: '%s'\n"), expected_address);
} else {
printf (_("Looking for: '%s'\n"), query_address);
}
}
if (verbose) {
printf("%s\n", command_line);
if (expected_address != NULL) {
printf(_("Looking for: '%s'\n"), expected_address);
} else {
printf(_("Looking for: '%s'\n"), query_address);
}
}
/* run the command */
if(np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) {
result = STATE_WARNING;
msg = (char *)_("dig returned an error status");
}
/* run the command */
if (np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) {
result = STATE_WARNING;
msg = (char *)_("dig returned an error status");
}
for(i = 0; i < chld_out.lines; i++) {
/* the server is responding, we just got the host name... */
if (strstr (chld_out.line[i], ";; ANSWER SECTION:")) {
for (i = 0; i < chld_out.lines; i++) {
/* the server is responding, we just got the host name... */
if (strstr(chld_out.line[i], ";; ANSWER SECTION:")) {
/* loop through the whole 'ANSWER SECTION' */
for(; i < chld_out.lines; i++) {
/* get the host address */
if (verbose)
printf ("%s\n", chld_out.line[i]);
/* loop through the whole 'ANSWER SECTION' */
for (; i < chld_out.lines; i++) {
/* get the host address */
if (verbose)
printf("%s\n", chld_out.line[i]);
if (strcasestr (chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) {
msg = chld_out.line[i];
result = STATE_OK;
if (strcasestr(chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) {
msg = chld_out.line[i];
result = STATE_OK;
/* Translate output TAB -> SPACE */
t = msg;
while ((t = strchr(t, '\t')) != NULL) *t = ' ';
break;
}
}
/* Translate output TAB -> SPACE */
t = msg;
while ((t = strchr(t, '\t')) != NULL)
*t = ' ';
break;
}
}
if (result == STATE_UNKNOWN) {
msg = (char *)_("Server not found in ANSWER SECTION");
result = STATE_WARNING;
}
if (result == STATE_UNKNOWN) {
msg = (char *)_("Server not found in ANSWER SECTION");
result = STATE_WARNING;
}
/* we found the answer section, so break out of the loop */
break;
}
}
/* we found the answer section, so break out of the loop */
break;
}
}
if (result == STATE_UNKNOWN) {
msg = (char *)_("No ANSWER SECTION found");
result = STATE_CRITICAL;
}
if (result == STATE_UNKNOWN) {
msg = (char *)_("No ANSWER SECTION found");
result = STATE_CRITICAL;
}
/* If we get anything on STDERR, at least set warning */
if(chld_err.buflen > 0) {
result = max_state(result, STATE_WARNING);
if(!msg) for(i = 0; i < chld_err.lines; i++) {
msg = strchr(chld_err.line[0], ':');
if(msg) {
msg++;
break;
}
}
}
/* If we get anything on STDERR, at least set warning */
if (chld_err.buflen > 0) {
result = max_state(result, STATE_WARNING);
if (!msg)
for (i = 0; i < chld_err.lines; i++) {
msg = strchr(chld_err.line[0], ':');
if (msg) {
msg++;
break;
}
}
}
microsec = deltime (tv);
elapsed_time = (double)microsec / 1.0e6;
microsec = deltime(tv);
elapsed_time = (double)microsec / 1.0e6;
if (critical_interval > UNDEFINED && elapsed_time > critical_interval)
result = STATE_CRITICAL;
if (critical_interval > UNDEFINED && elapsed_time > critical_interval)
result = STATE_CRITICAL;
else if (warning_interval > UNDEFINED && elapsed_time > warning_interval)
result = STATE_WARNING;
else if (warning_interval > UNDEFINED && elapsed_time > warning_interval)
result = STATE_WARNING;
printf ("DNS %s - %.3f seconds response time (%s)|%s\n",
state_text (result), elapsed_time,
msg ? msg : _("Probably a non-existent host/domain"),
fperfdata("time", elapsed_time, "s",
(warning_interval>UNDEFINED ? true:false),
warning_interval,
(critical_interval>UNDEFINED ? true:false),
critical_interval,
true, 0, false, 0));
return result;
printf("DNS %s - %.3f seconds response time (%s)|%s\n", state_text(result), elapsed_time,
msg ? msg : _("Probably a non-existent host/domain"),
fperfdata("time", elapsed_time, "s", (warning_interval > UNDEFINED ? true : false), warning_interval,
(critical_interval > UNDEFINED ? true : false), critical_interval, true, 0, false, 0));
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int process_arguments(int argc, char **argv) {
int c;
int option = 0;
static struct option longopts[] = {
{"hostname", required_argument, 0, 'H'},
{"query_address", required_argument, 0, 'l'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"timeout", required_argument, 0, 't'},
{"dig-arguments", required_argument, 0, 'A'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"record_type", required_argument, 0, 'T'},
{"expected_address", required_argument, 0, 'a'},
{"port", required_argument, 0, 'p'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{0, 0, 0, 0}
};
int option = 0;
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
{"query_address", required_argument, 0, 'l'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"timeout", required_argument, 0, 't'},
{"dig-arguments", required_argument, 0, 'A'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"record_type", required_argument, 0, 'T'},
{"expected_address", required_argument, 0, 'a'},
{"port", required_argument, 0, 'p'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{0, 0, 0, 0}};
if (argc < 2)
return ERROR;
if (argc < 2)
return ERROR;
while (1) {
c = getopt_long (argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option);
while (1) {
c = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option);
if (c == -1 || c == EOF)
break;
if (c == -1 || c == EOF)
break;
switch (c) {
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'H': /* hostname */
host_or_die(optarg);
dns_server = optarg;
break;
case 'p': /* server port */
if (is_intpos (optarg)) {
server_port = atoi (optarg);
}
else {
usage_va(_("Port must be a positive integer - %s"), optarg);
}
break;
case 'l': /* address to lookup */
query_address = optarg;
break;
case 'w': /* warning */
if (is_nonnegative (optarg)) {
warning_interval = strtod (optarg, NULL);
}
else {
usage_va(_("Warning interval must be a positive integer - %s"), optarg);
}
break;
case 'c': /* critical */
if (is_nonnegative (optarg)) {
critical_interval = strtod (optarg, NULL);
}
else {
usage_va(_("Critical interval must be a positive integer - %s"), optarg);
}
break;
case 't': /* timeout */
if (is_intnonneg (optarg)) {
timeout_interval = atoi (optarg);
}
else {
usage_va(_("Timeout interval must be a positive integer - %s"), optarg);
}
break;
case 'A': /* dig arguments */
dig_args = strdup(optarg);
break;
case 'v': /* verbose */
verbose = true;
break;
case 'T':
record_type = optarg;
break;
case 'a':
expected_address = optarg;
break;
case '4':
query_transport = "-4";
break;
case '6':
query_transport = "-6";
break;
default: /* usage5 */
usage5();
}
}
switch (c) {
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'H': /* hostname */
host_or_die(optarg);
dns_server = optarg;
break;
case 'p': /* server port */
if (is_intpos(optarg)) {
server_port = atoi(optarg);
} else {
usage_va(_("Port must be a positive integer - %s"), optarg);
}
break;
case 'l': /* address to lookup */
query_address = optarg;
break;
case 'w': /* warning */
if (is_nonnegative(optarg)) {
warning_interval = strtod(optarg, NULL);
} else {
usage_va(_("Warning interval must be a positive integer - %s"), optarg);
}
break;
case 'c': /* critical */
if (is_nonnegative(optarg)) {
critical_interval = strtod(optarg, NULL);
} else {
usage_va(_("Critical interval must be a positive integer - %s"), optarg);
}
break;
case 't': /* timeout */
if (is_intnonneg(optarg)) {
timeout_interval = atoi(optarg);
} else {
usage_va(_("Timeout interval must be a positive integer - %s"), optarg);
}
break;
case 'A': /* dig arguments */
dig_args = strdup(optarg);
break;
case 'v': /* verbose */
verbose = true;
break;
case 'T':
record_type = optarg;
break;
case 'a':
expected_address = optarg;
break;
case '4':
query_transport = "-4";
break;
case '6':
query_transport = "-6";
break;
default: /* usage5 */
usage5();
}
}
c = optind;
if (dns_server == NULL) {
if (c < argc) {
host_or_die(argv[c]);
dns_server = argv[c];
}
else {
if (strcmp(query_transport,"-6") == 0)
dns_server = strdup("::1");
else
dns_server = strdup ("127.0.0.1");
}
}
c = optind;
if (dns_server == NULL) {
if (c < argc) {
host_or_die(argv[c]);
dns_server = argv[c];
} else {
if (strcmp(query_transport, "-6") == 0)
dns_server = strdup("::1");
else
dns_server = strdup("127.0.0.1");
}
}
return validate_arguments ();
return validate_arguments();
}
int
validate_arguments (void)
{
if (query_address != NULL)
return OK;
else
return ERROR;
int validate_arguments(void) {
if (query_address != NULL)
return OK;
return ERROR;
}
void print_help(void) {
char *myport;
xasprintf(&myport, "%d", DEFAULT_PORT);
void
print_help (void)
{
char *myport;
print_revision(progname, NP_VERSION);
xasprintf (&myport, "%d", DEFAULT_PORT);
printf("Copyright (c) 2000 Karl DeBisschop <kdebisschop@users.sourceforge.net>\n");
printf(COPYRIGHT, copyright, email);
print_revision (progname, NP_VERSION);
printf(_("This plugin tests the DNS service on the specified host using dig"));
printf ("Copyright (c) 2000 Karl DeBisschop <kdebisschop@users.sourceforge.net>\n");
printf (COPYRIGHT, copyright, email);
printf("\n\n");
printf (_("This plugin tests the DNS service on the specified host using dig"));
print_usage();
printf ("\n\n");
printf(UT_HELP_VRSN);
print_usage ();
printf(UT_EXTRA_OPTS);
printf (UT_HELP_VRSN);
printf(UT_HOST_PORT, 'p', myport);
printf (UT_EXTRA_OPTS);
printf(" %s\n", "-4, --use-ipv4");
printf(" %s\n", _("Force dig to only use IPv4 query transport"));
printf(" %s\n", "-6, --use-ipv6");
printf(" %s\n", _("Force dig to only use IPv6 query transport"));
printf(" %s\n", "-l, --query_address=STRING");
printf(" %s\n", _("Machine name to lookup"));
printf(" %s\n", "-T, --record_type=STRING");
printf(" %s\n", _("Record type to lookup (default: A)"));
printf(" %s\n", "-a, --expected_address=STRING");
printf(" %s\n", _("An address expected to be in the answer section. If not set, uses whatever"));
printf(" %s\n", _("was in -l"));
printf(" %s\n", "-A, --dig-arguments=STRING");
printf(" %s\n", _("Pass STRING as argument(s) to dig"));
printf(UT_WARN_CRIT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_VERBOSE);
printf (UT_HOST_PORT, 'p', myport);
printf("\n");
printf("%s\n", _("Examples:"));
printf(" %s\n", "check_dig -H DNSSERVER -l www.example.com -A \"+tcp\"");
printf(" %s\n", "This will send a tcp query to DNSSERVER for www.example.com");
printf (" %s\n","-4, --use-ipv4");
printf (" %s\n",_("Force dig to only use IPv4 query transport"));
printf (" %s\n","-6, --use-ipv6");
printf (" %s\n",_("Force dig to only use IPv6 query transport"));
printf (" %s\n","-l, --query_address=STRING");
printf (" %s\n",_("Machine name to lookup"));
printf (" %s\n","-T, --record_type=STRING");
printf (" %s\n",_("Record type to lookup (default: A)"));
printf (" %s\n","-a, --expected_address=STRING");
printf (" %s\n",_("An address expected to be in the answer section. If not set, uses whatever"));
printf (" %s\n",_("was in -l"));
printf (" %s\n","-A, --dig-arguments=STRING");
printf (" %s\n",_("Pass STRING as argument(s) to dig"));
printf (UT_WARN_CRIT);
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_VERBOSE);
printf ("\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "check_dig -H DNSSERVER -l www.example.com -A \"+tcp\"");
printf (" %s\n", "This will send a tcp query to DNSSERVER for www.example.com");
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -l <query_address> [-H <host>] [-p <server port>]\n", progname);
printf (" [-T <query type>] [-w <warning interval>] [-c <critical interval>]\n");
printf (" [-t <timeout>] [-a <expected answer address>] [-v]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -l <query_address> [-H <host>] [-p <server port>]\n", progname);
printf(" [-T <query type>] [-w <warning interval>] [-c <critical interval>]\n");
printf(" [-t <timeout>] [-a <expected answer address>] [-v]\n");
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,124 +1,111 @@
/*****************************************************************************
*
* Monitoring check_dummy plugin
*
* License: GPL
* Copyright (c) 1999-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_dummy plugin
*
* This plugin will simply return the state corresponding to the numeric value
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_dummy plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_dummy plugin
*
* This plugin will simply return the state corresponding to the numeric value
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_dummy";
const char *copyright = "1999-2007";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
void print_help (void);
void print_usage (void);
static void print_help(void);
void print_usage(void);
int main(int argc, char **argv) {
int result = STATE_UNKNOWN;
int
main (int argc, char **argv)
{
int result = STATE_UNKNOWN;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
if (argc < 2)
usage4(_("Could not parse arguments"));
else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) {
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
} else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
print_help();
exit(STATE_UNKNOWN);
} else if (!is_integer(argv[1]))
usage4(_("Arguments to check_dummy must be an integer"));
else
result = atoi(argv[1]);
if (argc < 2)
usage4 (_("Could not parse arguments"));
else if (strcmp (argv[1], "-V") == 0 || strcmp (argv[1], "--version") == 0) {
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
}
else if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) {
print_help ();
exit (STATE_UNKNOWN);
}
else if (!is_integer (argv[1]))
usage4 (_("Arguments to check_dummy must be an integer"));
else
result = atoi (argv[1]);
switch (result) {
case STATE_OK:
printf(_("OK"));
break;
case STATE_WARNING:
printf(_("WARNING"));
break;
case STATE_CRITICAL:
printf(_("CRITICAL"));
break;
case STATE_UNKNOWN:
printf(_("UNKNOWN"));
break;
default:
printf(_("UNKNOWN"));
printf(": ");
printf(_("Status %d is not a supported error state\n"), result);
return STATE_UNKNOWN;
}
switch (result) {
case STATE_OK:
printf (_("OK"));
break;
case STATE_WARNING:
printf (_("WARNING"));
break;
case STATE_CRITICAL:
printf (_("CRITICAL"));
break;
case STATE_UNKNOWN:
printf (_("UNKNOWN"));
break;
default:
printf (_("UNKNOWN"));
printf (": ");
printf (_("Status %d is not a supported error state\n"), result);
return STATE_UNKNOWN;
}
if (argc >= 3)
printf(": %s", argv[2]);
if (argc >= 3)
printf (": %s", argv[2]);
printf("\n");
printf("\n");
return result;
return result;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("%s\n", _("This plugin will simply return the state corresponding to the numeric value"));
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf("%s\n", _("of the <state> argument with optional text"));
printf ("%s\n", _("This plugin will simply return the state corresponding to the numeric value"));
printf("\n\n");
printf ("%s\n", _("of the <state> argument with optional text"));
print_usage();
printf ("\n\n");
printf(UT_HELP_VRSN);
print_usage ();
printf (UT_HELP_VRSN);
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s <integer state> [optional text]\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s <integer state> [optional text]\n", progname);
}

View file

@ -1,36 +1,36 @@
/*****************************************************************************
*
* Monitoring check_fping plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_disk plugin
*
* This plugin will use the fping command to ping the specified host for a
* fast check
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_fping plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_disk plugin
*
* This plugin will use the fping command to ping the specified host for a
* fast check
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_fping";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -40,488 +40,449 @@ const char *email = "devel@monitoring-plugins.org";
#include <stdbool.h>
enum {
PACKET_COUNT = 1,
PACKET_SIZE = 56,
PL = 0,
RTA = 1
PACKET_COUNT = 1,
PACKET_SIZE = 56,
PL = 0,
RTA = 1
};
int textscan (char *buf);
int process_arguments (int, char **);
int get_threshold (char *arg, char *rv[2]);
void print_help (void);
void print_usage (void);
static int textscan(char *buf);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int get_threshold(char *arg, char *rv[2]);
static void print_help(void);
void print_usage(void);
char *server_name = NULL;
char *sourceip = NULL;
char *sourceif = NULL;
int packet_size = PACKET_SIZE;
int packet_count = PACKET_COUNT;
int target_timeout = 0;
int packet_interval = 0;
bool verbose = false;
int cpl;
int wpl;
double crta;
double wrta;
bool cpl_p = false;
bool wpl_p = false;
bool alive_p = false;
bool crta_p = false;
bool wrta_p = false;
static char *server_name = NULL;
static char *sourceip = NULL;
static char *sourceif = NULL;
static int packet_size = PACKET_SIZE;
static int packet_count = PACKET_COUNT;
static int target_timeout = 0;
static int packet_interval = 0;
static bool verbose = false;
static int cpl;
static int wpl;
static double crta;
static double wrta;
static bool cpl_p = false;
static bool wpl_p = false;
static bool alive_p = false;
static bool crta_p = false;
static bool wrta_p = false;
int
main (int argc, char **argv)
{
/* normally should be int result = STATE_UNKNOWN; */
int main(int argc, char **argv) {
/* normally should be int result = STATE_UNKNOWN; */
int status = STATE_UNKNOWN;
int result = 0;
char *fping_prog = NULL;
char *server = NULL;
char *command_line = NULL;
char *input_buffer = NULL;
char *option_string = "";
input_buffer = malloc (MAX_INPUT_BUFFER);
int status = STATE_UNKNOWN;
int result = 0;
char *fping_prog = NULL;
char *server = NULL;
char *command_line = NULL;
char *input_buffer = NULL;
char *option_string = "";
input_buffer = malloc(MAX_INPUT_BUFFER);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
/* Parse extra opts if any */
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
server = strscpy (server, server_name);
server = strscpy(server, server_name);
/* compose the command */
if (target_timeout)
xasprintf(&option_string, "%s-t %d ", option_string, target_timeout);
if (packet_interval)
xasprintf(&option_string, "%s-p %d ", option_string, packet_interval);
if (sourceip)
xasprintf(&option_string, "%s-S %s ", option_string, sourceip);
if (sourceif)
xasprintf(&option_string, "%s-I %s ", option_string, sourceif);
/* compose the command */
if (target_timeout)
xasprintf(&option_string, "%s-t %d ", option_string, target_timeout);
if (packet_interval)
xasprintf(&option_string, "%s-p %d ", option_string, packet_interval);
if (sourceip)
xasprintf(&option_string, "%s-S %s ", option_string, sourceip);
if (sourceif)
xasprintf(&option_string, "%s-I %s ", option_string, sourceif);
#ifdef PATH_TO_FPING6
if (address_family != AF_INET && is_inet6_addr(server))
fping_prog = strdup(PATH_TO_FPING6);
else
fping_prog = strdup(PATH_TO_FPING);
if (address_family != AF_INET && is_inet6_addr(server))
fping_prog = strdup(PATH_TO_FPING6);
else
fping_prog = strdup(PATH_TO_FPING);
#else
fping_prog = strdup(PATH_TO_FPING);
fping_prog = strdup(PATH_TO_FPING);
#endif
xasprintf (&command_line, "%s %s-b %d -c %d %s", fping_prog,
option_string, packet_size, packet_count, server);
xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server);
if (verbose)
printf ("%s\n", command_line);
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;
}
/* 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);
}
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_state (status, textscan (input_buffer));
}
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
if (verbose)
printf("%s", input_buffer);
status = max_state(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_state (status, STATE_WARNING);
if (verbose)
printf ("%s", input_buffer);
status = max_state (status, textscan (input_buffer));
}
(void) fclose (child_stderr);
/* If we get anything on STDERR, at least set warning */
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
status = max_state(status, STATE_WARNING);
if (verbose)
printf("%s", input_buffer);
status = max_state(status, textscan(input_buffer));
}
(void)fclose(child_stderr);
/* close the pipe */
result = spclose (child_process);
if (result) {
/* need to use max_state not max */
status = max_state (status, STATE_WARNING);
}
/* close the pipe */
result = spclose(child_process);
if (result) {
/* need to use max_state not max */
status = max_state(status, STATE_WARNING);
}
if (result > 1 ) {
status = max_state (status, STATE_UNKNOWN);
if (result == 2) {
die (STATE_UNKNOWN, _("FPING UNKNOWN - IP address not found\n"));
}
if (result == 3) {
die (STATE_UNKNOWN, _("FPING UNKNOWN - invalid commandline argument\n"));
}
if (result == 4) {
die (STATE_UNKNOWN, _("FPING UNKNOWN - failed system call\n"));
}
if (result > 1) {
status = max_state(status, STATE_UNKNOWN);
if (result == 2) {
die(STATE_UNKNOWN, _("FPING UNKNOWN - IP address not found\n"));
}
if (result == 3) {
die(STATE_UNKNOWN, _("FPING UNKNOWN - invalid commandline argument\n"));
}
if (result == 4) {
die(STATE_UNKNOWN, _("FPING UNKNOWN - failed system call\n"));
}
}
}
printf("FPING %s - %s\n", state_text(status), server_name);
printf ("FPING %s - %s\n", state_text (status), server_name);
return status;
return status;
}
int textscan(char *buf) {
char *rtastr = NULL;
char *losstr = NULL;
char *xmtstr = NULL;
double loss;
double rta;
double xmt;
int status = STATE_UNKNOWN;
int textscan (char *buf) {
char *rtastr = NULL;
char *losstr = NULL;
char *xmtstr = NULL;
double loss;
double rta;
double xmt;
int status = STATE_UNKNOWN;
/* stops testing after the first successful reply. */
if (alive_p && strstr(buf, "avg, 0% loss)")) {
rtastr = strstr(buf, "ms (");
rtastr = 1 + index(rtastr, '(');
rta = strtod(rtastr, NULL);
loss = strtod("0", NULL);
die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta,
/* No loss since we only waited for the first reply
perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */
fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0));
}
/* stops testing after the first successful reply. */
if (alive_p && strstr(buf, "avg, 0% loss)")) {
rtastr = strstr (buf, "ms (");
rtastr = 1 + index(rtastr, '(');
rta = strtod(rtastr, NULL);
loss=strtod("0",NULL);
die (STATE_OK,
_("FPING %s - %s (rta=%f ms)|%s\n"),
state_text (STATE_OK), server_name,rta,
/* No loss since we only waited for the first reply
perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */
fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, true, 0, false, 0));
}
if (strstr(buf, "not found")) {
die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name);
if (strstr (buf, "not found")) {
die (STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name);
} else if (strstr(buf, "is unreachable") || strstr(buf, "Unreachable")) {
die(STATE_CRITICAL, _("FPING CRITICAL - %s is unreachable\n"), "host");
}
else if (strstr (buf, "is unreachable") || strstr (buf, "Unreachable")) {
die (STATE_CRITICAL, _("FPING CRITICAL - %s is unreachable\n"),
"host");
} else if (strstr(buf, "Operation not permitted") || strstr(buf, "No such device")) {
die(STATE_UNKNOWN, _("FPING UNKNOWN - %s parameter error\n"), "host");
} else if (strstr(buf, "is down")) {
die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
}
else if (strstr (buf, "Operation not permitted") || strstr (buf, "No such device") ) {
die (STATE_UNKNOWN, _("FPING UNKNOWN - %s parameter error\n"),
"host");
}
else if (strstr (buf, "is down")) {
die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
} else if (strstr(buf, "is alive")) {
status = STATE_OK;
}
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_p && loss > cpl)
status = STATE_CRITICAL;
else if (crta_p && rta > crta)
status = STATE_CRITICAL;
else if (wpl_p && loss > wpl)
status = STATE_WARNING;
else if (wrta_p && rta > wrta)
status = STATE_WARNING;
else
status = STATE_OK;
die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta,
perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100),
fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0));
}
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_p && loss > cpl)
status = STATE_CRITICAL;
else if (crta_p && rta > crta)
status = STATE_CRITICAL;
else if (wpl_p && loss > wpl)
status = STATE_WARNING;
else if (wrta_p && rta > wrta)
status = STATE_WARNING;
else
status = STATE_OK;
die (status,
_("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"),
state_text (status), server_name, loss, rta,
perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100),
fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, true, 0, false, 0));
} else if (strstr(buf, "xmt/rcv/%loss")) {
/* no min/max/avg if host was unreachable in fping v2.2.b1 */
/* in v2.4b2: 10.99.0.1 : xmt/rcv/%loss = 0/0/0% */
losstr = strstr(buf, "=");
xmtstr = 1 + losstr;
xmt = strtod(xmtstr, NULL);
if (xmt == 0)
die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
losstr = 1 + strstr(losstr, "/");
losstr = 1 + strstr(losstr, "/");
loss = strtod(losstr, NULL);
if (atoi(losstr) == 100)
status = STATE_CRITICAL;
else if (cpl_p && loss > cpl)
status = STATE_CRITICAL;
else if (wpl_p && loss > wpl)
status = STATE_WARNING;
else
status = STATE_OK;
/* loss=%.0f%%;%d;%d;0;100 */
die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss,
perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100));
}
else if(strstr (buf, "xmt/rcv/%loss") ) {
/* no min/max/avg if host was unreachable in fping v2.2.b1 */
/* in v2.4b2: 10.99.0.1 : xmt/rcv/%loss = 0/0/0% */
losstr = strstr (buf, "=");
xmtstr = 1 + losstr;
xmt = strtod (xmtstr, NULL);
if(xmt == 0)
die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
losstr = 1 + strstr (losstr, "/");
losstr = 1 + strstr (losstr, "/");
loss = strtod (losstr, NULL);
if (atoi(losstr) == 100)
status = STATE_CRITICAL;
else if (cpl_p && loss > cpl)
status = STATE_CRITICAL;
else if (wpl_p && loss > wpl)
status = STATE_WARNING;
else
status = STATE_OK;
/* loss=%.0f%%;%d;%d;0;100 */
die (status, _("FPING %s - %s (loss=%.0f%% )|%s\n"),
state_text (status), server_name, loss ,
perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100));
} else {
status = max_state(status, STATE_WARNING);
}
}
else {
status = max_state (status, STATE_WARNING);
}
return status;
return status;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
char *rv[2];
int process_arguments(int argc, char **argv) {
int c;
char *rv[2];
int option = 0;
static struct option longopts[] = {
{"hostname", required_argument, 0, 'H'},
{"sourceip", required_argument, 0, 'S'},
{"sourceif", required_argument, 0, 'I'},
{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"alive", no_argument, 0, 'a'},
{"bytes", required_argument, 0, 'b'},
{"number", required_argument, 0, 'n'},
{"target-timeout", required_argument, 0, 'T'},
{"interval", required_argument, 0, 'i'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{0, 0, 0, 0}
};
int option = 0;
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
{"sourceip", required_argument, 0, 'S'},
{"sourceif", required_argument, 0, 'I'},
{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"alive", no_argument, 0, 'a'},
{"bytes", required_argument, 0, 'b'},
{"number", required_argument, 0, 'n'},
{"target-timeout", required_argument, 0, 'T'},
{"interval", required_argument, 0, 'i'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{0, 0, 0, 0}};
rv[PL] = NULL;
rv[RTA] = NULL;
rv[PL] = NULL;
rv[RTA] = NULL;
if (argc < 2)
return ERROR;
if (argc < 2)
return ERROR;
if (!is_option (argv[1])) {
server_name = argv[1];
argv[1] = argv[0];
argv = &argv[1];
argc--;
}
if (!is_option(argv[1])) {
server_name = argv[1];
argv[1] = argv[0];
argv = &argv[1];
argc--;
}
while (1) {
c = getopt_long (argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:46", longopts, &option);
while (1) {
c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:46", longopts, &option);
if (c == -1 || c == EOF || c == 1)
break;
switch (c) {
case '?': /* print short usage statement if args not parsable */
usage5 ();
case 'a': /* host alive mode */
alive_p = true;
break;
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'v': /* verbose mode */
verbose = true;
break;
case 'H': /* hostname */
if (is_host (optarg) == false) {
usage2 (_("Invalid hostname/address"), optarg);
}
server_name = strscpy (server_name, optarg);
break;
case 'S': /* sourceip */
if (is_host (optarg) == false) {
usage2 (_("Invalid hostname/address"), optarg);
}
sourceip = strscpy (sourceip, optarg);
break;
case 'I': /* sourceip */
sourceif = strscpy (sourceif, optarg);
if (c == -1 || c == EOF || c == 1)
break;
case '4': /* IPv4 only */
address_family = AF_INET;
break;
case '6': /* IPv6 only */
switch (c) {
case '?': /* print short usage statement if args not parsable */
usage5();
case 'a': /* host alive mode */
alive_p = true;
break;
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'v': /* verbose mode */
verbose = true;
break;
case 'H': /* hostname */
if (is_host(optarg) == false) {
usage2(_("Invalid hostname/address"), optarg);
}
server_name = strscpy(server_name, optarg);
break;
case 'S': /* sourceip */
if (is_host(optarg) == false) {
usage2(_("Invalid hostname/address"), optarg);
}
sourceip = strscpy(sourceip, optarg);
break;
case 'I': /* sourceip */
sourceif = strscpy(sourceif, optarg);
break;
case '4': /* IPv4 only */
address_family = AF_INET;
break;
case '6': /* IPv6 only */
#ifdef USE_IPV6
address_family = AF_INET6;
address_family = AF_INET6;
#else
usage (_("IPv6 support not available\n"));
usage(_("IPv6 support not available\n"));
#endif
break;
case 'c':
get_threshold (optarg, rv);
if (rv[RTA]) {
crta = strtod (rv[RTA], NULL);
crta_p = true;
rv[RTA] = NULL;
}
if (rv[PL]) {
cpl = atoi (rv[PL]);
cpl_p = true;
rv[PL] = NULL;
}
break;
case 'w':
get_threshold (optarg, rv);
if (rv[RTA]) {
wrta = strtod (rv[RTA], NULL);
wrta_p = true;
rv[RTA] = NULL;
}
if (rv[PL]) {
wpl = atoi (rv[PL]);
wpl_p = true;
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;
case 'T': /* timeout in msec */
if (is_intpos (optarg))
target_timeout = atoi (optarg);
else
usage (_("Target timeout must be a positive integer"));
break;
case 'i': /* interval in msec */
if (is_intpos (optarg))
packet_interval = atoi (optarg);
else
usage (_("Interval must be a positive integer"));
break;
}
}
break;
case 'c':
get_threshold(optarg, rv);
if (rv[RTA]) {
crta = strtod(rv[RTA], NULL);
crta_p = true;
rv[RTA] = NULL;
}
if (rv[PL]) {
cpl = atoi(rv[PL]);
cpl_p = true;
rv[PL] = NULL;
}
break;
case 'w':
get_threshold(optarg, rv);
if (rv[RTA]) {
wrta = strtod(rv[RTA], NULL);
wrta_p = true;
rv[RTA] = NULL;
}
if (rv[PL]) {
wpl = atoi(rv[PL]);
wpl_p = true;
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;
case 'T': /* timeout in msec */
if (is_intpos(optarg))
target_timeout = atoi(optarg);
else
usage(_("Target timeout must be a positive integer"));
break;
case 'i': /* interval in msec */
if (is_intpos(optarg))
packet_interval = atoi(optarg);
else
usage(_("Interval must be a positive integer"));
break;
}
}
if (server_name == NULL)
usage4 (_("Hostname was not supplied"));
if (server_name == NULL)
usage4(_("Hostname was not supplied"));
return OK;
return OK;
}
int get_threshold(char *arg, char *rv[2]) {
char *arg1 = NULL;
char *arg2 = NULL;
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, ",:");
arg1 = strscpy (arg1, arg);
if (strpbrk (arg1, ",:"))
arg2 = 1 + strpbrk (arg1, ",:");
if (arg2) {
arg1[strcspn(arg1, ",:")] = 0;
if (strstr(arg1, "%") && strstr(arg2, "%"))
die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg);
if (!strstr(arg1, "%") && !strstr(arg2, "%"))
die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg);
}
if (arg2) {
arg1[strcspn (arg1, ",:")] = 0;
if (strstr (arg1, "%") && strstr (arg2, "%"))
die (STATE_UNKNOWN,
_("%s: Only one threshold may be packet loss (%s)\n"), progname,
arg);
if (!strstr (arg1, "%") && !strstr (arg2, "%"))
die (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;
}
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;
return OK;
}
void print_help(void) {
void print_help (void) {
print_revision(progname, NP_VERSION);
print_revision (progname, NP_VERSION);
printf("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n");
printf(COPYRIGHT, copyright, email);
printf ("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n");
printf (COPYRIGHT, copyright, email);
printf("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check"));
printf ("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check"));
printf("%s\n", _("Note that it is necessary to set the suid flag on fping."));
printf ("%s\n", _("Note that it is necessary to set the suid flag on fping."));
printf("\n\n");
printf ("\n\n");
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_IPv46);
printf (UT_IPv46);
printf(" %s\n", "-H, --hostname=HOST");
printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)"));
printf(" %s\n", "-w, --warning=THRESHOLD");
printf(" %s\n", _("warning threshold pair"));
printf(" %s\n", "-c, --critical=THRESHOLD");
printf(" %s\n", _("critical threshold pair"));
printf(" %s\n", "-a, --alive");
printf(" %s\n", _("Return OK after first successful reply"));
printf(" %s\n", "-b, --bytes=INTEGER");
printf(" %s (default: %d)\n", _("size of ICMP packet"), PACKET_SIZE);
printf(" %s\n", "-n, --number=INTEGER");
printf(" %s (default: %d)\n", _("number of ICMP packets to send"), PACKET_COUNT);
printf(" %s\n", "-T, --target-timeout=INTEGER");
printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)"));
printf(" %s\n", "-i, --interval=INTEGER");
printf(" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets"));
printf(" %s\n", "-S, --sourceip=HOST");
printf(" %s\n", _("name or IP Address of sourceip"));
printf(" %s\n", "-I, --sourceif=IF");
printf(" %s\n", _("source interface name"));
printf(UT_VERBOSE);
printf("\n");
printf(" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
printf(" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
printf(" %s\n", _("packet loss to trigger an alarm state."));
printf (" %s\n", "-H, --hostname=HOST");
printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)"));
printf (" %s\n", "-w, --warning=THRESHOLD");
printf (" %s\n", _("warning threshold pair"));
printf (" %s\n", "-c, --critical=THRESHOLD");
printf (" %s\n", _("critical threshold pair"));
printf (" %s\n", "-a, --alive");
printf (" %s\n", _("Return OK after first successful reply"));
printf (" %s\n", "-b, --bytes=INTEGER");
printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE);
printf (" %s\n", "-n, --number=INTEGER");
printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT);
printf (" %s\n", "-T, --target-timeout=INTEGER");
printf (" %s (default: fping's default for -t)\n", _("Target timeout (ms)"));
printf (" %s\n", "-i, --interval=INTEGER");
printf (" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets"));
printf (" %s\n", "-S, --sourceip=HOST");
printf (" %s\n", _("name or IP Address of sourceip"));
printf (" %s\n", "-I, --sourceif=IF");
printf (" %s\n", _("source interface name"));
printf (UT_VERBOSE);
printf ("\n");
printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
printf (" %s\n", _("packet loss to trigger an alarm state."));
printf("\n");
printf(" %s\n", _("IPv4 is used by default. Specify -6 to use IPv6."));
printf ("\n");
printf (" %s\n", _("IPv4 is used by default. Specify -6 to use IPv6."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname);
}

View file

@ -1,335 +1,308 @@
/*****************************************************************************
*
* Monitoring check_game plugin
*
* License: GPL
* Copyright (c) 2002-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_game plugin
*
* This plugin tests game server connections with the specified host.
* using the qstat program
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_game plugin
*
* License: GPL
* Copyright (c) 2002-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_game plugin
*
* This plugin tests game server connections with the specified host.
* using the qstat program
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_game";
const char *copyright = "2002-2007";
const char *copyright = "2002-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
#include "runcmd.h"
int process_arguments (int, char **);
int validate_arguments (void);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int validate_arguments(void);
static void print_help(void);
void print_usage(void);
#define QSTAT_DATA_DELIMITER ","
#define QSTAT_DATA_DELIMITER ","
#define QSTAT_HOST_ERROR "ERROR"
#define QSTAT_HOST_DOWN "DOWN"
#define QSTAT_HOST_TIMEOUT "TIMEOUT"
#define QSTAT_HOST_ERROR "ERROR"
#define QSTAT_HOST_DOWN "DOWN"
#define QSTAT_HOST_TIMEOUT "TIMEOUT"
#define QSTAT_MAX_RETURN_ARGS 12
char *server_ip;
char *game_type;
int port = 0;
static char *server_ip;
static char *game_type;
static int port = 0;
bool verbose = false;
static bool verbose = false;
int qstat_game_players_max = -1;
int qstat_game_players = -1;
int qstat_game_field = -1;
int qstat_map_field = -1;
int qstat_ping_field = -1;
static int qstat_game_players_max = -1;
static int qstat_game_players = -1;
static int qstat_game_field = -1;
static int qstat_map_field = -1;
static int qstat_ping_field = -1;
int main(int argc, char **argv) {
char *command_line;
int result = STATE_UNKNOWN;
char *p;
char *ret[QSTAT_MAX_RETURN_ARGS];
size_t i = 0;
output chld_out;
int
main (int argc, char **argv)
{
char *command_line;
int result = STATE_UNKNOWN;
char *p, *ret[QSTAT_MAX_RETURN_ARGS];
size_t i = 0;
output chld_out;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
/* Parse extra opts if any */
argv = np_extra_opts(&argc, argv, progname);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
if (process_arguments(argc, argv) == ERROR)
usage_va(_("Could not parse arguments"));
if (process_arguments (argc, argv) == ERROR)
usage_va(_("Could not parse arguments"));
result = STATE_OK;
result = STATE_OK;
/* create the command line to execute */
xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip);
/* create the command line to execute */
xasprintf (&command_line, "%s -raw %s -%s %s",
PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip);
if (port)
xasprintf(&command_line, "%s:%-d", command_line, port);
if (port)
xasprintf (&command_line, "%s:%-d", command_line, port);
if (verbose)
printf("%s\n", command_line);
if (verbose)
printf ("%s\n", command_line);
/* run the command. historically, this plugin ignores output on stderr,
* as well as return status of the qstat program */
(void)np_runcmd(command_line, &chld_out, NULL, 0);
/* run the command. historically, this plugin ignores output on stderr,
* as well as return status of the qstat program */
(void)np_runcmd(command_line, &chld_out, NULL, 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
/* 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
*/
In the end, I figured I'd simply let an error occur & then trap it
*/
if (!strncmp(chld_out.line[0], "unknown option", 14)) {
printf(_("CRITICAL - Host type parameter incorrect!\n"));
result = STATE_CRITICAL;
return result;
}
if (!strncmp (chld_out.line[0], "unknown option", 14)) {
printf (_("CRITICAL - Host type parameter incorrect!\n"));
result = STATE_CRITICAL;
return result;
}
p = (char *)strtok(chld_out.line[0], QSTAT_DATA_DELIMITER);
while (p != NULL) {
ret[i] = p;
p = (char *)strtok(NULL, QSTAT_DATA_DELIMITER);
i++;
if (i >= QSTAT_MAX_RETURN_ARGS)
break;
}
p = (char *) strtok (chld_out.line[0], 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(_("CRITICAL - Host not found\n"));
result = STATE_CRITICAL;
} else if (strstr(ret[2], QSTAT_HOST_DOWN)) {
printf(_("CRITICAL - Game server down or unavailable\n"));
result = STATE_CRITICAL;
} else if (strstr(ret[2], QSTAT_HOST_TIMEOUT)) {
printf(_("CRITICAL - Game server timeout\n"));
result = STATE_CRITICAL;
} else {
printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[qstat_game_players], ret[qstat_game_players_max], ret[qstat_game_field],
ret[qstat_map_field], ret[qstat_ping_field],
perfdata("players", atol(ret[qstat_game_players]), "", false, 0, false, 0, true, 0, true, atol(ret[qstat_game_players_max])),
fperfdata("ping", strtod(ret[qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, false, 0));
}
if (strstr (ret[2], QSTAT_HOST_ERROR)) {
printf (_("CRITICAL - Host not found\n"));
result = STATE_CRITICAL;
}
else if (strstr (ret[2], QSTAT_HOST_DOWN)) {
printf (_("CRITICAL - Game server down or unavailable\n"));
result = STATE_CRITICAL;
}
else if (strstr (ret[2], QSTAT_HOST_TIMEOUT)) {
printf (_("CRITICAL - Game server timeout\n"));
result = STATE_CRITICAL;
}
else {
printf ("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n",
ret[qstat_game_players],
ret[qstat_game_players_max],
ret[qstat_game_field],
ret[qstat_map_field],
ret[qstat_ping_field],
perfdata ("players", atol(ret[qstat_game_players]), "",
false, 0, false, 0,
true, 0, true, atol(ret[qstat_game_players_max])),
fperfdata ("ping", strtod(ret[qstat_ping_field], NULL), "",
false, 0, false, 0,
true, 0, false, 0));
}
return result;
return result;
}
int process_arguments(int argc, char **argv) {
int c;
int
process_arguments (int argc, char **argv)
{
int c;
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'},
{"port", required_argument, 0, 'P'},
{"game-type", required_argument, 0, 'G'},
{"map-field", required_argument, 0, 'm'},
{"ping-field", required_argument, 0, 'p'},
{"game-field", required_argument, 0, 'g'},
{"players-field", required_argument, 0, 129},
{"max-players-field", required_argument, 0, 130},
{0, 0, 0, 0}};
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'},
{"port", required_argument, 0, 'P'},
{"game-type", required_argument, 0, 'G'},
{"map-field", required_argument, 0, 'm'},
{"ping-field", required_argument, 0, 'p'},
{"game-field", required_argument, 0, 'g'},
{"players-field", required_argument, 0, 129},
{"max-players-field", required_argument, 0, 130},
{0, 0, 0, 0}
};
if (argc < 2)
return ERROR;
if (argc < 2)
return ERROR;
for (c = 1; c < argc; c++) {
if (strcmp("-mf", argv[c]) == 0)
strcpy(argv[c], "-m");
else if (strcmp("-pf", argv[c]) == 0)
strcpy(argv[c], "-p");
else if (strcmp("-gf", argv[c]) == 0)
strcpy(argv[c], "-g");
}
for (c = 1; c < argc; c++) {
if (strcmp ("-mf", argv[c]) == 0)
strcpy (argv[c], "-m");
else if (strcmp ("-pf", argv[c]) == 0)
strcpy (argv[c], "-p");
else if (strcmp ("-gf", argv[c]) == 0)
strcpy (argv[c], "-g");
}
while (1) {
c = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index);
while (1) {
c = getopt_long (argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index);
if (c == -1 || c == EOF)
break;
if (c == -1 || c == EOF)
break;
switch (c) {
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'v': /* version */
verbose = true;
break;
case 't': /* timeout period */
timeout_interval = atoi(optarg);
break;
case 'H': /* hostname */
if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH)
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
server_ip = optarg;
break;
case 'P': /* port */
port = atoi(optarg);
break;
case 'G': /* hostname */
if (strlen(optarg) >= MAX_INPUT_BUFFER)
die(STATE_UNKNOWN, _("Input buffer overflow\n"));
game_type = optarg;
break;
case 'p': /* index of ping field */
qstat_ping_field = atoi(optarg);
if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 'm': /* index on map field */
qstat_map_field = atoi(optarg);
if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 'g': /* index of game field */
qstat_game_field = atoi(optarg);
if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 129: /* index of player count field */
qstat_game_players = atoi(optarg);
if (qstat_game_players_max == 0)
qstat_game_players_max = qstat_game_players - 1;
if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 130: /* index of max players field */
qstat_game_players_max = atoi(optarg);
if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
default: /* args not parsable */
usage5();
}
}
switch (c) {
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'v': /* version */
verbose = true;
break;
case 't': /* timeout period */
timeout_interval = atoi (optarg);
break;
case 'H': /* hostname */
if (strlen (optarg) >= MAX_HOST_ADDRESS_LENGTH)
die (STATE_UNKNOWN, _("Input buffer overflow\n"));
server_ip = optarg;
break;
case 'P': /* port */
port = atoi (optarg);
break;
case 'G': /* hostname */
if (strlen (optarg) >= MAX_INPUT_BUFFER)
die (STATE_UNKNOWN, _("Input buffer overflow\n"));
game_type = optarg;
break;
case 'p': /* index of ping field */
qstat_ping_field = atoi (optarg);
if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 'm': /* index on map field */
qstat_map_field = atoi (optarg);
if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 'g': /* index of game field */
qstat_game_field = atoi (optarg);
if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 129: /* index of player count field */
qstat_game_players = atoi (optarg);
if (qstat_game_players_max == 0)
qstat_game_players_max = qstat_game_players - 1;
if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
case 130: /* index of max players field */
qstat_game_players_max = atoi (optarg);
if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
return ERROR;
break;
default: /* args not parsable */
usage5();
}
}
c = optind;
/* first option is the game type */
if (!game_type && c < argc)
game_type = strdup(argv[c++]);
c = optind;
/* first option is the game type */
if (!game_type && c<argc)
game_type = strdup (argv[c++]);
/* Second option is the server name */
if (!server_ip && c < argc)
server_ip = strdup(argv[c++]);
/* Second option is the server name */
if (!server_ip && c<argc)
server_ip = strdup (argv[c++]);
return validate_arguments ();
return validate_arguments();
}
int validate_arguments(void) {
if (qstat_game_players_max < 0)
qstat_game_players_max = 4;
int
validate_arguments (void)
{
if (qstat_game_players_max < 0)
qstat_game_players_max = 4;
if (qstat_game_players < 0)
qstat_game_players = 5;
if (qstat_game_players < 0)
qstat_game_players = 5;
if (qstat_game_field < 0)
qstat_game_field = 2;
if (qstat_game_field < 0)
qstat_game_field = 2;
if (qstat_map_field < 0)
qstat_map_field = 3;
if (qstat_map_field < 0)
qstat_map_field = 3;
if (qstat_ping_field < 0)
qstat_ping_field = 5;
if (qstat_ping_field < 0)
qstat_ping_field = 5;
return OK;
return OK;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n");
printf(COPYRIGHT, copyright, email);
printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n");
printf (COPYRIGHT, copyright, email);
printf(_("This plugin tests game server connections with the specified host."));
printf (_("This plugin tests game server connections with the specified host."));
printf("\n\n");
printf ("\n\n");
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(" %s\n", "-p");
printf(" %s\n", _("Optional port of which to connect"));
printf(" %s\n", "gf");
printf(" %s\n", _("Field number in raw qstat output that contains game name"));
printf(" %s\n", "-mf");
printf(" %s\n", _("Field number in raw qstat output that contains map name"));
printf(" %s\n", "-pf");
printf(" %s\n", _("Field number in raw qstat output that contains ping time"));
printf (" %s\n", "-p");
printf (" %s\n", _("Optional port of which to connect"));
printf (" %s\n", "gf");
printf (" %s\n", _("Field number in raw qstat output that contains game name"));
printf (" %s\n", "-mf");
printf (" %s\n", _("Field number in raw qstat output that contains map name"));
printf (" %s\n", "-pf");
printf (" %s\n", _("Field number in raw qstat output that contains ping time"));
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf("\n");
printf("%s\n", _("Notes:"));
printf(" %s\n", _("This plugin uses the 'qstat' command, the popular game server status query tool."));
printf(" %s\n", _("If you don't have the package installed, you will need to download it from"));
printf(" %s\n", _("https://github.com/multiplay/qstat before you can use this plugin."));
printf ("\n");
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("This plugin uses the 'qstat' command, the popular game server status query tool."));
printf (" %s\n", _("If you don't have the package installed, you will need to download it from"));
printf (" %s\n", _("https://github.com/multiplay/qstat before you can use this plugin."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field] [-p ping_field] [-G game-time] [-H hostname] <game> <ip_address>\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field] [-p ping_field] [-G game-time] [-H hostname] <game> "
"<ip_address>\n",
progname);
}
/******************************************************************************

View file

@ -1,36 +1,36 @@
/*****************************************************************************
*
* Monitoring check_hpjd plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_hpjd plugin
*
* This plugin tests the STATUS of an HP printer with a JetDirect card.
* Net-SNMP must be installed on the computer running the plugin.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_hpjd plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_hpjd plugin
*
* This plugin tests the STATUS of an HP printer with a JetDirect card.
* Net-SNMP must be installed on the computer running the plugin.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_hpjd";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -39,9 +39,7 @@ const char *email = "devel@monitoring-plugins.org";
#include "netutils.h"
#define DEFAULT_COMMUNITY "public"
#define DEFAULT_PORT "161"
const char *option_summary = "-H host [-C community]\n";
#define DEFAULT_PORT "161"
#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"
@ -56,22 +54,20 @@ const char *option_summary = "-H host [-C community]\n";
#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
#define ONLINE 0
#define OFFLINE 1
int process_arguments (int, char **);
int validate_arguments (void);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int validate_arguments(void);
static void print_help(void);
void print_usage(void);
char *community = NULL;
char *address = NULL;
unsigned int port = 0;
int check_paper_out = 1;
static char *community = NULL;
static char *address = NULL;
static unsigned int port = 0;
static int check_paper_out = 1;
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
char command_line[1024];
int result = STATE_UNKNOWN;
int line;
@ -94,116 +90,99 @@ main (int argc, char **argv)
errmsg = malloc(MAX_INPUT_BUFFER);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
/* 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);
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 -OQa -m : -v 1 -c %s %s:%u %s",
PATH_TO_SNMPGET,
community,
address,
port,
query_string);
sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, community, address, port, query_string);
/* run the command */
child_process = spopen (command_line);
child_process = spopen(command_line);
if (child_process == NULL) {
printf (_("Could not open pipe: %s\n"), command_line);
printf(_("Could not open pipe: %s\n"), command_line);
return STATE_UNKNOWN;
}
child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
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(_("Could not open stderr for %s\n"), command_line);
}
result = STATE_OK;
line = 0;
while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
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;
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, "=");
temp_buffer = strtok(input_buffer, "=");
temp_buffer = strtok(NULL, "=");
if (temp_buffer == NULL && line < 13) {
result = STATE_UNKNOWN;
strcpy (errmsg, input_buffer);
result = STATE_UNKNOWN;
strcpy(errmsg, input_buffer);
} else {
switch (line) {
case 1: /* 1st line should contain the line status */
line_status = atoi (temp_buffer);
case 1: /* 1st line should contain the line status */
line_status = atoi(temp_buffer);
break;
case 2: /* 2nd line should contain the paper status */
paper_status = atoi (temp_buffer);
case 2: /* 2nd line should contain the paper status */
paper_status = atoi(temp_buffer);
break;
case 3: /* 3rd line should be intervention required */
intervention_required = atoi (temp_buffer);
case 3: /* 3rd line should be intervention required */
intervention_required = atoi(temp_buffer);
break;
case 4: /* 4th line should be peripheral error */
peripheral_error = atoi (temp_buffer);
case 4: /* 4th line should be peripheral error */
peripheral_error = atoi(temp_buffer);
break;
case 5: /* 5th line should contain the paper jam status */
paper_jam = atoi (temp_buffer);
case 5: /* 5th line should contain the paper jam status */
paper_jam = atoi(temp_buffer);
break;
case 6: /* 6th line should contain the paper out status */
paper_out = atoi (temp_buffer);
case 6: /* 6th line should contain the paper out status */
paper_out = atoi(temp_buffer);
break;
case 7: /* 7th line should contain the toner low status */
toner_low = atoi (temp_buffer);
case 7: /* 7th line should contain the toner low status */
toner_low = atoi(temp_buffer);
break;
case 8: /* did data come too slow for engine */
page_punt = atoi (temp_buffer);
case 8: /* did data come too slow for engine */
page_punt = atoi(temp_buffer);
break;
case 9: /* did we run out of memory */
memory_out = atoi (temp_buffer);
case 9: /* did we run out of memory */
memory_out = atoi(temp_buffer);
break;
case 10: /* is there a door open */
door_open = atoi (temp_buffer);
case 10: /* is there a door open */
door_open = atoi(temp_buffer);
break;
case 11: /* is output tray full */
paper_output = atoi (temp_buffer);
case 11: /* is output tray full */
paper_output = atoi(temp_buffer);
break;
case 12: /* display panel message */
strcpy (display_message, temp_buffer + 1);
case 12: /* display panel message */
strcpy(display_message, temp_buffer + 1);
break;
default: /* fold multiline message */
strncat (display_message, input_buffer,
sizeof (display_message) - strlen (display_message) - 1);
default: /* fold multiline message */
strncat(display_message, input_buffer, sizeof(display_message) - strlen(display_message) - 1);
}
}
/* break out of the read loop if we encounter an error */
@ -212,29 +191,27 @@ main (int argc, char **argv)
}
/* WARNING if output found on stderr */
if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
result = max_state (result, STATE_WARNING);
if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
result = max_state(result, STATE_WARNING);
/* remove CRLF */
if (input_buffer[strlen (input_buffer) - 1] == '\n')
input_buffer[strlen (input_buffer) - 1] = 0;
sprintf (errmsg, "%s", input_buffer );
if (input_buffer[strlen(input_buffer) - 1] == '\n')
input_buffer[strlen(input_buffer) - 1] = 0;
sprintf(errmsg, "%s", input_buffer);
}
/* close stderr */
(void) fclose (child_stderr);
(void)fclose(child_stderr);
/* close the pipe */
if (spclose (child_process))
result = max_state (result, STATE_WARNING);
if (spclose(child_process))
result = max_state(result, STATE_WARNING);
/* if there wasn't any output, display an error */
if (line == 0) {
/* might not be the problem, but most likely is. */
result = STATE_UNKNOWN ;
xasprintf (&errmsg, "%s : Timeout from host %s\n", errmsg, address );
result = STATE_UNKNOWN;
xasprintf(&errmsg, "%s : Timeout from host %s\n", errmsg, address);
}
/* if we had no read errors, check the printer status results... */
@ -242,201 +219,171 @@ main (int argc, char **argv)
if (paper_jam) {
result = STATE_WARNING;
strcpy (errmsg, _("Paper Jam"));
}
else if (paper_out) {
strcpy(errmsg, _("Paper Jam"));
} else if (paper_out) {
if (check_paper_out)
result = STATE_WARNING;
strcpy (errmsg, _("Out of Paper"));
}
else if (line_status == OFFLINE) {
if (strcmp (errmsg, "POWERSAVE ON") != 0) {
strcpy(errmsg, _("Out of Paper"));
} else if (line_status == OFFLINE) {
if (strcmp(errmsg, "POWERSAVE ON") != 0) {
result = STATE_WARNING;
strcpy (errmsg, _("Printer Offline"));
strcpy(errmsg, _("Printer Offline"));
}
}
else if (peripheral_error) {
} else if (peripheral_error) {
result = STATE_WARNING;
strcpy (errmsg, _("Peripheral Error"));
}
else if (intervention_required) {
strcpy(errmsg, _("Peripheral Error"));
} else if (intervention_required) {
result = STATE_WARNING;
strcpy (errmsg, _("Intervention Required"));
}
else if (toner_low) {
strcpy(errmsg, _("Intervention Required"));
} else if (toner_low) {
result = STATE_WARNING;
strcpy (errmsg, _("Toner Low"));
}
else if (memory_out) {
strcpy(errmsg, _("Toner Low"));
} else if (memory_out) {
result = STATE_WARNING;
strcpy (errmsg, _("Insufficient Memory"));
}
else if (door_open) {
strcpy(errmsg, _("Insufficient Memory"));
} else if (door_open) {
result = STATE_WARNING;
strcpy (errmsg, _("A Door is Open"));
}
else if (paper_output) {
strcpy(errmsg, _("A Door is Open"));
} else if (paper_output) {
result = STATE_WARNING;
strcpy (errmsg, _("Output Tray is Full"));
}
else if (page_punt) {
strcpy(errmsg, _("Output Tray is Full"));
} else if (page_punt) {
result = STATE_WARNING;
strcpy (errmsg, _("Data too Slow for Engine"));
}
else if (paper_status) {
strcpy(errmsg, _("Data too Slow for Engine"));
} else if (paper_status) {
result = STATE_WARNING;
strcpy (errmsg, _("Unknown Paper Error"));
strcpy(errmsg, _("Unknown Paper Error"));
}
}
if (result == STATE_OK)
printf (_("Printer ok - (%s)\n"), display_message);
printf(_("Printer ok - (%s)\n"), display_message);
else if (result == STATE_UNKNOWN) {
printf ("%s\n", errmsg);
printf("%s\n", errmsg);
/* if printer could not be reached, escalate to critical */
if (strstr (errmsg, "Timeout"))
if (strstr(errmsg, "Timeout"))
result = STATE_CRITICAL;
}
else if (result == STATE_WARNING)
printf ("%s (%s)\n", errmsg, display_message);
printf("%s (%s)\n", errmsg, display_message);
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int process_arguments(int argc, char **argv) {
int c;
int option = 0;
static struct option longopts[] = {
{"hostname", required_argument, 0, 'H'},
{"community", required_argument, 0, 'C'},
/* {"critical", required_argument,0,'c'}, */
/* {"warning", required_argument,0,'w'}, */
{"port", required_argument,0,'p'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
{"community", required_argument, 0, 'C'},
/* {"critical", required_argument,0,'c'}, */
/* {"warning", required_argument,0,'w'}, */
{"port", required_argument, 0, 'p'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
if (argc < 2)
return ERROR;
while (1) {
c = getopt_long (argc, argv, "+hVH:C:p:D", longopts, &option);
c = getopt_long(argc, argv, "+hVH:C:p:D", longopts, &option);
if (c == -1 || c == EOF || c == 1)
break;
switch (c) {
case 'H': /* hostname */
if (is_host (optarg)) {
address = strscpy(address, optarg) ;
}
else {
usage2 (_("Invalid hostname/address"), optarg);
case 'H': /* hostname */
if (is_host(optarg)) {
address = strscpy(address, optarg);
} else {
usage2(_("Invalid hostname/address"), optarg);
}
break;
case 'C': /* community */
community = strscpy (community, optarg);
case 'C': /* community */
community = strscpy(community, optarg);
break;
case 'p':
if (!is_intpos(optarg))
usage2 (_("Port must be a positive short integer"), optarg);
usage2(_("Port must be a positive short integer"), optarg);
else
port = atoi(optarg);
break;
case 'D': /* disable paper out check*/
case 'D': /* disable paper out check*/
check_paper_out = 0;
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case '?': /* help */
usage5 ();
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case '?': /* help */
usage5();
}
}
c = optind;
if (address == NULL) {
if (is_host (argv[c])) {
if (is_host(argv[c])) {
address = argv[c++];
}
else {
usage2 (_("Invalid hostname/address"), argv[c]);
} else {
usage2(_("Invalid hostname/address"), argv[c]);
}
}
if (community == NULL) {
if (argv[c] != NULL )
if (argv[c] != NULL)
community = argv[c];
else
community = strdup (DEFAULT_COMMUNITY);
community = strdup(DEFAULT_COMMUNITY);
}
if (port == 0) {
port = atoi(DEFAULT_PORT);
}
return validate_arguments ();
return validate_arguments();
}
int validate_arguments(void) { return OK; }
int
validate_arguments (void)
{
return OK;
void print_help(void) {
print_revision(progname, NP_VERSION);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
printf("%s\n", _("This plugin tests the STATUS of an HP printer with a JetDirect card."));
printf("%s\n", _("Net-snmp must be installed on the computer running the plugin."));
printf("\n\n");
print_usage();
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf(" %s\n", "-C, --community=STRING");
printf(" %s", _("The SNMP community name "));
printf(_("(default=%s)"), DEFAULT_COMMUNITY);
printf("\n");
printf(" %s\n", "-p, --port=STRING");
printf(" %s", _("Specify the port to check "));
printf(_("(default=%s)"), DEFAULT_PORT);
printf("\n");
printf(" %s\n", "-D");
printf(" %s", _("Disable paper check "));
printf(UT_SUPPORT);
}
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin tests the STATUS of an HP printer with a JetDirect card."));
printf ("%s\n", _("Net-snmp must be installed on the computer running the plugin."));
printf ("\n\n");
print_usage ();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf (" %s\n", "-C, --community=STRING");
printf (" %s", _("The SNMP community name "));
printf (_("(default=%s)"), DEFAULT_COMMUNITY);
printf ("\n");
printf (" %s\n", "-p, --port=STRING");
printf (" %s", _("Specify the port to check "));
printf (_("(default=%s)"), DEFAULT_PORT);
printf ("\n");
printf (" %s\n", "-D");
printf (" %s", _("Disable paper check "));
printf (UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -H host [-C community] [-p port] [-D]\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -H host [-C community] [-p port] [-D]\n", progname);
}

View file

@ -3,7 +3,7 @@
* Monitoring check_http plugin
*
* License: GPL
* Copyright (c) 1999-2013 Monitoring Plugins Development Team
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -32,7 +32,7 @@
*****************************************************************************/
const char *progname = "check_http";
const char *copyright = "1999-2022";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
// Do NOT sort those headers, it will break the build

View file

@ -1,112 +1,105 @@
/*****************************************************************************
*
* Monitoring check_ide_smart plugin
* ide-smart 1.3 - IDE S.M.A.R.T. checking tool
*
* License: GPL
* Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>
* 1998 Gadi Oxman <gadio@netvision.net.il>
* Copyright (c) 2000 Robert Dale <rdale@digital-mission.com>
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ide_smart plugin
*
* This plugin checks a local hard drive with the (Linux specific) SMART
* interface
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_ide_smart plugin
* ide-smart 1.3 - IDE S.M.A.R.T. checking tool
*
* License: GPL
* Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>
* 1998 Gadi Oxman <gadio@netvision.net.il>
* Copyright (c) 2000 Robert Dale <rdale@digital-mission.com>
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ide_smart plugin
*
* This plugin checks a local hard drive with the (Linux specific) SMART
* interface
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_ide_smart";
const char *copyright = "1998-2007";
const char *copyright = "1998-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
void print_help (void);
void print_usage (void);
static void print_help(void);
void print_usage(void);
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#ifdef __linux__
#include <linux/hdreg.h>
#include <linux/types.h>
# include <linux/hdreg.h>
# include <linux/types.h>
#define OPEN_MODE O_RDONLY
# define OPEN_MODE O_RDONLY
#endif /* __linux__ */
#ifdef __NetBSD__
#include <sys/device.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/videoio.h> /* for __u8 and friends */
#include <sys/scsiio.h>
#include <sys/ataio.h>
#include <dev/ata/atareg.h>
#include <dev/ic/wdcreg.h>
# include <sys/device.h>
# include <sys/param.h>
# include <sys/sysctl.h>
# include <sys/videoio.h> /* for __u8 and friends */
# include <sys/scsiio.h>
# include <sys/ataio.h>
# include <dev/ata/atareg.h>
# include <dev/ic/wdcreg.h>
#define SMART_ENABLE WDSM_ENABLE_OPS
#define SMART_DISABLE WDSM_DISABLE_OPS
#define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM
#define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */
# define SMART_ENABLE WDSM_ENABLE_OPS
# define SMART_DISABLE WDSM_DISABLE_OPS
# define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM
# define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */
#define OPEN_MODE O_RDWR
# define OPEN_MODE O_RDWR
#endif /* __NetBSD__ */
#include <errno.h>
#define NR_ATTRIBUTES 30
#define PREFAILURE 2
#define ADVISORY 1
#define OPERATIONAL 0
#define UNKNOWN -1
typedef struct threshold_s
{
#define NR_ATTRIBUTES 30
#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;
} __attribute__((packed)) threshold_t;
typedef struct thresholds_s
{
typedef struct thresholds_s {
__u16 revision;
threshold_t thresholds[NR_ATTRIBUTES];
__u8 reserved[18];
__u8 vendor[131];
__u8 checksum;
}
__attribute__ ((packed)) thresholds_t;
} __attribute__((packed)) thresholds_t;
typedef struct value_s
{
typedef struct value_s {
__u8 id;
__u16 status;
__u8 value;
__u8 vendor[8];
}
__attribute__ ((packed)) value_t;
} __attribute__((packed)) value_t;
typedef struct values_s
{
typedef struct values_s {
__u16 revision;
value_t values[NR_ATTRIBUTES];
__u8 offline_status;
@ -118,90 +111,71 @@ typedef struct values_s
__u8 reserved[16];
__u8 vendor[125];
__u8 checksum;
}
__attribute__ ((packed)) values_t;
} __attribute__((packed)) values_t;
struct
{
struct {
__u8 value;
char *text;
}
offline_status_text[] =
{
{0x00, "NeverStarted"},
{0x02, "Completed"},
{0x04, "Suspended"},
{0x05, "Aborted"},
{0x06, "Failed"},
{0, 0}
};
static offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"},
{0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}};
struct
{
static 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"}};
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
};
static char *get_offline_text(int);
static int smart_read_values(int, values_t *);
static int nagios(values_t *, thresholds_t *);
static void print_value(value_t *, threshold_t *);
static void print_values(values_t *, thresholds_t *);
static int smart_cmd_simple(int, enum SmartCommand, __u8, bool);
static int smart_read_thresholds(int, thresholds_t *);
static bool verbose = false;
/* 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);
int smart_read_values (int, values_t *);
int nagios (values_t *, thresholds_t *);
void print_value (value_t *, threshold_t *);
void print_values (values_t *, thresholds_t *);
int smart_cmd_simple (int, enum SmartCommand, __u8, bool);
int smart_read_thresholds (int, thresholds_t *);
bool verbose = false;
int
main (int argc, char *argv[])
{
int main(int argc, char *argv[]) {
char *device = NULL;
int o, longindex;
int o;
int longindex;
int retval = 0;
thresholds_t thresholds;
values_t values;
int fd;
static 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'},
{"nagios", no_argument, 0, 'n'}, /* DEPRECATED, but we still accept it */
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0}
};
static 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'},
{"nagios", no_argument, 0, 'n'}, /* DEPRECATED, but we still accept it */
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0}};
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
while (true) {
o = getopt_long (argc, argv, "+d:iq10nhVv", longopts, &longindex);
o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex);
if (o == -1 || o == EOF || o == 1)
break;
@ -211,30 +185,30 @@ main (int argc, char *argv[])
device = optarg;
break;
case 'q':
fprintf (stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\"."));
fprintf (stderr, "%s\n", _("Nagios-compatible output is now always returned."));
fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\"."));
fprintf(stderr, "%s\n", _("Nagios-compatible output is now always returned."));
break;
case 'i':
case '1':
case '0':
printf ("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help)."));
printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help)."));
return STATE_CRITICAL;
break;
case 'n':
fprintf (stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the"));
fprintf (stderr, "%s\n", _("default and will be removed from future releases."));
fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the"));
fprintf(stderr, "%s\n", _("default and will be removed from future releases."));
break;
case 'v': /* verbose */
verbose = true;
break;
case 'h':
print_help ();
print_help();
return STATE_UNKNOWN;
case 'V':
print_revision (progname, NP_VERSION);
print_revision(progname, NP_VERSION);
return STATE_UNKNOWN;
default:
usage5 ();
usage5();
}
}
@ -243,36 +217,33 @@ main (int argc, char *argv[])
}
if (!device) {
print_help ();
print_help();
return STATE_UNKNOWN;
}
fd = open (device, OPEN_MODE);
fd = open(device, OPEN_MODE);
if (fd < 0) {
printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno));
printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno));
return STATE_CRITICAL;
}
if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, false)) {
printf (_("CRITICAL - SMART_CMD_ENABLE\n"));
if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) {
printf(_("CRITICAL - SMART_CMD_ENABLE\n"));
return STATE_CRITICAL;
}
smart_read_values (fd, &values);
smart_read_thresholds (fd, &thresholds);
retval = nagios (&values, &thresholds);
if (verbose) print_values (&values, &thresholds);
smart_read_values(fd, &values);
smart_read_thresholds(fd, &thresholds);
retval = nagios(&values, &thresholds);
if (verbose)
print_values(&values, &thresholds);
close (fd);
close(fd);
return retval;
}
char *
get_offline_text (int status)
{
char *get_offline_text(int status) {
int i;
for (i = 0; offline_status_text[i].text; i++) {
if (offline_status_text[i].value == status) {
@ -282,11 +253,7 @@ get_offline_text (int status)
return "UNKNOWN";
}
int
smart_read_values (int fd, values_t * values)
{
int smart_read_values(int fd, values_t *values) {
#ifdef __linux__
int e;
__u8 args[4 + 512];
@ -294,12 +261,12 @@ smart_read_values (int fd, values_t * values)
args[1] = 0;
args[2] = SMART_READ_VALUES;
args[3] = 1;
if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
e = errno;
printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno));
printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
return e;
}
memcpy (values, args + 4, 512);
memcpy(values, args + 4, 512);
#endif /* __linux__ */
#ifdef __NetBSD__
struct atareq req;
@ -323,7 +290,7 @@ smart_read_values (int fd, values_t * values)
if (errno != 0) {
int e = errno;
printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno));
printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
return e;
}
@ -332,13 +299,9 @@ smart_read_values (int fd, values_t * values)
return 0;
}
int
nagios (values_t * p, thresholds_t * t)
{
value_t * value = p->values;
threshold_t * threshold = t->thresholds;
int nagios(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;
@ -353,13 +316,11 @@ nagios (values_t * p, thresholds_t * t)
if (value->status & 1) {
status = PREFAILURE;
++prefailure;
}
else {
} else {
status = ADVISORY;
++advisory;
}
}
else {
} else {
++passed;
}
++total;
@ -369,81 +330,49 @@ nagios (values_t * p, thresholds_t * t)
}
switch (status) {
case PREFAILURE:
printf (_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"),
prefailure,
prefailure > 1 ? 's' : ' ',
failed,
total);
status=STATE_CRITICAL;
printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed,
total);
status = STATE_CRITICAL;
break;
case ADVISORY:
printf (_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"),
advisory,
advisory > 1 ? "ies" : "y",
failed,
total);
status=STATE_WARNING;
printf(_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"), advisory, advisory > 1 ? "ies" : "y", failed, total);
status = STATE_WARNING;
break;
case OPERATIONAL:
printf (_("OK - Operational (%d/%d tests passed)\n"), passed, total);
status=STATE_OK;
printf(_("OK - Operational (%d/%d tests passed)\n"), passed, total);
status = STATE_OK;
break;
default:
printf (_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status,
passed, total);
printf(_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status, passed, total);
status = STATE_UNKNOWN;
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_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;
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++);
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" : "");
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" : "");
}
int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_error) {
int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_error) {
int e = STATE_UNKNOWN;
#ifdef __linux__
__u8 args[4];
@ -451,14 +380,14 @@ int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_er
args[1] = val0;
args[2] = smart_command[command].value;
args[3] = 0;
if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
e = STATE_CRITICAL;
if (show_error)
printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
} else {
e = STATE_OK;
if (show_error)
printf (_("OK - Command sent (%s)\n"), smart_command[command].text);
printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
}
#endif /* __linux__ */
@ -483,35 +412,31 @@ int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_er
if (errno != 0) {
e = STATE_CRITICAL;
if (show_error)
printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
} else {
e = STATE_OK;
if (show_error)
printf (_("OK - Command sent (%s)\n"), smart_command[command].text);
printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
}
#endif /* __NetBSD__ */
return e;
}
int
smart_read_thresholds (int fd, thresholds_t * thresholds)
{
int smart_read_thresholds(int fd, thresholds_t *thresholds) {
#ifdef __linux__
int e;
__u8 args[4 + 512];
args[0] = WIN_SMART;
args[1] = 0;
args[2] = SMART_READ_THRESHOLDS;
args[3] = 1;
if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
args[1] = 0;
args[2] = SMART_READ_THRESHOLDS;
args[3] = 1;
if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
e = errno;
printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno));
printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
return e;
}
memcpy (thresholds, args + 4, 512);
memcpy(thresholds, args + 4, 512);
#endif /* __linux__ */
#ifdef __NetBSD__
struct atareq req;
@ -535,7 +460,7 @@ smart_read_thresholds (int fd, thresholds_t * thresholds)
if (errno != 0) {
int e = errno;
printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno));
printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
return e;
}
@ -544,45 +469,43 @@ smart_read_thresholds (int fd, thresholds_t * thresholds)
return 0;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
printf("Plugin implementation - 1999 Robert Dale <rdale@digital-mission.com>\n");
printf(COPYRIGHT, copyright, email);
printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
printf ("Plugin implementation - 1999 Robert Dale <rdale@digital-mission.com>\n");
printf (COPYRIGHT, copyright, email);
printf(_("This plugin checks a local hard drive with the (Linux specific) SMART interface "
"[http://smartlinux.sourceforge.net/smart/index.php]."));
printf (_("This plugin checks a local hard drive with the (Linux specific) SMART interface [http://smartlinux.sourceforge.net/smart/index.php]."));
printf("\n\n");
printf ("\n\n");
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(" %s\n", "-d, --device=DEVICE");
printf(" %s\n", _("Select device DEVICE"));
printf(" %s\n", _("Note: if the device is specified without this option, any further option will"));
printf(" %s\n", _("be ignored."));
printf (" %s\n", "-d, --device=DEVICE");
printf (" %s\n", _("Select device DEVICE"));
printf (" %s\n", _("Note: if the device is specified without this option, any further option will"));
printf (" %s\n", _("be ignored."));
printf(UT_VERBOSE);
printf (UT_VERBOSE);
printf("\n");
printf("%s\n", _("Notes:"));
printf(" %s\n", _("The SMART command modes (-i/--immediate, -0/--auto-off and -1/--auto-on) were"));
printf(" %s\n", _("broken in an underhand manner and have been disabled. You can use smartctl"));
printf(" %s\n", _("instead:"));
printf(" %s\n", _("-0/--auto-off: use \"smartctl --offlineauto=off\""));
printf(" %s\n", _("-1/--auto-on: use \"smartctl --offlineauto=on\""));
printf(" %s\n", _("-i/--immediate: use \"smartctl --test=offline\""));
printf ("\n");
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("The SMART command modes (-i/--immediate, -0/--auto-off and -1/--auto-on) were"));
printf (" %s\n", _("broken in an underhand manner and have been disabled. You can use smartctl"));
printf (" %s\n", _("instead:"));
printf (" %s\n", _("-0/--auto-off: use \"smartctl --offlineauto=off\""));
printf (" %s\n", _("-1/--auto-on: use \"smartctl --offlineauto=on\""));
printf (" %s\n", _("-i/--immediate: use \"smartctl --test=offline\""));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
/* todo : add to the long nanual as example
/* todo : add to the long nanual as example
*
* Run with: check_ide-smart --nagios [-d] <DRIVE>
* Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc
@ -593,10 +516,7 @@ print_help (void)
* - Returns -1 not too often
*/
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s [-d <device>] [-v]", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s [-d <device>] [-v]", progname);
}

View file

@ -3,7 +3,7 @@
* Monitoring check_ldap plugin
*
* License: GPL
* Copyright (c) 2000-2008 Monitoring Plugins Development Team
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -28,7 +28,7 @@
/* progname may be check_ldaps */
char *progname = "check_ldap";
const char *copyright = "2000-2008";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"

View file

@ -1,88 +1,79 @@
/*****************************************************************************
*
* Monitoring check_mrtg plugin
*
* License: GPL
* Copyright (c) 1999-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_mrtg plugin
*
* This plugin will check either the average or maximum value of one of the
* two variables recorded in an MRTG log file.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_mrtg plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_mrtg plugin
*
* This plugin will check either the average or maximum value of one of the
* two variables recorded in an MRTG log file.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_mrtg";
const char *copyright = "1999-2007";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
int process_arguments (int, char **);
int validate_arguments (void);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int validate_arguments(void);
static void print_help(void);
void print_usage(void);
char *log_file = NULL;
int expire_minutes = 0;
bool use_average = true;
int variable_number = -1;
unsigned long value_warning_threshold = 0L;
unsigned long value_critical_threshold = 0L;
char *label;
char *units;
static char *log_file = NULL;
static int expire_minutes = 0;
static bool use_average = true;
static int variable_number = -1;
static unsigned long value_warning_threshold = 0L;
static unsigned long value_critical_threshold = 0L;
static char *label;
static char *units;
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;
time_t timestamp = 0L;
unsigned long average_value_rate = 0L;
unsigned long maximum_value_rate = 0L;
unsigned long rate = 0L;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments\n"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments\n"));
/* open the MRTG log file for reading */
fp = fopen (log_file, "r");
if (fp == NULL) {
printf (_("Unable to open MRTG log file\n"));
FILE *mtrg_log_file = fopen(log_file, "r");
if (mtrg_log_file == NULL) {
printf(_("Unable to open MRTG log file\n"));
return STATE_UNKNOWN;
}
line = 0;
while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
time_t timestamp = 0L;
unsigned long average_value_rate = 0L;
unsigned long maximum_value_rate = 0L;
char input_buffer[MAX_INPUT_BUFFER];
int line = 0;
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mtrg_log_file)) {
line++;
@ -95,291 +86,260 @@ main (int argc, char **argv)
break;
/* grab the timestamp */
temp_buffer = strtok (input_buffer, " ");
timestamp = strtoul (temp_buffer, NULL, 10);
char *temp_buffer = strtok(input_buffer, " ");
timestamp = strtoul(temp_buffer, NULL, 10);
/* grab the average value 1 rate */
temp_buffer = strtok (NULL, " ");
temp_buffer = strtok(NULL, " ");
if (variable_number == 1)
average_value_rate = strtoul (temp_buffer, NULL, 10);
average_value_rate = strtoul(temp_buffer, NULL, 10);
/* grab the average value 2 rate */
temp_buffer = strtok (NULL, " ");
temp_buffer = strtok(NULL, " ");
if (variable_number == 2)
average_value_rate = strtoul (temp_buffer, NULL, 10);
average_value_rate = strtoul(temp_buffer, NULL, 10);
/* grab the maximum value 1 rate */
temp_buffer = strtok (NULL, " ");
temp_buffer = strtok(NULL, " ");
if (variable_number == 1)
maximum_value_rate = strtoul (temp_buffer, NULL, 10);
maximum_value_rate = strtoul(temp_buffer, NULL, 10);
/* grab the maximum value 2 rate */
temp_buffer = strtok (NULL, " ");
temp_buffer = strtok(NULL, " ");
if (variable_number == 2)
maximum_value_rate = strtoul (temp_buffer, NULL, 10);
maximum_value_rate = strtoul(temp_buffer, NULL, 10);
}
/* close the log file */
fclose (fp);
fclose(mtrg_log_file);
/* if we couldn't read enough data, return an unknown error */
if (line <= 2) {
printf (_("Unable to process MRTG log file\n"));
printf(_("Unable to process MRTG log file\n"));
return STATE_UNKNOWN;
}
/* make sure the MRTG data isn't too old */
time (&current_time);
if (expire_minutes > 0
&& (current_time - timestamp) > (expire_minutes * 60)) {
printf (_("MRTG data has expired (%d minutes old)\n"),
(int) ((current_time - timestamp) / 60));
time_t current_time;
time(&current_time);
if (expire_minutes > 0 && (current_time - timestamp) > (expire_minutes * 60)) {
printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60));
return STATE_WARNING;
}
unsigned long rate = 0L;
/* else check the incoming/outgoing rates */
if (use_average)
rate = average_value_rate;
else
rate = maximum_value_rate;
int result = STATE_OK;
if (rate > value_critical_threshold)
result = STATE_CRITICAL;
else if (rate > value_warning_threshold)
result = STATE_WARNING;
printf("%s. %s = %lu %s|%s\n",
(use_average) ? _("Avg") : _("Max"),
label, rate, units,
perfdata(label, (long) rate, units,
(int) value_warning_threshold, (long) value_warning_threshold,
(int) value_critical_threshold, (long) value_critical_threshold,
0, 0, 0, 0));
printf("%s. %s = %lu %s|%s\n", (use_average) ? _("Avg") : _("Max"), label, rate, units,
perfdata(label, (long)rate, units, (int)value_warning_threshold, (long)value_warning_threshold, (int)value_critical_threshold,
(long)value_critical_threshold, 0, 0, 0, 0));
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int option = 0;
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {
{"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'},
{"variable", required_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
{"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'}, {"variable", required_argument, 0, 'v'},
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
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");
for (int i = 1; i < argc; i++) {
if (strcmp("-to", argv[i]) == 0)
strcpy(argv[i], "-t");
else if (strcmp("-wt", argv[i]) == 0)
strcpy(argv[i], "-w");
else if (strcmp("-ct", argv[i]) == 0)
strcpy(argv[i], "-c");
}
int option_char;
int option = 0;
while (1) {
c = getopt_long (argc, argv, "hVF:e:a:v:c:w:l:u:", longopts,
&option);
option_char = getopt_long(argc, argv, "hVF:e:a:v:c:w:l:u:", longopts, &option);
if (c == -1 || c == EOF)
if (option_char == -1 || option_char == EOF)
break;
switch (c) {
case 'F': /* input file */
switch (option_char) {
case 'F': /* input file */
log_file = optarg;
break;
case 'e': /* ups name */
expire_minutes = atoi (optarg);
case 'e': /* ups name */
expire_minutes = atoi(optarg);
break;
case 'a': /* port */
if (!strcmp (optarg, "MAX"))
case 'a': /* port */
if (!strcmp(optarg, "MAX"))
use_average = false;
else
use_average = true;
break;
case 'v':
variable_number = atoi (optarg);
variable_number = atoi(optarg);
if (variable_number < 1 || variable_number > 2)
usage4 (_("Invalid variable number"));
usage4(_("Invalid variable number"));
break;
case 'w': /* critical time threshold */
value_warning_threshold = strtoul (optarg, NULL, 10);
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);
case 'c': /* warning time threshold */
value_critical_threshold = strtoul(optarg, NULL, 10);
break;
case 'l': /* label */
case 'l': /* label */
label = optarg;
break;
case 'u': /* timeout */
case 'u': /* timeout */
units = optarg;
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case '?': /* help */
usage5 ();
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case '?': /* help */
usage5();
}
}
c = optind;
if (log_file == NULL && argc > c) {
log_file = argv[c++];
option_char = optind;
if (log_file == NULL && argc > option_char) {
log_file = argv[option_char++];
}
if (expire_minutes <= 0 && argc > c) {
if (is_intpos (argv[c]))
expire_minutes = atoi (argv[c++]);
if (expire_minutes <= 0 && argc > option_char) {
if (is_intpos(argv[option_char]))
expire_minutes = atoi(argv[option_char++]);
else
die (STATE_UNKNOWN,
_("%s is not a valid expiration time\nUse '%s -h' for additional help\n"),
argv[c], progname);
die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[option_char], progname);
}
if (argc > c && strcmp (argv[c], "MAX") == 0) {
if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) {
use_average = false;
c++;
}
else if (argc > c && strcmp (argv[c], "AVG") == 0) {
option_char++;
} else if (argc > option_char && strcmp(argv[option_char], "AVG") == 0) {
use_average = true;
c++;
option_char++;
}
if (argc > c && variable_number == -1) {
variable_number = atoi (argv[c++]);
if (argc > option_char && variable_number == -1) {
variable_number = atoi(argv[option_char++]);
if (variable_number < 1 || variable_number > 2) {
printf ("%s :", argv[c]);
usage (_("Invalid variable number\n"));
printf("%s :", argv[option_char]);
usage(_("Invalid variable number\n"));
}
}
if (argc > c && value_warning_threshold == 0) {
value_warning_threshold = strtoul (argv[c++], NULL, 10);
if (argc > option_char && value_warning_threshold == 0) {
value_warning_threshold = strtoul(argv[option_char++], NULL, 10);
}
if (argc > c && value_critical_threshold == 0) {
value_critical_threshold = strtoul (argv[c++], NULL, 10);
if (argc > option_char && value_critical_threshold == 0) {
value_critical_threshold = strtoul(argv[option_char++], NULL, 10);
}
if (argc > c && strlen (label) == 0) {
label = argv[c++];
if (argc > option_char && strlen(label) == 0) {
label = argv[option_char++];
}
if (argc > c && strlen (units) == 0) {
units = argv[c++];
if (argc > option_char && strlen(units) == 0) {
units = argv[option_char++];
}
return validate_arguments ();
return validate_arguments();
}
int
validate_arguments (void)
{
int validate_arguments(void) {
if (variable_number == -1)
usage4 (_("You must supply the variable number"));
usage4(_("You must supply the variable number"));
if (label == NULL)
label = strdup ("value");
label = strdup("value");
if (units == NULL)
units = strdup ("");
units = strdup("");
return OK;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("%s\n", _("This plugin will check either the average or maximum value of one of the"));
printf("%s\n", _("two variables recorded in an MRTG log file."));
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf("\n\n");
printf ("%s\n", _("This plugin will check either the average or maximum value of one of the"));
printf ("%s\n", _("two variables recorded in an MRTG log file."));
print_usage();
printf ("\n\n");
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
print_usage ();
printf(" %s\n", "-F, --logfile=FILE");
printf(" %s\n", _("The MRTG log file containing the data you want to monitor"));
printf(" %s\n", "-e, --expires=MINUTES");
printf(" %s\n", _("Minutes before MRTG data is considered to be too old"));
printf(" %s\n", "-a, --aggregation=AVG|MAX");
printf(" %s\n", _("Should we check average or maximum values?"));
printf(" %s\n", "-v, --variable=INTEGER");
printf(" %s\n", _("Which variable set should we inspect? (1 or 2)"));
printf(" %s\n", "-w, --warning=INTEGER");
printf(" %s\n", _("Threshold value for data to result in WARNING status"));
printf(" %s\n", "-c, --critical=INTEGER");
printf(" %s\n", _("Threshold value for data to result in CRITICAL status"));
printf(" %s\n", "-l, --label=STRING");
printf(" %s\n", _("Type label for data (Examples: Conns, \"Processor Load\", In, Out)"));
printf(" %s\n", "-u, --units=STRING");
printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,"));
printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")"));
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf("\n");
printf(" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If"));
printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If"));
printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING"));
printf(" %s\n", _("status is returned and a warning message is printed."));
printf (" %s\n", "-F, --logfile=FILE");
printf (" %s\n", _("The MRTG log file containing the data you want to monitor"));
printf (" %s\n", "-e, --expires=MINUTES");
printf (" %s\n", _("Minutes before MRTG data is considered to be too old"));
printf (" %s\n", "-a, --aggregation=AVG|MAX");
printf (" %s\n", _("Should we check average or maximum values?"));
printf (" %s\n", "-v, --variable=INTEGER");
printf (" %s\n", _("Which variable set should we inspect? (1 or 2)"));
printf (" %s\n", "-w, --warning=INTEGER");
printf (" %s\n", _("Threshold value for data to result in WARNING status"));
printf (" %s\n", "-c, --critical=INTEGER");
printf (" %s\n", _("Threshold value for data to result in CRITICAL status"));
printf (" %s\n", "-l, --label=STRING");
printf (" %s\n", _("Type label for data (Examples: Conns, \"Processor Load\", In, Out)"));
printf (" %s\n", "-u, --units=STRING");
printf (" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,"));
printf (" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")"));
printf("\n");
printf(" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to"));
printf(" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
printf(" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
printf(" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"));
printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
printf ("\n");
printf (" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If"));
printf (" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If"));
printf (" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING"));
printf (" %s\n", _("status is returned and a warning message is printed."));
printf("%s\n", _("Notes:"));
printf(" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log"));
printf(" %s\n", _("file. If you want to monitor both values you will have to define two"));
printf(" %s\n", _("commands with different values for the <variable> argument. Of course,"));
printf(" %s\n", _("you can always hack the code to make this plugin work for you..."));
printf(" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from"));
printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
printf ("\n");
printf (" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to"));
printf (" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth)."));
printf (" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,"));
printf (" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows"));
printf (" %s\n", _("me to track processor utilization, user connections, drive space, etc and"));
printf (" %s\n\n", _("this plugin works well for monitoring that kind of data as well."));
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log"));
printf (" %s\n", _("file. If you want to monitor both values you will have to define two"));
printf (" %s\n", _("commands with different values for the <variable> argument. Of course,"));
printf (" %s\n", _("you can always hack the code to make this plugin work for you..."));
printf (" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from"));
printf (" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
/* original command line:
<log_file> <expire_minutes> <AVG|MAX> <variable> <vwl> <vcl> <label> [units] */
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n",progname);
printf ("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -F log_file -a <AVG | MAX> -v variable -w warning -c critical\n", progname);
printf("[-l label] [-u units] [-e expire_minutes] [-t timeout] [-v]\n");
}

View file

@ -1,94 +1,77 @@
/*****************************************************************************
*
* Monitoring check_mrtgtraf plugin
*
* License: GPL
* Copyright (c) 1999-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_mtrgtraf plugin
*
* This plugin will check the incoming/outgoing transfer rates of a router
* switch, etc recorded in an MRTG log.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_mrtgtraf plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_mtrgtraf plugin
*
* This plugin will check the incoming/outgoing transfer rates of a router
* switch, etc recorded in an MRTG log.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "utils.h"
const char *progname = "check_mrtgtraf";
const char *copyright = "1999-2007";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
int process_arguments (int, char **);
int validate_arguments (void);
void print_help(void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static void print_help(void);
void print_usage(void);
char *log_file = NULL;
int expire_minutes = -1;
bool 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;
static char *log_file = NULL;
static int expire_minutes = -1;
static bool use_average = true;
static unsigned long incoming_warning_threshold = 0L;
static unsigned long incoming_critical_threshold = 0L;
static unsigned long outgoing_warning_threshold = 0L;
static unsigned long outgoing_critical_threshold = 0L;
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
/* open the MRTG log file for reading */
FILE *mrtg_log_file_ptr = fopen(log_file, "r");
if (mrtg_log_file_ptr == NULL)
usage4(_("Unable to open MRTG log file"));
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;
time_t timestamp = 0L;
char input_buffer[MAX_INPUT_BUFFER];
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];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
/* open the MRTG log file for reading */
fp = fopen (log_file, "r");
if (fp == NULL)
usage4 (_("Unable to open MRTG log file"));
line = 0;
while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
int line = 0;
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mrtg_log_file_ptr)) {
line++;
@ -102,280 +85,254 @@ main (int argc, char **argv)
break;
/* grab the timestamp */
temp_buffer = strtok (input_buffer, " ");
timestamp = strtoul (temp_buffer, NULL, 10);
char *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);
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);
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);
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);
temp_buffer = strtok(NULL, " ");
maximum_outgoing_rate = strtoul(temp_buffer, NULL, 10);
}
/* close the log file */
fclose (fp);
fclose(mrtg_log_file_ptr);
/* if we couldn't read enough data, return an unknown error */
if (line <= 2)
usage4 (_("Unable to process MRTG log file"));
usage4(_("Unable to process MRTG log file"));
/* make sure the MRTG data isn't too old */
time (&current_time);
if ((expire_minutes > 0) &&
(current_time - timestamp) > (expire_minutes * 60))
die (STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"),
(int) ((current_time - timestamp) / 60));
time_t current_time;
time(&current_time);
if ((expire_minutes > 0) && (current_time - timestamp) > (expire_minutes * 60))
die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60));
unsigned long incoming_rate = 0L;
unsigned long outgoing_rate = 0L;
/* else check the incoming/outgoing rates */
if (use_average) {
incoming_rate = average_incoming_rate;
outgoing_rate = average_outgoing_rate;
}
else {
} else {
incoming_rate = maximum_incoming_rate;
outgoing_rate = maximum_outgoing_rate;
}
double adjusted_incoming_rate = 0.0;
char incoming_speed_rating[8];
/* report incoming traffic in Bytes/sec */
if (incoming_rate < 1024) {
strcpy (incoming_speed_rating, "B");
adjusted_incoming_rate = (double) incoming_rate;
strcpy(incoming_speed_rating, "B");
adjusted_incoming_rate = (double)incoming_rate;
}
/* report incoming traffic in KBytes/sec */
else if (incoming_rate < (1024 * 1024)) {
strcpy (incoming_speed_rating, "KB");
adjusted_incoming_rate = (double) (incoming_rate / 1024.0);
strcpy(incoming_speed_rating, "KB");
adjusted_incoming_rate = (double)(incoming_rate / 1024.0);
}
/* report incoming traffic in MBytes/sec */
else {
strcpy (incoming_speed_rating, "MB");
adjusted_incoming_rate = (double) (incoming_rate / 1024.0 / 1024.0);
strcpy(incoming_speed_rating, "MB");
adjusted_incoming_rate = (double)(incoming_rate / 1024.0 / 1024.0);
}
double adjusted_outgoing_rate = 0.0;
char outgoing_speed_rating[8];
/* report outgoing traffic in Bytes/sec */
if (outgoing_rate < 1024) {
strcpy (outgoing_speed_rating, "B");
adjusted_outgoing_rate = (double) outgoing_rate;
strcpy(outgoing_speed_rating, "B");
adjusted_outgoing_rate = (double)outgoing_rate;
}
/* report outgoing traffic in KBytes/sec */
else if (outgoing_rate < (1024 * 1024)) {
strcpy (outgoing_speed_rating, "KB");
adjusted_outgoing_rate = (double) (outgoing_rate / 1024.0);
strcpy(outgoing_speed_rating, "KB");
adjusted_outgoing_rate = (double)(outgoing_rate / 1024.0);
}
/* report outgoing traffic in MBytes/sec */
else {
strcpy (outgoing_speed_rating, "MB");
adjusted_outgoing_rate = (double) (outgoing_rate / 1024.0 / 1024.0);
strcpy(outgoing_speed_rating, "MB");
adjusted_outgoing_rate = (double)(outgoing_rate / 1024.0 / 1024.0);
}
if (incoming_rate > incoming_critical_threshold
|| outgoing_rate > outgoing_critical_threshold) {
int result = STATE_OK;
if (incoming_rate > incoming_critical_threshold || outgoing_rate > outgoing_critical_threshold) {
result = STATE_CRITICAL;
}
else if (incoming_rate > incoming_warning_threshold
|| outgoing_rate > outgoing_warning_threshold) {
} else if (incoming_rate > incoming_warning_threshold || outgoing_rate > outgoing_warning_threshold) {
result = STATE_WARNING;
}
xasprintf (&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"),
(use_average) ? _("Avg") : _("Max"), adjusted_incoming_rate,
incoming_speed_rating, (use_average) ? _("Avg") : _("Max"),
adjusted_outgoing_rate, outgoing_speed_rating,
fperfdata("in", adjusted_incoming_rate, incoming_speed_rating,
(int)incoming_warning_threshold, incoming_warning_threshold,
(int)incoming_critical_threshold, incoming_critical_threshold,
true, 0, false, 0),
fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating,
(int)outgoing_warning_threshold, outgoing_warning_threshold,
(int)outgoing_critical_threshold, outgoing_critical_threshold,
true, 0, false, 0));
char *error_message;
xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), (use_average) ? _("Avg") : _("Max"),
adjusted_incoming_rate, incoming_speed_rating, (use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate,
outgoing_speed_rating,
fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, (int)incoming_warning_threshold, incoming_warning_threshold,
(int)incoming_critical_threshold, incoming_critical_threshold, true, 0, false, 0),
fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, (int)outgoing_warning_threshold, outgoing_warning_threshold,
(int)outgoing_critical_threshold, outgoing_critical_threshold, true, 0, false, 0));
printf (_("Traffic %s - %s\n"), state_text(result), error_message);
printf(_("Traffic %s - %s\n"), state_text(result), error_message);
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int option = 0;
static struct option longopts[] = {
{"filename", required_argument, 0, 'F'},
{"expires", required_argument, 0, 'e'},
{"aggregation", required_argument, 0, 'a'},
{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"filename", required_argument, 0, 'F'},
{"expires", required_argument, 0, 'e'},
{"aggregation", required_argument, 0, 'a'},
{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
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");
for (int i = 1; i < argc; i++) {
if (strcmp("-to", argv[i]) == 0)
strcpy(argv[i], "-t");
else if (strcmp("-wt", argv[i]) == 0)
strcpy(argv[i], "-w");
else if (strcmp("-ct", argv[i]) == 0)
strcpy(argv[i], "-c");
}
int option_char;
int option = 0;
while (1) {
c = getopt_long (argc, argv, "hVF:e:a:c:w:", longopts, &option);
option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option);
if (c == -1 || c == EOF)
if (option_char == -1 || option_char == EOF)
break;
switch (c) {
case 'F': /* input file */
switch (option_char) {
case 'F': /* input file */
log_file = optarg;
break;
case 'e': /* expiration time */
expire_minutes = atoi (optarg);
case 'e': /* expiration time */
expire_minutes = atoi(optarg);
break;
case 'a': /* aggregation (AVE or MAX) */
if (!strcmp (optarg, "MAX"))
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);
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);
case 'w': /* critical threshold */
sscanf(optarg, "%lu,%lu", &incoming_warning_threshold, &outgoing_warning_threshold);
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case '?': /* help */
usage5 ();
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case '?': /* help */
usage5();
}
}
c = optind;
if (argc > c && log_file == NULL) {
log_file = argv[c++];
option_char = optind;
if (argc > option_char && log_file == NULL) {
log_file = argv[option_char++];
}
if (argc > c && expire_minutes == -1) {
expire_minutes = atoi (argv[c++]);
if (argc > option_char && expire_minutes == -1) {
expire_minutes = atoi(argv[option_char++]);
}
if (argc > c && strcmp (argv[c], "MAX") == 0) {
if (argc > option_char && strcmp(argv[option_char], "MAX") == 0) {
use_average = false;
c++;
}
else if (argc > c && strcmp (argv[c], "AVG") == 0) {
option_char++;
} else if (argc > option_char && strcmp(argv[option_char], "AVG") == 0) {
use_average = true;
c++;
option_char++;
}
if (argc > c && incoming_warning_threshold == 0) {
incoming_warning_threshold = strtoul (argv[c++], NULL, 10);
if (argc > option_char && incoming_warning_threshold == 0) {
incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10);
}
if (argc > c && incoming_critical_threshold == 0) {
incoming_critical_threshold = strtoul (argv[c++], NULL, 10);
if (argc > option_char && incoming_critical_threshold == 0) {
incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10);
}
if (argc > c && outgoing_warning_threshold == 0) {
outgoing_warning_threshold = strtoul (argv[c++], NULL, 10);
}
if (argc > c && outgoing_critical_threshold == 0) {
outgoing_critical_threshold = strtoul (argv[c++], NULL, 10);
if (argc > option_char && outgoing_warning_threshold == 0) {
outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10);
}
return validate_arguments ();
}
if (argc > option_char && outgoing_critical_threshold == 0) {
outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10);
}
int
validate_arguments (void)
{
return OK;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf("%s\n", _("This plugin will check the incoming/outgoing transfer rates of a router,"));
printf("%s\n", _("switch, etc recorded in an MRTG log. If the newest log entry is older"));
printf("%s\n", _("than <expire_minutes>, a WARNING status is returned. If either the"));
printf("%s\n", _("incoming or outgoing rates exceed the <icl> or <ocl> thresholds (in"));
printf("%s\n", _("Bytes/sec), a CRITICAL status results. If either of the rates exceed"));
printf("%s\n", _("the <iwl> or <owl> thresholds (in Bytes/sec), a WARNING status results."));
printf ("%s\n", _("This plugin will check the incoming/outgoing transfer rates of a router,"));
printf ("%s\n", _("switch, etc recorded in an MRTG log. If the newest log entry is older"));
printf ("%s\n", _("than <expire_minutes>, a WARNING status is returned. If either the"));
printf ("%s\n", _("incoming or outgoing rates exceed the <icl> or <ocl> thresholds (in"));
printf ("%s\n", _("Bytes/sec), a CRITICAL status results. If either of the rates exceed"));
printf ("%s\n", _("the <iwl> or <owl> thresholds (in Bytes/sec), a WARNING status results."));
printf("\n\n");
printf ("\n\n");
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(" %s\n", "-F, --filename=STRING");
printf(" %s\n", _("File to read log from"));
printf(" %s\n", "-e, --expires=INTEGER");
printf(" %s\n", _("Minutes after which log expires"));
printf(" %s\n", "-a, --aggregation=(AVG|MAX)");
printf(" %s\n", _("Test average or maximum"));
printf(" %s\n", "-w, --warning");
printf(" %s\n", _("Warning threshold pair <incoming>,<outgoing>"));
printf(" %s\n", "-c, --critical");
printf(" %s\n", _("Critical threshold pair <incoming>,<outgoing>"));
printf (" %s\n", "-F, --filename=STRING");
printf (" %s\n", _("File to read log from"));
printf (" %s\n", "-e, --expires=INTEGER");
printf (" %s\n", _("Minutes after which log expires"));
printf (" %s\n", "-a, --aggregation=(AVG|MAX)");
printf (" %s\n", _("Test average or maximum"));
printf (" %s\n", "-w, --warning");
printf (" %s\n", _("Warning threshold pair <incoming>,<outgoing>"));
printf (" %s\n", "-c, --critical");
printf (" %s\n", _("Critical threshold pair <incoming>,<outgoing>"));
printf("\n");
printf("%s\n", _("Notes:"));
printf(" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from"));
printf(" %s\n", " http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
printf(" %s\n", _("- While MRTG can monitor things other than traffic rates, this"));
printf(" %s\n", _(" plugin probably won't work with much else without modification."));
printf(" %s\n", _("- The calculated i/o rates are a little off from what MRTG actually"));
printf(" %s\n", _(" reports. I'm not sure why this is right now, but will look into it"));
printf(" %s\n", _(" for future enhancements of this plugin."));
printf ("\n");
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from"));
printf (" %s\n", " http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html");
printf (" %s\n", _("- While MRTG can monitor things other than traffic rates, this"));
printf (" %s\n", _(" plugin probably won't work with much else without modification."));
printf (" %s\n", _("- The calculated i/o rates are a little off from what MRTG actually"));
printf (" %s\n", _(" reports. I'm not sure why this is right now, but will look into it"));
printf (" %s\n", _(" for future enhancements of this plugin."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf (_("Usage"));
printf (" %s -F <log_file> -a <AVG | MAX> -w <warning_pair>\n",progname);
printf ("-c <critical_pair> [-e expire_minutes]\n");
void print_usage(void) {
printf(_("Usage"));
printf(" %s -F <log_file> -a <AVG | MAX> -w <warning_pair>\n", progname);
printf("-c <critical_pair> [-e expire_minutes]\n");
}

View file

@ -5,7 +5,7 @@
* License: GPL
* Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)
* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net)
* Copyright (c) 1999-2011 Monitoring Plugins Development Team
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -31,7 +31,7 @@
*****************************************************************************/
const char *progname = "check_mysql";
const char *copyright = "1999-2011";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#define SLAVERESULTSIZE 96
@ -59,8 +59,8 @@ bool ssl = false;
char *opt_file = NULL;
char *opt_group = NULL;
unsigned int db_port = MYSQL_PORT;
int check_slave = 0, warn_sec = 0, crit_sec = 0;
int ignore_auth = 0;
bool check_slave = false;
bool ignore_auth = false;
int verbose = 0;
static double warning_time = 0;
@ -456,10 +456,10 @@ process_arguments (int argc, char **argv)
db_port = atoi (optarg);
break;
case 'S':
check_slave = 1; /* check-slave */
check_slave = true; /* check-slave */
break;
case 'n':
ignore_auth = 1; /* ignore-auth */
ignore_auth = true; /* ignore-auth */
break;
case 'w':
warning = optarg;

View file

@ -1,36 +1,36 @@
/*****************************************************************************
*
* Monitoring check_mysql_query plugin
*
* License: GPL
* Copyright (c) 2006-2009 Monitoring Plugins Development Team
* Original code from check_mysql, copyright 1999 Didi Rieder
*
* Description:
*
* This file contains the check_mysql_query plugin
*
* This plugin is for running arbitrary SQL and checking the results
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_mysql_query plugin
*
* License: GPL
* Copyright (c) 2006-2024 Monitoring Plugins Development Team
* Original code from check_mysql, copyright 1999 Didi Rieder
*
* Description:
*
* This file contains the check_mysql_query plugin
*
* This plugin is for running arbitrary SQL and checking the results
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_mysql_query";
const char *copyright = "1999-2007";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -41,117 +41,109 @@ const char *email = "devel@monitoring-plugins.org";
#include <mysql.h>
#include <errmsg.h>
char *db_user = NULL;
char *db_host = NULL;
char *db_socket = NULL;
char *db_pass = NULL;
char *db = NULL;
char *opt_file = NULL;
char *opt_group = NULL;
unsigned int db_port = MYSQL_PORT;
static char *db_user = NULL;
static char *db_host = NULL;
static char *db_socket = NULL;
static char *db_pass = NULL;
static char *db = NULL;
static char *opt_file = NULL;
static char *opt_group = NULL;
static unsigned int db_port = MYSQL_PORT;
int process_arguments (int, char **);
int validate_arguments (void);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int validate_arguments(void);
static void print_help(void);
void print_usage(void);
char *sql_query = NULL;
int verbose = 0;
thresholds *my_thresholds = NULL;
static char *sql_query = NULL;
static int verbose = 0;
static thresholds *my_thresholds = NULL;
int
main (int argc, char **argv)
{
MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;
double value;
char *error = NULL;
int status;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
MYSQL mysql;
/* initialize mysql */
mysql_init (&mysql);
mysql_init(&mysql);
if (opt_file != NULL)
mysql_options(&mysql,MYSQL_READ_DEFAULT_FILE,opt_file);
mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file);
if (opt_group != NULL)
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,opt_group);
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group);
else
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client");
/* establish a connection to the server and error checking */
if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) {
if (mysql_errno (&mysql) == CR_UNKNOWN_HOST)
die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
else if (mysql_errno (&mysql) == CR_VERSION_ERROR)
die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
else if (mysql_errno (&mysql) == CR_OUT_OF_MEMORY)
die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
else if (mysql_errno (&mysql) == CR_IPSOCK_ERROR)
die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
else if (mysql_errno (&mysql) == CR_SOCKET_CREATE_ERROR)
die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) {
if (mysql_errno(&mysql) == CR_UNKNOWN_HOST)
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
else if (mysql_errno(&mysql) == CR_VERSION_ERROR)
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY)
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR)
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR)
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql));
else
die (STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error (&mysql));
die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql));
}
if (mysql_query (&mysql, sql_query) != 0) {
char *error = NULL;
if (mysql_query(&mysql, sql_query) != 0) {
error = strdup(mysql_error(&mysql));
mysql_close (&mysql);
die (STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error);
mysql_close(&mysql);
die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error);
}
MYSQL_RES *res;
/* store the result */
if ( (res = mysql_store_result (&mysql)) == NULL) {
if ((res = mysql_store_result(&mysql)) == NULL) {
error = strdup(mysql_error(&mysql));
mysql_close (&mysql);
die (STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error);
mysql_close(&mysql);
die(STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error);
}
/* Check there is some data */
if (mysql_num_rows(res) == 0) {
mysql_close(&mysql);
die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned"));
die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned"));
}
MYSQL_ROW row;
/* fetch the first row */
if ( (row = mysql_fetch_row (res)) == NULL) {
if ((row = mysql_fetch_row(res)) == NULL) {
error = strdup(mysql_error(&mysql));
mysql_free_result (res);
mysql_close (&mysql);
die (STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error);
mysql_free_result(res);
mysql_close(&mysql);
die(STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error);
}
if (! is_numeric(row[0])) {
die (STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]);
if (!is_numeric(row[0])) {
die(STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]);
}
value = strtod(row[0], NULL);
double value = strtod(row[0], NULL);
/* free the result */
mysql_free_result (res);
mysql_free_result(res);
/* close the connection */
mysql_close (&mysql);
mysql_close(&mysql);
if (verbose >= 3)
printf("mysql result: %f\n", value);
status = get_status(value, my_thresholds);
int status = get_status(value, my_thresholds);
if (status == STATE_OK) {
printf("QUERY %s: ", _("OK"));
@ -161,73 +153,54 @@ main (int argc, char **argv)
printf("QUERY %s: ", _("CRITICAL"));
}
printf(_("'%s' returned %f | %s"), sql_query, value,
fperfdata("result", value, "",
my_thresholds->warning?true:false, my_thresholds->warning?my_thresholds->warning->end:0,
my_thresholds->critical?true:false, my_thresholds->critical?my_thresholds->critical->end:0,
false, 0,
false, 0)
);
fperfdata("result", value, "", my_thresholds->warning ? true : false, my_thresholds->warning ? my_thresholds->warning->end : 0,
my_thresholds->critical ? true : false, my_thresholds->critical ? my_thresholds->critical->end : 0, false, 0, false,
0));
printf("\n");
return status;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
char *warning = NULL;
char *critical = NULL;
int option = 0;
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {
{"hostname", required_argument, 0, 'H'},
{"socket", required_argument, 0, 's'},
{"database", required_argument, 0, 'd'},
{"username", required_argument, 0, 'u'},
{"password", required_argument, 0, 'p'},
{"file", required_argument, 0, 'f'},
{"group", required_argument, 0, 'g'},
{"port", required_argument, 0, 'P'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"query", required_argument, 0, 'q'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{0, 0, 0, 0}
};
{"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, {"database", required_argument, 0, 'd'},
{"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'},
{"group", required_argument, 0, 'g'}, {"port", required_argument, 0, 'P'}, {"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"query", required_argument, 0, 'q'},
{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}};
if (argc < 1)
return ERROR;
while (1) {
c = getopt_long (argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option);
char *warning = NULL;
char *critical = NULL;
if (c == -1 || c == EOF)
while (true) {
int option = 0;
int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option);
if (option_char == -1 || option_char == EOF)
break;
switch (c) {
case 'H': /* hostname */
if (is_host (optarg)) {
switch (option_char) {
case 'H': /* hostname */
if (is_host(optarg)) {
db_host = optarg;
}
else {
usage2 (_("Invalid hostname/address"), optarg);
} else {
usage2(_("Invalid hostname/address"), optarg);
}
break;
case 's': /* socket */
case 's': /* socket */
db_socket = optarg;
break;
case 'd': /* database */
case 'd': /* database */
db = optarg;
break;
case 'u': /* username */
case 'u': /* username */
db_user = optarg;
break;
case 'p': /* authentication information: password */
case 'p': /* authentication information: password */
db_pass = strdup(optarg);
/* Delete the password from process list */
@ -236,24 +209,24 @@ process_arguments (int argc, char **argv)
optarg++;
}
break;
case 'f': /* client options file */
case 'f': /* client options file */
opt_file = optarg;
break;
case 'g': /* client options group */
case 'g': /* client options group */
opt_group = optarg;
break;
case 'P': /* critical time threshold */
db_port = atoi (optarg);
case 'P': /* critical time threshold */
db_port = atoi(optarg);
break;
case 'v':
verbose++;
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'q':
xasprintf(&sql_query, "%s", optarg);
break;
@ -263,22 +236,17 @@ process_arguments (int argc, char **argv)
case 'c':
critical = optarg;
break;
case '?': /* help */
usage5 ();
case '?': /* help */
usage5();
}
}
c = optind;
set_thresholds(&my_thresholds, warning, critical);
return validate_arguments ();
return validate_arguments();
}
int
validate_arguments (void)
{
int validate_arguments(void) {
if (sql_query == NULL)
usage("Must specify a SQL query to run");
@ -294,61 +262,55 @@ validate_arguments (void)
return OK;
}
void
print_help (void)
{
void print_help(void) {
char *myport;
xasprintf (&myport, "%d", MYSQL_PORT);
xasprintf(&myport, "%d", MYSQL_PORT);
print_revision (progname, NP_VERSION);
print_revision(progname, NP_VERSION);
printf (_(COPYRIGHT), copyright, email);
printf(_(COPYRIGHT), copyright, email);
printf ("%s\n", _("This program checks a query result against threshold levels"));
printf("%s\n", _("This program checks a query result against threshold levels"));
printf ("\n\n");
printf("\n\n");
print_usage ();
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf (" -q, --query=STRING\n");
printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
printf (UT_WARN_CRIT_RANGE);
printf (UT_HOST_PORT, 'P', myport);
printf (" %s\n", "-s, --socket=STRING");
printf (" %s\n", _("Use the specified socket (has no effect if -H is used)"));
printf (" -d, --database=STRING\n");
printf (" %s\n", _("Database to check"));
printf (" %s\n", "-f, --file=STRING");
printf (" %s\n", _("Read from the specified client options file"));
printf (" %s\n", "-g, --group=STRING");
printf (" %s\n", _("Use a client options group"));
printf (" -u, --username=STRING\n");
printf (" %s\n", _("Username to login with"));
printf (" -p, --password=STRING\n");
printf (" %s\n", _("Password to login with"));
printf (" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!"));
printf (" %s\n", _("Your clear-text password could be visible as a process table entry"));
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf(" -q, --query=STRING\n");
printf(" %s\n", _("SQL query to run. Only first column in first row will be read"));
printf(UT_WARN_CRIT_RANGE);
printf(UT_HOST_PORT, 'P', myport);
printf(" %s\n", "-s, --socket=STRING");
printf(" %s\n", _("Use the specified socket (has no effect if -H is used)"));
printf(" -d, --database=STRING\n");
printf(" %s\n", _("Database to check"));
printf(" %s\n", "-f, --file=STRING");
printf(" %s\n", _("Read from the specified client options file"));
printf(" %s\n", "-g, --group=STRING");
printf(" %s\n", _("Use a client options group"));
printf(" -u, --username=STRING\n");
printf(" %s\n", _("Username to login with"));
printf(" -p, --password=STRING\n");
printf(" %s\n", _("Password to login with"));
printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!"));
printf(" %s\n", _("Your clear-text password could be visible as a process table entry"));
printf ("\n");
printf (" %s\n", _("A query is required. The result from the query should be numeric."));
printf (" %s\n", _("For extra security, create a user with minimal access."));
printf("\n");
printf(" %s\n", _("A query is required. The result from the query should be numeric."));
printf(" %s\n", _("For extra security, create a user with minimal access."));
printf ("\n");
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("You must specify -p with an empty string to force an empty password,"));
printf (" %s\n", _("overriding any my.cnf settings."));
printf("\n");
printf("%s\n", _("Notes:"));
printf(" %s\n", _("You must specify -p with an empty string to force an empty password,"));
printf(" %s\n", _("overriding any my.cnf settings."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s -q SQL_query [-w warn] [-c crit] [-H host] [-P port] [-s socket]\n",progname);
printf (" [-d database] [-u user] [-p password] [-f optfile] [-g group]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s -q SQL_query [-w warn] [-c crit] [-H host] [-P port] [-s socket]\n", progname);
printf(" [-d database] [-u user] [-p password] [-f optfile] [-g group]\n");
}

View file

@ -1,58 +1,56 @@
/*****************************************************************************
*
* Monitoring check_nagios plugin
*
* License: GPL
* Copyright (c) 1999-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_nagios plugin
*
* This plugin checks the status of the Nagios process on the local machine.
* The plugin will check to make sure the Nagios status log is no older than
* the number of minutes specified by the expires option.
* It also checks the process table for a process matching the command
* argument.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_nagios plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_nagios plugin
*
* This plugin checks the status of the Nagios process on the local machine.
* The plugin will check to make sure the Nagios status log is no older than
* the number of minutes specified by the expires option.
* It also checks the process table for a process matching the command
* argument.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_nagios";
const char *copyright = "1999-2007";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "runcmd.h"
#include "utils.h"
int process_arguments (int, char **);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static void print_help(void);
void print_usage(void);
char *status_log = NULL;
char *process_string = NULL;
int expire_minutes = 0;
static char *status_log = NULL;
static char *process_string = NULL;
static int expire_minutes = 0;
int verbose = 0;
static int verbose = 0;
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
int result = STATE_UNKNOWN;
char input_buffer[MAX_INPUT_BUFFER];
unsigned long latest_entry_time = 0L;
@ -73,253 +71,231 @@ main (int argc, char **argv)
#endif /* PS_USES_PROCETIME */
char procprog[MAX_INPUT_BUFFER];
char *procargs;
int pos, cols;
int pos;
int cols;
int expected_cols = PS_COLS - 1;
const char *zombie = "Z";
char *temp_string;
output chld_out, chld_err;
output chld_out;
output chld_err;
size_t i;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
if (process_arguments(argc, argv) == ERROR)
usage_va(_("Could not parse arguments"));
/* Set signal handling and alarm timeout */
if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
usage_va(_("Cannot catch SIGALRM"));
}
/* handle timeouts gracefully... */
alarm (timeout_interval);
alarm(timeout_interval);
/* open the status log */
fp = fopen (status_log, "r");
fp = fopen(status_log, "r");
if (fp == NULL) {
die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!"));
die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot open status log for reading!"));
}
/* get the date/time of the last item updated in the log */
while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
if ((temp_ptr = strstr (input_buffer, "created=")) != NULL) {
temp_entry_time = strtoul (temp_ptr + 8, NULL, 10);
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
if ((temp_ptr = strstr(input_buffer, "created=")) != NULL) {
temp_entry_time = strtoul(temp_ptr + 8, NULL, 10);
latest_entry_time = temp_entry_time;
break;
} else if ((temp_ptr = strtok (input_buffer, "]")) != NULL) {
temp_entry_time = strtoul (temp_ptr + 1, NULL, 10);
}
if ((temp_ptr = strtok(input_buffer, "]")) != NULL) {
temp_entry_time = strtoul(temp_ptr + 1, NULL, 10);
if (temp_entry_time > latest_entry_time)
latest_entry_time = temp_entry_time;
}
}
fclose (fp);
fclose(fp);
if (verbose >= 2)
printf("command: %s\n", PS_COMMAND);
/* run the command to check for the Nagios process.. */
if((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0)
if ((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0)
result = STATE_WARNING;
/* count the number of matching Nagios processes... */
for(i = 0; i < chld_out.lines; i++) {
cols = sscanf (chld_out.line[i], PS_FORMAT, PS_VARLIST);
for (i = 0; i < chld_out.lines; i++) {
cols = sscanf(chld_out.line[i], PS_FORMAT, PS_VARLIST);
/* Zombie processes do not give a procprog command */
if ( cols == (expected_cols - 1) && strstr(procstat, zombie) ) {
if (cols == (expected_cols - 1) && strstr(procstat, zombie)) {
cols = expected_cols;
/* Set some value for procargs for the strip command further below
* Seen to be a problem on some Solaris 7 and 8 systems */
chld_out.line[i][pos] = '\n';
chld_out.line[i][pos+1] = 0x0;
chld_out.line[i][pos + 1] = 0x0;
}
if ( cols >= expected_cols ) {
xasprintf (&procargs, "%s", chld_out.line[i] + pos);
strip (procargs);
if (cols >= expected_cols) {
xasprintf(&procargs, "%s", chld_out.line[i] + pos);
strip(procargs);
/* Some ps return full pathname for command. This removes path */
temp_string = strtok ((char *)procprog, "/");
temp_string = strtok((char *)procprog, "/");
while (temp_string) {
strcpy(procprog, temp_string);
temp_string = strtok (NULL, "/");
temp_string = strtok(NULL, "/");
}
/* May get empty procargs */
if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs,"")) {
if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs, "")) {
proc_entries++;
if (verbose >= 2) {
printf (_("Found process: %s %s\n"), procprog, procargs);
printf(_("Found process: %s %s\n"), procprog, procargs);
}
}
}
}
/* If we get anything on stderr, at least set warning */
if(chld_err.buflen)
result = max_state (result, STATE_WARNING);
if (chld_err.buflen)
result = max_state(result, STATE_WARNING);
/* reset the alarm handler */
alarm (0);
alarm(0);
if (proc_entries == 0) {
die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Could not locate a running Nagios process!"));
die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Could not locate a running Nagios process!"));
}
if (latest_entry_time == 0L) {
die (STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time"));
die(STATE_CRITICAL, "NAGIOS %s: %s\n", _("CRITICAL"), _("Cannot parse Nagios log file for valid time"));
}
time (&current_time);
time(&current_time);
if ((int)(current_time - latest_entry_time) > (expire_minutes * 60)) {
result = STATE_WARNING;
} else {
result = STATE_OK;
}
printf ("NAGIOS %s: ", (result == STATE_OK) ? _("OK") : _("WARNING"));
printf (ngettext ("%d process", "%d processes", proc_entries), proc_entries);
printf (", ");
printf (
ngettext ("status log updated %d second ago",
"status log updated %d seconds ago",
(int) (current_time - latest_entry_time) ),
(int) (current_time - latest_entry_time) );
printf ("\n");
printf("NAGIOS %s: ", (result == STATE_OK) ? _("OK") : _("WARNING"));
printf(ngettext("%d process", "%d processes", proc_entries), proc_entries);
printf(", ");
printf(ngettext("status log updated %d second ago", "status log updated %d seconds ago", (int)(current_time - latest_entry_time)),
(int)(current_time - latest_entry_time));
printf("\n");
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int process_arguments(int argc, char **argv) {
int c;
int option = 0;
static struct option longopts[] = {
{"filename", required_argument, 0, 'F'},
{"expires", required_argument, 0, 'e'},
{"command", required_argument, 0, 'C'},
{"timeout", optional_argument, 0, 't'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'},
{"command", required_argument, 0, 'C'}, {"timeout", optional_argument, 0, 't'},
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0}};
if (argc < 2)
return ERROR;
if (!is_option (argv[1])) {
if (!is_option(argv[1])) {
status_log = argv[1];
if (is_intnonneg (argv[2]))
expire_minutes = atoi (argv[2]);
if (is_intnonneg(argv[2]))
expire_minutes = atoi(argv[2]);
else
die (STATE_UNKNOWN,
_("Expiration time must be an integer (seconds)\n"));
die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
process_string = argv[3];
return OK;
}
while (1) {
c = getopt_long (argc, argv, "+hVvF:C:e:t:", longopts, &option);
c = getopt_long(argc, argv, "+hVvF:C:e:t:", longopts, &option);
if (c == -1 || c == EOF || c == 1)
break;
switch (c) {
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'F': /* status log */
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'F': /* status log */
status_log = optarg;
break;
case 'C': /* command */
case 'C': /* command */
process_string = optarg;
break;
case 'e': /* expiry time */
if (is_intnonneg (optarg))
expire_minutes = atoi (optarg);
case 'e': /* expiry time */
if (is_intnonneg(optarg))
expire_minutes = atoi(optarg);
else
die (STATE_UNKNOWN,
_("Expiration time must be an integer (seconds)\n"));
die(STATE_UNKNOWN, _("Expiration time must be an integer (seconds)\n"));
break;
case 't': /* timeout */
if (is_intnonneg (optarg))
timeout_interval = atoi (optarg);
case 't': /* timeout */
if (is_intnonneg(optarg))
timeout_interval = atoi(optarg);
else
die (STATE_UNKNOWN,
_("Timeout must be an integer (seconds)\n"));
die(STATE_UNKNOWN, _("Timeout must be an integer (seconds)\n"));
break;
case 'v':
verbose++;
break;
default: /* print short usage_va statement if args not parsable */
default: /* print short usage_va statement if args not parsable */
usage5();
}
}
if (status_log == NULL)
die (STATE_UNKNOWN, _("You must provide the status_log\n"));
die(STATE_UNKNOWN, _("You must provide the status_log\n"));
if (process_string == NULL)
die (STATE_UNKNOWN, _("You must provide a process string\n"));
die(STATE_UNKNOWN, _("You must provide a process string\n"));
return OK;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
printf(_(COPYRIGHT), copyright, email);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("%s\n", _("This plugin checks the status of the Nagios process on the local machine"));
printf("%s\n", _("The plugin will check to make sure the Nagios status log is no older than"));
printf("%s\n", _("the number of minutes specified by the expires option."));
printf("%s\n", _("It also checks the process table for a process matching the command argument."));
printf (_(COPYRIGHT), copyright, email);
printf("\n\n");
printf ("%s\n", _("This plugin checks the status of the Nagios process on the local machine"));
printf ("%s\n", _("The plugin will check to make sure the Nagios status log is no older than"));
printf ("%s\n", _("the number of minutes specified by the expires option."));
printf ("%s\n", _("It also checks the process table for a process matching the command argument."));
print_usage();
printf ("\n\n");
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
print_usage ();
printf(" %s\n", "-F, --filename=FILE");
printf(" %s\n", _("Name of the log file to check"));
printf(" %s\n", "-e, --expires=INTEGER");
printf(" %s\n", _("Minutes aging after which logfile is considered stale"));
printf(" %s\n", "-C, --command=STRING");
printf(" %s\n", _("Substring to search for in process arguments"));
printf(" %s\n", "-t, --timeout=INTEGER");
printf(" %s\n", _("Timeout for the plugin in seconds"));
printf(UT_VERBOSE);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf("\n");
printf("%s\n", _("Examples:"));
printf(" %s\n", "check_nagios -t 20 -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios");
printf (" %s\n", "-F, --filename=FILE");
printf (" %s\n", _("Name of the log file to check"));
printf (" %s\n", "-e, --expires=INTEGER");
printf (" %s\n", _("Minutes aging after which logfile is considered stale"));
printf (" %s\n", "-C, --command=STRING");
printf (" %s\n", _("Substring to search for in process arguments"));
printf (" %s\n", "-t, --timeout=INTEGER");
printf (" %s\n", _("Timeout for the plugin in seconds"));
printf (UT_VERBOSE);
printf ("\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "check_nagios -t 20 -e 5 -F /usr/local/nagios/var/status.log -C /usr/local/nagios/bin/nagios");
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -F <status log file> -t <timeout_seconds> -e <expire_minutes> -C <process_string>\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -F <status log file> -t <timeout_seconds> -e <expire_minutes> -C <process_string>\n", progname);
}

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
*
* License: GPL
* Copyright (c) 2006 Sean Finney <seanius@seanius.net>
* Copyright (c) 2006-2008 Monitoring Plugins Development Team
* Copyright (c) 2006-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -31,7 +31,7 @@
*****************************************************************************/
const char *progname = "check_ntp";
const char *copyright = "2006-2008";
const char *copyright = "2006-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"

View file

@ -1,88 +1,88 @@
/*****************************************************************************
*
* Monitoring check_ntp_peer plugin
*
* License: GPL
* Copyright (c) 2006 Sean Finney <seanius@seanius.net>
* Copyright (c) 2006-2008 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ntp_peer plugin
*
* This plugin checks an NTP server independent of any commandline
* programs or external libraries.
*
* Use this plugin to check the health of an NTP server. It supports
* checking the offset with the sync peer, the jitter and stratum. This
* plugin will not check the clock offset between the local host and NTP
* server; please use check_ntp_time for that purpose.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_ntp_peer plugin
*
* License: GPL
* Copyright (c) 2006 Sean Finney <seanius@seanius.net>
* Copyright (c) 2006-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ntp_peer plugin
*
* This plugin checks an NTP server independent of any commandline
* programs or external libraries.
*
* Use this plugin to check the health of an NTP server. It supports
* checking the offset with the sync peer, the jitter and stratum. This
* plugin will not check the clock offset between the local host and NTP
* server; please use check_ntp_time for that purpose.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_ntp_peer";
const char *copyright = "2006-2008";
const char *copyright = "2006-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "netutils.h"
#include "utils.h"
static char *server_address=NULL;
static int port=123;
static int verbose=0;
static char *server_address = NULL;
static int port = 123;
static int verbose = 0;
static bool quiet = false;
static char *owarn="60";
static char *ocrit="120";
static char *owarn = "60";
static char *ocrit = "120";
static bool do_stratum = false;
static char *swarn="-1:16";
static char *scrit="-1:16";
static char *swarn = "-1:16";
static char *scrit = "-1:16";
static bool do_jitter = false;
static char *jwarn="-1:5000";
static char *jcrit="-1:10000";
static char *jwarn = "-1:5000";
static char *jcrit = "-1:10000";
static bool do_truechimers = false;
static char *twarn="0:";
static char *tcrit="0:";
static char *twarn = "0:";
static char *tcrit = "0:";
static bool syncsource_found = false;
static bool li_alarm = false;
int process_arguments (int, char **);
thresholds *offset_thresholds = NULL;
thresholds *jitter_thresholds = NULL;
thresholds *stratum_thresholds = NULL;
thresholds *truechimer_thresholds = NULL;
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static thresholds *offset_thresholds = NULL;
static thresholds *jitter_thresholds = NULL;
static thresholds *stratum_thresholds = NULL;
static thresholds *truechimer_thresholds = NULL;
static void print_help(void);
void print_usage(void);
/* max size of control message data */
#define MAX_CM_SIZE 468
/* this structure holds everything in an ntp control message as per rfc1305 */
typedef struct {
uint8_t flags; /* byte with leapindicator,vers,mode. see macros */
uint8_t op; /* R,E,M bits and Opcode */
uint16_t seq; /* Packet sequence */
uint16_t status; /* Clock status */
uint16_t assoc; /* Association */
uint16_t offset; /* Similar to TCP sequence # */
uint16_t count; /* # bytes of data */
uint8_t flags; /* byte with leapindicator,vers,mode. see macros */
uint8_t op; /* R,E,M bits and Opcode */
uint16_t seq; /* Packet sequence */
uint16_t status; /* Clock status */
uint16_t assoc; /* Association */
uint16_t offset; /* Similar to TCP sequence # */
uint16_t count; /* # bytes of data */
char data[MAX_CM_SIZE]; /* ASCII data of the request */
/* NB: not necessarily NULL terminated! */
/* NB: not necessarily NULL terminated! */
} ntp_control_message;
/* this is an association/status-word pair found in control packet responses */
@ -93,82 +93,96 @@ typedef struct {
/* bits 1,2 are the leap indicator */
#define LI_MASK 0xc0
#define LI(x) ((x&LI_MASK)>>6)
#define LI_SET(x,y) do{ x |= ((y<<6)&LI_MASK); }while(0)
#define LI(x) ((x & LI_MASK) >> 6)
#define LI_SET(x, y) \
do { \
x |= ((y << 6) & LI_MASK); \
} while (0)
/* and these are the values of the leap indicator */
#define LI_NOWARNING 0x00
#define LI_EXTRASEC 0x01
#define LI_NOWARNING 0x00
#define LI_EXTRASEC 0x01
#define LI_MISSINGSEC 0x02
#define LI_ALARM 0x03
#define LI_ALARM 0x03
/* bits 3,4,5 are the ntp version */
#define VN_MASK 0x38
#define VN(x) ((x&VN_MASK)>>3)
#define VN_SET(x,y) do{ x |= ((y<<3)&VN_MASK); }while(0)
#define VN(x) ((x & VN_MASK) >> 3)
#define VN_SET(x, y) \
do { \
x |= ((y << 3) & VN_MASK); \
} while (0)
#define VN_RESERVED 0x02
/* bits 6,7,8 are the ntp mode */
#define MODE_MASK 0x07
#define MODE(x) (x&MODE_MASK)
#define MODE_SET(x,y) do{ x |= (y&MODE_MASK); }while(0)
#define MODE(x) (x & MODE_MASK)
#define MODE_SET(x, y) \
do { \
x |= (y & MODE_MASK); \
} while (0)
/* here are some values */
#define MODE_CLIENT 0x03
#define MODE_CLIENT 0x03
#define MODE_CONTROLMSG 0x06
/* In control message, bits 8-10 are R,E,M bits */
#define REM_MASK 0xe0
#define REM_RESP 0x80
#define REM_MASK 0xe0
#define REM_RESP 0x80
#define REM_ERROR 0x40
#define REM_MORE 0x20
#define REM_MORE 0x20
/* In control message, bits 11 - 15 are opcode */
#define OP_MASK 0x1f
#define OP_SET(x,y) do{ x |= (y&OP_MASK); }while(0)
#define OP_SET(x, y) \
do { \
x |= (y & OP_MASK); \
} while (0)
#define OP_READSTAT 0x01
#define OP_READVAR 0x02
/* In peer status bytes, bits 6,7,8 determine clock selection status */
#define PEER_SEL(x) ((ntohs(x)>>8)&0x07)
#define PEER_SEL(x) ((ntohs(x) >> 8) & 0x07)
#define PEER_TRUECHIMER 0x02
#define PEER_INCLUDED 0x04
#define PEER_INCLUDED 0x04
#define PEER_SYNCSOURCE 0x06
/* NTP control message header is 12 bytes, plus any data in the data
* field, plus null padding to the nearest 32-bit boundary per rfc.
*/
#define SIZEOF_NTPCM(m) (12+ntohs(m.count)+((ntohs(m.count)%4)?4-(ntohs(m.count)%4):0))
#define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0))
/* finally, a little helper or two for debugging: */
#define DBG(x) do{if(verbose>1){ x; }}while(0);
#define PRINTSOCKADDR(x) \
do{ \
printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\
}while(0);
void print_ntp_control_message(const ntp_control_message *p){
int i=0, numpeers=0;
const ntp_assoc_status_pair *peer=NULL;
#define DBG(x) \
do { \
if (verbose > 1) { \
x; \
} \
} while (0);
#define PRINTSOCKADDR(x) \
do { \
printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \
} while (0);
void print_ntp_control_message(const ntp_control_message *p) {
printf("control packet contents:\n");
printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op);
printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK);
printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK);
printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK);
printf("\t response=%d (0x%.2x)\n", (p->op&REM_RESP)>0, p->op&REM_RESP);
printf("\t more=%d (0x%.2x)\n", (p->op&REM_MORE)>0, p->op&REM_MORE);
printf("\t error=%d (0x%.2x)\n", (p->op&REM_ERROR)>0, p->op&REM_ERROR);
printf("\t op=%d (0x%.2x)\n", p->op&OP_MASK, p->op&OP_MASK);
printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK);
printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK);
printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK);
printf("\t response=%d (0x%.2x)\n", (p->op & REM_RESP) > 0, p->op & REM_RESP);
printf("\t more=%d (0x%.2x)\n", (p->op & REM_MORE) > 0, p->op & REM_MORE);
printf("\t error=%d (0x%.2x)\n", (p->op & REM_ERROR) > 0, p->op & REM_ERROR);
printf("\t op=%d (0x%.2x)\n", p->op & OP_MASK, p->op & OP_MASK);
printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq));
printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status));
printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc));
printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset));
printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count));
numpeers=ntohs(p->count)/(sizeof(ntp_assoc_status_pair));
if(p->op&REM_RESP && p->op&OP_READSTAT){
peer=(ntp_assoc_status_pair*)p->data;
for(i=0;i<numpeers;i++){
printf("\tpeer id %.2x status %.2x",
ntohs(peer[i].assoc), ntohs(peer[i].status));
if(PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE){
int numpeers = ntohs(p->count) / (sizeof(ntp_assoc_status_pair));
if (p->op & REM_RESP && p->op & OP_READSTAT) {
const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)p->data;
for (int i = 0; i < numpeers; i++) {
printf("\tpeer id %.2x status %.2x", ntohs(peer[i].assoc), ntohs(peer[i].status));
if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) {
printf(" <-- current sync source");
} else if(PEER_SEL(peer[i].status) >= PEER_INCLUDED){
} else if (PEER_SEL(peer[i].status) >= PEER_INCLUDED) {
printf(" <-- current sync candidate");
} else if(PEER_SEL(peer[i].status) >= PEER_TRUECHIMER){
} else if (PEER_SEL(peer[i].status) >= PEER_TRUECHIMER) {
printf(" <-- outlyer, but truechimer");
}
printf("\n");
@ -176,8 +190,7 @@ void print_ntp_control_message(const ntp_control_message *p){
}
}
void
setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){
void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) {
memset(p, 0, sizeof(ntp_control_message));
LI_SET(p->flags, LI_NOWARNING);
VN_SET(p->flags, VN_RESERVED);
@ -198,19 +211,7 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){
* status is pretty much useless as syncsource_found is a global variable
* used later in main to check is the server was synchronized. It works
* so I left it alone */
int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers){
int conn=-1, i, npeers=0, num_candidates=0;
double tmp_offset = 0;
int min_peer_sel=PEER_INCLUDED;
int peers_size=0, peer_offset=0;
int status;
ntp_assoc_status_pair *peers=NULL;
ntp_control_message req;
const char *getvar = "stratum,offset,jitter";
char *data, *value, *nptr;
void *tmp;
status = STATE_OK;
int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers) {
*offset_result = STATE_UNKNOWN;
*jitter = *stratum = -1;
*num_truechimers = 0;
@ -231,11 +232,20 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
* 4) Extract the offset, jitter and stratum value from the data[]
* (it's ASCII)
*/
int min_peer_sel = PEER_INCLUDED;
int num_candidates = 0;
void *tmp;
ntp_assoc_status_pair *peers = NULL;
int peer_offset = 0;
int peers_size = 0;
int npeers = 0;
int conn = -1;
my_udp_connect(server_address, port, &conn);
/* keep sending requests until the server stops setting the
* REM_MORE bit, though usually this is only 1 packet. */
do{
ntp_control_message req;
do {
setup_control_request(&req, OP_READSTAT, 1);
DBG(printf("sending READSTAT request"));
write(conn, &req, SIZEOF_NTPCM(req));
@ -243,63 +253,73 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
do {
/* Attempt to read the largest size packet possible */
req.count=htons(MAX_CM_SIZE);
req.count = htons(MAX_CM_SIZE);
DBG(printf("receiving READSTAT response"))
if(read(conn, &req, SIZEOF_NTPCM(req)) == -1)
if (read(conn, &req, SIZEOF_NTPCM(req)) == -1)
die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
DBG(print_ntp_control_message(&req));
/* discard obviously invalid packets */
if (ntohs(req.count) > MAX_CM_SIZE)
die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n");
} while (!(req.op&OP_READSTAT && ntohs(req.seq) == 1));
} while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1));
if (LI(req.flags) == LI_ALARM) li_alarm = true;
if (LI(req.flags) == LI_ALARM)
li_alarm = true;
/* Each peer identifier is 4 bytes in the data section, which
* we represent as a ntp_assoc_status_pair datatype.
*/
peers_size+=ntohs(req.count);
if((tmp=realloc(peers, peers_size)) == NULL)
* we represent as a ntp_assoc_status_pair datatype.
*/
peers_size += ntohs(req.count);
if ((tmp = realloc(peers, peers_size)) == NULL)
free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n");
peers=tmp;
memcpy((void*)((ptrdiff_t)peers+peer_offset), (void*)req.data, ntohs(req.count));
npeers=peers_size/sizeof(ntp_assoc_status_pair);
peer_offset+=ntohs(req.count);
} while(req.op&REM_MORE);
peers = tmp;
memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count));
npeers = peers_size / sizeof(ntp_assoc_status_pair);
peer_offset += ntohs(req.count);
} while (req.op & REM_MORE);
/* first, let's find out if we have a sync source, or if there are
* at least some candidates. In the latter case we'll issue
* a warning but go ahead with the check on them. */
for (i = 0; i < npeers; i++){
if(PEER_SEL(peers[i].status) >= PEER_TRUECHIMER){
for (int i = 0; i < npeers; i++) {
if (PEER_SEL(peers[i].status) >= PEER_TRUECHIMER) {
(*num_truechimers)++;
if(PEER_SEL(peers[i].status) >= PEER_INCLUDED){
if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) {
num_candidates++;
if(PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE){
if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) {
syncsource_found = true;
min_peer_sel=PEER_SYNCSOURCE;
min_peer_sel = PEER_SYNCSOURCE;
}
}
}
}
if(verbose) printf("%d candidate peers available\n", num_candidates);
if(verbose && syncsource_found) printf("synchronization source found\n");
if(! syncsource_found){
if (verbose)
printf("%d candidate peers available\n", num_candidates);
if (verbose && syncsource_found)
printf("synchronization source found\n");
int status = STATE_OK;
if (!syncsource_found) {
status = STATE_WARNING;
if(verbose) printf("warning: no synchronization source found\n");
if (verbose)
printf("warning: no synchronization source found\n");
}
if(li_alarm){
if (li_alarm) {
status = STATE_WARNING;
if(verbose) printf("warning: LI_ALARM bit is set\n");
if (verbose)
printf("warning: LI_ALARM bit is set\n");
}
for (i = 0; i < npeers; i++){
const char *getvar = "stratum,offset,jitter";
char *data;
for (int i = 0; i < npeers; i++) {
/* Only query this server if it is the current sync source */
/* If there's no sync.peer, query all candidates and use the best one */
if (PEER_SEL(peers[i].status) >= min_peer_sel){
if(verbose) printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc));
if (PEER_SEL(peers[i].status) >= min_peer_sel) {
if (verbose)
printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc));
xasprintf(&data, "");
do{
do {
setup_control_request(&req, OP_READVAR, 2);
req.assoc = peers[i].assoc;
/* Putting the wanted variable names in the request
@ -309,7 +329,7 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
*/
/* Older servers doesn't know what jitter is, so if we get an
* error on the first pass we redo it with "dispersion" */
strncpy(req.data, getvar, MAX_CM_SIZE-1);
strncpy(req.data, getvar, MAX_CM_SIZE - 1);
req.count = htons(strlen(getvar));
DBG(printf("sending READVAR request...\n"));
write(conn, &req, SIZEOF_NTPCM(req));
@ -320,44 +340,53 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
DBG(printf("receiving READVAR response...\n"));
read(conn, &req, SIZEOF_NTPCM(req));
DBG(print_ntp_control_message(&req));
} while (!(req.op&OP_READVAR && ntohs(req.seq) == 2));
} while (!(req.op & OP_READVAR && ntohs(req.seq) == 2));
if(!(req.op&REM_ERROR))
if (!(req.op & REM_ERROR))
xasprintf(&data, "%s%s", data, req.data);
} while(req.op&REM_MORE);
} while (req.op & REM_MORE);
if(req.op&REM_ERROR) {
if(strstr(getvar, "jitter")) {
if(verbose) printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with 'dispersion'...\n");
if (req.op & REM_ERROR) {
if (strstr(getvar, "jitter")) {
if (verbose)
printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with "
"'dispersion'...\n");
getvar = "stratum,offset,dispersion";
i--;
continue;
} else if(strlen(getvar)) {
if(verbose) printf("Server didn't like dispersion either; will retrieve everything\n");
}
if (strlen(getvar)) {
if (verbose)
printf("Server didn't like dispersion either; will retrieve everything\n");
getvar = "";
i--;
continue;
}
}
if(verbose > 1)
if (verbose > 1)
printf("Server responded: >>>%s<<<\n", data);
double tmp_offset = 0;
char *value;
char *nptr;
/* get the offset */
if(verbose)
if (verbose)
printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc));
value = np_extract_ntpvar(data, "offset");
nptr=NULL;
nptr = NULL;
/* Convert the value if we have one */
if(value != NULL)
if (value != NULL)
tmp_offset = strtod(value, &nptr) / 1000;
/* If value is null or no conversion was performed */
if(value == NULL || value==nptr) {
if(verbose) printf("error: unable to read server offset response.\n");
if (value == NULL || value == nptr) {
if (verbose)
printf("error: unable to read server offset response.\n");
} else {
if(verbose) printf("%.10g\n", tmp_offset);
if(*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) {
if (verbose)
printf("%.10g\n", tmp_offset);
if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) {
*offset = tmp_offset;
*offset_result = STATE_OK;
} else {
@ -366,85 +395,75 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum
}
}
if(do_jitter) {
if (do_jitter) {
/* get the jitter */
if(verbose) {
printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", ntohs(peers[i].assoc));
if (verbose) {
printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter",
ntohs(peers[i].assoc));
}
value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter");
nptr=NULL;
nptr = NULL;
/* Convert the value if we have one */
if(value != NULL)
if (value != NULL)
*jitter = strtod(value, &nptr);
/* If value is null or no conversion was performed */
if(value == NULL || value==nptr) {
if(verbose) printf("error: unable to read server jitter/dispersion response.\n");
if (value == NULL || value == nptr) {
if (verbose)
printf("error: unable to read server jitter/dispersion response.\n");
*jitter = -1;
} else if(verbose) {
} else if (verbose) {
printf("%.10g\n", *jitter);
}
}
if(do_stratum) {
if (do_stratum) {
/* get the stratum */
if(verbose) {
if (verbose) {
printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc));
}
value = np_extract_ntpvar(data, "stratum");
nptr=NULL;
nptr = NULL;
/* Convert the value if we have one */
if(value != NULL)
if (value != NULL)
*stratum = strtol(value, &nptr, 10);
if(value == NULL || value==nptr) {
if(verbose) printf("error: unable to read server stratum response.\n");
if (value == NULL || value == nptr) {
if (verbose)
printf("error: unable to read server stratum response.\n");
*stratum = -1;
} else {
if(verbose) printf("%i\n", *stratum);
if (verbose)
printf("%i\n", *stratum);
}
}
} /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */
} /* for (i = 0; i < npeers; i++) */
} /* for (i = 0; i < npeers; i++) */
close(conn);
if(peers!=NULL) free(peers);
if (peers != NULL)
free(peers);
return status;
}
int process_arguments(int argc, char **argv){
int c;
int option=0;
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"quiet", no_argument, 0, 'q'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"swarn", required_argument, 0, 'W'},
{"scrit", required_argument, 0, 'C'},
{"jwarn", required_argument, 0, 'j'},
{"jcrit", required_argument, 0, 'k'},
{"twarn", required_argument, 0, 'm'},
{"tcrit", required_argument, 0, 'n'},
{"timeout", required_argument, 0, 't'},
{"hostname", required_argument, 0, 'H'},
{"port", required_argument, 0, 'p'},
{0, 0, 0, 0}
};
{"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'},
{"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'},
{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"swarn", required_argument, 0, 'W'},
{"scrit", required_argument, 0, 'C'}, {"jwarn", required_argument, 0, 'j'}, {"jcrit", required_argument, 0, 'k'},
{"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'},
{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}};
if (argc < 2)
usage ("\n");
usage("\n");
while (true) {
c = getopt_long (argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option);
if (c == -1 || c == EOF || c == 1)
int option = 0;
int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option);
if (option_char == -1 || option_char == EOF || option_char == 1)
break;
switch (c) {
switch (option_char) {
case 'h':
print_help();
exit(STATE_UNKNOWN);
@ -490,15 +509,15 @@ int process_arguments(int argc, char **argv){
tcrit = optarg;
break;
case 'H':
if(!is_host(optarg))
if (!is_host(optarg))
usage2(_("Invalid hostname/address"), optarg);
server_address = strdup(optarg);
break;
case 'p':
port=atoi(optarg);
port = atoi(optarg);
break;
case 't':
socket_timeout=atoi(optarg);
socket_timeout = atoi(optarg);
break;
case '4':
address_family = AF_INET;
@ -507,69 +526,53 @@ int process_arguments(int argc, char **argv){
#ifdef USE_IPV6
address_family = AF_INET6;
#else
usage4 (_("IPv6 support not available"));
usage4(_("IPv6 support not available"));
#endif
break;
case '?':
/* print short usage statement if args not parsable */
usage5 ();
usage5();
break;
}
}
if(server_address == NULL){
if (server_address == NULL) {
usage4(_("Hostname was not supplied"));
}
return 0;
}
char *perfd_offset (double offset)
{
return fperfdata ("offset", offset, "s",
true, offset_thresholds->warning->end,
true, offset_thresholds->critical->end,
false, 0, false, 0);
char *perfd_offset(double offset) {
return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false,
0);
}
char *perfd_jitter (double jitter)
{
return fperfdata ("jitter", jitter, "",
do_jitter, jitter_thresholds->warning->end,
do_jitter, jitter_thresholds->critical->end,
true, 0, false, 0);
char *perfd_jitter(double jitter) {
return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0,
false, 0);
}
char *perfd_stratum (int stratum)
{
return perfdata ("stratum", stratum, "",
do_stratum, (int)stratum_thresholds->warning->end,
do_stratum, (int)stratum_thresholds->critical->end,
true, 0, true, 16);
char *perfd_stratum(int stratum) {
return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum,
(int)stratum_thresholds->critical->end, true, 0, true, 16);
}
char *perfd_truechimers (int num_truechimers)
{
return perfdata ("truechimers", num_truechimers, "",
do_truechimers, (int)truechimer_thresholds->warning->end,
do_truechimers, (int)truechimer_thresholds->critical->end,
true, 0, false, 0);
char *perfd_truechimers(int num_truechimers) {
return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers,
(int)truechimer_thresholds->critical->end, true, 0, false, 0);
}
int main(int argc, char *argv[]){
int result, offset_result, stratum, num_truechimers;
double offset=0, jitter=0;
char *result_line, *perfdata_line;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char *argv[]) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
set_thresholds(&offset_thresholds, owarn, ocrit);
set_thresholds(&jitter_thresholds, jwarn, jcrit);
@ -577,15 +580,20 @@ int main(int argc, char *argv[]){
set_thresholds(&truechimer_thresholds, twarn, tcrit);
/* initialize alarm signal handling */
signal (SIGALRM, socket_timeout_alarm_handler);
signal(SIGALRM, socket_timeout_alarm_handler);
/* set socket timeout */
alarm (socket_timeout);
alarm(socket_timeout);
int offset_result;
int stratum;
int num_truechimers;
double offset = 0;
double jitter = 0;
/* This returns either OK or WARNING (See comment preceding ntp_request) */
result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers);
int result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers);
if(offset_result == STATE_UNKNOWN) {
if (offset_result == STATE_UNKNOWN) {
/* if there's no sync peer (this overrides ntp_request output): */
result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL);
} else {
@ -597,50 +605,49 @@ int main(int argc, char *argv[]){
int oresult = result;
int tresult = STATE_UNKNOWN;
if(do_truechimers) {
if (do_truechimers) {
tresult = get_status(num_truechimers, truechimer_thresholds);
result = max_state_alt(result, tresult);
}
int sresult = STATE_UNKNOWN;
if(do_stratum) {
if (do_stratum) {
sresult = get_status(stratum, stratum_thresholds);
result = max_state_alt(result, sresult);
}
int jresult = STATE_UNKNOWN;
if(do_jitter) {
if (do_jitter) {
jresult = get_status(jitter, jitter_thresholds);
result = max_state_alt(result, jresult);
}
char *result_line;
switch (result) {
case STATE_CRITICAL :
xasprintf(&result_line, _("NTP CRITICAL:"));
break;
case STATE_WARNING :
xasprintf(&result_line, _("NTP WARNING:"));
break;
case STATE_OK :
xasprintf(&result_line, _("NTP OK:"));
break;
default :
xasprintf(&result_line, _("NTP UNKNOWN:"));
break;
case STATE_CRITICAL:
xasprintf(&result_line, _("NTP CRITICAL:"));
break;
case STATE_WARNING:
xasprintf(&result_line, _("NTP WARNING:"));
break;
case STATE_OK:
xasprintf(&result_line, _("NTP OK:"));
break;
default:
xasprintf(&result_line, _("NTP UNKNOWN:"));
break;
}
if(!syncsource_found)
if (!syncsource_found)
xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized"));
else if(li_alarm)
else if (li_alarm)
xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set"));
if(offset_result == STATE_UNKNOWN){
char *perfdata_line;
if (offset_result == STATE_UNKNOWN) {
xasprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
xasprintf(&perfdata_line, "");
} else if (oresult == STATE_WARNING) {
@ -649,9 +656,9 @@ int main(int argc, char *argv[]){
xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), offset);
} else {
xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset);
}
}
xasprintf(&perfdata_line, "%s", perfd_offset(offset));
if (do_jitter) {
if (jresult == STATE_WARNING) {
xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter);
@ -684,45 +691,46 @@ int main(int argc, char *argv[]){
}
printf("%s|%s\n", result_line, perfdata_line);
if(server_address!=NULL) free(server_address);
if (server_address != NULL)
free(server_address);
return result;
}
void print_help(void){
void print_help(void) {
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 2006 Sean Finney\n");
printf (COPYRIGHT, copyright, email);
printf("Copyright (c) 2006 Sean Finney\n");
printf(COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin checks the selected ntp server"));
printf("%s\n", _("This plugin checks the selected ntp server"));
printf ("\n\n");
printf("\n\n");
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf (UT_IPv46);
printf (UT_HOST_PORT, 'p', "123");
printf (" %s\n", "-q, --quiet");
printf (" %s\n", _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized"));
printf (" %s\n", "-w, --warning=THRESHOLD");
printf (" %s\n", _("Offset to result in warning status (seconds)"));
printf (" %s\n", "-c, --critical=THRESHOLD");
printf (" %s\n", _("Offset to result in critical status (seconds)"));
printf (" %s\n", "-W, --swarn=THRESHOLD");
printf (" %s\n", _("Warning threshold for stratum of server's synchronization peer"));
printf (" %s\n", "-C, --scrit=THRESHOLD");
printf (" %s\n", _("Critical threshold for stratum of server's synchronization peer"));
printf (" %s\n", "-j, --jwarn=THRESHOLD");
printf (" %s\n", _("Warning threshold for jitter"));
printf (" %s\n", "-k, --jcrit=THRESHOLD");
printf (" %s\n", _("Critical threshold for jitter"));
printf (" %s\n", "-m, --twarn=THRESHOLD");
printf (" %s\n", _("Warning threshold for number of usable time sources (\"truechimers\")"));
printf (" %s\n", "-n, --tcrit=THRESHOLD");
printf (" %s\n", _("Critical threshold for number of usable time sources (\"truechimers\")"));
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_VERBOSE);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf(UT_IPv46);
printf(UT_HOST_PORT, 'p', "123");
printf(" %s\n", "-q, --quiet");
printf(" %s\n", _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized"));
printf(" %s\n", "-w, --warning=THRESHOLD");
printf(" %s\n", _("Offset to result in warning status (seconds)"));
printf(" %s\n", "-c, --critical=THRESHOLD");
printf(" %s\n", _("Offset to result in critical status (seconds)"));
printf(" %s\n", "-W, --swarn=THRESHOLD");
printf(" %s\n", _("Warning threshold for stratum of server's synchronization peer"));
printf(" %s\n", "-C, --scrit=THRESHOLD");
printf(" %s\n", _("Critical threshold for stratum of server's synchronization peer"));
printf(" %s\n", "-j, --jwarn=THRESHOLD");
printf(" %s\n", _("Warning threshold for jitter"));
printf(" %s\n", "-k, --jcrit=THRESHOLD");
printf(" %s\n", _("Critical threshold for jitter"));
printf(" %s\n", "-m, --twarn=THRESHOLD");
printf(" %s\n", _("Warning threshold for number of usable time sources (\"truechimers\")"));
printf(" %s\n", "-n, --tcrit=THRESHOLD");
printf(" %s\n", _("Critical threshold for number of usable time sources (\"truechimers\")"));
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_VERBOSE);
printf("\n");
printf("%s\n", _("This plugin checks an NTP server independent of any commandline"));
@ -751,13 +759,11 @@ void print_help(void){
printf(" %s\n", _("Check only stratum:"));
printf(" %s\n", ("./check_ntp_peer -H ntpserv -W 4 -C 6"));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage(void)
{
printf ("%s\n", _("Usage:"));
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-W <warn>] [-C <crit>]\n", progname);
printf(" [-j <warn>] [-k <crit>] [-v verbose]\n");
}

View file

@ -1,63 +1,63 @@
/*****************************************************************************
*
* Monitoring check_ntp_time plugin
*
* License: GPL
* Copyright (c) 2006 Sean Finney <seanius@seanius.net>
* Copyright (c) 2006-2008 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ntp_time plugin
*
* This plugin checks the clock offset between the local host and a
* remote NTP server. It is independent of any commandline programs or
* external libraries.
*
* If you'd rather want to monitor an NTP server, please use
* check_ntp_peer.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_ntp_time plugin
*
* License: GPL
* Copyright (c) 2006 Sean Finney <seanius@seanius.net>
* Copyright (c) 2006-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ntp_time plugin
*
* This plugin checks the clock offset between the local host and a
* remote NTP server. It is independent of any commandline programs or
* external libraries.
*
* If you'd rather want to monitor an NTP server, please use
* check_ntp_peer.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_ntp_time";
const char *copyright = "2006-2008";
const char *copyright = "2006-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "netutils.h"
#include "utils.h"
static char *server_address=NULL;
static char *port="123";
static int verbose=0;
static char *server_address = NULL;
static char *port = "123";
static int verbose = 0;
static bool quiet = false;
static char *owarn="60";
static char *ocrit="120";
static int time_offset=0;
static char *owarn = "60";
static char *ocrit = "120";
static int time_offset = 0;
int process_arguments (int, char **);
thresholds *offset_thresholds = NULL;
void print_help (void);
void print_usage (void);
static int process_arguments(int, char **);
static thresholds *offset_thresholds = NULL;
static void print_help(void);
void print_usage(void);
/* number of times to perform each request to get a good average. */
#ifndef AVG_NUM
#define AVG_NUM 4
# define AVG_NUM 4
#endif
/* max size of control message data */
@ -65,17 +65,17 @@ void print_usage (void);
/* this structure holds everything in an ntp request/response as per rfc1305 */
typedef struct {
uint8_t flags; /* byte with leapindicator,vers,mode. see macros */
uint8_t stratum; /* clock stratum */
int8_t poll; /* polling interval */
int8_t precision; /* precision of the local clock */
int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */
uint32_t rtdisp; /* like above, but for max err to primary src */
uint32_t refid; /* ref clock identifier */
uint64_t refts; /* reference timestamp. local time local clock */
uint64_t origts; /* time at which request departed client */
uint64_t rxts; /* time at which request arrived at server */
uint64_t txts; /* time at which request departed server */
uint8_t flags; /* byte with leapindicator,vers,mode. see macros */
uint8_t stratum; /* clock stratum */
int8_t poll; /* polling interval */
int8_t precision; /* precision of the local clock */
int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */
uint32_t rtdisp; /* like above, but for max err to primary src */
uint32_t refid; /* ref clock identifier */
uint64_t refts; /* reference timestamp. local time local clock */
uint64_t origts; /* time at which request departed client */
uint64_t rxts; /* time at which request arrived at server */
uint64_t txts; /* time at which request departed server */
} ntp_message;
/* this structure holds data about results from querying offset from a peer */
@ -86,43 +86,55 @@ typedef struct {
double rtdelay; /* converted from the ntp_message */
double rtdisp; /* converted from the ntp_message */
double offset[AVG_NUM]; /* offsets from each response */
uint8_t flags; /* byte with leapindicator,vers,mode. see macros */
uint8_t flags; /* byte with leapindicator,vers,mode. see macros */
} ntp_server_results;
/* bits 1,2 are the leap indicator */
#define LI_MASK 0xc0
#define LI(x) ((x&LI_MASK)>>6)
#define LI_SET(x,y) do{ x |= ((y<<6)&LI_MASK); }while(0)
#define LI(x) ((x & LI_MASK) >> 6)
#define LI_SET(x, y) \
do { \
x |= ((y << 6) & LI_MASK); \
} while (0)
/* and these are the values of the leap indicator */
#define LI_NOWARNING 0x00
#define LI_EXTRASEC 0x01
#define LI_NOWARNING 0x00
#define LI_EXTRASEC 0x01
#define LI_MISSINGSEC 0x02
#define LI_ALARM 0x03
#define LI_ALARM 0x03
/* bits 3,4,5 are the ntp version */
#define VN_MASK 0x38
#define VN(x) ((x&VN_MASK)>>3)
#define VN_SET(x,y) do{ x |= ((y<<3)&VN_MASK); }while(0)
#define VN(x) ((x & VN_MASK) >> 3)
#define VN_SET(x, y) \
do { \
x |= ((y << 3) & VN_MASK); \
} while (0)
#define VN_RESERVED 0x02
/* bits 6,7,8 are the ntp mode */
#define MODE_MASK 0x07
#define MODE(x) (x&MODE_MASK)
#define MODE_SET(x,y) do{ x |= (y&MODE_MASK); }while(0)
#define MODE(x) (x & MODE_MASK)
#define MODE_SET(x, y) \
do { \
x |= (y & MODE_MASK); \
} while (0)
/* here are some values */
#define MODE_CLIENT 0x03
#define MODE_CLIENT 0x03
#define MODE_CONTROLMSG 0x06
/* In control message, bits 8-10 are R,E,M bits */
#define REM_MASK 0xe0
#define REM_RESP 0x80
#define REM_MASK 0xe0
#define REM_RESP 0x80
#define REM_ERROR 0x40
#define REM_MORE 0x20
#define REM_MORE 0x20
/* In control message, bits 11 - 15 are opcode */
#define OP_MASK 0x1f
#define OP_SET(x,y) do{ x |= (y&OP_MASK); }while(0)
#define OP_SET(x, y) \
do { \
x |= (y & OP_MASK); \
} while (0)
#define OP_READSTAT 0x01
#define OP_READVAR 0x02
/* In peer status bytes, bits 6,7,8 determine clock selection status */
#define PEER_SEL(x) ((ntohs(x)>>8)&0x07)
#define PEER_INCLUDED 0x04
#define PEER_SEL(x) ((ntohs(x) >> 8) & 0x07)
#define PEER_INCLUDED 0x04
#define PEER_SYNCSOURCE 0x06
/**
@ -136,82 +148,91 @@ typedef struct {
/* macros to access the left/right 16 bits of a 32-bit ntp "fixed point"
number. note that these can be used as lvalues too */
#define L16(x) (((uint16_t*)&x)[0])
#define R16(x) (((uint16_t*)&x)[1])
#define L16(x) (((uint16_t *)&x)[0])
#define R16(x) (((uint16_t *)&x)[1])
/* macros to access the left/right 32 bits of a 64-bit ntp "fixed point"
number. these too can be used as lvalues */
#define L32(x) (((uint32_t*)&x)[0])
#define R32(x) (((uint32_t*)&x)[1])
#define L32(x) (((uint32_t *)&x)[0])
#define R32(x) (((uint32_t *)&x)[1])
/* ntp wants seconds since 1/1/00, epoch is 1/1/70. this is the difference */
#define EPOCHDIFF 0x83aa7e80UL
/* extract a 32-bit ntp fixed point number into a double */
#define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x))/65536.0)
#define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x)) / 65536.0)
/* likewise for a 64-bit ntp fp number */
#define NTP64asDOUBLE(n) (double)(((uint64_t)n)?\
(ntohl(L32(n))-EPOCHDIFF) + \
(.00000001*(0.5+(double)(ntohl(R32(n))/42.94967296))):\
0)
#define NTP64asDOUBLE(n) \
(double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) : 0)
/* convert a struct timeval to a double */
#define TVasDOUBLE(x) (double)(x.tv_sec+(0.000001*x.tv_usec))
#define TVasDOUBLE(x) (double)(x.tv_sec + (0.000001 * x.tv_usec))
/* convert an ntp 64-bit fp number to a struct timeval */
#define NTP64toTV(n,t) \
do{ if(!n) t.tv_sec = t.tv_usec = 0; \
else { \
t.tv_sec=ntohl(L32(n))-EPOCHDIFF; \
t.tv_usec=(int)(0.5+(double)(ntohl(R32(n))/4294.967296)); \
} \
}while(0)
#define NTP64toTV(n, t) \
do { \
if (!n) \
t.tv_sec = t.tv_usec = 0; \
else { \
t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \
t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \
} \
} while (0)
/* convert a struct timeval to an ntp 64-bit fp number */
#define TVtoNTP64(t,n) \
do{ if(!t.tv_usec && !t.tv_sec) n=0x0UL; \
else { \
L32(n)=htonl(t.tv_sec + EPOCHDIFF); \
R32(n)=htonl((uint64_t)((4294.967296*t.tv_usec)+.5)); \
} \
} while(0)
#define TVtoNTP64(t, n) \
do { \
if (!t.tv_usec && !t.tv_sec) \
n = 0x0UL; \
else { \
L32(n) = htonl(t.tv_sec + EPOCHDIFF); \
R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \
} \
} while (0)
/* NTP control message header is 12 bytes, plus any data in the data
* field, plus null padding to the nearest 32-bit boundary per rfc.
*/
#define SIZEOF_NTPCM(m) (12+ntohs(m.count)+((m.count)?4-(ntohs(m.count)%4):0))
#define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((m.count) ? 4 - (ntohs(m.count) % 4) : 0))
/* finally, a little helper or two for debugging: */
#define DBG(x) do{if(verbose>1){ x; }}while(0);
#define PRINTSOCKADDR(x) \
do{ \
printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\
}while(0);
#define DBG(x) \
do { \
if (verbose > 1) { \
x; \
} \
} while (0);
#define PRINTSOCKADDR(x) \
do { \
printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \
} while (0);
/* calculate the offset of the local clock */
static inline double calc_offset(const ntp_message *m, const struct timeval *t){
double client_tx, peer_rx, peer_tx, client_rx;
client_tx = NTP64asDOUBLE(m->origts);
peer_rx = NTP64asDOUBLE(m->rxts);
peer_tx = NTP64asDOUBLE(m->txts);
client_rx=TVasDOUBLE((*t));
return (.5*((peer_tx-client_rx)+(peer_rx-client_tx)));
static inline double calc_offset(const ntp_message *m, const struct timeval *t) {
double client_tx = NTP64asDOUBLE(m->origts);
double peer_rx = NTP64asDOUBLE(m->rxts);
double peer_tx = NTP64asDOUBLE(m->txts);
double client_rx = TVasDOUBLE((*t));
return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx)));
}
/* print out a ntp packet in human readable/debuggable format */
void print_ntp_message(const ntp_message *p){
struct timeval ref, orig, rx, tx;
void print_ntp_message(const ntp_message *p) {
struct timeval ref;
struct timeval orig;
struct timeval rx;
struct timeval tx;
NTP64toTV(p->refts,ref);
NTP64toTV(p->origts,orig);
NTP64toTV(p->rxts,rx);
NTP64toTV(p->txts,tx);
NTP64toTV(p->refts, ref);
NTP64toTV(p->origts, orig);
NTP64toTV(p->rxts, rx);
NTP64toTV(p->txts, tx);
printf("packet contents:\n");
printf("\tflags: 0x%.2x\n", p->flags);
printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK);
printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK);
printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK);
printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK);
printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK);
printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK);
printf("\tstratum = %d\n", p->stratum);
printf("\tpoll = %g\n", pow(2, p->poll));
printf("\tprecision = %g\n", pow(2, p->precision));
@ -224,41 +245,42 @@ void print_ntp_message(const ntp_message *p){
printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts));
}
void setup_request(ntp_message *p){
struct timeval t;
void setup_request(ntp_message *p) {
memset(p, 0, sizeof(ntp_message));
LI_SET(p->flags, LI_ALARM);
VN_SET(p->flags, 4);
MODE_SET(p->flags, MODE_CLIENT);
p->poll=4;
p->precision=(int8_t)0xfa;
L16(p->rtdelay)=htons(1);
L16(p->rtdisp)=htons(1);
p->poll = 4;
p->precision = (int8_t)0xfa;
L16(p->rtdelay) = htons(1);
L16(p->rtdisp) = htons(1);
struct timeval t;
gettimeofday(&t, NULL);
TVtoNTP64(t,p->txts);
TVtoNTP64(t, p->txts);
}
/* select the "best" server from a list of servers, and return its index.
* this is done by filtering servers based on stratum, dispersion, and
* finally round-trip delay. */
int best_offset_server(const ntp_server_results *slist, int nservers){
int cserver=0, best_server=-1;
int best_offset_server(const ntp_server_results *slist, int nservers) {
int best_server = -1;
/* for each server */
for(cserver=0; cserver<nservers; cserver++){
for (int cserver = 0; cserver < nservers; cserver++) {
/* We don't want any servers that fails these tests */
/* Sort out servers that didn't respond or responede with a 0 stratum;
* stratum 0 is for reference clocks so no NTP server should ever report
* a stratum 0 */
if ( slist[cserver].stratum == 0){
if (verbose) printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum);
if (slist[cserver].stratum == 0) {
if (verbose)
printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum);
continue;
}
/* Sort out servers with error flags */
if ( LI(slist[cserver].flags) == LI_ALARM ){
if (verbose) printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags));
if (LI(slist[cserver].flags) == LI_ALARM) {
if (verbose)
printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags));
continue;
}
@ -272,13 +294,13 @@ int best_offset_server(const ntp_server_results *slist, int nservers){
/* compare the server to the best one we've seen so far */
/* does it have an equal or better stratum? */
DBG(printf("comparing peer %d with peer %d\n", cserver, best_server));
if(slist[cserver].stratum <= slist[best_server].stratum){
if (slist[cserver].stratum <= slist[best_server].stratum) {
DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server));
/* does it have an equal or better dispersion? */
if(slist[cserver].rtdisp <= slist[best_server].rtdisp){
if (slist[cserver].rtdisp <= slist[best_server].rtdisp) {
DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server));
/* does it have a better rtdelay? */
if(slist[cserver].rtdelay < slist[best_server].rtdelay){
if (slist[cserver].rtdelay < slist[best_server].rtdelay) {
DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server));
best_server = cserver;
DBG(printf("peer %d is now our best candidate\n", best_server));
@ -287,13 +309,12 @@ int best_offset_server(const ntp_server_results *slist, int nservers){
}
}
if(best_server >= 0) {
if (best_server >= 0) {
DBG(printf("best server selected: peer %d\n", best_server));
return best_server;
} else {
DBG(printf("no peers meeting synchronization criteria :(\n"));
return -1;
}
DBG(printf("no peers meeting synchronization criteria :(\n"));
return -1;
}
/* do everything we need to get the total average offset
@ -301,178 +322,190 @@ int best_offset_server(const ntp_server_results *slist, int nservers){
* we don't waste time sitting around waiting for single packets.
* - we also "manually" handle resolving host names and connecting, because
* we have to do it in a way that our lazy macros don't handle currently :( */
double offset_request(const char *host, int *status){
int i=0, j=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0;
int servers_completed=0, one_read=0, servers_readable=0, best_index=-1;
time_t now_time=0, start_ts=0;
ntp_message *req=NULL;
double avg_offset=0.;
struct timeval recv_time;
struct addrinfo *ai=NULL, *ai_tmp=NULL, hints;
struct pollfd *ufds=NULL;
ntp_server_results *servers=NULL;
double offset_request(const char *host, int *status) {
/* setup hints to only return results from getaddrinfo that we'd like */
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = address_family;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
/* fill in ai with the list of hosts resolved by the host name */
ga_result = getaddrinfo(host, port, &hints, &ai);
if(ga_result!=0){
die(STATE_UNKNOWN, "error getting address for %s: %s\n",
host, gai_strerror(ga_result));
struct addrinfo *ai = NULL;
int ga_result = getaddrinfo(host, port, &hints, &ai);
if (ga_result != 0) {
die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result));
}
/* count the number of returned hosts, and allocate stuff accordingly */
for(ai_tmp=ai; ai_tmp!=NULL; ai_tmp=ai_tmp->ai_next){ num_hosts++; }
req=(ntp_message*)malloc(sizeof(ntp_message)*num_hosts);
if(req==NULL) die(STATE_UNKNOWN, "can not allocate ntp message array");
socklist=(int*)malloc(sizeof(int)*num_hosts);
if(socklist==NULL) die(STATE_UNKNOWN, "can not allocate socket array");
ufds=(struct pollfd*)malloc(sizeof(struct pollfd)*num_hosts);
if(ufds==NULL) die(STATE_UNKNOWN, "can not allocate socket array");
servers=(ntp_server_results*)malloc(sizeof(ntp_server_results)*num_hosts);
if(servers==NULL) die(STATE_UNKNOWN, "can not allocate server array");
memset(servers, 0, sizeof(ntp_server_results)*num_hosts);
int num_hosts = 0;
for (struct addrinfo *ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
num_hosts++;
}
ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts);
if (req == NULL)
die(STATE_UNKNOWN, "can not allocate ntp message array");
int *socklist = (int *)malloc(sizeof(int) * num_hosts);
if (socklist == NULL)
die(STATE_UNKNOWN, "can not allocate socket array");
struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts);
if (ufds == NULL)
die(STATE_UNKNOWN, "can not allocate socket array");
ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts);
if (servers == NULL)
die(STATE_UNKNOWN, "can not allocate server array");
memset(servers, 0, sizeof(ntp_server_results) * num_hosts);
DBG(printf("Found %d peers to check\n", num_hosts));
/* setup each socket for writing, and the corresponding struct pollfd */
ai_tmp=ai;
for(i=0;ai_tmp;i++){
socklist[i]=socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
if(socklist[i] == -1) {
struct addrinfo *ai_tmp = ai;
for (int i = 0; ai_tmp; i++) {
socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
if (socklist[i] == -1) {
perror(NULL);
die(STATE_UNKNOWN, "can not create new socket");
}
if(connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)){
if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) {
/* don't die here, because it is enough if there is one server
answering in time. This also would break for dual ipv4/6 stacked
ntp servers when the client only supports on of them.
*/
DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno)));
} else {
ufds[i].fd=socklist[i];
ufds[i].events=POLLIN;
ufds[i].revents=0;
ufds[i].fd = socklist[i];
ufds[i].events = POLLIN;
ufds[i].revents = 0;
}
ai_tmp = ai_tmp->ai_next;
}
/* now do AVG_NUM checks to each host. We stop before timeout/2 seconds
* have passed in order to ensure post-processing and jitter time. */
now_time=start_ts=time(NULL);
while(servers_completed<num_hosts && now_time-start_ts <= socket_timeout/2){
time_t start_ts = 0;
time_t now_time = 0;
now_time = start_ts = time(NULL);
int servers_completed = 0;
bool one_read = false;
while (servers_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) {
/* loop through each server and find each one which hasn't
* been touched in the past second or so and is still lacking
* some responses. For each of these servers, send a new request,
* and update the "waiting" timestamp with the current time. */
now_time=time(NULL);
now_time = time(NULL);
for(i=0; i<num_hosts; i++){
if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
if(verbose && servers[i].waiting != 0) printf("re-");
if(verbose) printf("sending request to peer %d\n", i);
for (int i = 0; i < num_hosts; i++) {
if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) {
if (verbose && servers[i].waiting != 0)
printf("re-");
if (verbose)
printf("sending request to peer %d\n", i);
setup_request(&req[i]);
write(socklist[i], &req[i], sizeof(ntp_message));
servers[i].waiting=now_time;
servers[i].waiting = now_time;
break;
}
}
/* quickly poll for any sockets with pending data */
servers_readable=poll(ufds, num_hosts, 100);
if(servers_readable==-1){
int servers_readable = poll(ufds, num_hosts, 100);
if (servers_readable == -1) {
perror("polling ntp sockets");
die(STATE_UNKNOWN, "communication errors");
}
/* read from any sockets with pending data */
for(i=0; servers_readable && i<num_hosts; i++){
if(ufds[i].revents&POLLIN && servers[i].num_responses < AVG_NUM){
if(verbose) {
for (int i = 0; servers_readable && i < num_hosts; i++) {
if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) {
if (verbose) {
printf("response from peer %d: ", i);
}
read(ufds[i].fd, &req[i], sizeof(ntp_message));
struct timeval recv_time;
gettimeofday(&recv_time, NULL);
DBG(print_ntp_message(&req[i]));
respnum=servers[i].num_responses++;
servers[i].offset[respnum]=calc_offset(&req[i], &recv_time)+time_offset;
if(verbose) {
int respnum = servers[i].num_responses++;
servers[i].offset[respnum] = calc_offset(&req[i], &recv_time) + time_offset;
if (verbose) {
printf("offset %.10g\n", servers[i].offset[respnum]);
}
servers[i].stratum=req[i].stratum;
servers[i].rtdisp=NTP32asDOUBLE(req[i].rtdisp);
servers[i].rtdelay=NTP32asDOUBLE(req[i].rtdelay);
servers[i].waiting=0;
servers[i].flags=req[i].flags;
servers[i].stratum = req[i].stratum;
servers[i].rtdisp = NTP32asDOUBLE(req[i].rtdisp);
servers[i].rtdelay = NTP32asDOUBLE(req[i].rtdelay);
servers[i].waiting = 0;
servers[i].flags = req[i].flags;
servers_readable--;
one_read = 1;
if(servers[i].num_responses==AVG_NUM) servers_completed++;
one_read = true;
if (servers[i].num_responses == AVG_NUM)
servers_completed++;
}
}
/* lather, rinse, repeat. */
}
if (one_read == 0) {
if (one_read == false) {
die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
}
/* now, pick the best server from the list */
best_index=best_offset_server(servers, num_hosts);
if(best_index < 0){
*status=STATE_UNKNOWN;
double avg_offset = 0.;
int best_index = best_offset_server(servers, num_hosts);
if (best_index < 0) {
*status = STATE_UNKNOWN;
} else {
/* finally, calculate the average offset */
for(i=0; i<servers[best_index].num_responses;i++){
avg_offset+=servers[best_index].offset[i];
for (int i = 0; i < servers[best_index].num_responses; i++) {
avg_offset += servers[best_index].offset[i];
}
avg_offset/=servers[best_index].num_responses;
avg_offset /= servers[best_index].num_responses;
}
/* cleanup */
for(j=0; j<num_hosts; j++){ close(socklist[j]); }
for (int j = 0; j < num_hosts; j++) {
close(socklist[j]);
}
free(socklist);
free(ufds);
free(servers);
free(req);
freeaddrinfo(ai);
if(verbose) printf("overall average offset: %.10g\n", avg_offset);
if (verbose)
printf("overall average offset: %.10g\n", avg_offset);
return avg_offset;
}
int process_arguments(int argc, char **argv){
int c;
int option=0;
static struct option longopts[] = {
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"quiet", no_argument, 0, 'q'},
{"time-offset", optional_argument, 0, 'o'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"timeout", required_argument, 0, 't'},
{"hostname", required_argument, 0, 'H'},
{"port", required_argument, 0, 'p'},
{0, 0, 0, 0}
};
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"quiet", no_argument, 0, 'q'},
{"time-offset", optional_argument, 0, 'o'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"timeout", required_argument, 0, 't'},
{"hostname", required_argument, 0, 'H'},
{"port", required_argument, 0, 'p'},
{0, 0, 0, 0}};
if (argc < 2)
usage ("\n");
usage("\n");
while (1) {
c = getopt_long (argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option);
if (c == -1 || c == EOF || c == 1)
while (true) {
int option = 0;
int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option);
if (option_char == -1 || option_char == EOF || option_char == 1)
break;
switch (c) {
switch (option_char) {
case 'h':
print_help();
exit(STATE_UNKNOWN);
@ -494,7 +527,7 @@ int process_arguments(int argc, char **argv){
ocrit = optarg;
break;
case 'H':
if(!is_host(optarg))
if (!is_host(optarg))
usage2(_("Invalid hostname/address"), optarg);
server_address = strdup(optarg);
break;
@ -502,11 +535,11 @@ int process_arguments(int argc, char **argv){
port = strdup(optarg);
break;
case 't':
socket_timeout=atoi(optarg);
socket_timeout = atoi(optarg);
break;
case 'o':
time_offset=atoi(optarg);
break;
time_offset = atoi(optarg);
break;
case '4':
address_family = AF_INET;
break;
@ -514,77 +547,74 @@ int process_arguments(int argc, char **argv){
#ifdef USE_IPV6
address_family = AF_INET6;
#else
usage4 (_("IPv6 support not available"));
usage4(_("IPv6 support not available"));
#endif
break;
case '?':
/* print short usage statement if args not parsable */
usage5 ();
usage5();
break;
}
}
if(server_address == NULL){
if (server_address == NULL) {
usage4(_("Hostname was not supplied"));
}
return 0;
}
char *perfd_offset (double offset) {
return fperfdata ("offset", offset, "s",
true, offset_thresholds->warning->end,
true, offset_thresholds->critical->end,
false, 0, false, 0);
char *perfd_offset(double offset) {
return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false,
0);
}
int main(int argc, char *argv[]){
int result, offset_result;
double offset=0;
char *result_line, *perfdata_line;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
result = offset_result = STATE_OK;
int main(int argc, char *argv[]) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
set_thresholds(&offset_thresholds, owarn, ocrit);
/* initialize alarm signal handling */
signal (SIGALRM, socket_timeout_alarm_handler);
signal(SIGALRM, socket_timeout_alarm_handler);
/* set socket timeout */
alarm (socket_timeout);
alarm(socket_timeout);
offset = offset_request(server_address, &offset_result);
int offset_result = STATE_OK;
int result = STATE_OK;
double offset = offset_request(server_address, &offset_result);
if (offset_result == STATE_UNKNOWN) {
result = ( (!quiet) ? STATE_UNKNOWN : STATE_CRITICAL);
result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL);
} else {
result = get_status(fabs(offset), offset_thresholds);
}
char *result_line;
switch (result) {
case STATE_CRITICAL :
xasprintf(&result_line, _("NTP CRITICAL:"));
break;
case STATE_WARNING :
xasprintf(&result_line, _("NTP WARNING:"));
break;
case STATE_OK :
xasprintf(&result_line, _("NTP OK:"));
break;
default :
xasprintf(&result_line, _("NTP UNKNOWN:"));
break;
case STATE_CRITICAL:
xasprintf(&result_line, _("NTP CRITICAL:"));
break;
case STATE_WARNING:
xasprintf(&result_line, _("NTP WARNING:"));
break;
case STATE_OK:
xasprintf(&result_line, _("NTP OK:"));
break;
default:
xasprintf(&result_line, _("NTP UNKNOWN:"));
break;
}
if(offset_result == STATE_UNKNOWN){
char *perfdata_line;
if (offset_result == STATE_UNKNOWN) {
xasprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
xasprintf(&perfdata_line, "");
} else {
@ -593,35 +623,36 @@ int main(int argc, char *argv[]){
}
printf("%s|%s\n", result_line, perfdata_line);
if(server_address!=NULL) free(server_address);
if (server_address != NULL)
free(server_address);
return result;
}
void print_help(void){
void print_help(void) {
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 2006 Sean Finney\n");
printf (COPYRIGHT, copyright, email);
printf("Copyright (c) 2006 Sean Finney\n");
printf(COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin checks the clock offset with the ntp server"));
printf("%s\n", _("This plugin checks the clock offset with the ntp server"));
printf ("\n\n");
printf("\n\n");
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf (UT_IPv46);
printf (UT_HOST_PORT, 'p', "123");
printf (" %s\n", "-q, --quiet");
printf (" %s\n", _("Returns UNKNOWN instead of CRITICAL if offset cannot be found"));
printf (" %s\n", "-w, --warning=THRESHOLD");
printf (" %s\n", _("Offset to result in warning status (seconds)"));
printf (" %s\n", "-c, --critical=THRESHOLD");
printf (" %s\n", _("Offset to result in critical status (seconds)"));
printf (" %s\n", "-o, --time_offset=INTEGER");
printf (" %s\n", _("Expected offset of the ntp server relative to local server (seconds)"));
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_VERBOSE);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf(UT_IPv46);
printf(UT_HOST_PORT, 'p', "123");
printf(" %s\n", "-q, --quiet");
printf(" %s\n", _("Returns UNKNOWN instead of CRITICAL if offset cannot be found"));
printf(" %s\n", "-w, --warning=THRESHOLD");
printf(" %s\n", _("Offset to result in warning status (seconds)"));
printf(" %s\n", "-c, --critical=THRESHOLD");
printf(" %s\n", _("Offset to result in critical status (seconds)"));
printf(" %s\n", "-o, --time_offset=INTEGER");
printf(" %s\n", _("Expected offset of the ntp server relative to local server (seconds)"));
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_VERBOSE);
printf("\n");
printf("%s\n", _("This plugin checks the clock offset between the local host and a"));
@ -641,13 +672,10 @@ void print_help(void){
printf("%s\n", _("Examples:"));
printf(" %s\n", ("./check_ntp_time -H ntpserv -w 0.5 -c 1"));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage(void)
{
printf ("%s\n", _("Usage:"));
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>]\n", progname);
}

File diff suppressed because it is too large Load diff

View file

@ -1,36 +1,36 @@
/*****************************************************************************
*
* Monitoring check_overcr plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_overcr plugin
*
* This plugin attempts to contact the Over-CR collector daemon running on the
* remote UNIX server in order to gather the requested system 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_overcr plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_overcr plugin
*
* This plugin attempts to contact the Over-CR collector daemon running on the
* remote UNIX server in order to gather the requested system 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_overcr";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -66,13 +66,11 @@ char *disk_name = NULL;
char *process_name = NULL;
char send_buffer[MAX_INPUT_BUFFER];
int process_arguments (int, char **);
void print_usage (void);
void print_help (void);
int process_arguments(int, char **);
void print_usage(void);
void print_help(void);
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
int result = STATE_UNKNOWN;
char recv_buffer[MAX_INPUT_BUFFER];
char temp_buffer[MAX_INPUT_BUFFER];
@ -91,66 +89,62 @@ main (int argc, char **argv)
int uptime_hours = 0;
int uptime_minutes = 0;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
/* initialize alarm signal handling */
signal (SIGALRM, socket_timeout_alarm_handler);
signal(SIGALRM, socket_timeout_alarm_handler);
/* set socket timeout */
alarm (socket_timeout);
alarm(socket_timeout);
result = process_tcp_request2 (server_address,
server_port,
send_buffer,
recv_buffer,
sizeof (recv_buffer));
result = process_tcp_request2(server_address, server_port, send_buffer, recv_buffer, sizeof(recv_buffer));
switch (vars_to_check) {
case LOAD1:
case LOAD5:
case LOAD15:
if (result != STATE_OK)
die (result, _("Unknown error fetching load data\n"));
die(result, _("Unknown error fetching load data\n"));
temp_ptr = (char *) strtok (recv_buffer, "\r\n");
temp_ptr = (char *)strtok(recv_buffer, "\r\n");
if (temp_ptr == NULL)
die (STATE_CRITICAL, _("Invalid response from server - no load information\n"));
die(STATE_CRITICAL, _("Invalid response from server - no load information\n"));
else
load_1min = strtod (temp_ptr, NULL);
load_1min = strtod(temp_ptr, NULL);
temp_ptr = (char *) strtok (NULL, "\r\n");
temp_ptr = (char *)strtok(NULL, "\r\n");
if (temp_ptr == NULL)
die (STATE_CRITICAL, _("Invalid response from server after load 1\n"));
die(STATE_CRITICAL, _("Invalid response from server after load 1\n"));
else
load_5min = strtod (temp_ptr, NULL);
load_5min = strtod(temp_ptr, NULL);
temp_ptr = (char *) strtok (NULL, "\r\n");
temp_ptr = (char *)strtok(NULL, "\r\n");
if (temp_ptr == NULL)
die (STATE_CRITICAL, _("Invalid response from server after load 5\n"));
die(STATE_CRITICAL, _("Invalid response from server after load 5\n"));
else
load_15min = strtod (temp_ptr, NULL);
load_15min = strtod(temp_ptr, NULL);
switch (vars_to_check) {
case LOAD1:
strcpy (temp_buffer, "1");
strcpy(temp_buffer, "1");
load = load_1min;
break;
case LOAD5:
strcpy (temp_buffer, "5");
strcpy(temp_buffer, "5");
load = load_5min;
break;
default:
strcpy (temp_buffer, "15");
strcpy(temp_buffer, "15");
load = load_15min;
break;
}
@ -160,98 +154,82 @@ main (int argc, char **argv)
else if (check_warning_value && (load >= warning_value))
result = STATE_WARNING;
die (result,
_("Load %s - %s-min load average = %0.2f"),
state_text(result),
temp_buffer,
load);
die(result, _("Load %s - %s-min load average = %0.2f"), state_text(result), temp_buffer, load);
break;
break;
case DPU:
if (result != STATE_OK)
die (result, _("Unknown error fetching disk data\n"));
die(result, _("Unknown error fetching disk data\n"));
for (temp_ptr = (char *) strtok (recv_buffer, " ");
temp_ptr != NULL;
temp_ptr = (char *) strtok (NULL, " ")) {
for (temp_ptr = (char *)strtok(recv_buffer, " "); temp_ptr != NULL; temp_ptr = (char *)strtok(NULL, " ")) {
if (!strcmp (temp_ptr, disk_name)) {
if (!strcmp(temp_ptr, disk_name)) {
found_disk = true;
temp_ptr = (char *) strtok (NULL, "%");
temp_ptr = (char *)strtok(NULL, "%");
if (temp_ptr == NULL)
die (STATE_CRITICAL, _("Invalid response from server\n"));
die(STATE_CRITICAL, _("Invalid response from server\n"));
else
percent_used_disk_space = strtoul (temp_ptr, NULL, 10);
percent_used_disk_space = strtoul(temp_ptr, NULL, 10);
break;
}
temp_ptr = (char *) strtok (NULL, "\r\n");
temp_ptr = (char *)strtok(NULL, "\r\n");
}
/* error if we couldn't find the info for the disk */
if (!found_disk)
die (STATE_CRITICAL,
"CRITICAL - Disk '%s' non-existent or not mounted",
disk_name);
die(STATE_CRITICAL, "CRITICAL - Disk '%s' non-existent or not mounted", disk_name);
if (check_critical_value && (percent_used_disk_space >= critical_value))
result = STATE_CRITICAL;
else if (check_warning_value && (percent_used_disk_space >= warning_value))
result = STATE_WARNING;
die (result, "Disk %s - %lu%% used on %s", state_text(result), percent_used_disk_space, disk_name);
die(result, "Disk %s - %lu%% used on %s", state_text(result), percent_used_disk_space, disk_name);
break;
case NETSTAT:
if (result != STATE_OK)
die (result, _("Unknown error fetching network status\n"));
die(result, _("Unknown error fetching network status\n"));
else
port_connections = strtod (recv_buffer, NULL);
port_connections = strtod(recv_buffer, NULL);
if (check_critical_value && (port_connections >= critical_value))
result = STATE_CRITICAL;
else if (check_warning_value && (port_connections >= warning_value))
result = STATE_WARNING;
die (result,
_("Net %s - %d connection%s on port %d"),
state_text(result),
port_connections,
(port_connections == 1) ? "" : "s",
netstat_port);
die(result, _("Net %s - %d connection%s on port %d"), state_text(result), port_connections, (port_connections == 1) ? "" : "s",
netstat_port);
break;
case PROCS:
if (result != STATE_OK)
die (result, _("Unknown error fetching process status\n"));
die(result, _("Unknown error fetching process status\n"));
temp_ptr = (char *) strtok (recv_buffer, "(");
temp_ptr = (char *)strtok(recv_buffer, "(");
if (temp_ptr == NULL)
die (STATE_CRITICAL, _("Invalid response from server\n"));
die(STATE_CRITICAL, _("Invalid response from server\n"));
temp_ptr = (char *) strtok (NULL, ")");
temp_ptr = (char *)strtok(NULL, ")");
if (temp_ptr == NULL)
die (STATE_CRITICAL, _("Invalid response from server\n"));
die(STATE_CRITICAL, _("Invalid response from server\n"));
else
processes = strtod (temp_ptr, NULL);
processes = strtod(temp_ptr, NULL);
if (check_critical_value && (processes >= critical_value))
result = STATE_CRITICAL;
else if (check_warning_value && (processes >= warning_value))
result = STATE_WARNING;
die (result,
_("Process %s - %d instance%s of %s running"),
state_text(result),
processes,
(processes == 1) ? "" : "s",
process_name);
die(result, _("Process %s - %d instance%s of %s running"), state_text(result), processes, (processes == 1) ? "" : "s",
process_name);
break;
case UPTIME:
@ -259,8 +237,8 @@ main (int argc, char **argv)
if (result != STATE_OK)
return result;
uptime_raw_hours = strtod (recv_buffer, NULL);
uptime_raw_minutes = (unsigned long) (uptime_raw_hours * 60.0);
uptime_raw_hours = strtod(recv_buffer, NULL);
uptime_raw_minutes = (unsigned long)(uptime_raw_hours * 60.0);
if (check_critical_value && (uptime_raw_minutes <= critical_value))
result = STATE_CRITICAL;
@ -273,46 +251,31 @@ main (int argc, char **argv)
uptime_raw_minutes %= 60;
uptime_minutes = uptime_raw_minutes;
die (result,
_("Uptime %s - Up %d days %d hours %d minutes"),
state_text(result),
uptime_days,
uptime_hours,
uptime_minutes);
die(result, _("Uptime %s - Up %d days %d hours %d minutes"), state_text(result), uptime_days, uptime_hours, uptime_minutes);
break;
default:
die (STATE_UNKNOWN, _("Nothing to check!\n"));
die(STATE_UNKNOWN, _("Nothing to check!\n"));
break;
}
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int process_arguments(int argc, char **argv) {
int c;
int option = 0;
static struct option longopts[] = {
{"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}
};
{"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}};
/* no options were supplied */
if (argc < 2)
return ERROR;
/* backwards compatibility */
if (!is_option (argv[1])) {
if (!is_option(argv[1])) {
server_address = argv[1];
argv[1] = argv[0];
argv = &argv[1];
@ -320,150 +283,136 @@ process_arguments (int argc, char **argv)
}
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");
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) {
c = getopt_long (argc, argv, "+hVH:t:c:w:p:v:", longopts,
&option);
c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:", longopts, &option);
if (c == -1 || c == EOF || c == 1)
break;
switch (c) {
case '?': /* print short usage statement if args not parsable */
usage5 ();
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'H': /* hostname */
case '?': /* print short usage statement if args not parsable */
usage5();
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'H': /* hostname */
server_address = optarg;
break;
case 'p': /* port */
if (is_intnonneg (optarg))
server_port = atoi (optarg);
case 'p': /* port */
if (is_intnonneg(optarg))
server_port = atoi(optarg);
else
die (STATE_UNKNOWN,
_("Server port an integer\n"));
die(STATE_UNKNOWN, _("Server port an integer\n"));
break;
case 'v': /* variable */
if (strcmp (optarg, "LOAD") == 0) {
strcpy (send_buffer, "LOAD\r\nQUIT\r\n");
if (strcmp (optarg, "LOAD1") == 0)
case 'v': /* variable */
if (strcmp(optarg, "LOAD") == 0) {
strcpy(send_buffer, "LOAD\r\nQUIT\r\n");
if (strcmp(optarg, "LOAD1") == 0)
vars_to_check = LOAD1;
else if (strcmp (optarg, "LOAD5") == 0)
else if (strcmp(optarg, "LOAD5") == 0)
vars_to_check = LOAD5;
else if (strcmp (optarg, "LOAD15") == 0)
else if (strcmp(optarg, "LOAD15") == 0)
vars_to_check = LOAD15;
}
else if (strcmp (optarg, "UPTIME") == 0) {
} else if (strcmp(optarg, "UPTIME") == 0) {
vars_to_check = UPTIME;
strcpy (send_buffer, "UPTIME\r\n");
}
else if (strstr (optarg, "PROC") == optarg) {
strcpy(send_buffer, "UPTIME\r\n");
} else if (strstr(optarg, "PROC") == optarg) {
vars_to_check = PROCS;
process_name = strscpy (process_name, optarg + 4);
sprintf (send_buffer, "PROCESS %s\r\n", process_name);
}
else if (strstr (optarg, "NET") == optarg) {
process_name = strscpy(process_name, optarg + 4);
sprintf(send_buffer, "PROCESS %s\r\n", process_name);
} else if (strstr(optarg, "NET") == optarg) {
vars_to_check = NETSTAT;
netstat_port = atoi (optarg + 3);
sprintf (send_buffer, "NETSTAT %d\r\n", netstat_port);
}
else if (strstr (optarg, "DPU") == optarg) {
netstat_port = atoi(optarg + 3);
sprintf(send_buffer, "NETSTAT %d\r\n", netstat_port);
} else if (strstr(optarg, "DPU") == optarg) {
vars_to_check = DPU;
strcpy (send_buffer, "DISKSPACE\r\n");
disk_name = strscpy (disk_name, optarg + 3);
}
else
strcpy(send_buffer, "DISKSPACE\r\n");
disk_name = strscpy(disk_name, optarg + 3);
} else
return ERROR;
break;
case 'w': /* warning threshold */
warning_value = strtoul (optarg, NULL, 10);
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);
case 'c': /* critical threshold */
critical_value = strtoul(optarg, NULL, 10);
check_critical_value = true;
break;
case 't': /* timeout */
socket_timeout = atoi (optarg);
case 't': /* timeout */
socket_timeout = atoi(optarg);
if (socket_timeout <= 0)
return ERROR;
}
}
return OK;
}
void
print_help (void)
{
void print_help(void) {
char *myport;
xasprintf (&myport, "%d", PORT);
xasprintf(&myport, "%d", PORT);
print_revision (progname, NP_VERSION);
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin attempts to contact the Over-CR collector daemon running on the"));
printf ("%s\n", _("remote UNIX server in order to gather the requested system information."));
printf("%s\n", _("This plugin attempts to contact the Over-CR collector daemon running on the"));
printf("%s\n", _("remote UNIX server in order to gather the requested system information."));
printf ("\n\n");
printf("\n\n");
print_usage ();
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HOST_PORT, 'p', myport);
printf(UT_HOST_PORT, 'p', myport);
printf (" %s\n", "-w, --warning=INTEGER");
printf (" %s\n", _("Threshold which will result in a warning status"));
printf (" %s\n", "-c, --critical=INTEGER");
printf (" %s\n", _("Threshold which will result in a critical status"));
printf (" %s\n", "-v, --variable=STRING");
printf (" %s\n", _("Variable to check. Valid variables include:"));
printf (" %s\n", _("LOAD1 = 1 minute average CPU load"));
printf (" %s\n", _("LOAD5 = 5 minute average CPU load"));
printf (" %s\n", _("LOAD15 = 15 minute average CPU load"));
printf (" %s\n", _("DPU<filesys> = percent used disk space on filesystem <filesys>"));
printf (" %s\n", _("PROC<process> = number of running processes with name <process>"));
printf (" %s\n", _("NET<port> = number of active connections on TCP port <port>"));
printf (" %s\n", _("UPTIME = system uptime in seconds"));
printf(" %s\n", "-w, --warning=INTEGER");
printf(" %s\n", _("Threshold which will result in a warning status"));
printf(" %s\n", "-c, --critical=INTEGER");
printf(" %s\n", _("Threshold which will result in a critical status"));
printf(" %s\n", "-v, --variable=STRING");
printf(" %s\n", _("Variable to check. Valid variables include:"));
printf(" %s\n", _("LOAD1 = 1 minute average CPU load"));
printf(" %s\n", _("LOAD5 = 5 minute average CPU load"));
printf(" %s\n", _("LOAD15 = 15 minute average CPU load"));
printf(" %s\n", _("DPU<filesys> = percent used disk space on filesystem <filesys>"));
printf(" %s\n", _("PROC<process> = number of running processes with name <process>"));
printf(" %s\n", _("NET<port> = number of active connections on TCP port <port>"));
printf(" %s\n", _("UPTIME = system uptime in seconds"));
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_VERBOSE);
printf(UT_VERBOSE);
printf ("\n");
printf ("%s\n", _("This plugin requires that Eric Molitors' Over-CR collector daemon be"));
printf ("%s\n", _("running on the remote server."));
printf ("%s\n", _("Over-CR can be downloaded from http://www.molitor.org/overcr"));
printf ("%s\n", _("This plugin was tested with version 0.99.53 of the Over-CR collector"));
printf("\n");
printf("%s\n", _("This plugin requires that Eric Molitors' Over-CR collector daemon be"));
printf("%s\n", _("running on the remote server."));
printf("%s\n", _("Over-CR can be downloaded from http://www.molitor.org/overcr"));
printf("%s\n", _("This plugin was tested with version 0.99.53 of the Over-CR collector"));
printf ("\n");
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("For the available options, the critical threshold value should always be"));
printf (" %s\n", _("higher than the warning threshold value, EXCEPT with the uptime variable"));
printf("\n");
printf("%s\n", _("Notes:"));
printf(" %s\n", _("For the available options, the critical threshold value should always be"));
printf(" %s\n", _("higher than the warning threshold value, EXCEPT with the uptime variable"));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", progname);
}

View file

@ -1,35 +1,35 @@
/*****************************************************************************
*
* Monitoring check_pgsql plugin
*
* License: GPL
* Copyright (c) 1999-2011 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_pgsql plugin
*
* Test whether a PostgreSQL Database is accepting connections.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_pgsql plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_pgsql plugin
*
* Test whether a PostgreSQL Database is accepting connections.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_pgsql";
const char *copyright = "1999-2011";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -40,22 +40,18 @@ const char *email = "devel@monitoring-plugins.org";
#include <libpq-fe.h>
#include <pg_config_manual.h>
#define DEFAULT_DB "template1"
#define DEFAULT_DB "template1"
#define DEFAULT_HOST "127.0.0.1"
/* return the PSQL server version as a 3-tuple */
#define PSQL_SERVER_VERSION3(server_version) \
(server_version) / 10000, \
(server_version) / 100 - (int)((server_version) / 10000) * 100, \
(server_version) - (int)((server_version) / 100) * 100
#define PSQL_SERVER_VERSION3(server_version) \
(server_version) / 10000, (server_version) / 100 - (int)((server_version) / 10000) * 100, \
(server_version) - (int)((server_version) / 100) * 100
/* return true if the given host is a UNIX domain socket */
#define PSQL_IS_UNIX_DOMAIN_SOCKET(host) \
((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host)))
#define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host)))
/* return a 3-tuple identifying a host/port independent of the socket type */
#define PSQL_SOCKET3(host, port) \
((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \
PSQL_IS_UNIX_DOMAIN_SOCKET (host) ? "/.s.PGSQL." : ":", \
port
#define PSQL_SOCKET3(host, port) \
((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port
enum {
DEFAULT_PORT = 5432,
@ -63,33 +59,30 @@ enum {
DEFAULT_CRIT = 8
};
static int process_arguments(int /*argc*/, char ** /*argv*/);
static void print_help(void);
static bool is_pg_logname(char * /*username*/);
static int do_query(PGconn * /*conn*/, char * /*query*/);
void print_usage(void);
static char *pghost = NULL; /* host name of the backend server */
static char *pgport = NULL; /* port of the backend server */
static char *pgoptions = NULL;
static char *pgtty = NULL;
static char dbName[NAMEDATALEN] = DEFAULT_DB;
static char *pguser = NULL;
static char *pgpasswd = NULL;
static char *pgparams = NULL;
static double twarn = (double)DEFAULT_WARN;
static double tcrit = (double)DEFAULT_CRIT;
static char *pgquery = NULL;
static char *pgqueryname = NULL;
static char *query_warning = NULL;
static char *query_critical = NULL;
static thresholds *qthresholds = NULL;
static int verbose = 0;
int process_arguments (int, char **);
int validate_arguments (void);
void print_usage (void);
void print_help (void);
bool is_pg_logname (char *);
int do_query (PGconn *, char *);
char *pghost = NULL; /* host name of the backend server */
char *pgport = NULL; /* port of the backend server */
int default_port = DEFAULT_PORT;
char *pgoptions = NULL;
char *pgtty = NULL;
char dbName[NAMEDATALEN] = DEFAULT_DB;
char *pguser = NULL;
char *pgpasswd = NULL;
char *pgparams = NULL;
double twarn = (double)DEFAULT_WARN;
double tcrit = (double)DEFAULT_CRIT;
char *pgquery = NULL;
#define OPTID_QUERYNAME -1000
char *pgqueryname = NULL;
char *query_warning = NULL;
char *query_critical = NULL;
thresholds *qthresholds = NULL;
int verbose = 0;
/******************************************************************************
@ -141,78 +134,67 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
-@@
******************************************************************************/
int
main (int argc, char **argv)
{
PGconn *conn;
char *conninfo = NULL;
struct timeval start_timeval;
struct timeval end_timeval;
double elapsed_time;
int status = STATE_UNKNOWN;
int query_status = STATE_UNKNOWN;
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* 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 */
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
pgoptions = NULL; /* special options to start up the backend server */
pgtty = NULL; /* debugging tty for the backend server */
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
if (verbose > 2)
printf("Arguments initialized\n");
/* Set signal handling and alarm */
if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
usage4 (_("Cannot catch SIGALRM"));
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
usage4(_("Cannot catch SIGALRM"));
}
alarm (timeout_interval);
alarm(timeout_interval);
char *conninfo = NULL;
if (pgparams)
asprintf (&conninfo, "%s ", pgparams);
asprintf(&conninfo, "%s ", pgparams);
asprintf (&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName);
asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName);
if (pghost)
asprintf (&conninfo, "%s host = '%s'", conninfo, pghost);
asprintf(&conninfo, "%s host = '%s'", conninfo, pghost);
if (pgport)
asprintf (&conninfo, "%s port = '%s'", conninfo, pgport);
asprintf(&conninfo, "%s port = '%s'", conninfo, pgport);
if (pgoptions)
asprintf (&conninfo, "%s options = '%s'", conninfo, pgoptions);
asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions);
/* if (pgtty) -- ignored by PQconnectdb */
if (pguser)
asprintf (&conninfo, "%s user = '%s'", conninfo, pguser);
asprintf(&conninfo, "%s user = '%s'", conninfo, pguser);
if (verbose) /* do not include password (see right below) in output */
printf ("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo,
pgpasswd ? " password = <hidden>" : "");
printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, pgpasswd ? " password = <hidden>" : "");
if (pgpasswd)
asprintf (&conninfo, "%s password = '%s'", conninfo, pgpasswd);
asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd);
/* make a connection to the database */
gettimeofday (&start_timeval, NULL);
conn = PQconnectdb (conninfo);
gettimeofday (&end_timeval, NULL);
struct timeval start_timeval;
gettimeofday(&start_timeval, NULL);
PGconn *conn = PQconnectdb(conninfo);
struct timeval end_timeval;
gettimeofday(&end_timeval, NULL);
while (start_timeval.tv_usec > end_timeval.tv_usec) {
--end_timeval.tv_sec;
end_timeval.tv_usec += 1000000;
}
elapsed_time = (double)(end_timeval.tv_sec - start_timeval.tv_sec)
+ (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
double elapsed_time =
(double)(end_timeval.tv_sec - start_timeval.tv_sec) + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
if (verbose)
printf("Time elapsed: %f\n", elapsed_time);
@ -220,152 +202,139 @@ main (int argc, char **argv)
/* check to see that the backend connection was successfully made */
if (verbose)
printf("Verifying connection\n");
if (PQstatus (conn) == CONNECTION_BAD) {
printf (_("CRITICAL - no connection to '%s' (%s).\n"),
dbName, PQerrorMessage (conn));
PQfinish (conn);
if (PQstatus(conn) == CONNECTION_BAD) {
printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, PQerrorMessage(conn));
PQfinish(conn);
return STATE_CRITICAL;
}
else if (elapsed_time > tcrit) {
int status = STATE_UNKNOWN;
if (elapsed_time > tcrit) {
status = STATE_CRITICAL;
}
else if (elapsed_time > twarn) {
} else if (elapsed_time > twarn) {
status = STATE_WARNING;
}
else {
} else {
status = STATE_OK;
}
if (verbose) {
char *server_host = PQhost (conn);
int server_version = PQserverVersion (conn);
char *server_host = PQhost(conn);
int server_version = PQserverVersion(conn);
printf ("Successfully connected to database %s (user %s) "
"at server %s%s%s (server version: %d.%d.%d, "
"protocol version: %d, pid: %d)\n",
PQdb (conn), PQuser (conn),
PSQL_SOCKET3 (server_host, PQport (conn)),
PSQL_SERVER_VERSION3 (server_version),
PQprotocolVersion (conn), PQbackendPID (conn));
printf("Successfully connected to database %s (user %s) "
"at server %s%s%s (server version: %d.%d.%d, "
"protocol version: %d, pid: %d)\n",
PQdb(conn), PQuser(conn), PSQL_SOCKET3(server_host, PQport(conn)), PSQL_SERVER_VERSION3(server_version),
PQprotocolVersion(conn), PQbackendPID(conn));
}
printf (_(" %s - database %s (%f sec.)|%s\n"),
state_text(status), dbName, elapsed_time,
fperfdata("time", elapsed_time, "s",
!!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false,0));
printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), dbName, elapsed_time,
fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false, 0));
int query_status = STATE_UNKNOWN;
if (pgquery)
query_status = do_query (conn, pgquery);
query_status = do_query(conn, pgquery);
if (verbose)
printf("Closing connection\n");
PQfinish (conn);
PQfinish(conn);
return (pgquery && query_status > status) ? query_status : status;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"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'},
{"option", required_argument, 0, 'o'},
{"query", required_argument, 0, 'q'},
{"queryname", required_argument, 0, OPTID_QUERYNAME},
{"query_critical", required_argument, 0, 'C'},
{"query_warning", required_argument, 0, 'W'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}};
int option = 0;
static struct option longopts[] = {
{"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'},
{"option", required_argument, 0, 'o'},
{"query", required_argument, 0, 'q'},
{"queryname", required_argument, 0, OPTID_QUERYNAME},
{"query_critical", required_argument, 0, 'C'},
{"query_warning", required_argument, 0, 'W'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
while (true) {
int option = 0;
int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option);
while (1) {
c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v",
longopts, &option);
if (c == EOF)
if (option_char == EOF)
break;
switch (c) {
case '?': /* usage */
usage5 ();
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 't': /* timeout period */
if (!is_integer (optarg))
usage2 (_("Timeout interval must be a positive integer"), optarg);
switch (option_char) {
case '?': /* usage */
usage5();
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 't': /* timeout period */
if (!is_integer(optarg))
usage2(_("Timeout interval must be a positive integer"), optarg);
else
timeout_interval = atoi (optarg);
timeout_interval = atoi(optarg);
break;
case 'c': /* critical time threshold */
if (!is_nonnegative (optarg))
usage2 (_("Critical threshold must be a positive integer"), optarg);
case 'c': /* critical time threshold */
if (!is_nonnegative(optarg))
usage2(_("Critical threshold must be a positive integer"), optarg);
else
tcrit = strtod (optarg, NULL);
tcrit = strtod(optarg, NULL);
break;
case 'w': /* warning time threshold */
if (!is_nonnegative (optarg))
usage2 (_("Warning threshold must be a positive integer"), optarg);
case 'w': /* warning time threshold */
if (!is_nonnegative(optarg))
usage2(_("Warning threshold must be a positive integer"), optarg);
else
twarn = strtod (optarg, NULL);
twarn = strtod(optarg, NULL);
break;
case 'C': /* critical query threshold */
case 'C': /* critical query threshold */
query_critical = optarg;
break;
case 'W': /* warning query threshold */
case 'W': /* warning query threshold */
query_warning = optarg;
break;
case 'H': /* host */
if ((*optarg != '/') && (!is_host (optarg)))
usage2 (_("Invalid hostname/address"), optarg);
case 'H': /* host */
if ((*optarg != '/') && (!is_host(optarg)))
usage2(_("Invalid hostname/address"), optarg);
else
pghost = optarg;
break;
case 'P': /* port */
if (!is_integer (optarg))
usage2 (_("Port must be a positive integer"), optarg);
case 'P': /* port */
if (!is_integer(optarg))
usage2(_("Port must be a positive integer"), optarg);
else
pgport = optarg;
break;
case 'd': /* database name */
case 'd': /* database name */
if (strlen(optarg) >= NAMEDATALEN) {
usage2 (_("Database name exceeds the maximum length"), optarg);
usage2(_("Database name exceeds the maximum length"), optarg);
}
snprintf(dbName, NAMEDATALEN, "%s", optarg);
break;
case 'l': /* login name */
if (!is_pg_logname (optarg))
usage2 (_("User name is not valid"), optarg);
case 'l': /* login name */
if (!is_pg_logname(optarg))
usage2(_("User name is not valid"), optarg);
else
pguser = optarg;
break;
case 'p': /* authentication password */
case 'p': /* authentication password */
case 'a':
pgpasswd = optarg;
break;
case 'o':
if (pgparams)
asprintf (&pgparams, "%s %s", pgparams, optarg);
asprintf(&pgparams, "%s %s", pgparams, optarg);
else
asprintf (&pgparams, "%s", optarg);
asprintf(&pgparams, "%s", optarg);
break;
case 'q':
pgquery = optarg;
@ -379,37 +348,8 @@ process_arguments (int argc, char **argv)
}
}
set_thresholds (&qthresholds, query_warning, query_critical);
set_thresholds(&qthresholds, query_warning, query_critical);
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;
}
@ -437,10 +377,8 @@ should be added.</para>
-@@
******************************************************************************/
bool is_pg_logname (char *username) {
if (strlen (username) > NAMEDATALEN - 1)
bool is_pg_logname(char *username) {
if (strlen(username) > NAMEDATALEN - 1)
return (false);
return (true);
}
@ -453,182 +391,155 @@ bool is_pg_logname (char *username) {
-@@
******************************************************************************/
void
print_help (void)
{
void print_help(void) {
char *myport;
xasprintf (&myport, "%d", DEFAULT_PORT);
xasprintf(&myport, "%d", DEFAULT_PORT);
print_revision (progname, NP_VERSION);
print_revision(progname, NP_VERSION);
printf (COPYRIGHT, copyright, email);
printf(COPYRIGHT, copyright, email);
printf (_("Test whether a PostgreSQL Database is accepting connections."));
printf(_("Test whether a PostgreSQL Database is accepting connections."));
printf ("\n\n");
printf("\n\n");
print_usage ();
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HOST_PORT, 'P', myport);
printf(UT_HOST_PORT, 'P', myport);
printf (" %s\n", "-d, --database=STRING");
printf (" %s", _("Database to check "));
printf (_("(default: %s)\n"), DEFAULT_DB);
printf (" %s\n", "-l, --logname = STRING");
printf (" %s\n", _("Login name of user"));
printf (" %s\n", "-p, --password = STRING");
printf (" %s\n", _("Password (BIG SECURITY ISSUE)"));
printf (" %s\n", "-o, --option = STRING");
printf (" %s\n", _("Connection parameters (keyword = value), see below"));
printf(" %s\n", "-d, --database=STRING");
printf(" %s", _("Database to check "));
printf(_("(default: %s)\n"), DEFAULT_DB);
printf(" %s\n", "-l, --logname = STRING");
printf(" %s\n", _("Login name of user"));
printf(" %s\n", "-p, --password = STRING");
printf(" %s\n", _("Password (BIG SECURITY ISSUE)"));
printf(" %s\n", "-o, --option = STRING");
printf(" %s\n", _("Connection parameters (keyword = value), see below"));
printf (UT_WARN_CRIT);
printf(UT_WARN_CRIT);
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (" %s\n", "-q, --query=STRING");
printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
printf (" %s\n", "--queryname=STRING");
printf (" %s\n", _("A name for the query, this string is used instead of the query"));
printf (" %s\n", _("in the long output of the plugin"));
printf (" %s\n", "-W, --query-warning=RANGE");
printf (" %s\n", _("SQL query value to result in warning status (double)"));
printf (" %s\n", "-C, --query-critical=RANGE");
printf (" %s\n", _("SQL query value to result in critical status (double)"));
printf(" %s\n", "-q, --query=STRING");
printf(" %s\n", _("SQL query to run. Only first column in first row will be read"));
printf(" %s\n", "--queryname=STRING");
printf(" %s\n", _("A name for the query, this string is used instead of the query"));
printf(" %s\n", _("in the long output of the plugin"));
printf(" %s\n", "-W, --query-warning=RANGE");
printf(" %s\n", _("SQL query value to result in warning status (double)"));
printf(" %s\n", "-C, --query-critical=RANGE");
printf(" %s\n", _("SQL query value to result in critical status (double)"));
printf (UT_VERBOSE);
printf(UT_VERBOSE);
printf ("\n");
printf (" %s\n", _("All parameters are optional."));
printf (" %s\n", _("This plugin tests a PostgreSQL DBMS to determine whether it is active and"));
printf (" %s\n", _("accepting queries. In its current operation, it simply connects to the"));
printf (" %s\n", _("specified database, and then disconnects. If no database is specified, it"));
printf (" %s\n", _("connects to the template1 database, which is present in every functioning"));
printf (" %s\n\n", _("PostgreSQL DBMS."));
printf("\n");
printf(" %s\n", _("All parameters are optional."));
printf(" %s\n", _("This plugin tests a PostgreSQL DBMS to determine whether it is active and"));
printf(" %s\n", _("accepting queries. In its current operation, it simply connects to the"));
printf(" %s\n", _("specified database, and then disconnects. If no database is specified, it"));
printf(" %s\n", _("connects to the template1 database, which is present in every functioning"));
printf(" %s\n\n", _("PostgreSQL DBMS."));
printf (" %s\n", _("If a query is specified using the -q option, it will be executed after"));
printf (" %s\n", _("connecting to the server. The result from the query has to be numeric."));
printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
printf (" %s\n", _("of the last command is taken into account only. The value of the first"));
printf (" %s\n", _("column in the first row is used as the check result. If a second column is"));
printf (" %s\n", _("present in the result set, this is added to the plugin output with a"));
printf (" %s\n", _("prefix of \"Extra Info:\". This information can be displayed in the system"));
printf (" %s\n\n", _("executing the plugin."));
printf(" %s\n", _("If a query is specified using the -q option, it will be executed after"));
printf(" %s\n", _("connecting to the server. The result from the query has to be numeric."));
printf(" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
printf(" %s\n", _("of the last command is taken into account only. The value of the first"));
printf(" %s\n", _("column in the first row is used as the check result. If a second column is"));
printf(" %s\n", _("present in the result set, this is added to the plugin output with a"));
printf(" %s\n", _("prefix of \"Extra Info:\". This information can be displayed in the system"));
printf(" %s\n\n", _("executing the plugin."));
printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
printf (" %s\n\n", _("for details about how to access internal statistics of the database server."));
printf(" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
printf(" %s\n\n", _("for details about how to access internal statistics of the database server."));
printf (" %s\n", _("For a list of available connection parameters which may be used with the -o"));
printf (" %s\n", _("command line option, see the documentation for PQconnectdb() in the chapter"));
printf (" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be"));
printf (" %s\n", _("used to specify a service name in pg_service.conf to be used for additional"));
printf (" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:"));
printf (" %s\n\n", _("-o 'sslmode=require'."));
printf(" %s\n", _("For a list of available connection parameters which may be used with the -o"));
printf(" %s\n", _("command line option, see the documentation for PQconnectdb() in the chapter"));
printf(" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be"));
printf(" %s\n", _("used to specify a service name in pg_service.conf to be used for additional"));
printf(" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:"));
printf(" %s\n\n", _("-o 'sslmode=require'."));
printf (" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To"));
printf (" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP"));
printf (" %s\n\n", _("connections (start the postmaster with the -i option)."));
printf(" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To"));
printf(" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP"));
printf(" %s\n\n", _("connections (start the postmaster with the -i option)."));
printf (" %s\n", _("Typically, the monitoring user (unless the --logname option is used) should be"));
printf (" %s\n", _("able to connect to the database without a password. The plugin can also send"));
printf (" %s\n", _("a password, but no effort is made to obscure or encrypt the password."));
printf(" %s\n", _("Typically, the monitoring user (unless the --logname option is used) should be"));
printf(" %s\n", _("able to connect to the database without a password. The plugin can also send"));
printf(" %s\n", _("a password, but no effort is made to obscure or encrypt the password."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s [-H <host>] [-P <port>] [-c <critical time>] [-w <warning time>]\n", progname);
printf (" [-t <timeout>] [-d <database>] [-l <logname>] [-p <password>]\n"
"[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s [-H <host>] [-P <port>] [-c <critical time>] [-w <warning time>]\n", progname);
printf(" [-t <timeout>] [-d <database>] [-l <logname>] [-p <password>]\n"
"[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
}
int
do_query (PGconn *conn, char *query)
{
PGresult *res;
int do_query(PGconn *conn, char *query) {
if (verbose)
printf("Executing SQL query \"%s\".\n", query);
PGresult *res = PQexec(conn, query);
char *val_str;
char *extra_info;
double value;
if (PGRES_TUPLES_OK != PQresultStatus(res)) {
printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"), PQerrorMessage(conn));
return STATE_CRITICAL;
}
if (PQntuples(res) < 1) {
printf("QUERY %s - %s.\n", _("WARNING"), _("No rows returned"));
return STATE_WARNING;
}
if (PQnfields(res) < 1) {
printf("QUERY %s - %s.\n", _("WARNING"), _("No columns returned"));
return STATE_WARNING;
}
char *val_str = PQgetvalue(res, 0, 0);
if (!val_str) {
printf("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned"));
return STATE_CRITICAL;
}
char *endptr = NULL;
int my_status = STATE_UNKNOWN;
double value = strtod(val_str, &endptr);
if (verbose)
printf ("Executing SQL query \"%s\".\n", query);
res = PQexec (conn, query);
if (PGRES_TUPLES_OK != PQresultStatus (res)) {
printf (_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"),
PQerrorMessage (conn));
return STATE_CRITICAL;
}
if (PQntuples (res) < 1) {
printf ("QUERY %s - %s.\n", _("WARNING"), _("No rows returned"));
return STATE_WARNING;
}
if (PQnfields (res) < 1) {
printf ("QUERY %s - %s.\n", _("WARNING"), _("No columns returned"));
return STATE_WARNING;
}
val_str = PQgetvalue (res, 0, 0);
if (! val_str) {
printf ("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned"));
return STATE_CRITICAL;
}
value = strtod (val_str, &endptr);
if (verbose)
printf ("Query result: %f\n", value);
printf("Query result: %f\n", value);
if (endptr == val_str) {
printf ("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
return STATE_CRITICAL;
}
else if ((endptr != NULL) && (*endptr != '\0')) {
if ((endptr != NULL) && (*endptr != '\0')) {
if (verbose)
printf ("Garbage after value: %s.\n", endptr);
printf("Garbage after value: %s.\n", endptr);
}
my_status = get_status (value, qthresholds);
printf ("QUERY %s - ",
(my_status == STATE_OK)
? _("OK")
: (my_status == STATE_WARNING)
? _("WARNING")
: (my_status == STATE_CRITICAL)
? _("CRITICAL")
: _("UNKNOWN"));
if(pgqueryname) {
printf (_("%s returned %f"), pgqueryname, value);
}
else {
printf (_("'%s' returned %f"), query, value);
int my_status = get_status(value, qthresholds);
printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK")
: (my_status == STATE_WARNING) ? _("WARNING")
: (my_status == STATE_CRITICAL) ? _("CRITICAL")
: _("UNKNOWN"));
if (pgqueryname) {
printf(_("%s returned %f"), pgqueryname, value);
} else {
printf(_("'%s' returned %f"), query, value);
}
printf ("|query=%f;%s;%s;;\n", value,
query_warning ? query_warning : "",
query_critical ? query_critical : "");
if (PQnfields (res) > 1) {
extra_info = PQgetvalue (res, 0, 1);
printf("|query=%f;%s;%s;;\n", value, query_warning ? query_warning : "", query_critical ? query_critical : "");
if (PQnfields(res) > 1) {
char *extra_info = PQgetvalue(res, 0, 1);
if (extra_info != NULL) {
printf ("Extra Info: %s\n", extra_info);
printf("Extra Info: %s\n", extra_info);
}
}
return my_status;
}

View file

@ -1,35 +1,35 @@
/*****************************************************************************
*
* Monitoring check_ping plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ping plugin
*
* Use the ping program to check connection statistics for a remote host.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_ping plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_ping plugin
*
* Use the ping program to check connection statistics for a remote host.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_ping";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -39,77 +39,73 @@ const char *email = "devel@monitoring-plugins.org";
#include <signal.h>
#define WARN_DUPLICATES "DUPLICATES FOUND! "
#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
#define WARN_DUPLICATES "DUPLICATES FOUND! "
#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
enum {
UNKNOWN_PACKET_LOSS = 200, /* 200% */
DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */
UNKNOWN_PACKET_LOSS = 200, /* 200% */
DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */
};
int process_arguments (int, char **);
int get_threshold (char *, float *, int *);
int validate_arguments (void);
int run_ping (const char *cmd, const char *addr);
int error_scan (char buf[MAX_INPUT_BUFFER], const char *addr);
void print_usage (void);
void print_help (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static int get_threshold(char * /*arg*/, float * /*trta*/, int * /*tpl*/);
static int validate_arguments(void);
static int run_ping(const char *cmd, const char *addr);
static int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr);
static void print_help(void);
void print_usage(void);
bool display_html = false;
int wpl = UNKNOWN_PACKET_LOSS;
int cpl = UNKNOWN_PACKET_LOSS;
float wrta = UNKNOWN_TRIP_TIME;
float crta = UNKNOWN_TRIP_TIME;
char **addresses = NULL;
int n_addresses = 0;
int max_addr = 1;
int max_packets = -1;
int verbose = 0;
static bool display_html = false;
static int wpl = UNKNOWN_PACKET_LOSS;
static int cpl = UNKNOWN_PACKET_LOSS;
static float wrta = UNKNOWN_TRIP_TIME;
static float crta = UNKNOWN_TRIP_TIME;
static char **addresses = NULL;
static int n_addresses = 0;
static int max_addr = 1;
static int max_packets = -1;
static int verbose = 0;
float rta = UNKNOWN_TRIP_TIME;
int pl = UNKNOWN_PACKET_LOSS;
static float rta = UNKNOWN_TRIP_TIME;
static int pl = UNKNOWN_PACKET_LOSS;
char *warn_text;
static char *warn_text;
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
char *cmd = NULL;
char *rawcmd = NULL;
int result = STATE_UNKNOWN;
int this_result = STATE_UNKNOWN;
int i;
setlocale (LC_ALL, "");
setlocale (LC_NUMERIC, "C");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
addresses = malloc (sizeof(char*) * max_addr);
addresses = malloc(sizeof(char *) * max_addr);
addresses[0] = NULL;
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
/* Set signal handling and alarm */
if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
usage4 (_("Cannot catch SIGALRM"));
if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
usage4(_("Cannot catch SIGALRM"));
}
/* If ./configure finds ping has timeout values, set plugin alarm slightly
* higher so that we can use response from command line ping */
#if defined(PING_PACKETS_FIRST) && defined(PING_HAS_TIMEOUT)
alarm (timeout_interval + 1);
alarm(timeout_interval + 1);
#else
alarm (timeout_interval);
alarm(timeout_interval);
#endif
for (i = 0 ; i < n_addresses ; i++) {
for (i = 0; i < n_addresses; i++) {
#ifdef PING6_COMMAND
if (address_family != AF_INET && is_inet6_addr(addresses[i]))
@ -120,27 +116,26 @@ main (int argc, char **argv)
rawcmd = strdup(PING_COMMAND);
#endif
/* does the host address of number of packets argument come first? */
/* does the host address of number of packets argument come first? */
#ifdef PING_PACKETS_FIRST
# ifdef PING_HAS_TIMEOUT
xasprintf (&cmd, rawcmd, timeout_interval, max_packets, addresses[i]);
# else
xasprintf (&cmd, rawcmd, max_packets, addresses[i]);
# endif
# ifdef PING_HAS_TIMEOUT
xasprintf(&cmd, rawcmd, timeout_interval, max_packets, addresses[i]);
# else
xasprintf(&cmd, rawcmd, max_packets, addresses[i]);
# endif
#else
xasprintf (&cmd, rawcmd, addresses[i], max_packets);
xasprintf(&cmd, rawcmd, addresses[i], max_packets);
#endif
if (verbose >= 2)
printf ("CMD: %s\n", cmd);
printf("CMD: %s\n", cmd);
/* run the command */
this_result = run_ping (cmd, addresses[i]);
this_result = run_ping(cmd, addresses[i]);
if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) {
printf ("%s\n", cmd);
die (STATE_UNKNOWN,
_("CRITICAL - Could not interpret output from ping command\n"));
printf("%s\n", cmd);
die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n"));
}
if (pl >= cpl || rta >= crta || rta < 0)
@ -148,267 +143,241 @@ main (int argc, char **argv)
else if (pl >= wpl || rta >= wrta)
this_result = STATE_WARNING;
else if (pl >= 0 && rta >= 0)
this_result = max_state (STATE_OK, this_result);
this_result = max_state(STATE_OK, this_result);
if (n_addresses > 1 && this_result != STATE_UNKNOWN)
die (STATE_OK, "%s is alive\n", addresses[i]);
die(STATE_OK, "%s is alive\n", addresses[i]);
if (display_html == true)
printf ("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]);
printf("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]);
if (pl == 100)
printf (_("PING %s - %sPacket loss = %d%%"), state_text (this_result), warn_text,
pl);
printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, pl);
else
printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"),
state_text (this_result), warn_text, pl, rta);
printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, pl, rta);
if (display_html == true)
printf ("</A>");
printf("</A>");
/* Print performance data */
if (pl != 100) {
printf("|%s", fperfdata ("rta", (double) rta, "ms",
wrta>0?true:false, wrta,
crta>0?true:false, crta,
true, 0, false, 0));
printf("|%s",
fperfdata("rta", (double)rta, "ms", wrta > 0 ? true : false, wrta, crta > 0 ? true : false, crta, true, 0, false, 0));
} else {
printf("| rta=U;%f;%f;;", wrta, crta);
}
printf(" %s\n", perfdata ("pl", (long) pl, "%",
wpl>0?true:false, wpl,
cpl>0?true:false, cpl,
true, 0, false, 0));
printf(" %s\n", perfdata("pl", (long)pl, "%", wpl > 0 ? true : false, wpl, cpl > 0 ? true : false, cpl, true, 0, false, 0));
if (verbose >= 2)
printf ("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl);
printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl);
result = max_state (result, this_result);
free (rawcmd);
free (cmd);
result = max_state(result, this_result);
free(rawcmd);
free(cmd);
}
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int process_arguments(int argc, char **argv) {
int c = 1;
char *ptr;
int option = 0;
static struct option longopts[] = {
STD_LONG_OPTS,
{"packets", required_argument, 0, 'p'},
{"nohtml", no_argument, 0, 'n'},
{"link", no_argument, 0, 'L'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{0, 0, 0, 0}
};
static struct option longopts[] = {STD_LONG_OPTS,
{"packets", required_argument, 0, 'p'},
{"nohtml", no_argument, 0, 'n'},
{"link", no_argument, 0, 'L'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{0, 0, 0, 0}};
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");
if (strcmp("-to", argv[c]) == 0)
strcpy(argv[c], "-t");
if (strcmp("-nohtml", argv[c]) == 0)
strcpy(argv[c], "-n");
}
while (1) {
c = getopt_long (argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
c = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
if (c == -1 || c == EOF)
break;
switch (c) {
case '?': /* usage */
usage5 ();
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case '?': /* usage */
usage5();
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
break;
case 't': /* timeout period */
timeout_interval = atoi (optarg);
case 't': /* timeout period */
timeout_interval = atoi(optarg);
break;
case 'v': /* verbose mode */
case 'v': /* verbose mode */
verbose++;
break;
case '4': /* IPv4 only */
case '4': /* IPv4 only */
address_family = AF_INET;
break;
case '6': /* IPv6 only */
case '6': /* IPv6 only */
#ifdef USE_IPV6
address_family = AF_INET6;
#else
usage (_("IPv6 support not available\n"));
usage(_("IPv6 support not available\n"));
#endif
break;
case 'H': /* hostname */
ptr=optarg;
case 'H': /* hostname */
ptr = optarg;
while (1) {
n_addresses++;
if (n_addresses > max_addr) {
max_addr *= 2;
addresses = realloc (addresses, sizeof(char*) * max_addr);
addresses = realloc(addresses, sizeof(char *) * max_addr);
if (addresses == NULL)
die (STATE_UNKNOWN, _("Could not realloc() addresses\n"));
die(STATE_UNKNOWN, _("Could not realloc() addresses\n"));
}
addresses[n_addresses-1] = ptr;
if ((ptr = index (ptr, ','))) {
strcpy (ptr, "");
addresses[n_addresses - 1] = ptr;
if ((ptr = index(ptr, ','))) {
strcpy(ptr, "");
ptr += sizeof(char);
} else {
break;
}
}
break;
case 'p': /* number of packets to send */
if (is_intnonneg (optarg))
max_packets = atoi (optarg);
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);
usage2(_("<max_packets> (%s) must be a non-negative number\n"), optarg);
break;
case 'n': /* no HTML */
case 'n': /* no HTML */
display_html = false;
break;
case 'L': /* show HTML */
case 'L': /* show HTML */
display_html = true;
break;
case 'c':
get_threshold (optarg, &crta, &cpl);
get_threshold(optarg, &crta, &cpl);
break;
case 'w':
get_threshold (optarg, &wrta, &wpl);
get_threshold(optarg, &wrta, &wpl);
break;
}
}
c = optind;
if (c == argc)
return validate_arguments ();
return validate_arguments();
if (addresses[0] == NULL) {
if (!is_host (argv[c])) {
usage2 (_("Invalid hostname/address"), argv[c]);
if (!is_host(argv[c])) {
usage2(_("Invalid hostname/address"), argv[c]);
} else {
addresses[0] = argv[c++];
n_addresses++;
if (c == argc)
return validate_arguments ();
return validate_arguments();
}
}
if (wpl == UNKNOWN_PACKET_LOSS) {
if (!is_intpercent (argv[c])) {
printf (_("<wpl> (%s) must be an integer percentage\n"), argv[c]);
if (!is_intpercent(argv[c])) {
printf(_("<wpl> (%s) must be an integer percentage\n"), argv[c]);
return ERROR;
} else {
wpl = atoi (argv[c++]);
wpl = atoi(argv[c++]);
if (c == argc)
return validate_arguments ();
return validate_arguments();
}
}
if (cpl == UNKNOWN_PACKET_LOSS) {
if (!is_intpercent (argv[c])) {
printf (_("<cpl> (%s) must be an integer percentage\n"), argv[c]);
if (!is_intpercent(argv[c])) {
printf(_("<cpl> (%s) must be an integer percentage\n"), argv[c]);
return ERROR;
} else {
cpl = atoi (argv[c++]);
cpl = atoi(argv[c++]);
if (c == argc)
return validate_arguments ();
return validate_arguments();
}
}
if (wrta < 0.0) {
if (is_negative (argv[c])) {
printf (_("<wrta> (%s) must be a non-negative number\n"), argv[c]);
if (is_negative(argv[c])) {
printf(_("<wrta> (%s) must be a non-negative number\n"), argv[c]);
return ERROR;
} else {
wrta = atof (argv[c++]);
wrta = atof(argv[c++]);
if (c == argc)
return validate_arguments ();
return validate_arguments();
}
}
if (crta < 0.0) {
if (is_negative (argv[c])) {
printf (_("<crta> (%s) must be a non-negative number\n"), argv[c]);
if (is_negative(argv[c])) {
printf(_("<crta> (%s) must be a non-negative number\n"), argv[c]);
return ERROR;
} else {
crta = atof (argv[c++]);
crta = atof(argv[c++]);
if (c == argc)
return validate_arguments ();
return validate_arguments();
}
}
if (max_packets == -1) {
if (is_intnonneg (argv[c])) {
max_packets = atoi (argv[c++]);
if (is_intnonneg(argv[c])) {
max_packets = atoi(argv[c++]);
} else {
printf (_("<max_packets> (%s) must be a non-negative number\n"), argv[c]);
printf(_("<max_packets> (%s) must be a non-negative number\n"), argv[c]);
return ERROR;
}
}
return validate_arguments ();
return validate_arguments();
}
int
get_threshold (char *arg, float *trta, int *tpl)
{
if (is_intnonneg (arg) && sscanf (arg, "%f", trta) == 1)
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)
else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2)
return OK;
else if (strstr (arg, "%") && sscanf (arg, "%d%%", tpl) == 1)
else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1)
return OK;
usage2 (_("%s: Warning threshold must be integer or percentage!\n\n"), arg);
usage2(_("%s: Warning threshold must be integer or percentage!\n\n"), arg);
return STATE_UNKNOWN;
}
int
validate_arguments ()
{
int validate_arguments() {
float max_seconds;
int i;
if (wrta < 0.0) {
printf (_("<wrta> was not set\n"));
printf(_("<wrta> was not set\n"));
return ERROR;
}
else if (crta < 0.0) {
printf (_("<crta> was not set\n"));
} else if (crta < 0.0) {
printf(_("<crta> was not set\n"));
return ERROR;
}
else if (wpl == UNKNOWN_PACKET_LOSS) {
printf (_("<wpl> was not set\n"));
} 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"));
} 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);
} 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);
} else if (wpl > cpl) {
printf(_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), wpl, cpl);
return ERROR;
}
@ -419,68 +388,61 @@ validate_arguments ()
if (max_seconds > timeout_interval)
timeout_interval = (int)max_seconds;
for (i=0; i<n_addresses; i++) {
for (i = 0; i < n_addresses; i++) {
if (!is_host(addresses[i]))
usage2 (_("Invalid hostname/address"), addresses[i]);
usage2(_("Invalid hostname/address"), addresses[i]);
}
if (n_addresses == 0) {
usage (_("You must specify a server address or host name"));
usage(_("You must specify a server address or host name"));
}
return OK;
}
int
run_ping (const char *cmd, const char *addr)
{
int run_ping(const char *cmd, const char *addr) {
char buf[MAX_INPUT_BUFFER];
int result = STATE_UNKNOWN;
int match;
if ((child_process = spopen (cmd)) == NULL)
die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
if ((child_process = spopen(cmd)) == NULL)
die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
if (child_stderr == NULL)
printf (_("Cannot open stderr for %s\n"), cmd);
printf(_("Cannot open stderr for %s\n"), cmd);
while (fgets (buf, MAX_INPUT_BUFFER - 1, child_process)) {
while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) {
if (verbose >= 3)
printf("Output: %s", buf);
result = max_state (result, error_scan (buf, addr));
result = max_state(result, error_scan(buf, addr));
/* get the percent loss statistics */
match = 0;
if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% packet loss%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% loss, time%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d received, %d%% packet loss, time%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
(sscanf(buf,"%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
(sscanf(buf,"%*[^(](%d%% %*[^)])%n",&pl,&match) && match)
)
if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
(sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
(sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match))
continue;
/* get the round trip average */
else
if((sscanf(buf,"round-trip min/avg/max = %*f/%f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"round-trip (ms) min/avg/max = %*f/%f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
(sscanf(buf,"rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n",&rta,&match) && match) ||
(sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match)
)
else if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
(sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &rta, &match) && match) ||
(sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match))
continue;
}
@ -490,16 +452,14 @@ run_ping (const char *cmd, const char *addr)
/* check stderr, setting at least WARNING if there is output here */
/* Add warning into warn_text */
while (fgets (buf, MAX_INPUT_BUFFER - 1, child_stderr)) {
if (
! strstr(buf,"WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP")
&& ! strstr(buf,"Warning: time of day goes back")
while (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr)) {
if (!strstr(buf, "WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP") && !strstr(buf, "Warning: time of day goes back")
) {
if (verbose >= 3) {
printf("Got stderr: %s", buf);
}
if ((result=error_scan(buf, addr)) == STATE_OK) {
if ((result = error_scan(buf, addr)) == STATE_OK) {
result = STATE_WARNING;
if (warn_text == NULL) {
warn_text = strdup(_("System call sent warnings to stderr "));
@ -510,10 +470,9 @@ run_ping (const char *cmd, const char *addr)
}
}
(void) fclose (child_stderr);
(void)fclose(child_stderr);
spclose (child_process);
spclose(child_process);
if (warn_text == NULL)
warn_text = strdup("");
@ -521,100 +480,86 @@ run_ping (const char *cmd, const char *addr)
return result;
}
int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) {
if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route"))
die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr);
else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable"))
die(STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr);
else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable"))
die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr);
else if (strstr(buf, "Destination Protocol Unreachable"))
die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr);
else if (strstr(buf, "Destination Net Prohibited"))
die(STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr);
else if (strstr(buf, "Destination Host Prohibited"))
die(STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr);
else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited"))
die(STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr);
else if (strstr(buf, "unknown host"))
die(STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
die(STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
else if (strstr(buf, "Destination unreachable: "))
die(STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
int
error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
{
if (strstr (buf, "Network is unreachable") ||
strstr (buf, "Destination Net Unreachable") ||
strstr (buf, "No route")
)
die (STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr);
else if (strstr (buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable"))
die (STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr);
else if (strstr (buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable"))
die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr);
else if (strstr (buf, "Destination Protocol Unreachable"))
die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr);
else if (strstr (buf, "Destination Net Prohibited"))
die (STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr);
else if (strstr (buf, "Destination Host Prohibited"))
die (STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr);
else if (strstr (buf, "Packet filtered") || strstr(buf, "Administratively prohibited"))
die (STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr);
else if (strstr (buf, "unknown host" ))
die (STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
else if (strstr (buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
die (STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
else if (strstr (buf, "Destination unreachable: "))
die (STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
if (strstr (buf, "(DUP!)") || strstr (buf, "DUPLICATES FOUND")) {
if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) {
if (warn_text == NULL)
warn_text = strdup (_(WARN_DUPLICATES));
else if (! strstr (warn_text, _(WARN_DUPLICATES)) &&
xasprintf (&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1)
die (STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
warn_text = strdup(_(WARN_DUPLICATES));
else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1)
die(STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
return (STATE_WARNING);
}
return (STATE_OK);
}
void print_help(void) {
print_revision(progname, NP_VERSION);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf(_("Use ping to check connection statistics for a remote host."));
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf("\n\n");
printf (_("Use ping to check connection statistics for a remote host."));
print_usage();
printf ("\n\n");
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
print_usage ();
printf(UT_IPv46);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(" %s\n", "-H, --hostname=HOST");
printf(" %s\n", _("host to ping"));
printf(" %s\n", "-w, --warning=THRESHOLD");
printf(" %s\n", _("warning threshold pair"));
printf(" %s\n", "-c, --critical=THRESHOLD");
printf(" %s\n", _("critical threshold pair"));
printf(" %s\n", "-p, --packets=INTEGER");
printf(" %s ", _("number of ICMP ECHO packets to send"));
printf(_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
printf(" %s\n", "-L, --link");
printf(" %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
printf (UT_IPv46);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (" %s\n", "-H, --hostname=HOST");
printf (" %s\n", _("host to ping"));
printf (" %s\n", "-w, --warning=THRESHOLD");
printf (" %s\n", _("warning threshold pair"));
printf (" %s\n", "-c, --critical=THRESHOLD");
printf (" %s\n", _("critical threshold pair"));
printf (" %s\n", "-p, --packets=INTEGER");
printf (" %s ", _("number of ICMP ECHO packets to send"));
printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
printf (" %s\n", "-L, --link");
printf (" %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
printf("\n");
printf("%s\n", _("THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel"));
printf("%s\n", _("time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the"));
printf("%s\n", _("percentage of packet loss to trigger an alarm state."));
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf("\n");
printf("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss"));
printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output"));
printf("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in"));
printf("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/"));
printf ("\n");
printf ("%s\n", _("THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel"));
printf ("%s\n", _("time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the"));
printf ("%s\n", _("percentage of packet loss to trigger an alarm state."));
printf ("\n");
printf ("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss"));
printf ("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output"));
printf ("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in"));
printf ("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/"));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n", progname);
printf (" [-p packets] [-t timeout] [-4|-6]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n", progname);
printf(" [-p packets] [-t timeout] [-4|-6]\n");
}

View file

@ -3,7 +3,7 @@
* Monitoring check_procs plugin
*
* License: GPL
* Copyright (c) 2000-2008 Monitoring Plugins Development Team
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -36,7 +36,7 @@
const char *progname = "check_procs";
const char *program_name = "check_procs"; /* Required for coreutils libs */
const char *copyright = "2000-2008";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"

View file

@ -3,7 +3,7 @@
* Monitoring check_radius plugin
*
* License: GPL
* Copyright (c) 1999-2008 Monitoring Plugins Development Team
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -29,7 +29,7 @@
*****************************************************************************/
const char *progname = "check_radius";
const char *copyright = "2000-2008";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"

View file

@ -1,35 +1,35 @@
/*****************************************************************************
*
* Monitoring check_real plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_real plugin
*
* This plugin tests the REAL service on the specified host.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_real plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_real plugin
*
* This plugin tests the REAL service on the specified host.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_real";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -37,121 +37,111 @@ const char *email = "devel@monitoring-plugins.org";
#include "utils.h"
enum {
PORT = 554
PORT = 554
};
#define EXPECT "RTSP/1."
#define URL ""
#define EXPECT "RTSP/1."
#define URL ""
int process_arguments (int, char **);
int validate_arguments (void);
void print_help (void);
void print_usage (void);
static int process_arguments(int, char **);
static void print_help(void);
void print_usage(void);
int server_port = PORT;
char *server_address;
char *host_name;
char *server_url = NULL;
char *server_expect;
int warning_time = 0;
bool check_warning_time = false;
int critical_time = 0;
bool check_critical_time = false;
bool verbose = false;
static int server_port = PORT;
static char *server_address;
static char *host_name;
static char *server_url = NULL;
static char *server_expect;
static int warning_time = 0;
static bool check_warning_time = false;
static int critical_time = 0;
static bool check_critical_time = false;
static bool verbose = false;
int
main (int argc, char **argv)
{
int sd;
int result = STATE_UNKNOWN;
char buffer[MAX_INPUT_BUFFER];
char *status_line = NULL;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
/* initialize alarm signal handling */
signal (SIGALRM, socket_timeout_alarm_handler);
signal(SIGALRM, socket_timeout_alarm_handler);
/* set socket timeout */
alarm (socket_timeout);
time (&start_time);
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)
die (STATE_CRITICAL, _("Unable to connect to %s on port %d\n"),
server_address, server_port);
int socket;
if (my_tcp_connect(server_address, server_port, &socket) != STATE_OK)
die(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\r\n", host_name, server_port);
result = send (sd, buffer, strlen (buffer), 0);
char buffer[MAX_INPUT_BUFFER];
sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", host_name, server_port);
int result = send(socket, buffer, strlen(buffer), 0);
/* send the header sync */
sprintf (buffer, "CSeq: 1\r\n");
result = send (sd, buffer, strlen (buffer), 0);
sprintf(buffer, "CSeq: 1\r\n");
result = send(socket, buffer, strlen(buffer), 0);
/* send a newline so the server knows we're done with the request */
sprintf (buffer, "\r\n");
result = send (sd, buffer, strlen (buffer), 0);
sprintf(buffer, "\r\n");
result = send(socket, buffer, strlen(buffer), 0);
/* watch for the REAL connection string */
result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
/* return a CRITICAL status if we couldn't read any data */
if (result == -1)
die (STATE_CRITICAL, _("No data received from %s\n"), host_name);
die(STATE_CRITICAL, _("No data received from %s\n"), host_name);
char *status_line = NULL;
/* make sure we find the response we are looking for */
if (!strstr (buffer, server_expect)) {
if (!strstr(buffer, server_expect)) {
if (server_port == PORT)
printf ("%s\n", _("Invalid REAL response received from host"));
printf("%s\n", _("Invalid REAL response received from host"));
else
printf (_("Invalid REAL response received from host on port %d\n"),
server_port);
}
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);
time(&end_time);
result = STATE_OK;
status_line = (char *) strtok (buffer, "\n");
status_line = (char *)strtok(buffer, "\n");
if (strstr (status_line, "200"))
if (strstr(status_line, "200"))
result = STATE_OK;
/* client errors result in a warning state */
else if (strstr (status_line, "400"))
else if (strstr(status_line, "400"))
result = STATE_WARNING;
else if (strstr (status_line, "401"))
else if (strstr(status_line, "401"))
result = STATE_WARNING;
else if (strstr (status_line, "402"))
else if (strstr(status_line, "402"))
result = STATE_WARNING;
else if (strstr (status_line, "403"))
else if (strstr(status_line, "403"))
result = STATE_WARNING;
else if (strstr (status_line, "404"))
else if (strstr(status_line, "404"))
result = STATE_WARNING;
/* server errors result in a critical state */
else if (strstr (status_line, "500"))
else if (strstr(status_line, "500"))
result = STATE_CRITICAL;
else if (strstr (status_line, "501"))
else if (strstr(status_line, "501"))
result = STATE_CRITICAL;
else if (strstr (status_line, "502"))
else if (strstr(status_line, "502"))
result = STATE_CRITICAL;
else if (strstr (status_line, "503"))
else if (strstr(status_line, "503"))
result = STATE_CRITICAL;
else
@ -159,74 +149,70 @@ main (int argc, char **argv)
}
/* Part II - Check stream exists and is ok */
if ((result == STATE_OK )&& (server_url != NULL) ) {
if ((result == STATE_OK) && (server_url != NULL)) {
/* Part I - Server Check */
/* send the DESCRIBE request */
sprintf (buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", host_name,
server_port, server_url);
result = send (sd, buffer, strlen (buffer), 0);
sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", host_name, server_port, server_url);
result = send(socket, buffer, strlen(buffer), 0);
/* send the header sync */
sprintf (buffer, "CSeq: 2\r\n");
result = send (sd, buffer, strlen (buffer), 0);
sprintf(buffer, "CSeq: 2\r\n");
result = send(socket, buffer, strlen(buffer), 0);
/* send a newline so the server knows we're done with the request */
sprintf (buffer, "\r\n");
result = send (sd, buffer, strlen (buffer), 0);
sprintf(buffer, "\r\n");
result = send(socket, buffer, strlen(buffer), 0);
/* watch for the REAL connection string */
result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
buffer[result] = '\0'; /* null terminate received buffer */
/* return a CRITICAL status if we couldn't read any data */
if (result == -1) {
printf (_("No data received from host\n"));
printf(_("No data received from host\n"));
result = STATE_CRITICAL;
}
else {
} else {
/* make sure we find the response we are looking for */
if (!strstr (buffer, server_expect)) {
if (!strstr(buffer, server_expect)) {
if (server_port == PORT)
printf ("%s\n", _("Invalid REAL response received from host"));
printf("%s\n", _("Invalid REAL response received from host"));
else
printf (_("Invalid REAL response received from host on port %d\n"),
server_port);
}
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);
time(&end_time);
result = STATE_OK;
status_line = (char *) strtok (buffer, "\n");
status_line = (char *)strtok(buffer, "\n");
if (strstr (status_line, "200"))
if (strstr(status_line, "200"))
result = STATE_OK;
/* client errors result in a warning state */
else if (strstr (status_line, "400"))
else if (strstr(status_line, "400"))
result = STATE_WARNING;
else if (strstr (status_line, "401"))
else if (strstr(status_line, "401"))
result = STATE_WARNING;
else if (strstr (status_line, "402"))
else if (strstr(status_line, "402"))
result = STATE_WARNING;
else if (strstr (status_line, "403"))
else if (strstr(status_line, "403"))
result = STATE_WARNING;
else if (strstr (status_line, "404"))
else if (strstr(status_line, "404"))
result = STATE_WARNING;
/* server errors result in a critical state */
else if (strstr (status_line, "500"))
else if (strstr(status_line, "500"))
result = STATE_CRITICAL;
else if (strstr (status_line, "501"))
else if (strstr(status_line, "501"))
result = STATE_CRITICAL;
else if (strstr (status_line, "502"))
else if (strstr(status_line, "502"))
result = STATE_CRITICAL;
else if (strstr (status_line, "503"))
else if (strstr(status_line, "503"))
result = STATE_CRITICAL;
else
@ -238,217 +224,177 @@ main (int argc, char **argv)
/* Return results */
if (result == STATE_OK) {
if (check_critical_time
&& (end_time - start_time) > critical_time) result = STATE_CRITICAL;
else if (check_warning_time
&& (end_time - start_time) > warning_time) result =
STATE_WARNING;
if (check_critical_time && (end_time - start_time) > critical_time)
result = STATE_CRITICAL;
else if (check_warning_time && (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"),
state_text (result),
(int) (end_time - start_time));
}
else
printf ("%s\n", status_line);
printf(_("REAL %s - %d second response time\n"), state_text(result), (int)(end_time - start_time));
} else
printf("%s\n", status_line);
/* close the connection */
close (sd);
close(socket);
/* reset the alarm */
alarm (0);
alarm(0);
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int option = 0;
static struct option longopts[] = {
{"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}
};
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"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}};
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");
for (int i = 1; i < argc; i++) {
if (strcmp("-to", argv[i]) == 0)
strcpy(argv[i], "-t");
else if (strcmp("-wt", argv[i]) == 0)
strcpy(argv[i], "-w");
else if (strcmp("-ct", argv[i]) == 0)
strcpy(argv[i], "-c");
}
while (1) {
c = getopt_long (argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts,
&option);
int option_char;
while (true) {
int option = 0;
option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option);
if (c == -1 || c == EOF)
if (option_char == -1 || option_char == EOF)
break;
switch (c) {
case 'I': /* hostname */
case 'H': /* hostname */
switch (option_char) {
case 'I': /* hostname */
case 'H': /* hostname */
if (server_address)
break;
else if (is_host (optarg))
else if (is_host(optarg))
server_address = optarg;
else
usage2 (_("Invalid hostname/address"), optarg);
usage2(_("Invalid hostname/address"), optarg);
break;
case 'e': /* string to expect in response header */
case 'e': /* string to expect in response header */
server_expect = optarg;
break;
case 'u': /* server URL */
case 'u': /* server URL */
server_url = optarg;
break;
case 'p': /* port */
if (is_intpos (optarg)) {
server_port = atoi (optarg);
}
else {
usage4 (_("Port must be a positive integer"));
case 'p': /* port */
if (is_intpos(optarg)) {
server_port = atoi(optarg);
} else {
usage4(_("Port must be a positive integer"));
}
break;
case 'w': /* warning time threshold */
if (is_intnonneg (optarg)) {
warning_time = atoi (optarg);
case 'w': /* warning time threshold */
if (is_intnonneg(optarg)) {
warning_time = atoi(optarg);
check_warning_time = true;
}
else {
usage4 (_("Warning time must be a positive integer"));
} else {
usage4(_("Warning time must be a positive integer"));
}
break;
case 'c': /* critical time threshold */
if (is_intnonneg (optarg)) {
critical_time = atoi (optarg);
case 'c': /* critical time threshold */
if (is_intnonneg(optarg)) {
critical_time = atoi(optarg);
check_critical_time = true;
}
else {
usage4 (_("Critical time must be a positive integer"));
} else {
usage4(_("Critical time must be a positive integer"));
}
break;
case 'v': /* verbose */
case 'v': /* verbose */
verbose = true;
break;
case 't': /* timeout */
if (is_intnonneg (optarg)) {
socket_timeout = atoi (optarg);
}
else {
usage4 (_("Timeout interval must be a positive integer"));
case 't': /* timeout */
if (is_intnonneg(optarg)) {
socket_timeout = atoi(optarg);
} else {
usage4(_("Timeout interval must be a positive integer"));
}
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case '?': /* usage */
usage5 ();
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case '?': /* usage */
usage5();
}
}
c = optind;
if (server_address==NULL && argc>c) {
if (is_host (argv[c])) {
server_address = argv[c++];
}
else {
usage2 (_("Invalid hostname/address"), argv[c]);
option_char = optind;
if (server_address == NULL && argc > option_char) {
if (is_host(argv[option_char])) {
server_address = argv[option_char++];
} else {
usage2(_("Invalid hostname/address"), argv[option_char]);
}
}
if (server_address==NULL)
usage4 (_("You must provide a server to check"));
if (server_address == NULL)
usage4(_("You must provide a server to check"));
if (host_name==NULL)
host_name = strdup (server_address);
if (host_name == NULL)
host_name = strdup(server_address);
if (server_expect == NULL)
server_expect = strdup(EXPECT);
return validate_arguments ();
}
int
validate_arguments (void)
{
return OK;
}
void
print_help (void)
{
void print_help(void) {
char *myport;
xasprintf (&myport, "%d", PORT);
xasprintf(&myport, "%d", PORT);
print_revision (progname, NP_VERSION);
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 1999 Pedro Leite <leite@cic.ua.pt>\n");
printf (COPYRIGHT, copyright, email);
printf("Copyright (c) 1999 Pedro Leite <leite@cic.ua.pt>\n");
printf(COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin tests the REAL service on the specified host."));
printf("%s\n", _("This plugin tests the REAL service on the specified host."));
printf ("\n\n");
printf("\n\n");
print_usage ();
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HOST_PORT, 'p', myport);
printf(UT_HOST_PORT, 'p', myport);
printf (" %s\n", "-u, --url=STRING");
printf (" %s\n", _("Connect to this url"));
printf (" %s\n", "-e, --expect=STRING");
printf (_("String to expect in first line of server response (default: %s)\n"),
EXPECT);
printf(" %s\n", "-u, --url=STRING");
printf(" %s\n", _("Connect to this url"));
printf(" %s\n", "-e, --expect=STRING");
printf(_("String to expect in first line of server response (default: %s)\n"), EXPECT);
printf (UT_WARN_CRIT);
printf(UT_WARN_CRIT);
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_VERBOSE);
printf(UT_VERBOSE);
printf ("\n");
printf ("%s\n", _("This plugin will attempt to open an RTSP connection with the host."));
printf ("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return"));
printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects,"));
printf ("%s\n", _("but incorrect response messages from the host result in STATE_WARNING return"));
printf ("%s\n", _("values."));
printf("\n");
printf("%s\n", _("This plugin will attempt to open an RTSP connection with the host."));
printf("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return"));
printf("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects,"));
printf("%s\n", _("but incorrect response messages from the host result in STATE_WARNING return"));
printf("%s\n", _("values."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -H host [-e expect] [-p port] [-w warn] [-c crit] [-t timeout] [-v]\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -H host [-e expect] [-p port] [-w warn] [-c crit] [-t timeout] [-v]\n", progname);
}

View file

@ -3,7 +3,7 @@
* Monitoring check_smtp plugin
*
* License: GPL
* Copyright (c) 2000-2023 Monitoring Plugins Development Team
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -29,7 +29,7 @@
*****************************************************************************/
const char *progname = "check_smtp";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
* Monitoring check_ssh plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -29,7 +29,7 @@
*****************************************************************************/
const char *progname = "check_ssh";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "./common.h"

View file

@ -1,35 +1,35 @@
/*****************************************************************************
*
* Monitoring check_tcp plugin
*
* License: GPL
* Copyright (c) 1999-2013 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_tcp plugin
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*
*****************************************************************************/
*
* Monitoring check_tcp plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_tcp plugin
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*
*****************************************************************************/
/* progname "check_tcp" changes depending on symlink called */
char *progname;
const char *copyright = "1999-2008";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -43,17 +43,17 @@ const char *email = "devel@monitoring-plugins.org";
#ifdef HAVE_SSL
static bool check_cert = false;
static int days_till_exp_warn, days_till_exp_crit;
# define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len))
# define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0))
# define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len))
# define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0))
#else
# define my_recv(buf, len) read(sd, buf, len)
# define my_send(buf, len) send(sd, buf, len, 0)
# define my_recv(buf, len) read(sd, buf, len)
# define my_send(buf, len) send(sd, buf, len, 0)
#endif
/* int my_recv(char *, size_t); */
static int process_arguments (int, char **);
void print_help (void);
void print_usage (void);
static int process_arguments(int /*argc*/, char ** /*argv*/);
static void print_help(void);
void print_usage(void);
#define EXPECT server_expect[0]
static char *SERVICE = "TCP";
@ -91,38 +91,29 @@ static char *sni = NULL;
static bool sni_specified = false;
#endif
#define FLAG_SSL 0x01
#define FLAG_VERBOSE 0x02
#define FLAG_TIME_WARN 0x04
#define FLAG_TIME_CRIT 0x08
#define FLAG_SSL 0x01
#define FLAG_VERBOSE 0x02
#define FLAG_TIME_WARN 0x04
#define FLAG_TIME_CRIT 0x08
#define FLAG_HIDE_OUTPUT 0x10
static size_t flags;
int
main (int argc, char **argv)
{
int result = STATE_UNKNOWN;
char *status = NULL;
struct timeval tv;
struct timeval timeout;
int match = -1;
fd_set rfds;
FD_ZERO(&rfds);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* determine program- and service-name quickly */
progname = strrchr(argv[0], '/');
if(progname != NULL) progname++;
else progname = argv[0];
if (progname != NULL)
progname++;
else
progname = argv[0];
size_t prog_name_len = strlen(progname);
if(prog_name_len > 6 && !memcmp(progname, "check_", 6)) {
if (prog_name_len > 6 && !memcmp(progname, "check_", 6)) {
SERVICE = strdup(progname + 6);
for(size_t i = 0; i < prog_name_len - 6; i++)
for (size_t i = 0; i < prog_name_len - 6; i++)
SERVICE[i] = toupper(SERVICE[i]);
}
@ -133,23 +124,19 @@ main (int argc, char **argv)
/* determine defaults for this service's protocol */
if (!strncmp(SERVICE, "UDP", 3)) {
PROTOCOL = IPPROTO_UDP;
}
else if (!strncmp(SERVICE, "FTP", 3)) {
} else if (!strncmp(SERVICE, "FTP", 3)) {
EXPECT = "220";
QUIT = "QUIT\r\n";
PORT = 21;
}
else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) {
} else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) {
EXPECT = "+OK";
QUIT = "QUIT\r\n";
PORT = 110;
}
else if (!strncmp(SERVICE, "SMTP", 4)) {
} else if (!strncmp(SERVICE, "SMTP", 4)) {
EXPECT = "220";
QUIT = "QUIT\r\n";
PORT = 25;
}
else if (!strncmp(SERVICE, "IMAP", 4)) {
} else if (!strncmp(SERVICE, "IMAP", 4)) {
EXPECT = "* OK";
QUIT = "a1 LOGOUT\r\n";
PORT = 143;
@ -160,27 +147,23 @@ main (int argc, char **argv)
QUIT = "a1 LOGOUT\r\n";
flags |= FLAG_SSL;
PORT = 993;
}
else if (!strncmp(SERVICE, "SPOP", 4)) {
} else if (!strncmp(SERVICE, "SPOP", 4)) {
EXPECT = "+OK";
QUIT = "QUIT\r\n";
flags |= FLAG_SSL;
PORT = 995;
}
else if (!strncmp(SERVICE, "SSMTP", 5)) {
} else if (!strncmp(SERVICE, "SSMTP", 5)) {
EXPECT = "220";
QUIT = "QUIT\r\n";
flags |= FLAG_SSL;
PORT = 465;
}
else if (!strncmp(SERVICE, "JABBER", 6)) {
} else if (!strncmp(SERVICE, "JABBER", 6)) {
SEND = "<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n";
EXPECT = "<?xml version=\'1.0\'";
QUIT = "</stream:stream>\n";
flags |= FLAG_HIDE_OUTPUT;
PORT = 5222;
}
else if (!strncmp (SERVICE, "NNTPS", 5)) {
} else if (!strncmp(SERVICE, "NNTPS", 5)) {
server_expect_count = 2;
server_expect[0] = "200";
server_expect[1] = "201";
@ -189,83 +172,86 @@ main (int argc, char **argv)
PORT = 563;
}
#endif
else if (!strncmp (SERVICE, "NNTP", 4)) {
else if (!strncmp(SERVICE, "NNTP", 4)) {
server_expect_count = 2;
server_expect = malloc(sizeof(char *) * server_expect_count);
server_expect[0] = strdup("200");
server_expect[1] = strdup("201");
QUIT = "QUIT\r\n";
PORT = 119;
}
else if (!strncmp(SERVICE, "CLAMD", 5)) {
} else if (!strncmp(SERVICE, "CLAMD", 5)) {
SEND = "PING";
EXPECT = "PONG";
QUIT = NULL;
PORT = 3310;
}
/* fallthrough check, so it's supposed to use reverse matching */
else if (strcmp (SERVICE, "TCP"))
usage (_("CRITICAL - Generic check_tcp called with unknown service\n"));
else if (strcmp(SERVICE, "TCP"))
usage(_("CRITICAL - Generic check_tcp called with unknown service\n"));
server_address = "127.0.0.1";
server_port = PORT;
server_send = SEND;
server_quit = QUIT;
status = NULL;
char *status = NULL;
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
if(flags & FLAG_VERBOSE) {
if (flags & FLAG_VERBOSE) {
printf("Using service %s\n", SERVICE);
printf("Port: %d\n", server_port);
printf("flags: 0x%x\n", (int)flags);
}
if(EXPECT && !server_expect_count)
if (EXPECT && !server_expect_count)
server_expect_count++;
if(PROTOCOL==IPPROTO_UDP && !(server_expect_count && server_send)){
if (PROTOCOL == IPPROTO_UDP && !(server_expect_count && server_send)) {
usage(_("With UDP checks, a send/expect string must be specified."));
}
/* set up the timer */
signal (SIGALRM, socket_timeout_alarm_handler);
alarm (socket_timeout);
signal(SIGALRM, socket_timeout_alarm_handler);
alarm(socket_timeout);
/* try to connect to the host at the given port number */
gettimeofday (&tv, NULL);
struct timeval tv;
gettimeofday(&tv, NULL);
result = np_net_connect (server_address, server_port, &sd, PROTOCOL);
if (result == STATE_CRITICAL) return econn_refuse_state;
int result = STATE_UNKNOWN;
result = np_net_connect(server_address, server_port, &sd, PROTOCOL);
if (result == STATE_CRITICAL)
return econn_refuse_state;
#ifdef HAVE_SSL
if (flags & FLAG_SSL){
if (flags & FLAG_SSL) {
result = np_net_ssl_init_with_hostname(sd, (sni_specified ? sni : NULL));
if (result == STATE_OK && check_cert) {
result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
}
}
if(result != STATE_OK){
if(sd) close(sd);
if (result != STATE_OK) {
if (sd)
close(sd);
np_net_ssl_cleanup();
return result;
}
#endif /* HAVE_SSL */
if (server_send != NULL) { /* Something to send? */
if (server_send != NULL) { /* Something to send? */
my_send(server_send, strlen(server_send));
}
if (delay > 0) {
tv.tv_sec += delay;
sleep (delay);
sleep(delay);
}
if(flags & FLAG_VERBOSE) {
if (flags & FLAG_VERBOSE) {
if (server_send) {
printf("Send string: %s\n", server_send);
}
@ -273,13 +259,17 @@ main (int argc, char **argv)
printf("Quit string: %s\n", server_quit);
}
printf("server_expect_count: %d\n", (int)server_expect_count);
for(size_t i = 0; i < server_expect_count; i++)
for (size_t i = 0; i < server_expect_count; i++)
printf("\t%zd: %s\n", i, server_expect[i]);
}
/* if(len) later on, we know we have a non-NULL response */
ssize_t len = 0;
int match = -1;
struct timeval timeout;
fd_set rfds;
FD_ZERO(&rfds);
if (server_expect_count) {
ssize_t received = 0;
@ -294,17 +284,14 @@ main (int argc, char **argv)
if (maxbytes && len >= maxbytes)
break;
if ((match = np_expect_match(status,
server_expect,
server_expect_count,
match_flags)) != NP_MATCH_RETRY)
if ((match = np_expect_match(status, server_expect, server_expect_count, match_flags)) != NP_MATCH_RETRY)
break;
/* some protocols wait for further input, so make sure we don't wait forever */
FD_SET(sd, &rfds);
timeout.tv_sec = READ_TIMEOUT;
timeout.tv_sec = READ_TIMEOUT;
timeout.tv_usec = 0;
if(select(sd + 1, &rfds, NULL, NULL, &timeout) <= 0)
if (select(sd + 1, &rfds, NULL, NULL, &timeout) <= 0)
break;
}
@ -313,26 +300,26 @@ main (int argc, char **argv)
/* no data when expected, so return critical */
if (len == 0)
die (STATE_CRITICAL, _("No data received from host\n"));
die(STATE_CRITICAL, _("No data received from host\n"));
/* print raw output if we're debugging */
if(flags & FLAG_VERBOSE)
printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n",
(int)len + 1, status);
if (flags & FLAG_VERBOSE)
printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", (int)len + 1, status);
/* strip whitespace from end of output */
while(--len > 0 && isspace(status[len]))
while (--len > 0 && isspace(status[len]))
status[len] = '\0';
}
if (server_quit != NULL) {
my_send(server_quit, strlen(server_quit));
}
if (sd) close (sd);
if (sd)
close(sd);
#ifdef HAVE_SSL
np_net_ssl_cleanup();
#endif
microsec = deltime (tv);
microsec = deltime(tv);
elapsed_time = (double)microsec / 1.0e6;
if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time)
@ -341,142 +328,123 @@ main (int argc, char **argv)
result = STATE_WARNING;
/* did we get the response we hoped? */
if(match == NP_MATCH_FAILURE && result != STATE_CRITICAL)
if (match == NP_MATCH_FAILURE && result != STATE_CRITICAL)
result = expect_mismatch_state;
/* reset the alarm */
alarm (0);
alarm(0);
/* this is a bit stupid, because we don't want to print the
* response time (which can look ok to the user) if we didn't get
* the response we were looking for. if-else */
printf("%s %s - ", SERVICE, state_text(result));
if(match == NP_MATCH_FAILURE && len && !(flags & FLAG_HIDE_OUTPUT))
if (match == NP_MATCH_FAILURE && len && !(flags & FLAG_HIDE_OUTPUT))
printf("Unexpected response from host/socket: %s", status);
else {
if(match == NP_MATCH_FAILURE)
if (match == NP_MATCH_FAILURE)
printf("Unexpected response from host/socket on ");
else
printf("%.3f second response time on ", elapsed_time);
if(server_address[0] != '/') {
if (server_address[0] != '/') {
if (host_specified)
printf("%s port %d",
server_address, server_port);
printf("%s port %d", server_address, server_port);
else
printf("port %d", server_port);
}
else
} else
printf("socket %s", server_address);
}
if (match != NP_MATCH_FAILURE && !(flags & FLAG_HIDE_OUTPUT) && len)
printf (" [%s]", status);
printf(" [%s]", status);
/* perf-data doesn't apply when server doesn't talk properly,
* so print all zeroes on warn and crit. Use fperfdata since
* localisation settings can make different outputs */
if(match == NP_MATCH_FAILURE)
printf ("|%s",
fperfdata ("time", elapsed_time, "s",
(flags & FLAG_TIME_WARN ? true : false), 0,
(flags & FLAG_TIME_CRIT ? true : false), 0,
true, 0,
true, socket_timeout)
);
if (match == NP_MATCH_FAILURE)
printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), 0,
(flags & FLAG_TIME_CRIT ? true : false), 0, true, 0, true, socket_timeout));
else
printf("|%s",
fperfdata ("time", elapsed_time, "s",
(flags & FLAG_TIME_WARN ? true : false), warning_time,
(flags & FLAG_TIME_CRIT ? true : false), critical_time,
true, 0,
true, socket_timeout)
);
printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), warning_time,
(flags & FLAG_TIME_CRIT ? true : false), critical_time, true, 0, true, socket_timeout));
putchar('\n');
return result;
}
/* process command-line arguments */
static int process_arguments (int argc, char **argv) {
int c;
bool escape = false;
char *temp;
static int process_arguments(int argc, char **argv) {
enum {
SNI_OPTION = CHAR_MAX + 1
};
int option = 0;
static struct option longopts[] = {
{"hostname", required_argument, 0, 'H'},
{"critical", required_argument, 0, 'c'},
{"warning", 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'}, /* FIXME: Unhandled */
{"port", required_argument, 0, 'p'},
{"escape", no_argument, 0, 'E'},
{"all", no_argument, 0, 'A'},
{"send", required_argument, 0, 's'},
{"expect", required_argument, 0, 'e'},
{"maxbytes", required_argument, 0, 'm'},
{"quit", required_argument, 0, 'q'},
{"jail", no_argument, 0, 'j'},
{"delay", required_argument, 0, 'd'},
{"refuse", required_argument, 0, 'r'},
{"mismatch", required_argument, 0, 'M'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"ssl", no_argument, 0, 'S'},
{"sni", required_argument, 0, SNI_OPTION},
{"certificate", required_argument, 0, 'D'},
{0, 0, 0, 0}
};
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
{"critical", required_argument, 0, 'c'},
{"warning", 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'}, /* FIXME: Unhandled */
{"port", required_argument, 0, 'p'},
{"escape", no_argument, 0, 'E'},
{"all", no_argument, 0, 'A'},
{"send", required_argument, 0, 's'},
{"expect", required_argument, 0, 'e'},
{"maxbytes", required_argument, 0, 'm'},
{"quit", required_argument, 0, 'q'},
{"jail", no_argument, 0, 'j'},
{"delay", required_argument, 0, 'd'},
{"refuse", required_argument, 0, 'r'},
{"mismatch", required_argument, 0, 'M'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"ssl", no_argument, 0, 'S'},
{"sni", required_argument, 0, SNI_OPTION},
{"certificate", required_argument, 0, 'D'},
{0, 0, 0, 0}};
if (argc < 2)
usage4 (_("No arguments found"));
usage4(_("No arguments found"));
/* 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");
for (int i = 1; i < argc; i++) {
if (strcmp("-to", argv[i]) == 0)
strcpy(argv[i], "-t");
else if (strcmp("-wt", argv[i]) == 0)
strcpy(argv[i], "-w");
else if (strcmp("-ct", argv[i]) == 0)
strcpy(argv[i], "-c");
}
if (!is_option (argv[1])) {
if (!is_option(argv[1])) {
server_address = argv[1];
argv[1] = argv[0];
argv = &argv[1];
argc--;
}
while (1) {
c = getopt_long (argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:",
longopts, &option);
int option_char;
bool escape = false;
while (true) {
int option = 0;
option_char = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option);
if (c == -1 || c == EOF || c == 1)
if (option_char == -1 || option_char == EOF || option_char == 1)
break;
switch (c) {
case '?': /* print short usage statement if args not parsable */
usage5 ();
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'v': /* verbose mode */
switch (option_char) {
case '?': /* print short usage statement if args not parsable */
usage5();
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'v': /* verbose mode */
flags |= FLAG_VERBOSE;
match_flags |= NP_MATCH_VERBOSE;
break;
@ -487,43 +455,43 @@ static int process_arguments (int argc, char **argv) {
#ifdef USE_IPV6
address_family = AF_INET6;
#else
usage4 (_("IPv6 support not available"));
usage4(_("IPv6 support not available"));
#endif
break;
case 'H': /* hostname */
case 'H': /* hostname */
host_specified = true;
server_address = optarg;
break;
case 'c': /* critical */
critical_time = strtod (optarg, NULL);
case 'c': /* critical */
critical_time = strtod(optarg, NULL);
flags |= FLAG_TIME_CRIT;
break;
case 'j': /* hide output */
case 'j': /* hide output */
flags |= FLAG_HIDE_OUTPUT;
break;
case 'w': /* warning */
warning_time = strtod (optarg, NULL);
case 'w': /* warning */
warning_time = strtod(optarg, NULL);
flags |= FLAG_TIME_WARN;
break;
case 'C':
crit_codes = realloc (crit_codes, ++crit_codes_count);
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 = realloc(warn_codes, ++warn_codes_count);
warn_codes[warn_codes_count - 1] = optarg;
break;
case 't': /* timeout */
if (!is_intpos (optarg))
usage4 (_("Timeout interval must be a positive integer"));
case 't': /* timeout */
if (!is_intpos(optarg))
usage4(_("Timeout interval must be a positive integer"));
else
socket_timeout = atoi (optarg);
socket_timeout = atoi(optarg);
break;
case 'p': /* port */
if (!is_intpos (optarg))
usage4 (_("Port must be a positive integer"));
case 'p': /* port */
if (!is_intpos(optarg))
usage4(_("Port must be a positive integer"));
else
server_port = atoi (optarg);
server_port = atoi(optarg);
break;
case 'E':
escape = true;
@ -537,16 +505,16 @@ static int process_arguments (int argc, char **argv) {
case 'e': /* expect string (may be repeated) */
match_flags &= ~NP_MATCH_EXACT;
if (server_expect_count == 0)
server_expect = malloc (sizeof (char *) * (++server_expect_count));
server_expect = malloc(sizeof(char *) * (++server_expect_count));
else
server_expect = realloc (server_expect, sizeof (char *) * (++server_expect_count));
server_expect = realloc(server_expect, sizeof(char *) * (++server_expect_count));
server_expect[server_expect_count - 1] = optarg;
break;
case 'm':
if (!is_intpos (optarg))
usage4 (_("Maxbytes must be a positive integer"));
if (!is_intpos(optarg))
usage4(_("Maxbytes must be a positive integer"));
else
maxbytes = strtol (optarg, NULL, 0);
maxbytes = strtol(optarg, NULL, 0);
break;
case 'q':
if (escape)
@ -555,62 +523,62 @@ static int process_arguments (int argc, char **argv) {
xasprintf(&server_quit, "%s\r\n", optarg);
break;
case 'r':
if (!strncmp(optarg,"ok",2))
if (!strncmp(optarg, "ok", 2))
econn_refuse_state = STATE_OK;
else if (!strncmp(optarg,"warn",4))
else if (!strncmp(optarg, "warn", 4))
econn_refuse_state = STATE_WARNING;
else if (!strncmp(optarg,"crit",4))
else if (!strncmp(optarg, "crit", 4))
econn_refuse_state = STATE_CRITICAL;
else
usage4 (_("Refuse must be one of ok, warn, crit"));
usage4(_("Refuse must be one of ok, warn, crit"));
break;
case 'M':
if (!strncmp(optarg,"ok",2))
if (!strncmp(optarg, "ok", 2))
expect_mismatch_state = STATE_OK;
else if (!strncmp(optarg,"warn",4))
else if (!strncmp(optarg, "warn", 4))
expect_mismatch_state = STATE_WARNING;
else if (!strncmp(optarg,"crit",4))
else if (!strncmp(optarg, "crit", 4))
expect_mismatch_state = STATE_CRITICAL;
else
usage4 (_("Mismatch must be one of ok, warn, crit"));
usage4(_("Mismatch must be one of ok, warn, crit"));
break;
case 'd':
if (is_intpos (optarg))
delay = atoi (optarg);
if (is_intpos(optarg))
delay = atoi(optarg);
else
usage4 (_("Delay must be a positive integer"));
usage4(_("Delay must be a positive integer"));
break;
case 'D': /* Check SSL cert validity - days 'til certificate expiration */
case 'D': { /* Check SSL cert validity - days 'til certificate expiration */
#ifdef HAVE_SSL
# ifdef USE_OPENSSL /* XXX */
if ((temp=strchr(optarg,','))!=NULL) {
*temp='\0';
if (!is_intnonneg (optarg))
usage2 (_("Invalid certificate expiration period"), optarg);
days_till_exp_warn = atoi (optarg);
*temp=',';
temp++;
if (!is_intnonneg (temp))
usage2 (_("Invalid certificate expiration period"), temp);
days_till_exp_crit = atoi (temp);
}
else {
days_till_exp_crit=0;
if (!is_intnonneg (optarg))
usage2 (_("Invalid certificate expiration period"), optarg);
days_till_exp_warn = atoi (optarg);
# ifdef USE_OPENSSL /* XXX */
char *temp;
if ((temp = strchr(optarg, ',')) != NULL) {
*temp = '\0';
if (!is_intnonneg(optarg))
usage2(_("Invalid certificate expiration period"), optarg);
days_till_exp_warn = atoi(optarg);
*temp = ',';
temp++;
if (!is_intnonneg(temp))
usage2(_("Invalid certificate expiration period"), temp);
days_till_exp_crit = atoi(temp);
} else {
days_till_exp_crit = 0;
if (!is_intnonneg(optarg))
usage2(_("Invalid certificate expiration period"), optarg);
days_till_exp_warn = atoi(optarg);
}
check_cert = true;
flags |= FLAG_SSL;
break;
# endif /* USE_OPENSSL */
} break;
# endif /* USE_OPENSSL */
#endif
/* fallthrough if we don't have ssl */
case 'S':
#ifdef HAVE_SSL
flags |= FLAG_SSL;
#else
die (STATE_UNKNOWN, _("Invalid option - SSL is not available"));
die(STATE_UNKNOWN, _("Invalid option - SSL is not available"));
#endif
break;
case SNI_OPTION:
@ -619,7 +587,7 @@ static int process_arguments (int argc, char **argv) {
sni_specified = true;
sni = optarg;
#else
die (STATE_UNKNOWN, _("Invalid option - SSL is not available"));
die(STATE_UNKNOWN, _("Invalid option - SSL is not available"));
#endif
break;
case 'A':
@ -628,87 +596,81 @@ static int process_arguments (int argc, char **argv) {
}
}
c = optind;
if(!host_specified && c < argc)
server_address = strdup (argv[c++]);
option_char = optind;
if (!host_specified && option_char < argc)
server_address = strdup(argv[option_char++]);
if (server_address == NULL)
usage4 (_("You must provide a server address"));
usage4(_("You must provide a server address"));
else if (server_address[0] != '/' && !is_host(server_address))
die (STATE_CRITICAL, "%s %s - %s: %s\n", SERVICE, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"), server_address);
die(STATE_CRITICAL, "%s %s - %s: %s\n", SERVICE, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"),
server_address);
return OK;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf(COPYRIGHT, copyright, email);
printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
printf (COPYRIGHT, copyright, email);
printf(_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), SERVICE);
printf (_("This plugin tests %s connections with the specified host (or unix socket).\n\n"),
SERVICE);
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_HOST_PORT, 'p', "none");
printf (UT_HOST_PORT, 'p', "none");
printf(UT_IPv46);
printf (UT_IPv46);
printf (" %s\n", "-E, --escape");
printf (" %s\n", _("Can use \\n, \\r, \\t or \\\\ in send or quit string. Must come before send or quit option"));
printf (" %s\n", _("Default: nothing added to send, \\r\\n added to end of quit"));
printf (" %s\n", "-s, --send=STRING");
printf (" %s\n", _("String to send to the server"));
printf (" %s\n", "-e, --expect=STRING");
printf (" %s %s\n", _("String to expect in server response"), _("(may be repeated)"));
printf (" %s\n", "-A, --all");
printf (" %s\n", _("All expect strings need to occur in server response. Default is any"));
printf (" %s\n", "-q, --quit=STRING");
printf (" %s\n", _("String to send server to initiate a clean close of the connection"));
printf (" %s\n", "-r, --refuse=ok|warn|crit");
printf (" %s\n", _("Accept TCP refusals with states ok, warn, crit (default: crit)"));
printf (" %s\n", "-M, --mismatch=ok|warn|crit");
printf (" %s\n", _("Accept expected string mismatches with states ok, warn, crit (default: warn)"));
printf (" %s\n", "-j, --jail");
printf (" %s\n", _("Hide output from TCP socket"));
printf (" %s\n", "-m, --maxbytes=INTEGER");
printf (" %s\n", _("Close connection once more than this number of bytes are received"));
printf (" %s\n", "-d, --delay=INTEGER");
printf (" %s\n", _("Seconds to wait between sending string and polling for response"));
printf(" %s\n", "-E, --escape");
printf(" %s\n", _("Can use \\n, \\r, \\t or \\\\ in send or quit string. Must come before send or quit option"));
printf(" %s\n", _("Default: nothing added to send, \\r\\n added to end of quit"));
printf(" %s\n", "-s, --send=STRING");
printf(" %s\n", _("String to send to the server"));
printf(" %s\n", "-e, --expect=STRING");
printf(" %s %s\n", _("String to expect in server response"), _("(may be repeated)"));
printf(" %s\n", "-A, --all");
printf(" %s\n", _("All expect strings need to occur in server response. Default is any"));
printf(" %s\n", "-q, --quit=STRING");
printf(" %s\n", _("String to send server to initiate a clean close of the connection"));
printf(" %s\n", "-r, --refuse=ok|warn|crit");
printf(" %s\n", _("Accept TCP refusals with states ok, warn, crit (default: crit)"));
printf(" %s\n", "-M, --mismatch=ok|warn|crit");
printf(" %s\n", _("Accept expected string mismatches with states ok, warn, crit (default: warn)"));
printf(" %s\n", "-j, --jail");
printf(" %s\n", _("Hide output from TCP socket"));
printf(" %s\n", "-m, --maxbytes=INTEGER");
printf(" %s\n", _("Close connection once more than this number of bytes are received"));
printf(" %s\n", "-d, --delay=INTEGER");
printf(" %s\n", _("Seconds to wait between sending string and polling for response"));
#ifdef HAVE_SSL
printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
printf (" %s\n", _("Minimum number of days a certificate has to be valid."));
printf (" %s\n", _("1st is #days for warning, 2nd is critical (if not specified - 0)."));
printf (" %s\n", "-S, --ssl");
printf (" %s\n", _("Use SSL for the connection."));
printf (" %s\n", "--sni=STRING");
printf (" %s\n", _("SSL server_name"));
printf(" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
printf(" %s\n", _("Minimum number of days a certificate has to be valid."));
printf(" %s\n", _("1st is #days for warning, 2nd is critical (if not specified - 0)."));
printf(" %s\n", "-S, --ssl");
printf(" %s\n", _("Use SSL for the connection."));
printf(" %s\n", "--sni=STRING");
printf(" %s\n", _("SSL server_name"));
#endif
printf (UT_WARN_CRIT);
printf(UT_WARN_CRIT);
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_VERBOSE);
printf(UT_VERBOSE);
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]\n",progname);
printf ("[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]\n");
printf ("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n");
printf ("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]\n", progname);
printf("[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]\n");
printf("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n");
printf("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n");
}

View file

@ -1,35 +1,35 @@
/*****************************************************************************
*
* Monitoring check_time plugin
*
* License: GPL
* Copyright (c) 1999-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_time plugin
*
* This plugin will check the time difference with the specified host.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_time plugin
*
* License: GPL
* Copyright (c) 1999-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_time plugin
*
* This plugin will check the time difference with the specified host.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_time";
const char *copyright = "1999-2007";
const char *copyright = "1999-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
@ -40,55 +40,51 @@ enum {
TIME_PORT = 37
};
#define UNIX_EPOCH 2208988800UL
#define UNIX_EPOCH 2208988800UL
uint32_t raw_server_time;
unsigned long server_time, diff_time;
int warning_time = 0;
bool check_warning_time = false;
int critical_time = 0;
bool check_critical_time = false;
unsigned long warning_diff = 0;
bool check_warning_diff = false;
unsigned long critical_diff = 0;
bool check_critical_diff = false;
int server_port = TIME_PORT;
char *server_address = NULL;
bool use_udp = false;
static uint32_t raw_server_time;
static unsigned long server_time, diff_time;
static int warning_time = 0;
static bool check_warning_time = false;
static int critical_time = 0;
static bool check_critical_time = false;
static unsigned long warning_diff = 0;
static bool check_warning_diff = false;
static unsigned long critical_diff = 0;
static bool check_critical_diff = false;
static int server_port = TIME_PORT;
static char *server_address = NULL;
static bool use_udp = false;
int process_arguments (int, char **);
void print_help (void);
void print_usage (void);
static int process_arguments(int, char **);
static void print_help(void);
void print_usage(void);
int
main (int argc, char **argv)
{
int sd;
int result = STATE_UNKNOWN;
time_t conntime;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv=np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
/* initialize alarm signal handling */
signal (SIGALRM, socket_timeout_alarm_handler);
signal(SIGALRM, socket_timeout_alarm_handler);
/* set socket timeout */
alarm (socket_timeout);
time (&start_time);
alarm(socket_timeout);
time(&start_time);
int socket;
int result = STATE_UNKNOWN;
/* try to connect to the host at the given port number */
if (use_udp) {
result = my_udp_connect (server_address, server_port, &sd);
result = my_udp_connect(server_address, server_port, &socket);
} else {
result = my_tcp_connect (server_address, server_port, &sd);
result = my_tcp_connect(server_address, server_port, &socket);
}
if (result != STATE_OK) {
@ -98,34 +94,30 @@ main (int argc, char **argv)
result = STATE_WARNING;
else
result = STATE_UNKNOWN;
die (result,
_("TIME UNKNOWN - could not connect to server %s, port %d\n"),
server_address, server_port);
die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port);
}
if (use_udp) {
if (send (sd, "", 0, 0) < 0) {
if (send(socket, "", 0, 0) < 0) {
if (check_critical_time)
result = STATE_CRITICAL;
else if (check_warning_time)
result = STATE_WARNING;
else
result = STATE_UNKNOWN;
die (result,
_("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"),
server_address, server_port);
die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port);
}
}
/* watch for the connection string */
result = recv (sd, (void *)&raw_server_time, sizeof (raw_server_time), 0);
result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0);
/* close the connection */
close (sd);
close(socket);
/* reset the alarm */
time (&end_time);
alarm (0);
time(&end_time);
alarm(0);
/* return a WARNING status if we couldn't read any data */
if (result <= 0) {
@ -135,240 +127,205 @@ main (int argc, char **argv)
result = STATE_WARNING;
else
result = STATE_UNKNOWN;
die (result,
_("TIME UNKNOWN - no data received from server %s, port %d\n"),
server_address, server_port);
die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port);
}
result = STATE_OK;
conntime = (end_time - start_time);
if (check_critical_time&& conntime > critical_time)
time_t conntime = (end_time - start_time);
if (check_critical_time && conntime > critical_time)
result = STATE_CRITICAL;
else if (check_warning_time && conntime > warning_time)
result = STATE_WARNING;
if (result != STATE_OK)
die (result, _("TIME %s - %d second response time|%s\n"),
state_text (result), (int)conntime,
perfdata ("time", (long)conntime, "s",
check_warning_time, (long)warning_time,
check_critical_time, (long)critical_time,
true, 0, false, 0));
die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime,
perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0,
false, 0));
server_time = ntohl (raw_server_time) - UNIX_EPOCH;
server_time = ntohl(raw_server_time) - UNIX_EPOCH;
if (server_time > (unsigned long)end_time)
diff_time = server_time - (unsigned long)end_time;
else
diff_time = (unsigned long)end_time - server_time;
if (check_critical_diff&& diff_time > critical_diff)
if (check_critical_diff && diff_time > critical_diff)
result = STATE_CRITICAL;
else if (check_warning_diff&& diff_time > warning_diff)
else if (check_warning_diff && diff_time > warning_diff)
result = STATE_WARNING;
printf (_("TIME %s - %lu second time difference|%s %s\n"),
state_text (result), diff_time,
perfdata ("time", (long)conntime, "s",
check_warning_time, (long)warning_time,
check_critical_time, (long)critical_time,
true, 0, false, 0),
perfdata ("offset", diff_time, "s",
check_warning_diff, warning_diff,
check_critical_diff, critical_diff,
true, 0, false, 0));
printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time,
perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0,
false, 0),
perfdata("offset", diff_time, "s", check_warning_diff, warning_diff, check_critical_diff, critical_diff, true, 0, false, 0));
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int option = 0;
static struct option longopts[] = {
{"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'},
{"udp", no_argument, 0, 'u'},
{"timeout", required_argument, 0, 't'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"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'},
{"udp", no_argument, 0, 'u'},
{"timeout", required_argument, 0, 't'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
if (argc < 2)
usage ("\n");
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");
for (int i = 1; i < argc; i++) {
if (strcmp("-to", argv[i]) == 0)
strcpy(argv[i], "-t");
else if (strcmp("-wd", argv[i]) == 0)
strcpy(argv[i], "-w");
else if (strcmp("-cd", argv[i]) == 0)
strcpy(argv[i], "-c");
else if (strcmp("-wt", argv[i]) == 0)
strcpy(argv[i], "-W");
else if (strcmp("-ct", argv[i]) == 0)
strcpy(argv[i], "-C");
}
int option_char;
while (true) {
c = getopt_long (argc, argv, "hVH:w:c:W:C:p:t:u", longopts,
&option);
int option = 0;
option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option);
if (c == -1 || c == EOF)
if (option_char == -1 || option_char == EOF)
break;
switch (c) {
case '?': /* print short usage statement if args not parsable */
usage5 ();
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'H': /* hostname */
if (!is_host (optarg))
usage2 (_("Invalid hostname/address"), optarg);
switch (option_char) {
case '?': /* print short usage statement if args not parsable */
usage5();
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'H': /* hostname */
if (!is_host(optarg))
usage2(_("Invalid hostname/address"), optarg);
server_address = optarg;
break;
case 'w': /* warning-variance */
if (is_intnonneg (optarg)) {
warning_diff = strtoul (optarg, NULL, 10);
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) {
} 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 {
usage4(_("Warning thresholds must be a positive integer"));
}
else {
usage4 (_("Warning thresholds must be a positive integer"));
}
}
else {
usage4 (_("Warning threshold must be a positive integer"));
} else {
usage4(_("Warning threshold must be a positive integer"));
}
break;
case 'c': /* critical-variance */
if (is_intnonneg (optarg)) {
critical_diff = strtoul (optarg, NULL, 10);
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) {
} 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 {
usage4(_("Critical thresholds must be a positive integer"));
}
else {
usage4 (_("Critical thresholds must be a positive integer"));
}
}
else {
usage4 (_("Critical threshold must be a positive integer"));
} else {
usage4(_("Critical threshold must be a positive integer"));
}
break;
case 'W': /* warning-connect */
if (!is_intnonneg (optarg))
usage4 (_("Warning threshold must be a positive integer"));
case 'W': /* warning-connect */
if (!is_intnonneg(optarg))
usage4(_("Warning threshold must be a positive integer"));
else
warning_time = atoi (optarg);
warning_time = atoi(optarg);
check_warning_time = true;
break;
case 'C': /* critical-connect */
if (!is_intnonneg (optarg))
usage4 (_("Critical threshold must be a positive integer"));
case 'C': /* critical-connect */
if (!is_intnonneg(optarg))
usage4(_("Critical threshold must be a positive integer"));
else
critical_time = atoi (optarg);
critical_time = atoi(optarg);
check_critical_time = true;
break;
case 'p': /* port */
if (!is_intnonneg (optarg))
usage4 (_("Port must be a positive integer"));
case 'p': /* port */
if (!is_intnonneg(optarg))
usage4(_("Port must be a positive integer"));
else
server_port = atoi (optarg);
server_port = atoi(optarg);
break;
case 't': /* timeout */
if (!is_intnonneg (optarg))
usage2 (_("Timeout interval must be a positive integer"), optarg);
case 't': /* timeout */
if (!is_intnonneg(optarg))
usage2(_("Timeout interval must be a positive integer"), optarg);
else
socket_timeout = atoi (optarg);
socket_timeout = atoi(optarg);
break;
case 'u': /* udp */
case 'u': /* udp */
use_udp = true;
}
}
c = optind;
option_char = optind;
if (server_address == NULL) {
if (argc > c) {
if (!is_host (argv[c]))
usage2 (_("Invalid hostname/address"), optarg);
server_address = argv[c];
}
else {
usage4 (_("Hostname was not supplied"));
if (argc > option_char) {
if (!is_host(argv[option_char]))
usage2(_("Invalid hostname/address"), optarg);
server_address = argv[option_char];
} else {
usage4(_("Hostname was not supplied"));
}
}
return OK;
}
void
print_help (void)
{
void print_help(void) {
char *myport;
xasprintf (&myport, "%d", TIME_PORT);
xasprintf(&myport, "%d", TIME_PORT);
print_revision (progname, NP_VERSION);
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 1999 Ethan Galstad\n");
printf (COPYRIGHT, copyright, email);
printf("Copyright (c) 1999 Ethan Galstad\n");
printf(COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin will check the time on the specified host."));
printf("%s\n", _("This plugin will check the time on the specified host."));
printf ("\n\n");
printf("\n\n");
print_usage ();
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (UT_HOST_PORT, 'p', myport);
printf(UT_HOST_PORT, 'p', myport);
printf (" %s\n", "-u, --udp");
printf (" %s\n", _("Use UDP to connect, not TCP"));
printf (" %s\n", "-w, --warning-variance=INTEGER");
printf (" %s\n", _("Time difference (sec.) necessary to result in a warning status"));
printf (" %s\n", "-c, --critical-variance=INTEGER");
printf (" %s\n", _("Time difference (sec.) necessary to result in a critical status"));
printf (" %s\n", "-W, --warning-connect=INTEGER");
printf (" %s\n", _("Response time (sec.) necessary to result in warning status"));
printf (" %s\n", "-C, --critical-connect=INTEGER");
printf (" %s\n", _("Response time (sec.) necessary to result in critical status"));
printf(" %s\n", "-u, --udp");
printf(" %s\n", _("Use UDP to connect, not TCP"));
printf(" %s\n", "-w, --warning-variance=INTEGER");
printf(" %s\n", _("Time difference (sec.) necessary to result in a warning status"));
printf(" %s\n", "-c, --critical-variance=INTEGER");
printf(" %s\n", _("Time difference (sec.) necessary to result in a critical status"));
printf(" %s\n", "-W, --warning-connect=INTEGER");
printf(" %s\n", _("Response time (sec.) necessary to result in warning status"));
printf(" %s\n", "-C, --critical-connect=INTEGER");
printf(" %s\n", _("Response time (sec.) necessary to result in critical status"));
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -H <host_address> [-p port] [-u] [-w variance] [-c variance]\n",progname);
printf (" [-W connect_time] [-C connect_time] [-t timeout]\n");
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -H <host_address> [-p port] [-u] [-w variance] [-c variance]\n", progname);
printf(" [-W connect_time] [-C connect_time] [-t timeout]\n");
}

View file

@ -6,7 +6,7 @@
* Copyright (c) 2000 Tom Shields
* 2004 Alain Richard <alain.richard@equation.fr>
* 2004 Arnaud Quette <arnaud.quette@mgeups.com>
* Copyright (c) 2002-2023 Monitoring Plugins Development Team
* Copyright (c) 2002-2024 Monitoring Plugins Development Team
*
* Description:
*
@ -33,14 +33,16 @@
*****************************************************************************/
const char *progname = "check_ups";
const char *copyright = "2000-2023";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "netutils.h"
#include "utils.h"
enum { PORT = 3493 };
enum {
PORT = 3493
};
#define UPS_NONE 0 /* no supported options */
#define UPS_UTILITY 1 /* supports utility line */
@ -66,7 +68,9 @@ enum { PORT = 3493 };
#define UPSSTATUS_UNKNOWN 4096
#define UPSSTATUS_ALARM 8192
enum { NOSUCHVAR = ERROR - 1 };
enum {
NOSUCHVAR = ERROR - 1
};
typedef struct ups_config {
unsigned int server_port;
@ -141,7 +145,6 @@ int main(int argc, char **argv) {
return STATE_CRITICAL;
}
if (supported_options & UPS_STATUS) {
ups_status = strdup("");
@ -151,8 +154,7 @@ int main(int argc, char **argv) {
if (config.status & UPSSTATUS_OFF) {
xasprintf(&ups_status, "Off");
result = STATE_CRITICAL;
} else if ((config.status & (UPSSTATUS_OB | UPSSTATUS_LB)) ==
(UPSSTATUS_OB | UPSSTATUS_LB)) {
} else if ((config.status & (UPSSTATUS_OB | UPSSTATUS_LB)) == (UPSSTATUS_OB | UPSSTATUS_LB)) {
xasprintf(&ups_status, _("On Battery, Low Battery"));
result = STATE_CRITICAL;
} else {
@ -171,8 +173,7 @@ int main(int argc, char **argv) {
xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating"));
}
if (config.status & UPSSTATUS_RB) {
xasprintf(&ups_status, "%s%s", ups_status,
_(", Replace Battery"));
xasprintf(&ups_status, "%s%s", ups_status, _(", Replace Battery"));
result = max_state(result, STATE_WARNING);
}
if (config.status & UPSSTATUS_BYPASS) {
@ -233,24 +234,16 @@ int main(int argc, char **argv) {
}
if (config.check_variable == UPS_UTILITY) {
if (config.check_crit &&
ups_utility_deviation >= config.critical_value) {
if (config.check_crit && ups_utility_deviation >= config.critical_value) {
result = STATE_CRITICAL;
} else if (config.check_warn &&
ups_utility_deviation >= config.warning_value) {
} else if (config.check_warn && ups_utility_deviation >= config.warning_value) {
result = max_state(result, STATE_WARNING);
}
xasprintf(&data, "%s",
perfdata("voltage", (long)(1000 * ups_utility_voltage),
"mV", config.check_warn,
(long)(1000 * config.warning_value),
config.check_crit,
(long)(1000 * config.critical_value), true, 0,
false, 0));
perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", config.check_warn, (long)(1000 * config.warning_value),
config.check_crit, (long)(1000 * config.critical_value), true, 0, false, 0));
} else {
xasprintf(&data, "%s",
perfdata("voltage", (long)(1000 * ups_utility_voltage),
"mV", false, 0, false, 0, true, 0, false, 0));
xasprintf(&data, "%s", perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 0, true, 0, false, 0));
}
}
@ -268,22 +261,16 @@ int main(int argc, char **argv) {
xasprintf(&message, "%sBatt=%3.1f%% ", message, ups_battery_percent);
if (config.check_variable == UPS_BATTPCT) {
if (config.check_crit &&
ups_battery_percent <= config.critical_value) {
if (config.check_crit && ups_battery_percent <= config.critical_value) {
result = STATE_CRITICAL;
} else if (config.check_warn &&
ups_battery_percent <= config.warning_value) {
} else if (config.check_warn && ups_battery_percent <= config.warning_value) {
result = max_state(result, STATE_WARNING);
}
xasprintf(&data, "%s %s", data,
perfdata("battery", (long)ups_battery_percent, "%",
config.check_warn, (long)(config.warning_value),
config.check_crit, (long)(config.critical_value),
true, 0, true, 100));
perfdata("battery", (long)ups_battery_percent, "%", config.check_warn, (long)(config.warning_value),
config.check_crit, (long)(config.critical_value), true, 0, true, 100));
} else {
xasprintf(&data, "%s %s", data,
perfdata("battery", (long)ups_battery_percent, "%", false,
0, false, 0, true, 0, true, 100));
xasprintf(&data, "%s %s", data, perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 0, true, 100));
}
}
@ -301,22 +288,16 @@ int main(int argc, char **argv) {
xasprintf(&message, "%sLoad=%3.1f%% ", message, ups_load_percent);
if (config.check_variable == UPS_LOADPCT) {
if (config.check_crit &&
ups_load_percent >= config.critical_value) {
if (config.check_crit && ups_load_percent >= config.critical_value) {
result = STATE_CRITICAL;
} else if (config.check_warn &&
ups_load_percent >= config.warning_value) {
} else if (config.check_warn && ups_load_percent >= config.warning_value) {
result = max_state(result, STATE_WARNING);
}
xasprintf(&data, "%s %s", data,
perfdata("load", (long)ups_load_percent, "%",
config.check_warn, (long)(config.warning_value),
config.check_crit, (long)(config.critical_value),
true, 0, true, 100));
perfdata("load", (long)ups_load_percent, "%", config.check_warn, (long)(config.warning_value), config.check_crit,
(long)(config.critical_value), true, 0, true, 100));
} else {
xasprintf(&data, "%s %s", data,
perfdata("load", (long)ups_load_percent, "%", false, 0,
false, 0, true, 0, true, 100));
xasprintf(&data, "%s %s", data, perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, true, 100));
}
}
@ -345,19 +326,14 @@ int main(int argc, char **argv) {
if (config.check_variable == UPS_TEMP) {
if (config.check_crit && ups_temperature >= config.critical_value) {
result = STATE_CRITICAL;
} else if (config.check_warn &&
ups_temperature >= config.warning_value) {
} else if (config.check_warn && ups_temperature >= config.warning_value) {
result = max_state(result, STATE_WARNING);
}
xasprintf(&data, "%s %s", data,
perfdata("temp", (long)ups_temperature, tunits,
config.check_warn, (long)(config.warning_value),
config.check_crit, (long)(config.critical_value),
true, 0, false, 0));
perfdata("temp", (long)ups_temperature, tunits, config.check_warn, (long)(config.warning_value), config.check_crit,
(long)(config.critical_value), true, 0, false, 0));
} else {
xasprintf(&data, "%s %s", data,
perfdata("temp", (long)ups_temperature, tunits, false, 0,
false, 0, true, 0, false, 0));
xasprintf(&data, "%s %s", data, perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, false, 0));
}
}
@ -376,19 +352,14 @@ int main(int argc, char **argv) {
if (config.check_variable == UPS_REALPOWER) {
if (config.check_crit && ups_realpower >= config.critical_value) {
result = STATE_CRITICAL;
} else if (config.check_warn &&
ups_realpower >= config.warning_value) {
} else if (config.check_warn && ups_realpower >= config.warning_value) {
result = max_state(result, STATE_WARNING);
}
xasprintf(&data, "%s %s", data,
perfdata("realpower", (long)ups_realpower, "W",
config.check_warn, (long)(config.warning_value),
config.check_crit, (long)(config.critical_value),
true, 0, false, 0));
perfdata("realpower", (long)ups_realpower, "W", config.check_warn, (long)(config.warning_value), config.check_crit,
(long)(config.critical_value), true, 0, false, 0));
} else {
xasprintf(&data, "%s %s", data,
perfdata("realpower", (long)ups_realpower, "W", false, 0,
false, 0, true, 0, false, 0));
xasprintf(&data, "%s %s", data, perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, false, 0));
}
}
@ -425,8 +396,7 @@ int determine_status(ups_config *config, int *supported_options) {
char temp_buffer[MAX_INPUT_BUFFER];
strcpy(temp_buffer, recv_buffer);
for (char *ptr = (char *)strtok(temp_buffer, " "); ptr != NULL;
ptr = (char *)strtok(NULL, " ")) {
for (char *ptr = (char *)strtok(temp_buffer, " "); ptr != NULL; ptr = (char *)strtok(NULL, " ")) {
if (!strcmp(ptr, "OFF")) {
config->status |= UPSSTATUS_OFF;
} else if (!strcmp(ptr, "OL")) {
@ -467,8 +437,7 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) {
/* create the command string to send to the UPS daemon */
/* Add LOGOUT to avoid read failure logs */
int res = snprintf(send_buffer, sizeof(send_buffer),
"GET VAR %s %s\nLOGOUT\n", config.ups_name, varname);
int res = snprintf(send_buffer, sizeof(send_buffer), "GET VAR %s %s\nLOGOUT\n", config.ups_name, varname);
if ((res > 0) && ((size_t)res >= sizeof(send_buffer))) {
printf("%s\n", _("UPS name to long for buffer"));
return ERROR;
@ -477,9 +446,7 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) {
char temp_buffer[MAX_INPUT_BUFFER];
/* send the command to the daemon and get a response back */
if (process_tcp_request(config.server_address, config.server_port,
send_buffer, temp_buffer,
sizeof(temp_buffer)) != STATE_OK) {
if (process_tcp_request(config.server_address, config.server_port, send_buffer, temp_buffer, sizeof(temp_buffer)) != STATE_OK) {
printf("%s\n", _("Invalid response received from host"));
return ERROR;
}
@ -496,8 +463,7 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) {
ptr[len - 1] = 0;
}
if (strcmp(ptr, "ERR UNKNOWN-UPS") == 0) {
printf(_("CRITICAL - no such UPS '%s' on that host\n"),
config.ups_name);
printf(_("CRITICAL - no such UPS '%s' on that host\n"), config.ups_name);
return ERROR;
}
@ -694,8 +660,7 @@ void print_help(void) {
printf(" %s\n", "-T, --temperature");
printf(" %s\n", _("Output of temperatures in Celsius"));
printf(" %s\n", "-v, --variable=STRING");
printf(" %s %s\n", _("Valid values for STRING are"),
"LINE, TEMP, BATTPCT, LOADPCT or REALPOWER");
printf(" %s %s\n", _("Valid values for STRING are"), "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER");
printf(UT_WARN_CRIT);
@ -731,8 +696,7 @@ void print_help(void) {
"with Russell Kroll's"));
printf(" %s\n", _("Network UPS Tools be installed on the remote host. If "
"you do not have the"));
printf(" %s\n",
_("package installed on your system, you can download it from"));
printf(" %s\n", _("package installed on your system, you can download it from"));
printf(" %s\n", _("http://www.networkupstools.org"));
printf(UT_SUPPORT);

View file

@ -1,71 +1,69 @@
/*****************************************************************************
*
* Monitoring check_users plugin
*
* License: GPL
* Copyright (c) 2000-2012 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_users plugin
*
* This plugin checks the number of users currently logged in on the local
* system and generates an error if the number exceeds the thresholds
* specified.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring check_users plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the check_users plugin
*
* This plugin checks the number of users currently logged in on the local
* system and generates an error if the number exceeds the thresholds
* specified.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "check_users";
const char *copyright = "2000-2007";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
#if HAVE_WTSAPI32_H
# include <windows.h>
# include <wtsapi32.h>
# undef ERROR
# define ERROR -1
# include <windows.h>
# include <wtsapi32.h>
# undef ERROR
# define ERROR -1
#elif HAVE_UTMPX_H
# include <utmpx.h>
# include <utmpx.h>
#else
# include "popen.h"
# include "popen.h"
#endif
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#include <systemd/sd-login.h>
# include <systemd/sd-daemon.h>
# include <systemd/sd-login.h>
#endif
#define possibly_set(a,b) ((a) == 0 ? (b) : 0)
#define possibly_set(a, b) ((a) == 0 ? (b) : 0)
int process_arguments (int, char **);
void print_help (void);
void print_usage (void);
static int process_arguments(int, char **);
static void print_help(void);
void print_usage(void);
char *warning_range = NULL;
char *critical_range = NULL;
thresholds *thlds = NULL;
static char *warning_range = NULL;
static char *critical_range = NULL;
static thresholds *thlds = NULL;
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
int users = -1;
int result = STATE_UNKNOWN;
#if HAVE_WTSAPI32_H
@ -78,74 +76,71 @@ main (int argc, char **argv)
char input_buffer[MAX_INPUT_BUFFER];
#endif
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Parse extra opts if any */
argv = np_extra_opts (&argc, argv, progname);
argv = np_extra_opts(&argc, argv, progname);
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
if (process_arguments(argc, argv) == ERROR)
usage4(_("Could not parse arguments"));
users = 0;
#ifdef HAVE_LIBSYSTEMD
if (sd_booted () > 0)
users = sd_get_sessions (NULL);
if (sd_booted() > 0)
users = sd_get_sessions(NULL);
else {
#endif
#if HAVE_WTSAPI32_H
if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE,
0, 1, &wtsinfo, &wtscount)) {
printf(_("Could not enumerate RD sessions: %d\n"), GetLastError());
return STATE_UNKNOWN;
}
if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) {
printf(_("Could not enumerate RD sessions: %d\n"), GetLastError());
return STATE_UNKNOWN;
}
for (index = 0; index < wtscount; index++) {
LPTSTR username;
DWORD size;
int len;
for (index = 0; index < wtscount; index++) {
LPTSTR username;
DWORD size;
int len;
if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
wtsinfo[index].SessionId, WTSUserName, &username, &size))
continue;
if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size))
continue;
len = lstrlen(username);
len = lstrlen(username);
WTSFreeMemory(username);
WTSFreeMemory(username);
if (len == 0)
continue;
if (len == 0)
continue;
if (wtsinfo[index].State == WTSActive ||
wtsinfo[index].State == WTSDisconnected)
users++;
}
if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected)
users++;
}
WTSFreeMemory(wtsinfo);
WTSFreeMemory(wtsinfo);
#elif HAVE_UTMPX_H
/* get currently logged users from utmpx */
setutxent ();
setutxent();
while ((putmpx = getutxent ()) != NULL)
while ((putmpx = getutxent()) != NULL)
if (putmpx->ut_type == USER_PROCESS)
users++;
endutxent ();
endutxent();
#else
/* run the command */
child_process = spopen (WHO_COMMAND);
child_process = spopen(WHO_COMMAND);
if (child_process == NULL) {
printf (_("Could not open pipe: %s\n"), WHO_COMMAND);
printf(_("Could not open pipe: %s\n"), WHO_COMMAND);
return STATE_UNKNOWN;
}
child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
if (child_stderr == NULL)
printf (_("Could not open stderr for %s\n"), WHO_COMMAND);
printf(_("Could not open stderr for %s\n"), WHO_COMMAND);
while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
/* increment 'users' on all lines except total user count */
if (input_buffer[0] != '#') {
users++;
@ -153,18 +148,18 @@ main (int argc, char **argv)
}
/* get total logged in users */
if (sscanf (input_buffer, _("# users=%d"), &users) == 1)
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);
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);
if (spclose(child_process))
result = possibly_set(result, STATE_UNKNOWN);
#endif
#ifdef HAVE_LIBSYSTEMD
}
@ -174,109 +169,99 @@ main (int argc, char **argv)
result = get_status((double)users, thlds);
if (result == STATE_UNKNOWN)
printf ("%s\n", _("Unable to read output"));
printf("%s\n", _("Unable to read output"));
else {
printf (_("USERS %s - %d users currently logged in |%s\n"),
state_text(result), users,
sperfdata_int("users", users, "", warning_range,
critical_range, true, 0, false, 0));
printf(_("USERS %s - %d users currently logged in |%s\n"), state_text(result), users,
sperfdata_int("users", users, "", warning_range, critical_range, true, 0, false, 0));
}
return result;
}
/* process command-line arguments */
int
process_arguments (int argc, char **argv)
{
int c;
int option = 0;
static struct option longopts[] = {
{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
int process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
if (argc < 2)
usage ("\n");
usage("\n");
int option_char;
while (true) {
c = getopt_long (argc, argv, "+hVvc:w:", longopts, &option);
int option = 0;
option_char = getopt_long(argc, argv, "+hVvc:w:", longopts, &option);
if (c == -1 || c == EOF || c == 1)
if (option_char == -1 || option_char == EOF || option_char == 1)
break;
switch (c) {
case '?': /* print short usage statement if args not parsable */
usage5 ();
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (STATE_UNKNOWN);
case 'c': /* critical */
switch (option_char) {
case '?': /* print short usage statement if args not parsable */
usage5();
case 'h': /* help */
print_help();
exit(STATE_UNKNOWN);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(STATE_UNKNOWN);
case 'c': /* critical */
critical_range = optarg;
break;
case 'w': /* warning */
case 'w': /* warning */
warning_range = optarg;
break;
}
}
c = optind;
option_char = optind;
if (warning_range == NULL && argc > c)
warning_range = argv[c++];
if (warning_range == NULL && argc > option_char)
warning_range = argv[option_char++];
if (critical_range == NULL && argc > c)
critical_range = argv[c++];
if (critical_range == NULL && argc > option_char)
critical_range = argv[option_char++];
/* this will abort in case of invalid ranges */
set_thresholds (&thlds, warning_range, critical_range);
set_thresholds(&thlds, warning_range, critical_range);
if (!thlds->warning) {
usage4 (_("Warning threshold must be a valid range expression"));
usage4(_("Warning threshold must be a valid range expression"));
}
if (!thlds->critical) {
usage4 (_("Critical threshold must be a valid range expression"));
usage4(_("Critical threshold must be a valid range expression"));
}
return OK;
}
void
print_help (void)
{
print_revision (progname, NP_VERSION);
void print_help(void) {
print_revision(progname, NP_VERSION);
printf ("Copyright (c) 1999 Ethan Galstad\n");
printf (COPYRIGHT, copyright, email);
printf("Copyright (c) 1999 Ethan Galstad\n");
printf(COPYRIGHT, copyright, email);
printf ("%s\n", _("This plugin checks the number of users currently logged in on the local"));
printf ("%s\n", _("system and generates an error if the number exceeds the thresholds specified."));
printf("%s\n", _("This plugin checks the number of users currently logged in on the local"));
printf("%s\n", _("system and generates an error if the number exceeds the thresholds specified."));
printf ("\n\n");
printf("\n\n");
print_usage ();
print_usage();
printf (UT_HELP_VRSN);
printf (UT_EXTRA_OPTS);
printf(UT_HELP_VRSN);
printf(UT_EXTRA_OPTS);
printf (" %s\n", "-w, --warning=RANGE_EXPRESSION");
printf (" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION"));
printf (" %s\n", "-c, --critical=RANGE_EXPRESSION");
printf (" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION"));
printf(" %s\n", "-w, --warning=RANGE_EXPRESSION");
printf(" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION"));
printf(" %s\n", "-c, --critical=RANGE_EXPRESSION");
printf(" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION"));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s -w <users> -c <users>\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s -w <users> -c <users>\n", progname);
}

View file

@ -1,36 +1,36 @@
/*****************************************************************************
*
* Monitoring negate plugin
*
* License: GPL
* Copyright (c) 2002-2008 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the negate plugin
*
* Negates the status of a plugin (returns OK for CRITICAL, and vice-versa).
* Can also perform custom state switching.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring negate plugin
*
* License: GPL
* Copyright (c) 2002-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the negate plugin
*
* Negates the status of a plugin (returns OK for CRITICAL, and vice-versa).
* Can also perform custom state switching.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "negate";
const char *copyright = "2002-2008";
const char *copyright = "2002-2024";
const char *email = "devel@monitoring-plugins.org";
#define DEFAULT_TIMEOUT 11
@ -41,13 +41,11 @@ const char *email = "devel@monitoring-plugins.org";
#include <ctype.h>
/* char *command_line; */
static const char **process_arguments (int, char **);
void validate_arguments (char **);
void print_help (void);
void print_usage (void);
bool subst_text = false;
static const char **process_arguments(int /*argc*/, char ** /*argv*/);
static void validate_arguments(char ** /*command_line*/);
static void print_help(void);
void print_usage(void);
static bool subst_text = false;
static int state[4] = {
STATE_OK,
@ -56,185 +54,165 @@ static int state[4] = {
STATE_UNKNOWN,
};
int
main (int argc, char **argv)
{
int result = STATE_UNKNOWN;
char *sub;
char **command_line;
output chld_out, chld_err;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
int main(int argc, char **argv) {
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
timeout_interval = DEFAULT_TIMEOUT;
command_line = (char **) process_arguments (argc, argv);
char **command_line = (char **)process_arguments(argc, argv);
/* Set signal handling and alarm */
if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR)
die (STATE_UNKNOWN, _("Cannot catch SIGALRM"));
if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR)
die(STATE_UNKNOWN, _("Cannot catch SIGALRM"));
(void) alarm ((unsigned) timeout_interval);
(void)alarm((unsigned)timeout_interval);
int result = STATE_UNKNOWN;
output chld_out;
output chld_err;
/* catch when the command is quoted */
if(command_line[1] == NULL) {
result = cmd_run (command_line[0], &chld_out, &chld_err, 0);
if (command_line[1] == NULL) {
result = cmd_run(command_line[0], &chld_out, &chld_err, 0);
} else {
result = cmd_run_array (command_line, &chld_out, &chld_err, 0);
result = cmd_run_array(command_line, &chld_out, &chld_err, 0);
}
if (chld_err.lines > 0) {
for (size_t i = 0; i < chld_err.lines; i++) {
fprintf (stderr, "%s\n", chld_err.line[i]);
fprintf(stderr, "%s\n", chld_err.line[i]);
}
}
/* Return UNKNOWN or worse if no output is returned */
if (chld_out.lines == 0)
die (max_state_alt (result, STATE_UNKNOWN), _("No data returned from command\n"));
die(max_state_alt(result, STATE_UNKNOWN), _("No data returned from command\n"));
char *sub;
for (size_t i = 0; i < chld_out.lines; i++) {
if (subst_text && result >= 0 && result <= 4 && result != state[result]) {
if (subst_text && result >= 0 && result <= 4 && result != state[result]) {
/* Loop over each match found */
while ((sub = strstr (chld_out.line[i], state_text (result)))) {
while ((sub = strstr(chld_out.line[i], state_text(result)))) {
/* Terminate the first part and skip over the string we'll substitute */
*sub = '\0';
sub += strlen (state_text (result));
sub += strlen(state_text(result));
/* then put everything back together */
xasprintf (&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text (state[result]), sub);
xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text(state[result]), sub);
}
}
printf ("%s\n", chld_out.line[i]);
printf("%s\n", chld_out.line[i]);
}
if (result >= 0 && result <= 4) {
exit (state[result]);
exit(state[result]);
} else {
exit (result);
exit(result);
}
}
/* process command-line arguments */
static const char **
process_arguments (int argc, char **argv)
{
int c;
static const char **process_arguments(int argc, char **argv) {
static struct option longopts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'},
{"timeout", required_argument, 0, 't'}, {"timeout-result", required_argument, 0, 'T'},
{"ok", required_argument, 0, 'o'}, {"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'}, {"unknown", required_argument, 0, 'u'},
{"substitute", no_argument, 0, 's'}, {0, 0, 0, 0}};
bool permute = true;
while (true) {
int option = 0;
int option_char = getopt_long(argc, argv, "+hVt:T:o:w:c:u:s", longopts, &option);
int option = 0;
static struct option longopts[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"timeout", required_argument, 0, 't'},
{"timeout-result", required_argument, 0, 'T'},
{"ok", required_argument, 0, 'o'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{"unknown", required_argument, 0, 'u'},
{"substitute", no_argument, 0, 's'},
{0, 0, 0, 0}
};
while (1) {
c = getopt_long (argc, argv, "+hVt:T:o:w:c:u:s", longopts, &option);
if (c == -1 || c == EOF)
if (option_char == -1 || option_char == EOF)
break;
switch (c) {
case '?': /* help */
usage5 ();
switch (option_char) {
case '?': /* help */
usage5();
break;
case 'h': /* help */
print_help ();
exit (EXIT_SUCCESS);
case 'h': /* help */
print_help();
exit(EXIT_SUCCESS);
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (EXIT_SUCCESS);
case 't': /* timeout period */
if (!is_integer (optarg))
usage2 (_("Timeout interval must be a positive integer"), optarg);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(EXIT_SUCCESS);
case 't': /* timeout period */
if (!is_integer(optarg))
usage2(_("Timeout interval must be a positive integer"), optarg);
else
timeout_interval = atoi (optarg);
timeout_interval = atoi(optarg);
break;
case 'T': /* Result to return on timeouts */
case 'T': /* Result to return on timeouts */
if ((timeout_state = mp_translate_state(optarg)) == ERROR)
usage4 (_("Timeout result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
usage4(_("Timeout result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
break;
case 'o': /* replacement for OK */
case 'o': /* replacement for OK */
if ((state[STATE_OK] = mp_translate_state(optarg)) == ERROR)
usage4 (_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
usage4(_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
permute = false;
break;
case 'w': /* replacement for WARNING */
case 'w': /* replacement for WARNING */
if ((state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR)
usage4 (_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
usage4(_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
permute = false;
break;
case 'c': /* replacement for CRITICAL */
case 'c': /* replacement for CRITICAL */
if ((state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR)
usage4 (_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
usage4(_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
permute = false;
break;
case 'u': /* replacement for UNKNOWN */
case 'u': /* replacement for UNKNOWN */
if ((state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR)
usage4 (_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
usage4(_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
permute = false;
break;
case 's': /* Substitute status text */
case 's': /* Substitute status text */
subst_text = true;
break;
}
}
validate_arguments (&argv[optind]);
validate_arguments(&argv[optind]);
if (permute) { /* No [owcu] switch specified, default to this */
state[STATE_OK] = STATE_CRITICAL;
state[STATE_CRITICAL] = STATE_OK;
}
return (const char **) &argv[optind];
return (const char **)&argv[optind];
}
void
validate_arguments (char **command_line)
{
void validate_arguments(char **command_line) {
if (command_line[0] == NULL)
usage4 (_("Could not parse arguments"));
usage4(_("Could not parse arguments"));
if (strncmp(command_line[0],"/",1) != 0 && strncmp(command_line[0],"./",2) != 0)
usage4 (_("Require path to command"));
if (strncmp(command_line[0], "/", 1) != 0 && strncmp(command_line[0], "./", 2) != 0)
usage4(_("Require path to command"));
}
void print_help(void) {
print_revision(progname, NP_VERSION);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf(COPYRIGHT, copyright, email);
printf (COPYRIGHT, copyright, email);
printf("%s\n", _("Negates only the return code of a plugin (returns OK for CRITICAL and vice-versa) by default."));
printf("%s\n", _("Additional switches can be used to control:\n"));
printf("\t - which state becomes what\n");
printf("\t - changing the plugin output text to match the return code");
printf ("%s\n", _("Negates only the return code of a plugin (returns OK for CRITICAL and vice-versa) by default."));
printf ("%s\n", _("Additional switches can be used to control:\n"));
printf ("\t - which state becomes what\n");
printf ("\t - changing the plugin output text to match the return code");
printf("\n\n");
printf ("\n\n");
print_usage();
print_usage ();
printf(UT_HELP_VRSN);
printf (UT_HELP_VRSN);
printf (UT_PLUG_TIMEOUT, timeout_interval);
printf (" %s\n", _("Keep timeout longer than the plugin timeout to retain CRITICAL status."));
printf (" -T, --timeout-result=STATUS\n");
printf (" %s\n", _("Custom result on Negate timeouts; see below for STATUS definition\n"));
printf(UT_PLUG_TIMEOUT, timeout_interval);
printf(" %s\n", _("Keep timeout longer than the plugin timeout to retain CRITICAL status."));
printf(" -T, --timeout-result=STATUS\n");
printf(" %s\n", _("Custom result on Negate timeouts; see below for STATUS definition\n"));
printf(" -o, --ok=STATUS\n");
printf(" -w, --warning=STATUS\n");
@ -246,31 +224,27 @@ print_help (void)
printf(" -s, --substitute\n");
printf(_(" Substitute output text as well. Will only substitute text in CAPITALS\n"));
printf ("\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "negate /usr/local/nagios/libexec/check_ping -H host");
printf (" %s\n", _("Run check_ping and invert result. Must use full path to plugin"));
printf (" %s\n", "negate -w OK -c UNKNOWN /usr/local/nagios/libexec/check_procs -a 'vi negate.c'");
printf (" %s\n", _("This will return OK instead of WARNING and UNKNOWN instead of CRITICAL"));
printf ("\n");
printf ("%s\n", _("Notes:"));
printf (" %s\n", _("This plugin is a wrapper to take the output of another plugin and invert it."));
printf (" %s\n", _("The full path of the plugin must be provided."));
printf (" %s\n", _("If the wrapped plugin returns OK, the wrapper will return CRITICAL."));
printf (" %s\n", _("If the wrapped plugin returns CRITICAL, the wrapper will return OK."));
printf (" %s\n", _("Otherwise, the output state of the wrapped plugin is unchanged."));
printf ("\n");
printf (" %s\n", _("Using timeout-result, it is possible to override the timeout behaviour or a"));
printf (" %s\n", _("plugin by setting the negate timeout a bit lower."));
printf("\n");
printf("%s\n", _("Examples:"));
printf(" %s\n", "negate /usr/local/nagios/libexec/check_ping -H host");
printf(" %s\n", _("Run check_ping and invert result. Must use full path to plugin"));
printf(" %s\n", "negate -w OK -c UNKNOWN /usr/local/nagios/libexec/check_procs -a 'vi negate.c'");
printf(" %s\n", _("This will return OK instead of WARNING and UNKNOWN instead of CRITICAL"));
printf("\n");
printf("%s\n", _("Notes:"));
printf(" %s\n", _("This plugin is a wrapper to take the output of another plugin and invert it."));
printf(" %s\n", _("The full path of the plugin must be provided."));
printf(" %s\n", _("If the wrapped plugin returns OK, the wrapper will return CRITICAL."));
printf(" %s\n", _("If the wrapped plugin returns CRITICAL, the wrapper will return OK."));
printf(" %s\n", _("Otherwise, the output state of the wrapped plugin is unchanged."));
printf("\n");
printf(" %s\n", _("Using timeout-result, it is possible to override the timeout behaviour or a"));
printf(" %s\n", _("plugin by setting the negate timeout a bit lower."));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s [-t timeout] [-Towcu STATE] [-s] <definition of wrapped plugin>\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s [-t timeout] [-Towcu STATE] [-s] <definition of wrapped plugin>\n", progname);
}

View file

@ -1,31 +1,31 @@
/*****************************************************************************
*
* Monitoring Plugins network utilities
*
* License: GPL
* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
* Copyright (c) 2003-2008 Monitoring Plugins Development Team
*
* Description:
*
* This file contains commons functions used in many of the plugins.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring Plugins network utilities
*
* License: GPL
* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
* Copyright (c) 2003-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains commons functions used in many of the plugins.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "netutils.h"
@ -42,25 +42,19 @@ int address_family = AF_INET;
#endif
/* handles socket timeouts */
void
socket_timeout_alarm_handler (int sig)
{
void socket_timeout_alarm_handler(int sig) {
if (sig == SIGALRM)
printf (_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout);
printf(_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout);
else
printf (_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout);
printf(_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout);
exit (socket_timeout_state);
exit(socket_timeout_state);
}
/* 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 (const char *server_address, int server_port,
const char *send_buffer, char *recv_buffer, int recv_size)
{
int process_tcp_request2(const char *server_address, int server_port, const char *send_buffer, char *recv_buffer, int recv_size) {
int result;
int send_result;
@ -70,13 +64,13 @@ process_tcp_request2 (const char *server_address, int server_port,
fd_set readfds;
int recv_length = 0;
result = np_net_connect (server_address, server_port, &sd, IPPROTO_TCP);
result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP);
if (result != STATE_OK)
return STATE_CRITICAL;
send_result = send (sd, send_buffer, strlen (send_buffer), 0);
if (send_result<0 || (size_t)send_result!=strlen(send_buffer)) {
printf ("%s\n", _("Send failed"));
send_result = send(sd, send_buffer, strlen(send_buffer), 0);
if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) {
printf("%s\n", _("Send failed"));
result = STATE_WARNING;
}
@ -85,38 +79,32 @@ process_tcp_request2 (const char *server_address, int server_port,
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);
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 (!FD_ISSET(sd, &readfds)) { /* it hasn't */
if (!recv_length) {
strcpy (recv_buffer, "");
printf ("%s\n", _("No data was received from host!"));
strcpy(recv_buffer, "");
printf("%s\n", _("No data was received from host!"));
result = STATE_WARNING;
}
else { /* this one failed, but previous ones worked */
} 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,
(size_t)recv_size - recv_length - 1, 0);
} else { /* it has */
recv_result = recv(sd, recv_buffer + recv_length, (size_t)recv_size - recv_length - 1, 0);
if (recv_result == -1) {
/* recv failed, bail out */
strcpy (recv_buffer + recv_length, "");
strcpy(recv_buffer + recv_length, "");
result = STATE_WARNING;
break;
}
else if (recv_result == 0) {
} else if (recv_result == 0) {
/* end of file ? */
recv_buffer[recv_length] = 0;
break;
}
else { /* we got data! */
} else { /* we got data! */
recv_length += recv_result;
if (recv_length >= recv_size - 1) {
/* buffer full, we're done */
@ -129,42 +117,35 @@ process_tcp_request2 (const char *server_address, int server_port,
}
/* end while(1) */
close (sd);
close(sd);
return result;
}
/* connects to a host on a specified port, sends a string, and gets a
response */
int
process_request (const char *server_address, int server_port, int proto,
const char *send_buffer, char *recv_buffer, int recv_size)
{
int process_request(const char *server_address, int server_port, int proto, const char *send_buffer, char *recv_buffer, int recv_size) {
int result;
int sd;
result = STATE_OK;
result = np_net_connect (server_address, server_port, &sd, proto);
result = np_net_connect(server_address, server_port, &sd, proto);
if (result != STATE_OK)
return STATE_CRITICAL;
result = send_request (sd, proto, send_buffer, recv_buffer, recv_size);
result = send_request(sd, proto, send_buffer, recv_buffer, recv_size);
close (sd);
close(sd);
return result;
}
/* opens a tcp or udp connection to a remote host or local socket */
int
np_net_connect (const char *host_name, int port, int *sd, int proto)
{
/* send back STATE_UNKOWN if there's an error
send back STATE_OK if we connect
send back STATE_CRITICAL if we can't connect.
Let upstream figure out what to send to the user. */
int np_net_connect(const char *host_name, int port, int *sd, int proto) {
/* send back STATE_UNKOWN if there's an error
send back STATE_OK if we connect
send back STATE_CRITICAL if we can't connect.
Let upstream figure out what to send to the user. */
struct addrinfo hints;
struct addrinfo *r, *res;
struct sockaddr_un su;
@ -176,13 +157,13 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
/* as long as it doesn't start with a '/', it's assumed a host or ip */
if (!is_socket){
memset (&hints, 0, sizeof (hints));
if (!is_socket) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = address_family;
hints.ai_protocol = proto;
hints.ai_socktype = socktype;
len = strlen (host_name);
len = strlen(host_name);
/* check for an [IPv6] address (and strip the brackets) */
if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') {
host_name++;
@ -190,29 +171,29 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
}
if (len >= sizeof(host))
return STATE_UNKNOWN;
memcpy (host, host_name, len);
memcpy(host, host_name, len);
host[len] = '\0';
snprintf (port_str, sizeof (port_str), "%d", port);
result = getaddrinfo (host, port_str, &hints, &res);
snprintf(port_str, sizeof(port_str), "%d", port);
result = getaddrinfo(host, port_str, &hints, &res);
if (result != 0) {
printf ("%s\n", gai_strerror (result));
printf("%s\n", gai_strerror(result));
return STATE_UNKNOWN;
}
r = res;
while (r) {
/* attempt to create a socket */
*sd = socket (r->ai_family, socktype, r->ai_protocol);
*sd = socket(r->ai_family, socktype, r->ai_protocol);
if (*sd < 0) {
printf ("%s\n", _("Socket creation failed"));
freeaddrinfo (r);
printf("%s\n", _("Socket creation failed"));
freeaddrinfo(r);
return STATE_UNKNOWN;
}
/* attempt to open a connection */
result = connect (*sd, r->ai_addr, r->ai_addrlen);
result = connect(*sd, r->ai_addr, r->ai_addrlen);
if (result == 0) {
was_refused = false;
@ -227,21 +208,21 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
}
}
close (*sd);
close(*sd);
r = r->ai_next;
}
freeaddrinfo (res);
freeaddrinfo(res);
}
/* else the hostname is interpreted as a path to a unix socket */
else {
if(strlen(host_name) >= UNIX_PATH_MAX){
if (strlen(host_name) >= UNIX_PATH_MAX) {
die(STATE_UNKNOWN, _("Supplied path too long unix domain socket"));
}
memset(&su, 0, sizeof(su));
su.sun_family = AF_UNIX;
strncpy(su.sun_path, host_name, UNIX_PATH_MAX);
*sd = socket(PF_UNIX, SOCK_STREAM, 0);
if(*sd < 0){
if (*sd < 0) {
die(STATE_UNKNOWN, _("Socket creation failed"));
}
result = connect(*sd, (struct sockaddr *)&su, sizeof(su));
@ -259,37 +240,32 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
if (is_socket)
printf("connect to file socket %s: %s\n", host_name, strerror(errno));
else
printf("connect to address %s and port %d: %s\n",
host_name, port, strerror(errno));
printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno));
return STATE_CRITICAL;
break;
default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */
return STATE_UNKNOWN;
break;
}
}
else {
} else {
if (is_socket)
printf("connect to file socket %s: %s\n", host_name, strerror(errno));
else
printf("connect to address %s and port %d: %s\n",
host_name, port, strerror(errno));
printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno));
return STATE_CRITICAL;
}
}
int
send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size)
{
int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size) {
int result = STATE_OK;
int send_result;
int recv_result;
struct timeval tv;
fd_set readfds;
send_result = send (sd, send_buffer, strlen (send_buffer), 0);
if (send_result<0 || (size_t)send_result!=strlen(send_buffer)) {
printf ("%s\n", _("Send failed"));
send_result = send(sd, send_buffer, strlen(send_buffer), 0);
if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) {
printf("%s\n", _("Send failed"));
result = STATE_WARNING;
}
@ -297,26 +273,25 @@ send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int
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);
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 ("%s\n", _("No data was received from host!"));
if (!FD_ISSET(sd, &readfds)) {
strcpy(recv_buffer, "");
printf("%s\n", _("No data was received from host!"));
result = STATE_WARNING;
}
else {
recv_result = recv (sd, recv_buffer, (size_t)recv_size - 1, 0);
recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0);
if (recv_result == -1) {
strcpy (recv_buffer, "");
strcpy(recv_buffer, "");
if (proto != IPPROTO_TCP)
printf ("%s\n", _("Receive failed"));
printf("%s\n", _("Receive failed"));
result = STATE_WARNING;
}
else
} else
recv_buffer[recv_result] = 0;
/* die returned string */
@ -325,51 +300,46 @@ send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int
return result;
}
bool is_host (const char *address) {
if (is_addr (address) || is_hostname (address))
bool is_host(const char *address) {
if (is_addr(address) || is_hostname(address))
return (true);
return (false);
}
void
host_or_die(const char *str)
{
if(!str || (!is_addr(str) && !is_hostname(str)))
void host_or_die(const char *str) {
if (!str || (!is_addr(str) && !is_hostname(str)))
usage_va(_("Invalid hostname/address - %s"), str);
}
bool is_addr (const char *address) {
bool is_addr(const char *address) {
#ifdef USE_IPV6
if (address_family == AF_INET && is_inet_addr (address))
if (address_family == AF_INET && is_inet_addr(address))
return true;
else if (address_family == AF_INET6 && is_inet6_addr (address))
else if (address_family == AF_INET6 && is_inet6_addr(address))
return true;
#else
if (is_inet_addr (address))
if (is_inet_addr(address))
return (true);
#endif
return (false);
}
int
dns_lookup (const char *in, struct sockaddr_storage *ss, int family)
{
int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) {
struct addrinfo hints;
struct addrinfo *res;
int retval;
memset (&hints, 0, sizeof(struct addrinfo));
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = family;
retval = getaddrinfo (in, NULL, &hints, &res);
retval = getaddrinfo(in, NULL, &hints, &res);
if (retval != 0)
return false;
if (ss != NULL)
memcpy (ss, res->ai_addr, res->ai_addrlen);
freeaddrinfo (res);
memcpy(ss, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
return true;
}

File diff suppressed because it is too large Load diff

View file

@ -1,42 +1,42 @@
/*****************************************************************************
*
* Monitoring Plugins popen
*
* License: GPL
* Copyright (c) 2005-2007 Monitoring Plugins Development Team
*
* Description:
*
* A safe alternative to popen
*
* Provides spopen and spclose
*
* FILE * spopen(const char *);
* int spclose(FILE *);
*
* Code taken with little 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 essentially empty. (popen create
* a shell and passes the environment to it).
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring Plugins popen
*
* License: GPL
* Copyright (c) 2005-2024 Monitoring Plugins Development Team
*
* Description:
*
* A safe alternative to popen
*
* Provides spopen and spclose
*
* FILE * spopen(const char *);
* int spclose(FILE *);
*
* Code taken with little 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 essentially empty. (popen create
* a shell and passes the environment to it).
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "./common.h"
#include "./utils.h"
@ -47,63 +47,52 @@ extern pid_t *childpid;
extern int *child_stderr_array;
extern FILE *child_process;
FILE *spopen (const char *);
int spclose (FILE *);
FILE *spopen(const char * /*cmdstring*/);
int spclose(FILE * /*fp*/);
#ifdef REDHAT_SPOPEN_ERROR
void popen_sigchld_handler (int);
void popen_sigchld_handler(int);
#endif
void popen_timeout_alarm_handler (int);
void popen_timeout_alarm_handler(int /*signo*/);
#include <stdarg.h> /* ANSI C header file */
#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>
# include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
# 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)
# define SIG_ERR ((Sigfunc *)-1)
#endif
char *pname = NULL; /* caller can set this from argv[0] */
char *pname = NULL; /* caller can set this from argv[0] */
#ifdef REDHAT_SPOPEN_ERROR
static volatile int childtermd = 0;
#endif
FILE *
spopen (const char *cmdstring)
{
char *env[2];
char *cmd = NULL;
char **argv = NULL;
char *str, *tmp;
int argc;
int i = 0, pfd[2], pfderr[2];
pid_t pid;
#ifdef RLIMIT_CORE
FILE *spopen(const char *cmdstring) {
#ifdef RLIMIT_CORE
/* do not leave core files */
struct rlimit limit;
getrlimit (RLIMIT_CORE, &limit);
getrlimit(RLIMIT_CORE, &limit);
limit.rlim_cur = 0;
setrlimit (RLIMIT_CORE, &limit);
setrlimit(RLIMIT_CORE, &limit);
#endif
char *env[2];
env[0] = strdup("LC_ALL=C");
env[1] = NULL;
@ -111,184 +100,182 @@ spopen (const char *cmdstring)
if (cmdstring == NULL)
return (NULL);
char *cmd = 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);
cmd = malloc(strlen(cmdstring) + 1);
if (cmd == NULL)
return NULL;
strcpy (cmd, cmdstring);
strcpy(cmd, cmdstring);
/* This is not a shell, so we don't handle "???" */
if (strstr (cmdstring, "\""))
if (strstr(cmdstring, "\""))
return NULL;
/* allow single quotes, but only if non-whitesapce doesn't occur on both sides */
if (strstr (cmdstring, " ' ") || strstr (cmdstring, "'''"))
if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''"))
return NULL;
int argc;
char **argv = NULL;
/* there cannot be more args than characters */
argc = strlen (cmdstring) + 1; /* add 1 for NULL termination */
argv = malloc (sizeof(char*)*argc);
argc = strlen(cmdstring) + 1; /* add 1 for NULL termination */
argv = malloc(sizeof(char *) * argc);
if (argv == NULL) {
printf ("%s\n", _("Could not malloc argv array in popen()"));
printf("%s\n", _("Could not malloc argv array in popen()"));
return NULL;
}
int i = 0;
char *str;
/* loop to get arguments to command */
while (cmd) {
str = cmd;
str += strspn (str, " \t\r\n"); /* trim any leading whitespace */
str += strspn(str, " \t\r\n"); /* trim any leading whitespace */
if (i >= argc - 2) {
printf ("%s\n",_("CRITICAL - You need more args!!!"));
printf("%s\n", _("CRITICAL - You need more args!!!"));
return (NULL);
}
if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */
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 (strcspn(str,"'") < strcspn (str, " \t\r\n")) {
/* handle --option='foo bar' strings */
tmp = str + strcspn(str, "'") + 1;
if (!strstr (tmp, "'"))
return NULL; /* balanced? */
tmp += strcspn(tmp,"'") + 1;
if (!strstr(str, "'"))
return NULL; /* balanced? */
cmd = 1 + strstr(str, "'");
str[strcspn(str, "'")] = 0;
} else if (strcspn(str, "'") < strcspn(str, " \t\r\n")) {
/* handle --option='foo bar' strings */
char *tmp = str + strcspn(str, "'") + 1;
if (!strstr(tmp, "'"))
return NULL; /* balanced? */
tmp += strcspn(tmp, "'") + 1;
*tmp = 0;
cmd = tmp + 1;
} else {
if (strpbrk (str, " \t\r\n")) {
cmd = 1 + strpbrk (str, " \t\r\n");
str[strcspn (str, " \t\r\n")] = 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"))
if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n"))
cmd = NULL;
argv[i++] = str;
}
argv[i] = NULL;
long maxfd = mp_open_max();
if (childpid == NULL) { /* first time through */
if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL)
if (childpid == NULL) { /* first time through */
if ((childpid = calloc((size_t)maxfd, sizeof(pid_t))) == NULL)
return (NULL);
}
if (child_stderr_array == NULL) { /* first time through */
if ((child_stderr_array = calloc ((size_t)maxfd, sizeof (int))) == NULL)
if (child_stderr_array == NULL) { /* first time through */
if ((child_stderr_array = calloc((size_t)maxfd, sizeof(int))) == NULL)
return (NULL);
}
if (pipe (pfd) < 0)
return (NULL); /* errno set by pipe() */
int pfd[2];
if (pipe(pfd) < 0)
return (NULL); /* errno set by pipe() */
if (pipe (pfderr) < 0)
return (NULL); /* errno set by pipe() */
int pfderr[2];
if (pipe(pfderr) < 0)
return (NULL); /* errno set by pipe() */
#ifdef REDHAT_SPOPEN_ERROR
if (signal (SIGCHLD, popen_sigchld_handler) == SIG_ERR) {
usage4 (_("Cannot catch SIGCHLD"));
if (signal(SIGCHLD, popen_sigchld_handler) == SIG_ERR) {
usage4(_("Cannot catch SIGCHLD"));
}
#endif
if ((pid = fork ()) < 0)
return (NULL); /* errno set by fork() */
else if (pid == 0) { /* child */
close (pfd[0]);
pid_t pid;
if ((pid = fork()) < 0)
return (NULL); /* errno set by fork() */
if (pid == 0) { /* child */
close(pfd[0]);
if (pfd[1] != STDOUT_FILENO) {
dup2 (pfd[1], STDOUT_FILENO);
close (pfd[1]);
dup2(pfd[1], STDOUT_FILENO);
close(pfd[1]);
}
close (pfderr[0]);
close(pfderr[0]);
if (pfderr[1] != STDERR_FILENO) {
dup2 (pfderr[1], STDERR_FILENO);
close (pfderr[1]);
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);
close(i);
execve (argv[0], argv, env);
_exit (0);
execve(argv[0], argv, env);
_exit(0);
}
close (pfd[1]); /* parent */
if ((child_process = fdopen (pfd[0], "r")) == NULL)
close(pfd[1]); /* parent */
if ((child_process = fdopen(pfd[0], "r")) == NULL)
return (NULL);
close (pfderr[1]);
close(pfderr[1]);
childpid[fileno (child_process)] = pid; /* remember child pid for this fd */
child_stderr_array[fileno (child_process)] = pfderr[0]; /* remember STDERR */
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, status;
pid_t pid;
int spclose(FILE *fp) {
if (childpid == NULL)
return (1); /* popen() has never been called */
return (1); /* popen() has never been called */
fd = fileno (fp);
pid_t pid;
int fd = fileno(fp);
if ((pid = childpid[fd]) == 0)
return (1); /* fp wasn't opened by popen() */
return (1); /* fp wasn't opened by popen() */
childpid[fd] = 0;
if (fclose (fp) == EOF)
if (fclose(fp) == EOF)
return (1);
#ifdef REDHAT_SPOPEN_ERROR
while (!childtermd); /* wait until SIGCHLD */
while (!childtermd)
; /* wait until SIGCHLD */
#endif
while (waitpid (pid, &status, 0) < 0)
int status;
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
return (1); /* error other than EINTR from waitpid() */
return (1); /* error other than EINTR from waitpid() */
if (WIFEXITED (status))
return (WEXITSTATUS (status)); /* return child's termination status */
if (WIFEXITED(status))
return (WEXITSTATUS(status)); /* return child's termination status */
return (1);
}
#ifdef REDHAT_SPOPEN_ERROR
void
popen_sigchld_handler (int signo)
{
void popen_sigchld_handler(int signo) {
if (signo == SIGCHLD)
childtermd = 1;
}
#endif
void
popen_timeout_alarm_handler (int signo)
{
int fh;
void popen_timeout_alarm_handler(int signo) {
if (signo == SIGALRM) {
if (child_process != NULL) {
fh=fileno (child_process);
if(fh >= 0){
kill (childpid[fh], SIGKILL);
int fh = fileno(child_process);
if (fh >= 0) {
kill(childpid[fh], SIGKILL);
}
printf (_("CRITICAL - Plugin timed out after %d seconds\n"),
timeout_interval);
printf(_("CRITICAL - Plugin timed out after %d seconds\n"), timeout_interval);
} else {
printf ("%s\n", _("CRITICAL - popen timeout received, but no child process"));
printf("%s\n", _("CRITICAL - popen timeout received, but no child process"));
}
exit (STATE_CRITICAL);
exit(STATE_CRITICAL);
}
}

View file

@ -1,63 +1,63 @@
/*****************************************************************************
*
* Monitoring run command utilities
*
* License: GPL
* Copyright (c) 2005-2006 Monitoring Plugins Development Team
*
* Description :
*
* A simple interface to executing programs from other programs, using an
* optimized and safe popen()-like implementation. It is considered safe
* in that no shell needs to be spawned and the environment passed to the
* execve()'d program is essentially empty.
*
* The code in this file is a derivative of popen.c which in turn was taken
* from "Advanced Programming for the Unix Environment" by W. Richard Stevens.
*
* Care has been taken to make sure the functions are async-safe. The one
* function which isn't is np_runcmd_init() which it doesn't make sense to
* call twice anyway, so the api as a whole should be considered async-safe.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring run command utilities
*
* License: GPL
* Copyright (c) 2005-2024 Monitoring Plugins Development Team
*
* Description :
*
* A simple interface to executing programs from other programs, using an
* optimized and safe popen()-like implementation. It is considered safe
* in that no shell needs to be spawned and the environment passed to the
* execve()'d program is essentially empty.
*
* The code in this file is a derivative of popen.c which in turn was taken
* from "Advanced Programming for the Unix Environment" by W. Richard Stevens.
*
* Care has been taken to make sure the functions are async-safe. The one
* function which isn't is np_runcmd_init() which it doesn't make sense to
* call twice anyway, so the api as a whole should be considered async-safe.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#define NAGIOSPLUG_API_C 1
/** includes **/
#include "runcmd.h"
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# include <sys/wait.h>
#endif
#include "./utils.h"
/** macros **/
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
# 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)
# define SIG_ERR ((Sigfunc *)-1)
#endif
#include "../lib/maxfd.h"
@ -72,33 +72,26 @@
static pid_t *np_pids = NULL;
/** prototypes **/
static int np_runcmd_open(const char *, int *, int *)
__attribute__((__nonnull__(1, 2, 3)));
static int np_runcmd_open(const char *, int *, int *) __attribute__((__nonnull__(1, 2, 3)));
static int np_fetch_output(int, output *, int)
__attribute__((__nonnull__(2)));
static int np_fetch_output(int, output *, int) __attribute__((__nonnull__(2)));
static int np_runcmd_close(int);
/* prototype imported from utils.h */
extern void die (int, const char *, ...)
__attribute__((__noreturn__,__format__(__printf__, 2, 3)));
extern void die(int, const char *, ...) __attribute__((__noreturn__, __format__(__printf__, 2, 3)));
/* this function is NOT async-safe. It is exported so multithreaded
* plugins (or other apps) can call it prior to running any commands
* through this api and thus achieve async-safeness throughout the api */
void np_runcmd_init(void)
{
long maxfd = mp_open_max();
if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t));
void np_runcmd_init(void) {
long maxfd = mp_open_max();
if (!np_pids)
np_pids = calloc(maxfd, sizeof(pid_t));
}
/* Start running a command */
static int
np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
{
static int np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) {
char *env[2];
char *cmd = NULL;
char **argv = NULL;
@ -112,7 +105,8 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
int i = 0;
if(!np_pids) NP_RUNCMD_INIT;
if (!np_pids)
NP_RUNCMD_INIT;
env[0] = strdup("LC_ALL=C");
env[1] = NULL;
@ -120,15 +114,17 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
/* make copy of command string so strtok() doesn't silently modify it */
/* (the calling program may want to access it later) */
cmdlen = strlen(cmdstring);
if((cmd = malloc(cmdlen + 1)) == NULL) return -1;
if ((cmd = malloc(cmdlen + 1)) == NULL)
return -1;
memcpy(cmd, cmdstring, cmdlen);
cmd[cmdlen] = '\0';
/* This is not a shell, so we don't handle "???" */
if (strstr (cmdstring, "\"")) return -1;
if (strstr(cmdstring, "\""))
return -1;
/* allow single quotes, but only if non-whitesapce doesn't occur on both sides */
if (strstr (cmdstring, " ' ") || strstr (cmdstring, "'''"))
if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''"))
return -1;
/* each arg must be whitespace-separated, so args can be a maximum
@ -137,32 +133,31 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
argv = calloc(sizeof(char *), argc);
if (argv == NULL) {
printf ("%s\n", _("Could not malloc argv array in popen()"));
printf("%s\n", _("Could not malloc argv array in popen()"));
return -1;
}
/* get command arguments (stupidly, but fairly quickly) */
while (cmd) {
str = cmd;
str += strspn (str, " \t\r\n"); /* trim any leading whitespace */
str += strspn(str, " \t\r\n"); /* trim any leading whitespace */
if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */
if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */
str++;
if (!strstr (str, "'")) return -1; /* 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 {
if (!strstr(str, "'"))
return -1; /* 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"))
if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n"))
cmd = NULL;
argv[i++] = str;
@ -173,33 +168,33 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
/* child runs exceve() and _exit. */
if (pid == 0) {
#ifdef RLIMIT_CORE
#ifdef RLIMIT_CORE
/* the program we execve shouldn't leave core files */
getrlimit (RLIMIT_CORE, &limit);
getrlimit(RLIMIT_CORE, &limit);
limit.rlim_cur = 0;
setrlimit (RLIMIT_CORE, &limit);
setrlimit(RLIMIT_CORE, &limit);
#endif
close (pfd[0]);
close(pfd[0]);
if (pfd[1] != STDOUT_FILENO) {
dup2 (pfd[1], STDOUT_FILENO);
close (pfd[1]);
dup2(pfd[1], STDOUT_FILENO);
close(pfd[1]);
}
close (pfderr[0]);
close(pfderr[0]);
if (pfderr[1] != STDERR_FILENO) {
dup2 (pfderr[1], STDERR_FILENO);
close (pfderr[1]);
dup2(pfderr[1], STDERR_FILENO);
close(pfderr[1]);
}
/* close all descriptors in np_pids[]
* This is executed in a separate address space (pure child),
* so we don't have to worry about async safety */
long maxfd = mp_open_max();
long maxfd = mp_open_max();
for (i = 0; i < maxfd; i++)
if(np_pids[i] > 0)
close (i);
if (np_pids[i] > 0)
close(i);
execve (argv[0], argv, env);
_exit (STATE_UNKNOWN);
execve(argv[0], argv, env);
_exit(STATE_UNKNOWN);
}
/* parent picks up execution here */
@ -213,49 +208,44 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
return pfd[0];
}
static int
np_runcmd_close(int fd)
{
static int np_runcmd_close(int fd) {
int status;
pid_t pid;
/* make sure this fd was opened by popen() */
long maxfd = mp_open_max();
if(fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0)
long maxfd = mp_open_max();
if (fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0)
return -1;
np_pids[fd] = 0;
if (close (fd) == -1) return -1;
if (close(fd) == -1)
return -1;
/* EINTR is ok (sort of), everything else is bad */
while (waitpid (pid, &status, 0) < 0)
if (errno != EINTR) return -1;
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
return -1;
/* return child's termination status */
return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1;
}
void
runcmd_timeout_alarm_handler (int signo)
{
void runcmd_timeout_alarm_handler(int signo) {
if (signo == SIGALRM)
puts(_("CRITICAL - Plugin timed out while executing system call"));
long maxfd = mp_open_max();
if(np_pids) for(long int i = 0; i < maxfd; i++) {
if(np_pids[i] != 0) kill(np_pids[i], SIGKILL);
}
long maxfd = mp_open_max();
if (np_pids)
for (long int i = 0; i < maxfd; i++) {
if (np_pids[i] != 0)
kill(np_pids[i], SIGKILL);
}
exit (STATE_CRITICAL);
exit(STATE_CRITICAL);
}
static int
np_fetch_output(int fd, output *op, int flags)
{
static int np_fetch_output(int fd, output *op, int flags) {
size_t len = 0, i = 0, lineno = 0;
size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */
char *buf = NULL;
@ -264,7 +254,7 @@ np_fetch_output(int fd, output *op, int flags)
op->buf = NULL;
op->buflen = 0;
while((ret = read(fd, tmpbuf, sizeof(tmpbuf))) > 0) {
while ((ret = read(fd, tmpbuf, sizeof(tmpbuf))) > 0) {
len = (size_t)ret;
op->buf = realloc(op->buf, op->buflen + len + 1);
memcpy(op->buf + op->buflen, tmpbuf, len);
@ -272,33 +262,33 @@ np_fetch_output(int fd, output *op, int flags)
i++;
}
if(ret < 0) {
if (ret < 0) {
printf("read() returned %d: %s\n", ret, strerror(errno));
return ret;
}
/* some plugins may want to keep output unbroken, and some commands
* will yield no output, so return here for those */
if(flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen)
if (flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen)
return op->buflen;
/* and some may want both */
if(flags & RUNCMD_NO_ASSOC) {
if (flags & RUNCMD_NO_ASSOC) {
buf = malloc(op->buflen);
memcpy(buf, op->buf, op->buflen);
}
else buf = op->buf;
} else
buf = op->buf;
op->line = NULL;
op->lens = NULL;
i = 0;
while(i < op->buflen) {
while (i < op->buflen) {
/* make sure we have enough memory */
if(lineno >= ary_size) {
if (lineno >= ary_size) {
/* ary_size must never be zero */
do {
ary_size = op->buflen >> --rsf;
} while(!ary_size);
} while (!ary_size);
op->line = realloc(op->line, ary_size * sizeof(char *));
op->lens = realloc(op->lens, ary_size * sizeof(size_t));
@ -308,7 +298,8 @@ np_fetch_output(int fd, output *op, int flags)
op->line[lineno] = &buf[i];
/* hop to next newline or end of buffer */
while(buf[i] != '\n' && i < op->buflen) i++;
while (buf[i] != '\n' && i < op->buflen)
i++;
buf[i] = '\0';
/* calculate the string length using pointer difference */
@ -321,21 +312,22 @@ np_fetch_output(int fd, output *op, int flags)
return lineno;
}
int
np_runcmd(const char *cmd, output *out, output *err, int flags)
{
int np_runcmd(const char *cmd, output *out, output *err, int flags) {
int fd, pfd_out[2], pfd_err[2];
/* initialize the structs */
if(out) memset(out, 0, sizeof(output));
if(err) memset(err, 0, sizeof(output));
if (out)
memset(out, 0, sizeof(output));
if (err)
memset(err, 0, sizeof(output));
if((fd = np_runcmd_open(cmd, pfd_out, pfd_err)) == -1)
die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
if ((fd = np_runcmd_open(cmd, pfd_out, pfd_err)) == -1)
die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
if(out) out->lines = np_fetch_output(pfd_out[0], out, flags);
if(err) err->lines = np_fetch_output(pfd_err[0], err, flags);
if (out)
out->lines = np_fetch_output(pfd_out[0], out, flags);
if (err)
err->lines = np_fetch_output(pfd_err[0], err, flags);
return np_runcmd_close(fd);
}

View file

@ -1,46 +1,42 @@
/*****************************************************************************
*
* Monitoring Plugins SSL utilities
*
* License: GPL
* Copyright (c) 2005-2010 Monitoring Plugins Development Team
*
* Description:
*
* This file contains common functions for plugins that require SSL.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring Plugins SSL utilities
*
* License: GPL
* Copyright (c) 2005-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains common functions for plugins that require SSL.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#define MAX_CN_LENGTH 256
#include "common.h"
#include "netutils.h"
#ifdef HAVE_SSL
static SSL_CTX *ctx=NULL;
static SSL *s=NULL;
static SSL_CTX *ctx = NULL;
static SSL *s = NULL;
int np_net_ssl_init(int sd) {
return np_net_ssl_init_with_hostname(sd, NULL);
}
int np_net_ssl_init(int sd) { return np_net_ssl_init_with_hostname(sd, NULL); }
int np_net_ssl_init_with_hostname(int sd, char *host_name) {
return np_net_ssl_init_with_hostname_and_version(sd, host_name, 0);
}
int np_net_ssl_init_with_hostname(int sd, char *host_name) { return np_net_ssl_init_with_hostname_and_version(sd, host_name, 0); }
int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) {
return np_net_ssl_init_with_hostname_version_and_cert(sd, host_name, version, NULL, NULL);
@ -59,145 +55,141 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
printf("%s\n", _("UNKNOWN - SSL protocol version 2 is not supported by your SSL library."));
return STATE_UNKNOWN;
case MP_SSLv3: /* SSLv3 protocol */
#if defined(OPENSSL_NO_SSL3)
# if defined(OPENSSL_NO_SSL3)
printf("%s\n", _("UNKNOWN - SSL protocol version 3 is not supported by your SSL library."));
return STATE_UNKNOWN;
#else
# else
SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
break;
#endif
# endif
case MP_TLSv1: /* TLSv1 protocol */
#if defined(OPENSSL_NO_TLS1)
# if defined(OPENSSL_NO_TLS1)
printf("%s\n", _("UNKNOWN - TLS protocol version 1 is not supported by your SSL library."));
return STATE_UNKNOWN;
#else
# else
SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
break;
#endif
# endif
case MP_TLSv1_1: /* TLSv1.1 protocol */
#if !defined(SSL_OP_NO_TLSv1_1)
# if !defined(SSL_OP_NO_TLSv1_1)
printf("%s\n", _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library."));
return STATE_UNKNOWN;
#else
# else
SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
break;
#endif
# endif
case MP_TLSv1_2: /* TLSv1.2 protocol */
#if !defined(SSL_OP_NO_TLSv1_2)
# if !defined(SSL_OP_NO_TLSv1_2)
printf("%s\n", _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library."));
return STATE_UNKNOWN;
#else
# else
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
break;
#endif
# endif
case MP_TLSv1_2_OR_NEWER:
#if !defined(SSL_OP_NO_TLSv1_1)
# if !defined(SSL_OP_NO_TLSv1_1)
printf("%s\n", _("UNKNOWN - Disabling TLSv1.1 is not supported by your SSL library."));
return STATE_UNKNOWN;
#else
# else
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
break;
#endif
# endif
case MP_TLSv1_1_OR_NEWER:
#if !defined(SSL_OP_NO_TLSv1)
# if !defined(SSL_OP_NO_TLSv1)
printf("%s\n", _("UNKNOWN - Disabling TLSv1 is not supported by your SSL library."));
return STATE_UNKNOWN;
#else
# else
SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
break;
#endif
# endif
case MP_TLSv1_OR_NEWER:
#if defined(SSL_OP_NO_SSLv3)
# if defined(SSL_OP_NO_SSLv3)
SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
break;
#endif
# endif
case MP_SSLv3_OR_NEWER:
#if defined(SSL_OP_NO_SSLv2)
# if defined(SSL_OP_NO_SSLv2)
SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
break;
#endif
# endif
}
if (cert && privkey) {
#ifdef USE_OPENSSL
# ifdef USE_OPENSSL
if (!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
#elif USE_GNUTLS
# elif USE_GNUTLS
if (!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)) {
#else
#error Unported for unknown SSL library
#endif
printf ("%s\n", _("CRITICAL - Unable to open certificate chain file!\n"));
# else
# error Unported for unknown SSL library
# endif
printf("%s\n", _("CRITICAL - Unable to open certificate chain file!\n"));
return STATE_CRITICAL;
}
SSL_CTX_use_PrivateKey_file(ctx, privkey, SSL_FILETYPE_PEM);
#ifdef USE_OPENSSL
# ifdef USE_OPENSSL
if (!SSL_CTX_check_private_key(ctx)) {
printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
printf("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
return STATE_CRITICAL;
}
#endif
# endif
}
#ifdef SSL_OP_NO_TICKET
# ifdef SSL_OP_NO_TICKET
options |= SSL_OP_NO_TICKET;
#endif
# endif
SSL_CTX_set_options(ctx, options);
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
if ((s = SSL_new(ctx)) != NULL) {
#ifdef SSL_set_tlsext_host_name
# ifdef SSL_set_tlsext_host_name
if (host_name != NULL)
SSL_set_tlsext_host_name(s, host_name);
#endif
# endif
SSL_set_fd(s, sd);
if (SSL_connect(s) == 1) {
return OK;
} else {
printf("%s\n", _("CRITICAL - Cannot make SSL connection."));
# ifdef USE_OPENSSL /* XXX look into ERR_error_string */
# ifdef USE_OPENSSL /* XXX look into ERR_error_string */
ERR_print_errors_fp(stdout);
# endif /* USE_OPENSSL */
# endif /* USE_OPENSSL */
}
} else {
printf("%s\n", _("CRITICAL - Cannot initiate SSL handshake."));
printf("%s\n", _("CRITICAL - Cannot initiate SSL handshake."));
}
return STATE_CRITICAL;
}
void np_net_ssl_cleanup() {
if (s) {
#ifdef SSL_set_tlsext_host_name
# ifdef SSL_set_tlsext_host_name
SSL_set_tlsext_host_name(s, NULL);
#endif
# endif
SSL_shutdown(s);
SSL_free(s);
if (ctx) {
SSL_CTX_free(ctx);
ctx=NULL;
ctx = NULL;
}
s=NULL;
s = NULL;
}
}
int np_net_ssl_write(const void *buf, int num) {
return SSL_write(s, buf, num);
}
int np_net_ssl_write(const void *buf, int num) { return SSL_write(s, buf, num); }
int np_net_ssl_read(void *buf, int num) {
return SSL_read(s, buf, num);
}
int np_net_ssl_read(void *buf, int num) { return SSL_read(s, buf, num); }
int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit){
# ifdef USE_OPENSSL
X509_NAME *subj=NULL;
int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit) {
# ifdef USE_OPENSSL
X509_NAME *subj = NULL;
char timestamp[50] = "";
char cn[MAX_CN_LENGTH]= "";
char cn[MAX_CN_LENGTH] = "";
char *tz;
int cnlen =-1;
int status=STATE_UNKNOWN;
int cnlen = -1;
int status = STATE_UNKNOWN;
ASN1_STRING *tm;
int offset;
@ -208,15 +200,15 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int
time_t tm_t;
if (!certificate) {
printf("%s\n",_("CRITICAL - Cannot retrieve server certificate."));
printf("%s\n", _("CRITICAL - Cannot retrieve server certificate."));
return STATE_CRITICAL;
}
/* Extract CN from certificate subject */
subj=X509_get_subject_name(certificate);
subj = X509_get_subject_name(certificate);
if (!subj) {
printf("%s\n",_("CRITICAL - Cannot retrieve certificate subject."));
printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject."));
return STATE_CRITICAL;
}
cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn));
@ -242,23 +234,16 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int
printf("%s\n", _("CRITICAL - Wrong time format in certificate."));
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 = (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 =
(tm->data[10 + offset] - '0') * 10 + (tm->data[11 + offset] - '0');
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 = (tm->data[10 + offset] - '0') * 10 + (tm->data[11 + offset] - '0');
stamp.tm_isdst = -1;
tm_t = timegm(&stamp);
@ -275,30 +260,30 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int
tzset();
if (days_left > 0 && days_left <= days_till_exp_warn) {
printf (_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left>days_till_exp_crit)?"WARNING":"CRITICAL", cn, days_left, timestamp);
printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn,
days_left, timestamp);
if (days_left > days_till_exp_crit)
status = STATE_WARNING;
else
status = STATE_CRITICAL;
} else if (days_left == 0 && time_left > 0) {
if (time_left >= 3600)
time_remaining = (int) time_left / 3600;
time_remaining = (int)time_left / 3600;
else
time_remaining = (int) time_left / 60;
time_remaining = (int)time_left / 60;
printf (_("%s - Certificate '%s' expires in %u %s (%s)\n"),
(days_left>days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, time_remaining,
time_left >= 3600 ? "hours" : "minutes", timestamp);
printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn,
time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp);
if ( days_left > days_till_exp_crit)
if (days_left > days_till_exp_crit)
status = STATE_WARNING;
else
status = STATE_CRITICAL;
} else if (time_left < 0) {
printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), cn, timestamp);
status=STATE_CRITICAL;
status = STATE_CRITICAL;
} else if (days_left == 0) {
printf (_("%s - Certificate '%s' just expired (%s).\n"), (days_left>days_till_exp_crit)?"WARNING":"CRITICAL", cn, timestamp);
printf(_("%s - Certificate '%s' just expired (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, timestamp);
if (days_left > days_till_exp_crit)
status = STATE_WARNING;
else
@ -309,22 +294,21 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int
}
X509_free(certificate);
return status;
# else /* ifndef USE_OPENSSL */
# else /* ifndef USE_OPENSSL */
printf("%s\n", _("WARNING - Plugin does not support checking certificates."));
return STATE_WARNING;
# endif /* USE_OPENSSL */
# endif /* USE_OPENSSL */
}
int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
# ifdef USE_OPENSSL
int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) {
# ifdef USE_OPENSSL
X509 *certificate = NULL;
certificate=SSL_get_peer_certificate(s);
return(np_net_ssl_check_certificate(certificate, days_till_exp_warn, days_till_exp_crit));
# else /* ifndef USE_OPENSSL */
certificate = SSL_get_peer_certificate(s);
return (np_net_ssl_check_certificate(certificate, days_till_exp_warn, days_till_exp_crit));
# else /* ifndef USE_OPENSSL */
printf("%s\n", _("WARNING - Plugin does not support checking certificates."));
return STATE_WARNING;
# endif /* USE_OPENSSL */
# endif /* USE_OPENSSL */
}
#endif /* HAVE_SSL */

View file

@ -1,51 +1,49 @@
/*****************************************************************************
*
* Monitoring urlize plugin
*
* License: GPL
* Copyright (c) 2000-2007 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the urlize plugin
*
* This plugin wraps the text output of another command (plugin) in HTML <A>
* tags. This plugin returns the status of the invoked plugin.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Monitoring urlize plugin
*
* License: GPL
* Copyright (c) 2000-2024 Monitoring Plugins Development Team
*
* Description:
*
* This file contains the urlize plugin
*
* This plugin wraps the text output of another command (plugin) in HTML <A>
* tags. This plugin returns the status of the invoked plugin.
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
const char *progname = "urlize";
const char *copyright = "2000-2006";
const char *copyright = "2000-2024";
const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
#include "popen.h"
#define PERF_CHARACTER "|"
#define PERF_CHARACTER "|"
#define NEWLINE_CHARACTER '\n'
void print_help (void);
void print_usage (void);
void print_help(void);
void print_usage(void);
int
main (int argc, char **argv)
{
int main(int argc, char **argv) {
int found = 0, result = STATE_UNKNOWN;
char *url = NULL;
char *cmd;
@ -56,79 +54,72 @@ main (int argc, char **argv)
int c;
int option = 0;
static struct option longopts[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"url", required_argument, 0, 'u'},
{0, 0, 0, 0}
};
{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"url", required_argument, 0, 'u'}, {0, 0, 0, 0}};
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* Need at least 2 args */
if (argc < 3) {
print_help();
exit (STATE_UNKNOWN);
exit(STATE_UNKNOWN);
}
while (1) {
c = getopt_long (argc, argv, "+hVu:", longopts, &option);
c = getopt_long(argc, argv, "+hVu:", longopts, &option);
if (c == -1 || c == EOF)
break;
switch (c) {
case 'h': /* help */
print_help ();
exit (EXIT_SUCCESS);
case 'h': /* help */
print_help();
exit(EXIT_SUCCESS);
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
exit (EXIT_SUCCESS);
case 'V': /* version */
print_revision(progname, NP_VERSION);
exit(EXIT_SUCCESS);
break;
case 'u':
url = strdup (argv[optind]);
url = strdup(argv[optind]);
break;
case '?':
default:
usage5 ();
usage5();
}
}
if (url == NULL)
url = strdup (argv[optind++]);
url = strdup(argv[optind++]);
cmd = strdup (argv[optind++]);
cmd = strdup(argv[optind++]);
for (c = optind; c < argc; c++) {
xasprintf (&cmd, "%s %s", cmd, argv[c]);
xasprintf(&cmd, "%s %s", cmd, argv[c]);
}
child_process = spopen (cmd);
child_process = spopen(cmd);
if (child_process == NULL) {
printf (_("Could not open pipe: %s\n"), cmd);
exit (STATE_UNKNOWN);
printf(_("Could not open pipe: %s\n"), cmd);
exit(STATE_UNKNOWN);
}
child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
if (child_stderr == NULL) {
printf (_("Could not open stderr for %s\n"), cmd);
printf(_("Could not open stderr for %s\n"), cmd);
}
bzero(tstr, sizeof(tstr));
buf = malloc(MAX_INPUT_BUFFER);
printf ("<A href=\"%s\">", argv[1]);
while (fgets (buf, MAX_INPUT_BUFFER - 1, child_process)) {
printf("<A href=\"%s\">", argv[1]);
while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) {
found++;
/* Collect the string in temp str so we can tokenize */
strcat(tstr, buf);
}
if (!found)
die (STATE_UNKNOWN,
_("%s UNKNOWN - No data received from host\nCMD: %s</A>\n"),
argv[0], cmd);
die(STATE_UNKNOWN, _("%s UNKNOWN - No data received from host\nCMD: %s</A>\n"), argv[0], cmd);
/* chop the newline character */
if ((nstr = strchr(tstr, NEWLINE_CHARACTER)) != NULL)
@ -136,63 +127,55 @@ main (int argc, char **argv)
/* tokenize the string for Perfdata if there is some */
nstr = strtok(tstr, PERF_CHARACTER);
printf ("%s", nstr);
printf ("</A>");
printf("%s", nstr);
printf("</A>");
nstr = strtok(NULL, PERF_CHARACTER);
if (nstr != NULL)
printf (" | %s", nstr);
printf(" | %s", nstr);
/* close the pipe */
result = spclose (child_process);
result = spclose(child_process);
/* WARNING if output found on stderr */
if (fgets (buf, MAX_INPUT_BUFFER - 1, child_stderr))
result = max_state (result, STATE_WARNING);
if (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr))
result = max_state(result, STATE_WARNING);
/* close stderr */
(void) fclose (child_stderr);
(void)fclose(child_stderr);
return result;
}
void print_help(void) {
print_revision(progname, NP_VERSION);
printf("Copyright (c) 2000 Karl DeBisschop <kdebisschop@users.sourceforge.net>\n");
printf(COPYRIGHT, copyright, email);
void
print_help (void)
{
print_revision (progname, NP_VERSION);
printf("%s\n", _("This plugin wraps the text output of another command (plugin) in HTML <A>"));
printf("%s\n", _("tags, thus displaying the child plugin's output as a clickable link in compatible"));
printf("%s\n", _("monitoring status screen. This plugin returns the status of the invoked plugin."));
printf ("Copyright (c) 2000 Karl DeBisschop <kdebisschop@users.sourceforge.net>\n");
printf (COPYRIGHT, copyright, email);
printf("\n\n");
printf ("%s\n", _("This plugin wraps the text output of another command (plugin) in HTML <A>"));
printf ("%s\n", _("tags, thus displaying the child plugin's output as a clickable link in compatible"));
printf ("%s\n", _("monitoring status screen. This plugin returns the status of the invoked plugin."));
print_usage();
printf ("\n\n");
printf(UT_HELP_VRSN);
print_usage ();
printf("\n");
printf("%s\n", _("Examples:"));
printf("%s\n", _("Pay close attention to quoting to ensure that the shell passes the expected"));
printf("%s\n\n", _("data to the plugin. For example, in:"));
printf(" %s\n\n", _("urlize http://example.com/ check_http -H example.com -r 'two words'"));
printf(" %s\n", _("the shell will remove the single quotes and urlize will see:"));
printf(" %s\n\n", _("urlize http://example.com/ check_http -H example.com -r two words"));
printf(" %s\n\n", _("You probably want:"));
printf(" %s\n", _("urlize http://example.com/ \"check_http -H example.com -r 'two words'\""));
printf (UT_HELP_VRSN);
printf ("\n");
printf ("%s\n", _("Examples:"));
printf ("%s\n", _("Pay close attention to quoting to ensure that the shell passes the expected"));
printf ("%s\n\n", _("data to the plugin. For example, in:"));
printf (" %s\n\n", _("urlize http://example.com/ check_http -H example.com -r 'two words'"));
printf (" %s\n", _("the shell will remove the single quotes and urlize will see:"));
printf (" %s\n\n", _("urlize http://example.com/ check_http -H example.com -r two words"));
printf (" %s\n\n", _("You probably want:"));
printf (" %s\n", _("urlize http://example.com/ \"check_http -H example.com -r 'two words'\""));
printf (UT_SUPPORT);
printf(UT_SUPPORT);
}
void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf ("%s <url> <plugin> <arg1> ... <argN>\n", progname);
void print_usage(void) {
printf("%s\n", _("Usage:"));
printf("%s <url> <plugin> <arg1> ... <argN>\n", progname);
}

View file

@ -1,26 +1,26 @@
/*****************************************************************************
*
* Library of useful functions for plugins
*
* License: GPL
* Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net)
* Copyright (c) 2002-2007 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
*
* Library of useful functions for plugins
*
* License: GPL
* Copyright (c) 2000 Karl DeBisschop (karl@debisschop.net)
* Copyright (c) 2002-2024 Monitoring Plugins Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
#include "common.h"
#include "./utils.h"
@ -34,7 +34,7 @@
#include <arpa/inet.h>
extern void print_usage (void);
extern void print_usage(void);
extern const char *progname;
#define STRLEN 64
@ -50,9 +50,7 @@ time_t start_time, end_time;
* Note that numerically the above does not hold
****************************************************************************/
int
max_state (int a, int b)
{
int max_state(int a, int b) {
if (a == STATE_CRITICAL || b == STATE_CRITICAL)
return STATE_CRITICAL;
else if (a == STATE_WARNING || b == STATE_WARNING)
@ -64,7 +62,7 @@ max_state (int a, int b)
else if (a == STATE_DEPENDENT || b == STATE_DEPENDENT)
return STATE_DEPENDENT;
else
return max (a, b);
return max(a, b);
}
/* **************************************************************************
@ -77,9 +75,7 @@ max_state (int a, int b)
* non-OK state.
****************************************************************************/
int
max_state_alt (int a, int b)
{
int max_state_alt(int a, int b) {
if (a == STATE_CRITICAL || b == STATE_CRITICAL)
return STATE_CRITICAL;
else if (a == STATE_WARNING || b == STATE_WARNING)
@ -91,124 +87,112 @@ max_state_alt (int a, int b)
else if (a == STATE_OK || b == STATE_OK)
return STATE_OK;
else
return max (a, b);
return max(a, b);
}
void usage (const char *msg)
{
printf ("%s\n", msg);
print_usage ();
exit (STATE_UNKNOWN);
void usage(const char *msg) {
printf("%s\n", msg);
print_usage();
exit(STATE_UNKNOWN);
}
void usage_va (const char *fmt, ...)
{
void usage_va(const char *fmt, ...) {
va_list ap;
printf("%s: ", progname);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf("\n");
exit (STATE_UNKNOWN);
exit(STATE_UNKNOWN);
}
void usage2(const char *msg, const char *arg)
{
printf ("%s: %s - %s\n", progname, msg, arg?arg:"(null)" );
print_usage ();
exit (STATE_UNKNOWN);
}
void
usage3 (const char *msg, int arg)
{
printf ("%s: %s - %c\n", progname, msg, arg);
void usage2(const char *msg, const char *arg) {
printf("%s: %s - %s\n", progname, msg, arg ? arg : "(null)");
print_usage();
exit (STATE_UNKNOWN);
exit(STATE_UNKNOWN);
}
void
usage4 (const char *msg)
{
printf ("%s: %s\n", progname, msg);
void usage3(const char *msg, int arg) {
printf("%s: %s - %c\n", progname, msg, arg);
print_usage();
exit (STATE_UNKNOWN);
exit(STATE_UNKNOWN);
}
void
usage5 (void)
{
void usage4(const char *msg) {
printf("%s: %s\n", progname, msg);
print_usage();
exit (STATE_UNKNOWN);
exit(STATE_UNKNOWN);
}
void
print_revision (const char *command_name, const char *revision)
{
printf ("%s v%s (%s %s)\n",
command_name, revision, PACKAGE, VERSION);
void usage5(void) {
print_usage();
exit(STATE_UNKNOWN);
}
bool is_numeric (char *number) {
void print_revision(const char *command_name, const char *revision) {
printf("%s v%s (%s %s)\n", command_name, revision, PACKAGE, VERSION);
}
bool is_numeric(char *number) {
char tmp[1];
float x;
if (!number)
return false;
else if (sscanf (number, "%f%c", &x, tmp) == 1)
else if (sscanf(number, "%f%c", &x, tmp) == 1)
return true;
else
return false;
}
bool is_positive (char *number) {
if (is_numeric (number) && atof (number) > 0.0)
bool is_positive(char *number) {
if (is_numeric(number) && atof(number) > 0.0)
return true;
else
return false;
}
bool is_negative (char *number) {
if (is_numeric (number) && atof (number) < 0.0)
bool is_negative(char *number) {
if (is_numeric(number) && atof(number) < 0.0)
return true;
else
return false;
}
bool is_nonnegative (char *number) {
if (is_numeric (number) && atof (number) >= 0.0)
bool is_nonnegative(char *number) {
if (is_numeric(number) && atof(number) >= 0.0)
return true;
else
return false;
}
bool is_percentage (char *number) {
bool is_percentage(char *number) {
int x;
if (is_numeric (number) && (x = atof (number)) >= 0 && x <= 100)
if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100)
return true;
else
return false;
}
bool is_percentage_expression (const char str[]) {
bool is_percentage_expression(const char str[]) {
if (!str) {
return false;
}
size_t len = strlen(str);
if (str[len-1] != '%') {
if (str[len - 1] != '%') {
return false;
}
char *foo = calloc(sizeof(char), len + 1);
if (!foo) {
die (STATE_UNKNOWN, _("calloc failed \n"));
die(STATE_UNKNOWN, _("calloc failed \n"));
}
strcpy(foo, str);
foo[len-1] = '\0';
foo[len - 1] = '\0';
bool result = is_numeric(foo);
@ -217,13 +201,13 @@ bool is_percentage_expression (const char str[]) {
return result;
}
bool is_integer (char *number) {
bool is_integer(char *number) {
long int n;
if (!number || (strspn (number, "-0123456789 ") != strlen (number)))
if (!number || (strspn(number, "-0123456789 ") != strlen(number)))
return false;
n = strtol (number, NULL, 10);
n = strtol(number, NULL, 10);
if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX)
return true;
@ -231,22 +215,22 @@ bool is_integer (char *number) {
return false;
}
bool is_intpos (char *number) {
if (is_integer (number) && atoi (number) > 0)
bool is_intpos(char *number) {
if (is_integer(number) && atoi(number) > 0)
return true;
else
return false;
}
bool is_intneg (char *number) {
if (is_integer (number) && atoi (number) < 0)
bool is_intneg(char *number) {
if (is_integer(number) && atoi(number) < 0)
return true;
else
return false;
}
bool is_intnonneg (char *number) {
if (is_integer (number) && atoi (number) >= 0)
bool is_intnonneg(char *number) {
if (is_integer(number) && atoi(number) >= 0)
return true;
else
return false;
@ -259,7 +243,7 @@ bool is_intnonneg (char *number) {
*/
bool is_int64(char *number, int64_t *target) {
errno = 0;
char *endptr = { 0 };
char *endptr = {0};
int64_t tmp = strtoll(number, &endptr, 10);
if (errno != 0) {
@ -287,7 +271,7 @@ bool is_int64(char *number, int64_t *target) {
*/
bool is_uint64(char *number, uint64_t *target) {
errno = 0;
char *endptr = { 0 };
char *endptr = {0};
unsigned long long tmp = strtoull(number, &endptr, 10);
if (errno != 0) {
@ -309,66 +293,50 @@ bool is_uint64(char *number, uint64_t *target) {
return true;
}
bool is_intpercent (char *number) {
bool is_intpercent(char *number) {
int i;
if (is_integer (number) && (i = atoi (number)) >= 0 && i <= 100)
if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100)
return true;
else
return false;
}
bool is_option (char *str) {
bool is_option(char *str) {
if (!str)
return false;
else if (strspn (str, "-") == 1 || strspn (str, "-") == 2)
else if (strspn(str, "-") == 1 || strspn(str, "-") == 2)
return true;
else
return false;
}
#ifdef NEED_GETTIMEOFDAY
int
gettimeofday (struct timeval *tv, struct timezone *tz)
{
int gettimeofday(struct timeval *tv, struct timezone *tz) {
tv->tv_usec = 0;
tv->tv_sec = (long) time ((time_t) 0);
tv->tv_sec = (long)time((time_t)0);
}
#endif
double
delta_time (struct timeval tv)
{
double delta_time(struct timeval tv) {
struct timeval now;
gettimeofday (&now, NULL);
gettimeofday(&now, NULL);
return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000);
}
long
deltime (struct timeval tv)
{
long deltime(struct timeval tv) {
struct timeval now;
gettimeofday (&now, NULL);
return (now.tv_sec - tv.tv_sec)*1000000 + now.tv_usec - tv.tv_usec;
gettimeofday(&now, NULL);
return (now.tv_sec - tv.tv_sec) * 1000000 + now.tv_usec - tv.tv_usec;
}
void
strip (char *buffer)
{
void strip(char *buffer) {
size_t x;
int i;
for (x = strlen (buffer); x >= 1; x--) {
for (x = strlen(buffer); x >= 1; x--) {
i = x - 1;
if (buffer[i] == ' ' ||
buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t')
buffer[i] = '\0';
else
break;
@ -376,7 +344,6 @@ strip (char *buffer)
return;
}
/******************************************************************************
*
* Copies one string to another. Any previously existing data in
@ -389,19 +356,15 @@ strip (char *buffer)
*
*****************************************************************************/
char *
strscpy (char *dest, const char *src)
{
char *strscpy(char *dest, const char *src) {
if (src == NULL)
return NULL;
xasprintf (&dest, "%s", src);
xasprintf(&dest, "%s", src);
return dest;
}
/******************************************************************************
*
* Returns a pointer to the next line of a multiline string buffer
@ -418,7 +381,7 @@ strscpy (char *dest, const char *src)
* This
* is
* a
*
*
* multiline string buffer
* ==============================
*
@ -431,7 +394,7 @@ strscpy (char *dest, const char *src)
* printf("%d %s",i++,firstword(ptr));
* ptr = strnl(ptr);
* }
*
*
* Produces the following:
*
* 1 This
@ -452,25 +415,22 @@ strscpy (char *dest, const char *src)
*
*****************************************************************************/
char *
strnl (char *str)
{
char *strnl(char *str) {
size_t len;
if (str == NULL)
return NULL;
str = strpbrk (str, "\r\n");
str = strpbrk(str, "\r\n");
if (str == NULL)
return NULL;
len = strspn (str, "\r\n");
len = strspn(str, "\r\n");
if (str[len] == '\0')
return NULL;
str += len;
if (strlen (str) == 0)
if (strlen(str) == 0)
return NULL;
return str;
}
/******************************************************************************
*
* Like strscpy, except only the portion of the source string up to
@ -487,29 +447,25 @@ strnl (char *str)
*
*****************************************************************************/
char *
strpcpy (char *dest, const char *src, const char *str)
{
char *strpcpy(char *dest, const char *src, const char *str) {
size_t len;
if (src)
len = strcspn (src, str);
len = strcspn(src, str);
else
return NULL;
if (dest == NULL || strlen (dest) < len)
dest = realloc (dest, len + 1);
if (dest == NULL || strlen(dest) < len)
dest = realloc(dest, len + 1);
if (dest == NULL)
die (STATE_UNKNOWN, _("failed realloc in strpcpy\n"));
die(STATE_UNKNOWN, _("failed realloc in strpcpy\n"));
strncpy (dest, src, len);
strncpy(dest, src, len);
dest[len] = '\0';
return dest;
}
/******************************************************************************
*
* Like strscat, except only the portion of the source string up to
@ -518,62 +474,54 @@ strpcpy (char *dest, const char *src, const char *str)
* 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)
{
char *strpcat(char *dest, const char *src, const char *str) {
size_t len, l2;
if (dest)
len = strlen (dest);
len = strlen(dest);
else
len = 0;
if (src) {
l2 = strcspn (src, str);
}
else {
l2 = strcspn(src, str);
} else {
return dest;
}
dest = realloc (dest, len + l2 + 1);
dest = realloc(dest, len + l2 + 1);
if (dest == NULL)
die (STATE_UNKNOWN, _("failed malloc in strscat\n"));
die(STATE_UNKNOWN, _("failed malloc in strscat\n"));
strncpy (dest + len, src, l2);
strncpy(dest + len, src, l2);
dest[len + l2] = '\0';
return dest;
}
/******************************************************************************
*
* asprintf, but die on failure
*
******************************************************************************/
int
xvasprintf (char **strp, const char *fmt, va_list ap)
{
int result = vasprintf (strp, fmt, ap);
int xvasprintf(char **strp, const char *fmt, va_list ap) {
int result = vasprintf(strp, fmt, ap);
if (result == -1 || *strp == NULL)
die (STATE_UNKNOWN, _("failed malloc in xvasprintf\n"));
die(STATE_UNKNOWN, _("failed malloc in xvasprintf\n"));
return result;
}
int
xasprintf (char **strp, const char *fmt, ...)
{
int xasprintf(char **strp, const char *fmt, ...) {
va_list ap;
int result;
va_start (ap, fmt);
result = xvasprintf (strp, fmt, ap);
va_end (ap);
va_start(ap, fmt);
result = xvasprintf(strp, fmt, ap);
va_end(ap);
return result;
}
@ -583,247 +531,192 @@ xasprintf (char **strp, const char *fmt, ...)
*
******************************************************************************/
char *perfdata (const char *label,
long int val,
const char *uom,
int warnp,
long int warn,
int critp,
long int crit,
int minp,
long int minv,
int maxp,
long int maxv)
{
char *perfdata(const char *label, long int val, const char *uom, int warnp, long int warn, int critp, long int crit, int minp,
long int minv, int maxp, long int maxv) {
char *data = NULL;
if (strpbrk (label, "'= "))
xasprintf (&data, "'%s'=%ld%s;", label, val, uom);
if (strpbrk(label, "'= "))
xasprintf(&data, "'%s'=%ld%s;", label, val, uom);
else
xasprintf (&data, "%s=%ld%s;", label, val, uom);
xasprintf(&data, "%s=%ld%s;", label, val, uom);
if (warnp)
xasprintf (&data, "%s%ld;", data, warn);
xasprintf(&data, "%s%ld;", data, warn);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (critp)
xasprintf (&data, "%s%ld;", data, crit);
xasprintf(&data, "%s%ld;", data, crit);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (minp)
xasprintf (&data, "%s%ld;", data, minv);
xasprintf(&data, "%s%ld;", data, minv);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (maxp)
xasprintf (&data, "%s%ld", data, maxv);
xasprintf(&data, "%s%ld", data, maxv);
return data;
}
char *perfdata_uint64 (const char *label,
uint64_t val,
const char *uom,
int warnp, /* Warning present */
uint64_t warn,
int critp, /* Critical present */
uint64_t crit,
int minp, /* Minimum present */
uint64_t minv,
int maxp, /* Maximum present */
uint64_t maxv)
{
char *perfdata_uint64(const char *label, uint64_t val, const char *uom, int warnp, /* Warning present */
uint64_t warn, int critp, /* Critical present */
uint64_t crit, int minp, /* Minimum present */
uint64_t minv, int maxp, /* Maximum present */
uint64_t maxv) {
char *data = NULL;
if (strpbrk (label, "'= "))
xasprintf (&data, "'%s'=%" PRIu64 "%s;", label, val, uom);
if (strpbrk(label, "'= "))
xasprintf(&data, "'%s'=%" PRIu64 "%s;", label, val, uom);
else
xasprintf (&data, "%s=%" PRIu64 "%s;", label, val, uom);
xasprintf(&data, "%s=%" PRIu64 "%s;", label, val, uom);
if (warnp)
xasprintf (&data, "%s%" PRIu64 ";", data, warn);
xasprintf(&data, "%s%" PRIu64 ";", data, warn);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (critp)
xasprintf (&data, "%s%" PRIu64 ";", data, crit);
xasprintf(&data, "%s%" PRIu64 ";", data, crit);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (minp)
xasprintf (&data, "%s%" PRIu64 ";", data, minv);
xasprintf(&data, "%s%" PRIu64 ";", data, minv);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (maxp)
xasprintf (&data, "%s%" PRIu64, data, maxv);
xasprintf(&data, "%s%" PRIu64, data, maxv);
return data;
}
char *perfdata_int64 (const char *label,
int64_t val,
const char *uom,
int warnp, /* Warning present */
int64_t warn,
int critp, /* Critical present */
int64_t crit,
int minp, /* Minimum present */
int64_t minv,
int maxp, /* Maximum present */
int64_t maxv)
{
char *perfdata_int64(const char *label, int64_t val, const char *uom, int warnp, /* Warning present */
int64_t warn, int critp, /* Critical present */
int64_t crit, int minp, /* Minimum present */
int64_t minv, int maxp, /* Maximum present */
int64_t maxv) {
char *data = NULL;
if (strpbrk (label, "'= "))
xasprintf (&data, "'%s'=%" PRId64 "%s;", label, val, uom);
if (strpbrk(label, "'= "))
xasprintf(&data, "'%s'=%" PRId64 "%s;", label, val, uom);
else
xasprintf (&data, "%s=%" PRId64 "%s;", label, val, uom);
xasprintf(&data, "%s=%" PRId64 "%s;", label, val, uom);
if (warnp)
xasprintf (&data, "%s%" PRId64 ";", data, warn);
xasprintf(&data, "%s%" PRId64 ";", data, warn);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (critp)
xasprintf (&data, "%s%" PRId64 ";", data, crit);
xasprintf(&data, "%s%" PRId64 ";", data, crit);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (minp)
xasprintf (&data, "%s%" PRId64 ";", data, minv);
xasprintf(&data, "%s%" PRId64 ";", data, minv);
else
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (maxp)
xasprintf (&data, "%s%" PRId64, data, maxv);
xasprintf(&data, "%s%" PRId64, data, maxv);
return data;
}
char *fperfdata (const char *label,
double val,
const char *uom,
int warnp,
double warn,
int critp,
double crit,
int minp,
double minv,
int maxp,
double maxv)
{
char *fperfdata(const char *label, double val, const char *uom, int warnp, double warn, int critp, double crit, int minp, double minv,
int maxp, double maxv) {
char *data = NULL;
if (strpbrk (label, "'= "))
xasprintf (&data, "'%s'=", label);
if (strpbrk(label, "'= "))
xasprintf(&data, "'%s'=", label);
else
xasprintf (&data, "%s=", label);
xasprintf(&data, "%s=", label);
xasprintf (&data, "%s%f", data, val);
xasprintf (&data, "%s%s;", data, uom);
xasprintf(&data, "%s%f", data, val);
xasprintf(&data, "%s%s;", data, uom);
if (warnp)
xasprintf (&data, "%s%f", data, warn);
xasprintf(&data, "%s%f", data, warn);
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (critp)
xasprintf (&data, "%s%f", data, crit);
xasprintf(&data, "%s%f", data, crit);
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (minp)
xasprintf (&data, "%s%f", data, minv);
xasprintf(&data, "%s%f", data, minv);
if (maxp) {
xasprintf (&data, "%s;", data);
xasprintf (&data, "%s%f", data, maxv);
xasprintf(&data, "%s;", data);
xasprintf(&data, "%s%f", data, maxv);
}
return data;
}
char *sperfdata (const char *label,
double val,
const char *uom,
char *warn,
char *crit,
int minp,
double minv,
int maxp,
double maxv)
{
char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, int minp, double minv, int maxp, double maxv) {
char *data = NULL;
if (strpbrk (label, "'= "))
xasprintf (&data, "'%s'=", label);
if (strpbrk(label, "'= "))
xasprintf(&data, "'%s'=", label);
else
xasprintf (&data, "%s=", label);
xasprintf(&data, "%s=", label);
xasprintf (&data, "%s%f", data, val);
xasprintf (&data, "%s%s;", data, uom);
xasprintf(&data, "%s%f", data, val);
xasprintf(&data, "%s%s;", data, uom);
if (warn!=NULL)
xasprintf (&data, "%s%s", data, warn);
if (warn != NULL)
xasprintf(&data, "%s%s", data, warn);
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (crit!=NULL)
xasprintf (&data, "%s%s", data, crit);
if (crit != NULL)
xasprintf(&data, "%s%s", data, crit);
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (minp)
xasprintf (&data, "%s%f", data, minv);
xasprintf(&data, "%s%f", data, minv);
if (maxp) {
xasprintf (&data, "%s;", data);
xasprintf (&data, "%s%f", data, maxv);
xasprintf(&data, "%s;", data);
xasprintf(&data, "%s%f", data, maxv);
}
return data;
}
char *sperfdata_int (const char *label,
int val,
const char *uom,
char *warn,
char *crit,
int minp,
int minv,
int maxp,
int maxv)
{
char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, int minp, int minv, int maxp, int maxv) {
char *data = NULL;
if (strpbrk (label, "'= "))
xasprintf (&data, "'%s'=", label);
if (strpbrk(label, "'= "))
xasprintf(&data, "'%s'=", label);
else
xasprintf (&data, "%s=", label);
xasprintf(&data, "%s=", label);
xasprintf (&data, "%s%d", data, val);
xasprintf (&data, "%s%s;", data, uom);
xasprintf(&data, "%s%d", data, val);
xasprintf(&data, "%s%s;", data, uom);
if (warn!=NULL)
xasprintf (&data, "%s%s", data, warn);
if (warn != NULL)
xasprintf(&data, "%s%s", data, warn);
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (crit!=NULL)
xasprintf (&data, "%s%s", data, crit);
if (crit != NULL)
xasprintf(&data, "%s%s", data, crit);
xasprintf (&data, "%s;", data);
xasprintf(&data, "%s;", data);
if (minp)
xasprintf (&data, "%s%d", data, minv);
xasprintf(&data, "%s%d", data, minv);
if (maxp) {
xasprintf (&data, "%s;", data);
xasprintf (&data, "%s%d", data, maxv);
xasprintf(&data, "%s;", data);
xasprintf(&data, "%s%d", data, maxv);
}
return data;