Merge pull request #2035 from RincewindsHat/cleanup/rest-of-plugins

Cleanup for some more plugins
This commit is contained in:
Lorenz Kästle 2024-10-31 14:57:43 +01:00 committed by GitHub
commit b1d260a821
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 11950 additions and 13447 deletions

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

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

@ -40,7 +40,9 @@ const char *email = "devel@monitoring-plugins.org";
#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;

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;