From 0b6423f9c99d9edf8c96fefd0f6c453859395aa1 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Mon, 30 Sep 2013 00:03:24 +0200 Subject: Import Nagios Plugins site Import the Nagios Plugins web site, Cronjobs, infrastructure scripts, and configuration files. --- web/attachments/137902-nagiosplug-runcmd.diff | 3012 +++++++++++++++++++++++++ 1 file changed, 3012 insertions(+) create mode 100644 web/attachments/137902-nagiosplug-runcmd.diff (limited to 'web/attachments/137902-nagiosplug-runcmd.diff') diff --git a/web/attachments/137902-nagiosplug-runcmd.diff b/web/attachments/137902-nagiosplug-runcmd.diff new file mode 100644 index 0000000..abebe78 --- /dev/null +++ b/web/attachments/137902-nagiosplug-runcmd.diff @@ -0,0 +1,3012 @@ +diff -urN ../nplg/plugins/check_by_ssh.c ./plugins/check_by_ssh.c +--- ../nplg/plugins/check_by_ssh.c 2005-01-05 21:53:11.000000000 +0100 ++++ ./plugins/check_by_ssh.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,19 +14,19 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_by_ssh.c,v 1.35 2004/12/25 12:09:19 opensides Exp $ ++ $Id: check_by_ssh.c,v 1.3 2005/06/06 11:37:06 exon Exp $ + + *****************************************************************************/ + + const char *progname = "check_by_ssh"; +-const char *revision = "$Revision: 1.35 $"; ++const char *revision = "$Revision: 1.3 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" + #include "netutils.h" + #include "utils.h" +-#include "popen.h" ++#include "runcmd.h" + + int process_arguments (int, char **); + int validate_arguments (void); +@@ -49,15 +49,15 @@ + main (int argc, char **argv) + { + +- char input_buffer[MAX_INPUT_BUFFER]; + char *result_text; + char *status_text; +- char *output; ++ char *msg; + char *eol = NULL; + int cresult; + int result = STATE_UNKNOWN; + time_t local_time; + FILE *fp = NULL; ++ struct output chld_out, chld_err; + + remotecmd = strdup (""); + comm = strdup (SSH_COMMAND); +@@ -82,48 +82,22 @@ + if (verbose) + printf ("%s\n", comm); + +- child_process = spopen (comm); +- +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), comm); +- return STATE_UNKNOWN; +- } +- +- +- /* open STDERR for spopen */ +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), SSH_COMMAND); +- } +- ++ result = np_runcmd(comm, &chld_out, &chld_err, 0); + + /* build up results from remote command in result_text */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) +- asprintf (&result_text, "%s%s", result_text, input_buffer); ++ if(skip_lines && skip_lines < chld_out.lines) ++ result_text = chld_out.line[skip_lines]; ++ else ++ result_text = chld_out.line[0]; + + /* WARNING if output found on stderr */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { +- if (skip_lines > 0) { +- if (input_buffer[strlen(input_buffer)-1] == '\n') { +- skip_lines--; +- } +- } else { +- printf ("%s", input_buffer); +- result = STATE_WARNING; +- } ++ if(chld_err.buflen) { ++ printf("%s\n", chld_err.line[0]); ++ return STATE_WARNING; + } +- (void) fclose (child_stderr); +- if (result == STATE_WARNING) +- return result; +- +- +- /* close the pipe */ +- result = spclose (child_process); +- + + /* process output */ + if (passive) { +- + if (!(fp = fopen (outputfile, "a"))) { + printf (_("SSH WARNING: could not open %s\n"), outputfile); + exit (STATE_UNKNOWN); +@@ -137,19 +111,19 @@ + printf ("%s", result_text); + return result; + } +- asprintf (&output, "%s", result_text); ++ asprintf (&msg, "%s", result_text); + result_text = strnl (status_text); +- eol = strpbrk (output, "\r\n"); ++ eol = strpbrk (msg, "\r\n"); + if (eol != NULL) + eol[0] = 0; + if (service[commands] && status_text +- && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) { ++ && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) ++ { + fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", +- (int) local_time, host_shortname, service[commands++], cresult, +- output); ++ (int) local_time, host_shortname, service[commands++], ++ cresult, msg); + } + } +- + } + + +@@ -206,7 +180,7 @@ + + while (1) { + c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts, +- &option); ++ &option); + + if (c == -1 || c == EOF) + break; +@@ -244,25 +218,27 @@ + passive = TRUE; + break; + case 's': /* description of service to check */ +- service = realloc (service, (++services) * sizeof(char *)); + p1 = optarg; ++ service = realloc (service, (++services) * sizeof(char *)); + while ((p2 = index (p1, ':'))) { + *p2 = '\0'; +- asprintf (&service[services-1], "%s", p1); ++ service[services - 1] = p1; + service = realloc (service, (++services) * sizeof(char *)); + p1 = p2 + 1; + } +- asprintf (&service[services-1], "%s", p1); ++ service[services - 1] = p1; + break; + case 'n': /* short name of host in nagios configuration */ + host_shortname = optarg; + break; ++ + case 'u': + c = 'l'; + case 'l': /* login name */ + case 'i': /* identity */ + asprintf (&comm, "%s -%c %s", comm, c, optarg); + break; ++ + case '1': /* Pass these switches directly to ssh */ + case '2': /* 1 to force version 1, 2 to force version 2 */ + case '4': /* -4 for IPv4 */ +diff -urN ../nplg/plugins/check_dig.c ./plugins/check_dig.c +--- ../nplg/plugins/check_dig.c 2005-01-28 15:00:58.000000000 +0100 ++++ ./plugins/check_dig.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,29 +14,33 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_dig.c,v 1.40 2005/01/26 21:21:01 tonvoon Exp $ ++ $Id: check_dig.c,v 1.3 2005/06/06 11:37:06 exon Exp $ + + *****************************************************************************/ + ++/* Hackers note: ++ * There are typecasts to (char *) from _("foo bar") in this file. ++ * They prevent compiler warnings. Never (ever), permute strings obtained ++ * that are typecast from (const char *) (which happens when --disable-nls) ++ * because on some architectures those strings are in non-writable memory */ ++ + const char *progname = "check_dig"; +-const char *revision = "$Revision: 1.40 $"; ++const char *revision = "$Revision: 1.3 $"; + const char *copyright = "2002-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" + #include "netutils.h" + #include "utils.h" +-#include "popen.h" ++#include "runcmd.h" + + int process_arguments (int, char **); + int validate_arguments (void); + void print_help (void); + void print_usage (void); + +-enum { +- UNDEFINED = 0, +- DEFAULT_PORT = 53 +-}; ++#define UNDEFINED 0 ++#define DEFAULT_PORT 53 + + char *query_address = NULL; + char *record_type = "A"; +@@ -51,16 +55,15 @@ + int + main (int argc, char **argv) + { +- char input_buffer[MAX_INPUT_BUFFER]; + char *command_line; +- char *output; ++ output chld_out, chld_err; ++ char *msg = NULL; ++ size_t i; + char *t; + long microsec; + double elapsed_time; + int result = STATE_UNKNOWN; + +- output = strdup (""); +- + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +@@ -89,100 +92,75 @@ + } + + /* run the command */ +- child_process = spopen (command_line); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), command_line); +- return STATE_UNKNOWN; ++ if((result = np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { ++ result = STATE_WARNING; ++ msg = (char *)_("dig returned an error status"); + } + +- 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)) { +- ++ for(i = 0; i < chld_out.lines; i++) { + /* the server is responding, we just got the host name... */ +- if (strstr (input_buffer, ";; ANSWER SECTION:")) { ++ if (strstr (chld_out.line[i], ";; ANSWER SECTION:")) { + + /* loop through the whole 'ANSWER SECTION' */ +- do { ++ for(; i < chld_out.lines; i++) { + /* get the host address */ +- if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) +- break; +- +- if (strpbrk (input_buffer, "\r\n")) +- input_buffer[strcspn (input_buffer, "\r\n")] = '\0'; ++ if (verbose) ++ printf ("%s\n", chld_out.line[i]); + +- if (verbose && !strstr (input_buffer, ";; ")) +- printf ("%s\n", input_buffer); +- +- if (expected_address==NULL && strstr (input_buffer, query_address) != NULL) { +- output = strdup(input_buffer); ++ if (strstr (chld_out.line[i], (expected_address == NULL ? query_address : expected_address)) != NULL) { ++ msg = chld_out.line[i]; + result = STATE_OK; +- } +- else if (expected_address != NULL && strstr (input_buffer, expected_address) != NULL) { +- output = strdup(input_buffer); +- result = STATE_OK; +- } + +- /* Translate output TAB -> SPACE */ +- t = output; +- while ((t = index(t, '\t')) != NULL) +- *t = ' '; +- +- } while (!strstr (input_buffer, ";; ")); ++ /* Translate output TAB -> SPACE */ ++ t = msg; ++ while ((t = strchr(t, '\t')) != NULL) *t = ' '; ++ break; ++ } ++ } + + if (result == STATE_UNKNOWN) { +- asprintf (&output, _("Server not found in ANSWER SECTION")); +- result = STATE_WARNING; +- } +- } +- +- } +- +- if (result == STATE_UNKNOWN) { +- asprintf (&output, _("No ANSWER SECTION found")); +- } ++ msg = (char *)_("Server not found in ANSWER SECTION"); ++ result = STATE_WARNING; ++ } + +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { +- /* If we get anything on STDERR, at least set warning */ +- result = max_state (result, STATE_WARNING); +- printf ("%s", input_buffer); +- if (strlen (output) == 0) +- output = strdup (1 + index (input_buffer, ':')); ++ /* we found the answer section, so break out of the loop */ ++ break; ++ } + } + +- (void) fclose (child_stderr); ++ if (result == STATE_UNKNOWN) ++ msg = (char *)_("No ANSWER SECTION found"); + +- /* close the pipe */ +- if (spclose (child_process)) { +- result = max_state (result, STATE_WARNING); +- if (strlen (output) == 0) +- asprintf (&output, _("dig returned an error status")); ++ /* 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; + +- if (output == NULL || strlen (output) == 0) +- asprintf (&output, _(" Probably a non-existent host/domain")); +- + if (critical_interval > UNDEFINED && elapsed_time > critical_interval) + result = STATE_CRITICAL; + + else if (warning_interval > UNDEFINED && elapsed_time > warning_interval) + result = STATE_WARNING; + +- asprintf (&output, _("%.3f seconds response time (%s)"), elapsed_time, output); +- +- printf ("DNS %s - %s|%s\n", +- state_text (result), output, ++ 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)); ++ (warning_interval>UNDEFINED?TRUE:FALSE), ++ warning_interval, ++ (critical_interval>UNDEFINED?TRUE:FALSE), ++ critical_interval, ++ TRUE, 0, FALSE, 0)); + return result; + } + +@@ -359,6 +337,6 @@ + { + printf ("\ + Usage: %s -H host -l lookup [-p ] [-T ]\n\ +- [-w ] [-c ] [-t ]\n\ +- [-a ] [-v]\n", progname); ++ [-w ] [-c ] [-t ]\n\ ++ [-a ] [-v]\n", progname); + } +diff -urN ../nplg/plugins/check_dns.c ./plugins/check_dns.c +--- ../nplg/plugins/check_dns.c 2005-01-05 21:53:12.000000000 +0100 ++++ ./plugins/check_dns.c 2005-06-10 15:01:26.000000000 +0200 +@@ -17,19 +17,19 @@ + LIMITATION: nslookup on Solaris 7 can return output over 2 lines, which will not + be picked up by this plugin + +- $Id: check_dns.c,v 1.47 2004/12/30 00:41:39 opensides Exp $ ++ $Id: check_dns.c,v 1.3 2005/06/06 11:37:06 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_dns"; +-const char *revision = "$Revision: 1.47 $"; ++const char *revision = "$Revision: 1.3 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" + #include "utils.h" + #include "netutils.h" ++#include "runcmd.h" + + int process_arguments (int, char **); + int validate_arguments (void); +@@ -51,8 +51,8 @@ + { + char *command_line = NULL; + char input_buffer[MAX_INPUT_BUFFER]; +- char *output = NULL; + char *address = NULL; ++ char *msg = NULL; + char *temp_buffer = NULL; + int non_authoritative = FALSE; + int result = STATE_UNKNOWN; +@@ -61,6 +61,8 @@ + struct timeval tv; + int multi_address; + int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ ++ output chld_out, chld_err; ++ size_t i; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -85,37 +87,31 @@ + 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; ++ if((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { ++ msg = (char *)_("nslookup returned error status"); ++ result = STATE_WARNING; + } + +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) +- printf (_("Could not open stderr for %s\n"), command_line); +- + /* scan stdout */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { +- ++ for(i = 0; i < chld_out.lines; i++) { + if (verbose) +- printf ("%s", input_buffer); ++ printf ("%s", chld_out.line[i]); + +- if (strstr (input_buffer, ".in-addr.arpa")) { +- if ((temp_buffer = strstr (input_buffer, "name = "))) ++ if (strstr (chld_out.line[i], ".in-addr.arpa")) { ++ if ((temp_buffer = strstr (chld_out.line[i], "name = "))) + address = strdup (temp_buffer + 7); + else { +- output = strdup (_("Warning plugin error")); ++ msg = (char *)_("Warning plugin error"); + result = STATE_WARNING; + } + } + + /* the server is responding, we just got the host name... */ +- if (strstr (input_buffer, "Name:")) ++ if (strstr (chld_out.line[i], "Name:")) + parse_address = TRUE; +- else if (parse_address == TRUE && (strstr (input_buffer, "Address:") || +- strstr (input_buffer, "Addresses:"))) { +- temp_buffer = index (input_buffer, ':'); ++ else if (parse_address == TRUE && (strstr (chld_out.line[i], "Address:") || ++ strstr (chld_out.line[i], "Addresses:"))) { ++ temp_buffer = index (chld_out.line[i], ':'); + temp_buffer++; + + /* Strip leading spaces */ +@@ -135,59 +131,47 @@ + asprintf(&address, "%s,%s", address, temp_buffer); + } + +- else if (strstr (input_buffer, _("Non-authoritative answer:"))) { ++ else if (strstr (chld_out.line[i], _("Non-authoritative answer:"))) { + non_authoritative = TRUE; + } + +- result = error_scan (input_buffer); ++ result = error_scan (chld_out.line[i]); + if (result != STATE_OK) { +- output = strdup (1 + index (input_buffer, ':')); +- strip (output); ++ msg = strchr (chld_out.line[i], ':'); ++ if(msg) msg++; + break; + } +- + } + + /* scan stderr */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { +- ++ for(i = 0; i < chld_err.lines; i++) { + if (verbose) +- printf ("%s", input_buffer); ++ printf ("%s", chld_err.line[i]); + +- if (error_scan (input_buffer) != STATE_OK) { +- result = max_state (result, error_scan (input_buffer)); +- output = strdup (1 + index (input_buffer, ':')); +- strip (output); ++ if (error_scan (chld_err.line[i]) != STATE_OK) { ++ result = max_state (result, error_scan (chld_err.line[i])); ++ msg = strchr(input_buffer, ':'); ++ if(msg) msg++; + } + } + +- /* close stderr */ +- (void) fclose (child_stderr); +- +- /* close stdout */ +- if (spclose (child_process)) { +- result = max_state (result, STATE_WARNING); +- if (output == NULL || !strcmp (output, "")) +- output = strdup (_("nslookup returned error status")); +- } +- +- /* If we got here, we should have an address string, +- and we can segfault if we do not */ ++ /* If we got here, we should have an address string, ++ * and we can segfault if we do not */ + if (address==NULL || strlen(address)==0) + die (STATE_CRITICAL, +- _("DNS CRITICAL - '%s' output parsing exited with no address\n"), ++ _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), + NSLOOKUP_COMMAND); + + /* compare to expected address */ + if (result == STATE_OK && match_expected_address && strcmp(address, expected_address)) { + result = STATE_CRITICAL; +- asprintf(&output, _("expected %s but got %s"), expected_address, address); ++ asprintf(&msg, _("expected %s but got %s"), expected_address, address); + } + + /* check if authoritative */ + if (result == STATE_OK && expect_authority && non_authoritative) { + result = STATE_CRITICAL; +- asprintf(&output, _("server %s is not authoritative for %s"), dns_server, query_address); ++ asprintf(&msg, _("server %s is not authoritative for %s"), dns_server, query_address); + } + + microsec = deltime (tv); +@@ -206,13 +190,13 @@ + } + else if (result == STATE_WARNING) + printf (_("DNS WARNING - %s\n"), +- !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); ++ !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg); + else if (result == STATE_CRITICAL) + printf (_("DNS CRITICAL - %s\n"), +- !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); ++ !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg); + else + printf (_("DNS UNKNOW - %s\n"), +- !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); ++ !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg); + + return result; + } +diff -urN ../nplg/plugins/check_fping.c ./plugins/check_fping.c +--- ../nplg/plugins/check_fping.c 2005-01-05 21:53:13.000000000 +0100 ++++ ./plugins/check_fping.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,26 +14,24 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_fping.c,v 1.24 2004/12/25 23:17:44 opensides Exp $ ++ $Id: check_fping.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_fping"; +-const char *revision = "$Revision: 1.24 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" + #include "netutils.h" + #include "utils.h" ++#include "runcmd.h" + +-enum { +- PACKET_COUNT = 1, +- PACKET_SIZE = 56, +- PL = 0, +- RTA = 1 +-}; ++#define PACKET_COUNT 1 ++#define PACKET_SIZE 56 ++#define PL 0 ++#define RTA 1 + + int textscan (char *buf); + int process_arguments (int, char **); +@@ -59,11 +57,11 @@ + { + /* normaly should be int result = STATE_UNKNOWN; */ + +- int status = STATE_UNKNOWN; ++ int result = STATE_UNKNOWN; + char *server = NULL; + char *command_line = NULL; +- char *input_buffer = NULL; +- input_buffer = malloc (MAX_INPUT_BUFFER); ++ output chld_out, chld_err; ++ size_t i; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -79,43 +77,21 @@ + packet_size, packet_count, server); + + if (verbose) +- printf ("%s\n", command_line); ++ printf ("command_line: %s\n", command_line); + + /* run the command */ +- child_process = spopen (command_line); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), command_line); +- return STATE_UNKNOWN; +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), command_line); +- } ++ if((np_runcmd(command_line, &chld_out, &chld_err, 0)) || chld_err.buflen) ++ result = STATE_WARNING; + +- 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); ++ for(i = 0; i < chld_out.lines; i++) ++ result = max_state (result, textscan (chld_out.line[i])); + +- /* close the pipe */ +- if (spclose (child_process)) +- /* need to use max_state not max */ +- status = max_state (status, STATE_WARNING); ++ printf ("FPING %s - %s\n", state_text (result), server_name); + +- printf ("FPING %s - %s\n", state_text (status), server_name); ++ if (verbose) for(i = 0; i < chld_out.lines; i++) ++ printf ("%s", chld_out.line[i]); + +- return status; ++ return result; + } + + +@@ -127,7 +103,7 @@ + char *losstr = NULL; + double loss; + double rta; +- int status = STATE_UNKNOWN; ++ int result = STATE_UNKNOWN; + + if (strstr (buf, "not found")) { + die (STATE_CRITICAL, _("FPING UNKNOW - %s not found\n"), server_name); +@@ -143,7 +119,7 @@ + + } + else if (strstr (buf, "is alive")) { +- status = STATE_OK; ++ result = STATE_OK; + + } + else if (strstr (buf, "xmt/rcv/%loss") && strstr (buf, "min/avg/max")) { +@@ -156,18 +132,18 @@ + loss = strtod (losstr, NULL); + rta = strtod (rtastr, NULL); + if (cpl_p == TRUE && loss > cpl) +- status = STATE_CRITICAL; ++ result = STATE_CRITICAL; + else if (crta_p == TRUE && rta > crta) +- status = STATE_CRITICAL; ++ result = STATE_CRITICAL; + else if (wpl_p == TRUE && loss > wpl) +- status = STATE_WARNING; ++ result = STATE_WARNING; + else if (wrta_p == TRUE && rta > wrta) +- status = STATE_WARNING; ++ result = STATE_WARNING; + else +- status = STATE_OK; +- die (status, ++ result = STATE_OK; ++ die (result, + _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), +- state_text (status), server_name, loss, rta, ++ state_text (result), 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)); + +@@ -179,24 +155,24 @@ + losstr = 1 + strstr (losstr, "/"); + loss = strtod (losstr, NULL); + if (atoi(losstr) == 100) +- status = STATE_CRITICAL; ++ result = STATE_CRITICAL; + else if (cpl_p == TRUE && loss > cpl) +- status = STATE_CRITICAL; ++ result = STATE_CRITICAL; + else if (wpl_p == TRUE && loss > wpl) +- status = STATE_WARNING; ++ result = STATE_WARNING; + else +- status = STATE_OK; ++ result = STATE_OK; + /* loss=%.0f%%;%d;%d;0;100 */ +- die (status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), +- state_text (status), server_name, loss , ++ die (result, _("FPING %s - %s (loss=%.0f%% )|%s\n"), ++ state_text (result), 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); ++ result = max_state (result, STATE_WARNING); + } + +- return status; ++ return result; + } + + +diff -urN ../nplg/plugins/check_game.c ./plugins/check_game.c +--- ../nplg/plugins/check_game.c 2005-01-05 21:53:13.000000000 +0100 ++++ ./plugins/check_game.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,17 +14,17 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * +-* $Id: check_game.c,v 1.22 2004/12/25 23:17:44 opensides Exp $ ++* $Id: check_game.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + *****************************************************************************/ + + const char *progname = "check_game"; +-const char *revision = "$Revision: 1.22 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "2002-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" + #include "utils.h" ++#include "runcmd.h" + + int process_arguments (int, char **); + int validate_arguments (void); +@@ -57,9 +57,9 @@ + char *command_line; + int result = STATE_UNKNOWN; + FILE *fp; +- char input_buffer[MAX_INPUT_BUFFER]; + char *p, *ret[QSTAT_MAX_RETURN_ARGS]; +- int i; ++ size_t i = 0; ++ output chld_out; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -80,17 +80,9 @@ + if (verbose > 0) + printf ("%s\n", command_line); + +- /* run the command */ +- fp = spopen (command_line); +- if (fp == NULL) { +- printf (_("Could not open pipe: %s\n"), command_line); +- return STATE_UNKNOWN; +- } +- +- fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */ +- +- /* strip the newline character from the end of the input */ +- input_buffer[strlen (input_buffer) - 1] = 0; ++ /* 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 +@@ -102,18 +94,13 @@ + In the end, I figured I'd simply let an error occur & then trap it + */ + +- if (!strncmp (input_buffer, "unknown option", 14)) { ++ if (!strncmp (chld_out.line[0], "unknown option", 14)) { + printf (_("CRITICAL - Host type parameter incorrect!\n")); + result = STATE_CRITICAL; + return result; + } + +- /* initialize the returned data buffer */ +- for (i = 0; i < QSTAT_MAX_RETURN_ARGS; i++) +- ret[i] = strdup(""); +- +- i = 0; +- p = (char *) strtok (input_buffer, QSTAT_DATA_DELIMITER); ++ p = (char *) strtok (chld_out.line[0], QSTAT_DATA_DELIMITER); + while (p != NULL) { + ret[i] = p; + p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER); +@@ -141,17 +128,14 @@ + ret[qstat_game_field], + ret[qstat_map_field], + ret[qstat_ping_field], +- perfdata ("players", atol(ret[qstat_game_players]), "", ++ 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), "", ++ fperfdata ("ping", strtod(ret[qstat_ping_field], NULL), "", + FALSE, 0, FALSE, 0, + TRUE, 0, FALSE, 0)); + } + +- /* close the pipe */ +- spclose (fp); +- + return result; + } + +diff -urN ../nplg/plugins/check_hpjd.c ./plugins/check_hpjd.c +--- ../nplg/plugins/check_hpjd.c 2005-01-05 21:53:13.000000000 +0100 ++++ ./plugins/check_hpjd.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,24 +14,22 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * +-* $Id: check_hpjd.c,v 1.31 2004/12/25 23:17:44 opensides Exp $ ++* $Id: check_hpjd.c,v 1.4 2005/06/06 11:37:06 exon Exp $ + *****************************************************************************/ + + const char *progname = "check_hpjd"; +-const char *revision = "$Revision: 1.31 $"; ++const char *revision = "$Revision: 1.4 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" + #include "utils.h" + #include "netutils.h" ++#include "runcmd.h" + + #define DEFAULT_COMMUNITY "public" + +- +-const char *option_summary = "-H host [-C community]\n"; +- ++/* this macro is only avavilable from main() */ + #define HPJD_LINE_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.1" + #define HPJD_PAPER_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.2" + #define HPJD_INTERVENTION_REQUIRED ".1.3.6.1.4.1.11.2.3.9.1.1.2.3" +@@ -44,42 +42,50 @@ + #define HPJD_GD_DOOR_OPEN ".1.3.6.1.4.1.11.2.3.9.1.1.2.17" + #define HPJD_GD_PAPER_OUTPUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.19" + #define HPJD_GD_STATUS_DISPLAY ".1.3.6.1.4.1.11.2.3.9.1.1.3" ++#define SNMP_VARS 12 + + #define ONLINE 0 + #define OFFLINE 1 + +-int process_arguments (int, char **); +-int validate_arguments (void); +-void print_help (void); ++/* make it compile without warnings when internationalization is disabled */ ++#ifndef ENABLE_NLS ++# ifdef _ ++# undef _ ++# endif ++# define _(x) x ++#endif ++ ++static int process_arguments (int, char **); ++static int validate_arguments (void); ++static void print_help (void); + void print_usage (void); + +-char *community = NULL; +-char *address = NULL; ++static char *community = NULL; ++static char *address = NULL; ++ + + int + main (int argc, char **argv) + { + char command_line[1024]; +- int result = STATE_UNKNOWN; +- int line; +- char input_buffer[MAX_INPUT_BUFFER]; +- char query_string[512]; +- char *errmsg; +- char *temp_buffer; +- int line_status = ONLINE; +- int paper_status = 0; +- int intervention_required = 0; +- int peripheral_error = 0; +- int paper_jam = 0; +- int paper_out = 0; +- int toner_low = 0; +- int page_punt = 0; +- int memory_out = 0; +- int door_open = 0; +- int paper_output = 0; +- char display_message[MAX_INPUT_BUFFER]; +- +- errmsg = malloc(MAX_INPUT_BUFFER); ++ int result = STATE_OK; ++ size_t i, val = 0; ++ int errorflag = 0; /* bitflag error tracker */ ++ output chld_out, chld_err; ++ char *errmsg_strings[11]; ++ ++ /* populate the the error message array */ ++ errmsg_strings[0] = _("Printer Offline"); ++ errmsg_strings[1] = _("Unknown Paper Error"); ++ errmsg_strings[2] = _("Intervention Required"); ++ errmsg_strings[3] = _("Peripheral Error"); ++ errmsg_strings[4] = _("Paper Jam"); ++ errmsg_strings[5] = _("Out of Paper"); ++ errmsg_strings[6] = _("Toner Low"); ++ errmsg_strings[7] = _("Data too Slow for Engine"); ++ errmsg_strings[8] = _("Insufficient Memory"); ++ errmsg_strings[9] = _("A Door is Open"); ++ errmsg_strings[10] = _("Output Tray is Full"); + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -88,206 +94,99 @@ + 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); +- +- /* get the command to run */ +- sprintf (command_line, "%s -OQa -m : -v 1 -c %s %s %s", PATH_TO_SNMPGET, community, +- address, query_string); ++ /* create the command-line. Get status display line first, so we can ++ * match line status against powersave as we parse it */ ++ sprintf (command_line, "%s -Oqv -m : -v 1 -c %s %s " ++ "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", ++ PATH_TO_SNMPGET, community, address, ++ HPJD_GD_STATUS_DISPLAY, ++ 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); + + /* run the command */ +- child_process = spopen (command_line); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), command_line); +- return STATE_UNKNOWN; +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), command_line); +- } +- +- result = STATE_OK; +- +- line = 0; +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { ++ if((np_runcmd(command_line, &chld_out, &chld_err, 0)) || chld_err.buflen) ++ result = STATE_WARNING; + +- /* strip the newline character from the end of the input */ +- if (input_buffer[strlen (input_buffer) - 1] == '\n') +- input_buffer[strlen (input_buffer) - 1] = 0; +- +- line++; +- +- temp_buffer = strtok (input_buffer, "="); +- temp_buffer = strtok (NULL, "="); +- +- if (temp_buffer == NULL) { +- +- result = STATE_UNKNOWN; +- strcpy (errmsg, input_buffer); +- +- } else { +- +- switch (line) { +- +- 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); +- break; +- 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); +- break; +- 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); +- break; +- 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); +- break; +- 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); +- break; +- case 11: /* is output tray full */ +- paper_output = atoi (temp_buffer); +- break; +- case 12: /* display panel message */ +- strcpy (display_message, temp_buffer + 1); +- break; +- default: +- break; +- } +- +- } +- +- /* break out of the read loop if we encounter an error */ +- if (result != STATE_OK) +- break; +- } ++ /* if there was none or not enough output, display an error and exit */ ++ if (chld_out.buflen == 0 || chld_out.lines != SNMP_VARS - 1) { ++ if(chld_err.buflen) printf("%s : ", chld_err.line[0]); + +- /* WARNING if output found on stderr */ +- 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(chld_out.buflen == 0) ++ printf (_("No data returned from %s\n"), address ); ++ else ++ printf(_("Not enough data returned from %s\n"), address); + +- } +- +- /* close stderr */ +- (void) fclose (child_stderr); +- +- /* close the pipe */ +- 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 ; +- asprintf (&errmsg, "%s : Timeout from host %s\n", errmsg, address ); +- ++ return STATE_UNKNOWN; + } + +- /* if we had no read errors, check the printer status results... */ +- if (result == STATE_OK) { ++ for(i = 1; i < chld_out.lines; i++) { ++ /* move to next if there's no error tag */ ++ if(!(val = (size_t)strtol(chld_out.line[i], NULL, 0))) ++ continue; ++ ++ /* tag the error */ ++ errorflag |= 1 << i; ++ ++ /* this switch statement is only for additional exception handling */ ++ switch (i) { ++ case 1: /* line status */ ++ /* clear this flag if it's powersaving (we know it's set if ++ * we get here, so use xor and save 2 instructions) */ ++ if(!strstr(chld_out.line[0], "POWERSAVE ON")) ++ errorflag ^= 1 << i; ++ break; + +- if (paper_jam) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Paper Jam")); +- } +- else if (paper_out) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Out of Paper")); +- } +- else if (line_status == OFFLINE) { +- if (strcmp (errmsg, "POWERSAVE ON") != 0) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Printer Offline")); +- } +- } +- else if (peripheral_error) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Peripheral Error")); +- } +- else if (intervention_required) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Intervention Required")); +- } +- else if (toner_low) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Toner Low")); +- } +- else if (memory_out) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Insufficient Memory")); +- } +- else if (door_open) { +- result = STATE_WARNING; +- strcpy (errmsg, _("A Door is Open")); +- } +- else if (paper_output) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Output Tray is Full")); +- } +- else if (page_punt) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Data too Slow for Engine")); +- } +- else if (paper_status) { +- result = STATE_WARNING; +- strcpy (errmsg, _("Unknown Paper Error")); ++ case 2: /* paper status */ ++ case 3: /* intervention required */ ++ case 4: /* peripheral error */ ++ case 5: /* paper jam */ ++ case 6: /* paper out */ ++ case 7: /* toner low */ ++ case 8: /* data came too slow for engine */ ++ case 9: /* out of memory */ ++ case 10: /* door open */ ++ case 11: /* output tray full */ ++ break; + } + } + +- if (result == STATE_OK) +- printf (_("Printer ok - (%s)\n"), display_message); +- +- else if (result == STATE_UNKNOWN) { ++ /* if some error occurred, print a starting line and all the errors */ ++ if(errorflag) { ++ printf ("%s (%s)", chld_err.buflen != 0 ? chld_err.buf : "", ++ chld_out.line[0]); + +- printf ("%s\n", errmsg); ++ for(i = 0; i < SNMP_VARS; i++) { /* loop the error flags */ ++ if((errorflag >> i) & 1) /* only print if flag is set */ ++ printf(" :: %s", errmsg_strings[i++]); ++ } + +- /* if printer could not be reached, escalate to critical */ +- if (strstr (errmsg, "Timeout")) +- result = STATE_CRITICAL; ++ return STATE_CRITICAL; + } + +- else if (result == STATE_WARNING) +- printf ("%s (%s)\n", errmsg, display_message); ++ /* set WARNING if output on stderr */ ++ if (chld_err.buflen) { ++ printf("WARNING - Printer seems ok, but %s printed to stderr (%s)", ++ PATH_TO_SNMPGET, chld_err.line[0]); ++ return STATE_WARNING; ++ } + +- return result; ++ /* all is well if we end up here */ ++ printf (_("Printer ok - (%s)\n"), chld_out.line[0]); ++ return STATE_OK; + } + + + /* process command-line arguments */ +-int ++static int + process_arguments (int argc, char **argv) + { + int c; +@@ -296,9 +195,6 @@ + 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} +@@ -307,7 +203,6 @@ + if (argc < 2) + return ERROR; + +- + while (1) { + c = getopt_long (argc, argv, "+hVH:C:", longopts, &option); + +@@ -317,7 +212,7 @@ + switch (c) { + case 'H': /* hostname */ + if (is_host (optarg)) { +- address = strscpy(address, optarg) ; ++ address = strdup(optarg) ; + } + else { + usage2 (_("Invalid hostname/address"), optarg); +@@ -346,26 +241,26 @@ + usage2 (_("Invalid hostname/address"), argv[c]); + } + } +- ++ + if (community == NULL) { + if (argv[c] != NULL ) + community = argv[c]; + else +- community = strdup (DEFAULT_COMMUNITY); ++ community = DEFAULT_COMMUNITY; + } + + return validate_arguments (); + } + + +-int ++static int + validate_arguments (void) + { + return OK; + } + + +-void ++static void + print_help (void) + { + print_revision (progname, revision); +@@ -389,7 +284,6 @@ + } + + +- + void + print_usage (void) + { +diff -urN ../nplg/plugins/check_load.c ./plugins/check_load.c +--- ../nplg/plugins/check_load.c 2005-05-30 17:44:13.000000000 +0200 ++++ ./plugins/check_load.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,18 +14,18 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_load.c,v 1.28 2005/05/28 01:21:54 seanius Exp $ ++ $Id: check_load.c,v 1.3 2005/06/05 21:55:26 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_load"; +-const char *revision = "$Revision: 1.28 $"; ++const char *revision = "$Revision: 1.3 $"; + const char *copyright = "1999-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" + #include "utils.h" +-#include "popen.h" ++#include "runcmd.h" + + #ifdef HAVE_SYS_LOADAVG_H + #include +@@ -47,12 +47,8 @@ + /* strictly for pretty-print usage in loops */ + static const int nums[3] = { 1, 5, 15 }; + +-/* provide some fairly sane defaults */ + double wload[3] = { 0.0, 0.0, 0.0 }; + double cload[3] = { 0.0, 0.0, 0.0 }; +-#define la1 la[0] +-#define la5 la[1] +-#define la15 la[2] + + char *status_line; + +@@ -86,14 +82,16 @@ + main (int argc, char **argv) + { + int result; +- int i; ++ size_t i; /* size_t so we can match against chld_out.lines if need be */ + + double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */ + #ifndef HAVE_GETLOADAVG +- char input_buffer[MAX_INPUT_BUFFER]; + # ifdef HAVE_PROC_LOADAVG ++ char input_buffer[MAX_INPUT_BUFFER]; + FILE *fp; + char *str, *next; ++# else ++ output chld_out, chld_err; + # endif + #endif + +@@ -126,23 +124,11 @@ + + fclose (fp); + # else +- child_process = spopen (PATH_TO_UPTIME); +- if (child_process == NULL) { +- printf (_("Error opening %s\n"), PATH_TO_UPTIME); +- return STATE_UNKNOWN; +- } +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), PATH_TO_UPTIME); +- } +- fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); +- sscanf (input_buffer, "%*[^l]load average: %f, %f, %f", &la1, &la5, &la15); ++ if((result = np_runcmd(PATH_TO_UPTIME, &chld_out, &chld_err, 0)) || chld_err.buflen) ++ die(STATE_UNKNOWN, _("Error code %d returned in %s\n"), ++ result, PATH_TO_UPTIME); + +- result = spclose (child_process); +- if (result) { +- printf (_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME); +- return STATE_UNKNOWN; +- } ++ sscanf (chld_out.buf, "%*[^l]load average: %f, %f, %f", &la[0], &la[1], &la[2]); + # endif + #endif + +@@ -162,17 +148,17 @@ + /* we got this far, so assume OK until we've measured */ + result = STATE_OK; + +- asprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15); +- + for(i = 0; i < 3; i++) { + if(la[i] > cload[i]) { + result = STATE_CRITICAL; + break; + } +- else if(la[i] > wload[i]) result = STATE_WARNING; ++ ++ if(la[i] > wload[i]) result = STATE_WARNING; + } + +- printf("%s - %s|", state_text(result), status_line); ++ printf(_("%s - load average: %.2f, %.2f, %.2f|"), ++ state_text(result), la[0], la[1], la[2]); + for(i = 0; i < 3; i++) + printf("load%d=%.3f;%.3f;%.3f;0; ", nums[i], la[i], wload[i], cload[i]); + +@@ -248,14 +234,13 @@ + int i = 0; + + /* match cload first, as it will give the most friendly error message +- * if user hasn't given the -c switch properly */ ++ * if user hasn't given the -c switch properly. Don't make sure wload[i] ++ * < cload[i] as it prevents users from forcing a critical state */ + for(i = 0; i < 3; i++) { +- if(cload[i] < 0) ++ if(cload[i] == 0.0) + die (STATE_UNKNOWN, _("Critical threshold for %d-minute load average is not specified\n"), nums[i]); +- if(wload[i] < 0) ++ if(wload[i] == 0.0) + die (STATE_UNKNOWN, _("Warning threshold for %d-minute load average is not specified\n"), nums[i]); +- if(wload[i] > cload[i]) +- die (STATE_UNKNOWN, _("Parameter inconsistency: %d-minute \"warning load\" is greater than \"critical load\"\n"), nums[i]); + } + + return OK; +diff -urN ../nplg/plugins/check_nagios.c ./plugins/check_nagios.c +--- ../nplg/plugins/check_nagios.c 2005-05-26 14:12:21.000000000 +0200 ++++ ./plugins/check_nagios.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,17 +14,17 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_nagios.c,v 1.26 2005/05/25 00:43:20 seanius Exp $ ++ $Id: check_nagios.c,v 1.3 2005/06/06 11:37:06 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_nagios"; +-const char *revision = "$Revision: 1.26 $"; ++const char *revision = "$Revision: 1.3 $"; + const char *copyright = "1999-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" ++#include "runcmd.h" + #include "utils.h" + + int process_arguments (int, char **); +@@ -55,6 +55,8 @@ + int procrss = 0; + float procpcpu = 0; + char procstat[8]; ++ /* procetime is unused in most configurations, but may be in PS_VAR_LIST ++ * so it must be here in spite of it producing compiler warnings */ + char procetime[MAX_INPUT_BUFFER]; + char procprog[MAX_INPUT_BUFFER]; + char *procargs; +@@ -62,6 +64,8 @@ + int expected_cols = PS_COLS - 1; + const char *zombie = "Z"; + char *temp_string; ++ output chld_out, chld_err; ++ size_t i; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -99,40 +103,30 @@ + printf(_("command: %s\n"), PS_COMMAND); + + /* run the command to check for the Nagios process.. */ +- child_process = spopen (PS_COMMAND); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), PS_COMMAND); +- return STATE_UNKNOWN; +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), PS_COMMAND); +- } +- +- fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); ++ if((result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0)) != 0) ++ result = STATE_WARNING; + + /* count the number of matching Nagios processes... */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { +- cols = sscanf (input_buffer, PS_FORMAT, PS_VARLIST); +- /* Zombie processes do not give a procprog command */ +- 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 */ +- input_buffer[pos] = '\n'; +- input_buffer[pos+1] = 0x0; +- } ++ 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) ) { ++ 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; ++ } + if ( cols >= expected_cols ) { +- asprintf (&procargs, "%s", input_buffer + pos); ++ asprintf (&procargs, "%s", chld_out.line[i] + pos); + strip (procargs); +- ++ + /* Some ps return full pathname for command. This removes path */ +- temp_string = strtok ((char *)procprog, "/"); +- while (temp_string) { +- strcpy(procprog, temp_string); +- temp_string = strtok (NULL, "/"); +- } ++ temp_string = strtok ((char *)procprog, "/"); ++ while (temp_string) { ++ strcpy(procprog, temp_string); ++ temp_string = strtok (NULL, "/"); ++ } + + /* May get empty procargs */ + if (!strstr(procargs, argv[0]) && strstr(procargs, process_string) && strcmp(procargs,"")) { +@@ -145,14 +139,7 @@ + } + + /* If we get anything on stderr, at least set warning */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) +- result = max_state (result, STATE_WARNING); +- +- /* close stderr */ +- (void) fclose (child_stderr); +- +- /* close the pipe */ +- if (spclose (child_process)) ++ if(chld_err.buflen) + result = max_state (result, STATE_WARNING); + + /* reset the alarm handler */ +diff -urN ../nplg/plugins/check_ping.c ./plugins/check_ping.c +--- ../nplg/plugins/check_ping.c 2005-05-26 14:12:21.000000000 +0200 ++++ ./plugins/check_ping.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,18 +14,18 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_ping.c,v 1.44 2005/05/25 14:25:55 sghosh Exp $ ++ $Id: check_ping.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_ping"; +-const char *revision = "$Revision: 1.44 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" + #include "netutils.h" +-#include "popen.h" ++#include "runcmd.h" + #include "utils.h" + + #define WARN_DUPLICATES "DUPLICATES FOUND! " +@@ -40,7 +40,7 @@ + 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); ++int error_scan (const char *buf, const char *addr); + void print_usage (void); + void print_help (void); + +@@ -58,7 +58,7 @@ + float rta = UNKNOWN_TRIP_TIME; + int pl = UNKNOWN_PACKET_LOSS; + +-char *warn_text; ++char *warn_text = NULL; + + + +@@ -95,10 +95,8 @@ + if (is_inet6_addr(addresses[i]) && address_family != AF_INET) + rawcmd = strdup(PING6_COMMAND); + else +- rawcmd = strdup(PING_COMMAND); +-#else +- rawcmd = strdup(PING_COMMAND); + #endif ++ rawcmd = strdup(PING_COMMAND); + + /* does the host address of number of packets argument come first? */ + #ifdef PING_PACKETS_FIRST +@@ -119,8 +117,7 @@ + + if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) { + printf ("%s\n", cmd); +- die (STATE_UNKNOWN, +- _("CRITICAL - Could not interpret output from ping command\n")); ++ die (STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n")); + } + + if (pl >= cpl || rta >= crta || rta < 0) +@@ -136,11 +133,11 @@ + if (display_html == TRUE) + printf ("", 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 ? warn_text : " ", pl); + else + printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), +- state_text (this_result), warn_text, pl, rta); ++ state_text (this_result), warn_text ? warn_text : " ", pl, rta); + if (display_html == TRUE) + printf (""); + printf ("\n"); +@@ -399,42 +396,42 @@ + int + run_ping (const char *cmd, const char *addr) + { +- char buf[MAX_INPUT_BUFFER]; + int result = STATE_UNKNOWN; +- +- 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"); +- if (child_stderr == NULL) +- printf (_("Cannot open stderr for %s\n"), cmd); +- +- while (fgets (buf, MAX_INPUT_BUFFER - 1, child_process)) { +- +- result = max_state (result, error_scan (buf, addr)); +- +- /* get the percent loss statistics */ +- if(sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss",&pl)==1 || +- sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% packet loss",&pl)==1 || +- sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% loss, time",&pl)==1 || +- sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time", &pl)==1 || +- sscanf(buf,"%*d packets transmitted, %*d received, %d%% packet loss, time", &pl)==1 || +- sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss", &pl) == 1 || +- sscanf(buf,"%*d packets transmitted %*d received, +%*d errors, %d%% packet loss", &pl) == 1 +- ) ++ output chld_out, chld_err; ++ char *p; ++ size_t mult = 1, i; ++ ++ if((result = np_runcmd(cmd, &chld_out, &chld_err, 0)) != 0) ++ result = STATE_WARNING; ++ ++ for(i = 0; i < chld_out.lines; i++) { ++ /* get the packet loss. Find the % sign and count backwards */ ++ if((p = memchr(chld_out.line[i], '%', chld_out.lens[i]))) { ++ p--; ++ pl = 0; ++ while(p != chld_out.line[i] && isdigit(*p)) { ++ pl += *p - '0' * mult; ++ mult *= 10; ++ p--; ++ } + continue; +- ++ } + /* get the round trip average */ +- else +- if(sscanf(buf,"round-trip min/avg/max = %*f/%f/%*f",&rta)==1 || +- sscanf(buf,"round-trip min/avg/max/mdev = %*f/%f/%*f/%*f",&rta)==1 || +- sscanf(buf,"round-trip min/avg/max/sdev = %*f/%f/%*f/%*f",&rta)==1 || +- sscanf(buf,"round-trip min/avg/max/stddev = %*f/%f/%*f/%*f",&rta)==1 || +- sscanf(buf,"round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f",&rta)==1 || +- sscanf(buf,"round-trip (ms) min/avg/max = %*f/%f/%*f",&rta)==1 || +- sscanf(buf,"round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f",&rta)==1 || +- sscanf(buf,"rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms",&rta)==1) +- continue; ++ else { ++ if(sscanf(chld_out.line[i], "round-trip min/avg/max = %*f/%f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "round-trip (ms) min/avg/max = %*f/%f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f", &rta) == 1 || ++ sscanf(chld_out.line[i], "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms", &rta) == 1) ++ { ++ continue; ++ } ++ ++ result = max_state (result, error_scan (chld_out.line[i], addr)); ++ } + } + + /* this is needed because there is no rta if all packets are lost */ +@@ -442,19 +439,10 @@ + rta = crta; + + /* check stderr, setting at least WARNING if there is output here */ +- while (fgets (buf, MAX_INPUT_BUFFER - 1, child_stderr)) +- if (! strstr(buf,"WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP")) +- result = max_state (STATE_WARNING, error_scan (buf, addr)); +- +- (void) fclose (child_stderr); +- +- +- /* close the pipe - WARNING if status is set */ +- if (spclose (child_process)) +- result = max_state (result, STATE_WARNING); +- +- if (warn_text == NULL) +- warn_text = strdup(""); ++ if(chld_err.buflen > 0) { ++ if (! strstr(chld_err.line[0], "WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP")) ++ result = max_state (STATE_WARNING, error_scan (chld_err.line[0], addr)); ++ } + + return result; + } +@@ -462,7 +450,7 @@ + + + int +-error_scan (char buf[MAX_INPUT_BUFFER], const char *addr) ++error_scan (const char *buf, const char *addr) + { + if (strstr (buf, "Network is unreachable")) + die (STATE_CRITICAL, _("CRITICAL - Network unreachable (%s)"), addr); +diff -urN ../nplg/plugins/check_procs.c ./plugins/check_procs.c +--- ../nplg/plugins/check_procs.c 2005-06-03 19:35:45.000000000 +0200 ++++ ./plugins/check_procs.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,17 +14,17 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_procs.c,v 1.45 2005/06/03 13:53:43 seanius Exp $ ++ $Id: check_procs.c,v 1.3 2005/06/06 11:37:06 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_procs"; +-const char *revision = "$Revision: 1.45 $"; ++const char *revision = "$Revision: 1.3 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" ++#include "runcmd.h" + #include "utils.h" + + #include +@@ -96,7 +96,7 @@ + char procstat[8]; + char procetime[MAX_INPUT_BUFFER] = { '\0' }; + char *procargs; +- char *temp_string; ++ output chld_out, chld_err; + + const char *zombie = "Z"; + +@@ -118,7 +118,7 @@ + input_buffer = malloc (MAX_INPUT_BUFFER); + procprog = malloc (MAX_INPUT_BUFFER); + +- asprintf (&metric_name, "PROCS"); ++ metric_name = "PROCS"; + metric = METRIC_PROCS; + + if (process_arguments (argc, argv) == ERROR) +@@ -136,27 +136,15 @@ + if (verbose >= 2) + printf (_("CMD: %s\n"), PS_COMMAND); + +- child_process = spopen (PS_COMMAND); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), PS_COMMAND); +- return STATE_UNKNOWN; +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) +- printf (_("Could not open stderr for %s\n"), PS_COMMAND); +- +- /* flush first line */ +- fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); +- while ( input_buffer[strlen(input_buffer)-1] != '\n' ) +- fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); +- +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { +- asprintf (&input_line, "%s", input_buffer); +- while ( input_buffer[strlen(input_buffer)-1] != '\n' ) { +- fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); +- asprintf (&input_line, "%s%s", input_line, input_buffer); +- } ++ result = np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0); ++ if(result) { ++ printf (_("System call returned nonzero status\n")); ++ result = max_state (result, STATE_WARNING); ++ } ++ ++ /* start parsing on second line */ ++ for(i = 1; i < chld_out.lines; i++) { ++ input_line = chld_out.line[i]; + + if (verbose >= 3) + printf ("%s", input_line); +@@ -177,8 +165,7 @@ + + /* Some ps return full pathname for command. This removes path */ + #ifdef HAVE_BASENAME +- temp_string = strdup(procprog); +- procprog = basename(temp_string); ++ procprog = strdup(basename(procprog)); + #endif /* HAVE_BASENAME */ + + /* we need to convert the elapsed time to seconds */ +@@ -248,27 +235,17 @@ + } + + /* If we get anything on STDERR, at least set warning */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { +- if (verbose) +- printf ("STDERR: %s", input_buffer); ++ if(chld_err.buflen > 0) { + result = max_state (result, STATE_WARNING); + printf (_("System call sent warnings to stderr\n")); + } +- +- (void) fclose (child_stderr); +- +- /* close the pipe */ +- if (spclose (child_process)) { +- printf (_("System call returned nonzero status\n")); +- result = max_state (result, STATE_WARNING); +- } + + if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ + printf (_("Unable to read output\n")); + return result; + } + +- if ( result == STATE_UNKNOWN ) ++ if ( result == STATE_UNKNOWN ) + result = STATE_OK; + + /* Needed if procs found, but none match filter */ +@@ -459,7 +436,7 @@ + } + usage4 (_("PCPU must be a float!")); + case 'm': +- asprintf (&metric_name, "%s", optarg); ++ metric_name = optarg; + if ( strcmp(optarg, "PROCS") == 0) { + metric = METRIC_PROCS; + break; +@@ -494,7 +471,7 @@ + if (cmax == -1 && argv[c]) + cmax = atoi (argv[c++]); + if (statopts == NULL && argv[c]) { +- asprintf (&statopts, "%s", argv[c++]); ++ statopts = argv[c++]; + asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); + options |= STAT; + } +diff -urN ../nplg/plugins/check_snmp.c ./plugins/check_snmp.c +--- ../nplg/plugins/check_snmp.c 2005-06-03 12:07:28.000000000 +0200 ++++ ./plugins/check_snmp.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,18 +14,18 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_snmp.c,v 1.57 2005/06/01 19:41:01 sghosh Exp $ ++ $Id: check_snmp.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + + ******************************************************************************/ + + const char *progname = "check_snmp"; +-const char *revision = "$Revision: 1.57 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "1999-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" + #include "utils.h" +-#include "popen.h" ++#include "runcmd.h" + + #define DEFAULT_COMMUNITY "public" + #define DEFAULT_PORT "161" +@@ -136,11 +136,12 @@ + char *command_line = NULL; + char *response = NULL; + char *outbuff; +- char *output; ++ char *msg; + char *ptr = NULL; + char *p2 = NULL; + char *show = NULL; + char type[8]; ++ output chld_out, chld_err; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -157,7 +158,7 @@ + units = strdup (""); + port = strdup (DEFAULT_PORT); + outbuff = strdup (""); +- output = strdup (""); ++ msg = strdup (""); + delimiter = strdup (" = "); + output_delim = strdup (DEFAULT_OUTPUT_DELIMITER); + /* miblist = strdup (DEFAULT_MIBLIST); */ +@@ -168,41 +169,25 @@ + usage4 (_("Could not parse arguments")); + + /* create the command line to execute */ +- if(usesnmpgetnext == TRUE) { +- asprintf(&command_line, "%s -t %d -r %d -m %s -v %s %s %s:%s %s", +- PATH_TO_SNMPGETNEXT, timeout_interval, retries, miblist, proto, +- authpriv, server_address, port, oid); +- }else{ +- +- asprintf (&command_line, "%s -t %d -r %d -m %s -v %s %s %s:%s %s", +- PATH_TO_SNMPGET, timeout_interval, retries, miblist, proto, +- authpriv, server_address, port, oid); +- } +- ++ asprintf(&command_line, "%s -t %d -r %d -m %s -v %s %s %s:%s %s", ++ usesnmpgetnext == TRUE ? PATH_TO_SNMPGETNEXT : PATH_TO_SNMPGET, ++ timeout_interval, retries, miblist, proto, ++ authpriv, server_address, port, oid); ++ + 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); +- exit (STATE_UNKNOWN); +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), command_line); +- } ++ if((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0 || chld_err.buflen) ++ result = STATE_WARNING; + +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) +- asprintf (&output, "%s%s", output, input_buffer); ++ for(i = 0; (size_t)i < chld_out.lines; i++) ++ asprintf (&msg, "%s%s", msg, input_buffer); + + if (verbose) +- printf ("%s\n", output); +- +- ptr = output; ++ printf ("%s\n", msg); + ++ ptr = msg; + strcat(perfstr, "| "); + while (ptr) { + char *foo; +@@ -261,18 +246,11 @@ + iresult = STATE_DEPENDENT; + + /* Process this block for integer comparisons */ +- if (eval_method[i] & CRIT_GT || +- eval_method[i] & CRIT_LT || +- eval_method[i] & CRIT_GE || +- eval_method[i] & CRIT_LE || +- eval_method[i] & CRIT_EQ || +- eval_method[i] & CRIT_NE || +- eval_method[i] & WARN_GT || +- eval_method[i] & WARN_LT || +- eval_method[i] & WARN_GE || +- eval_method[i] & WARN_LE || +- eval_method[i] & WARN_EQ || +- eval_method[i] & WARN_NE) { ++ if (eval_method[i] & (CRIT_GT | CRIT_LT | CRIT_GE | ++ CRIT_LE | CRIT_EQ | CRIT_NE | ++ WARN_GT | WARN_LT | WARN_GE | ++ WARN_LE | WARN_EQ | WARN_NE)) ++ { + p2 = strpbrk (p2, "0123456789"); + if (p2 == NULL) + die (STATE_UNKNOWN,_("No valid data returned")); +@@ -350,20 +328,6 @@ + label, + command_line); + +- /* WARNING if output found on stderr */ +- if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) +- result = max_state (result, STATE_WARNING); +- +- /* close stderr */ +- (void) fclose (child_stderr); +- +- /* close the pipe */ +- if (spclose (child_process)) +- result = max_state (result, STATE_WARNING); +- +-/* if (nunits == 1 || i == 1) */ +-/* printf ("%s %s -%s %s\n", label, state_text (result), outbuff, units); */ +-/* else */ + printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr); + + return result; +diff -urN ../nplg/plugins/check_swap.c ./plugins/check_swap.c +--- ../nplg/plugins/check_swap.c 2005-01-24 08:29:54.000000000 +0100 ++++ ./plugins/check_swap.c 2005-06-10 15:01:26.000000000 +0200 +@@ -21,18 +21,18 @@ + * + * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) + * +- * $Id: check_swap.c,v 1.47 2005/01/19 21:14:47 tonvoon Exp $ ++ * $Id: check_swap.c,v 1.4 2005/06/06 11:37:06 exon Exp $ + * + *****************************************************************************/ + + const char *progname = "check_swap"; +-const char *revision = "$Revision: 1.47 $"; ++const char *revision = "$Revision: 1.4 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" + #include "utils.h" ++#include "runcmd.h" + + int check_swap (int usp, float free_swap); + int process_arguments (int argc, char **argv); +@@ -64,6 +64,8 @@ + char *temp_buffer; + char *swap_command; + char *swap_format; ++ output chld_out, chld_err; ++ size_t i = 0; + # else + # ifdef HAVE_DECL_SWAPCTL + int i=0, nswaps=0, swapctl_res=0; +@@ -79,14 +81,13 @@ + # endif + #endif + char str[32]; +- char *status, *tmp_status; ++ char *status; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + status = strdup (""); +- tmp_status = strdup (""); + perf = strdup (""); + + if (process_arguments (argc, argv) == ERROR) +@@ -146,15 +147,9 @@ + if (verbose >= 3) + printf (_("Format: %s\n"), swap_format); + +- child_process = spopen (swap_command); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), swap_command); +- return STATE_UNKNOWN; +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) +- printf (_("Could not open stderr for %s\n"), swap_command); ++ /* run the command. set WARNING if non-zero return or output on stderr */ ++ if((np_runcmd(swap_command, &chld_out, &chld_err, 0)) || chld_err.buflen) ++ result = STATE_WARNING; + + sprintf (str, "%s", ""); + /* read 1st line */ +@@ -210,17 +205,6 @@ + # ifdef _AIX + } + # endif +- +- /* If we get anything on STDERR, at least set warning */ +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) +- result = max_state (result, STATE_WARNING); +- +- /* close stderr */ +- (void) fclose (child_stderr); +- +- /* close the pipe */ +- if (spclose (child_process)) +- result = max_state (result, STATE_WARNING); + # else + # ifdef CHECK_SWAP_SWAPCTL_SVR4 + +@@ -314,16 +298,19 @@ + percent_used = 100 * ((double) used_swap) / ((double) total_swap); + result = max_state (result, check_swap (percent_used, free_swap)); + /* broken into two steps because of funkiness with builtin asprintf */ +- asprintf (&tmp_status, _(" %d%% free (%.0f MB out of %.0f MB)"), +- (100 - percent_used), free_swap, total_swap); +- asprintf (&status, "%s%s", tmp_status, status); +- +- asprintf (&perf, "%s", perfdata ("swap", (long) free_swap, "MB", +- TRUE, (long) max (warn_size/1024, warn_percent/100.0*total_swap), +- TRUE, (long) max (crit_size/1024, crit_percent/100.0*total_swap), +- TRUE, 0, +- TRUE, (long) total_swap)); +- printf ("SWAP %s:%s |%s\n", state_text (result), status, perf); ++ /* the breaking was removed because it was stupid. There's no reason ++ * to concatenate a string using asprintf() just to print it to stdout ++ * in the next statement. */ ++ printf (_("SWAP %s - %d%% free (%.0f MB out of %.0f MB) %s|"), ++ state_text (result), ++ (100 - percent_used), free_swap, total_swap, status); ++ ++ puts (perfdata ("swap", (long) free_swap, "MB", ++ TRUE, (long) max (warn_size/1024, warn_percent/100.0*total_swap), ++ TRUE, (long) max (crit_size/1024, crit_percent/100.0*total_swap), ++ TRUE, 0, ++ TRUE, (long) total_swap)); ++ + return result; + } + +@@ -383,7 +370,7 @@ + } + else if (strstr (optarg, ",") && + strstr (optarg, "%") && +- sscanf (optarg, "%.0f,%d%%", &warn_size, &warn_percent) == 2) { ++ sscanf (optarg, "%f,%d%%", &warn_size, &warn_percent) == 2) { + break; + } + else if (strstr (optarg, "%") && +@@ -400,7 +387,7 @@ + } + else if (strstr (optarg, ",") && + strstr (optarg, "%") && +- sscanf (optarg, "%.0f,%d%%", &crit_size, &crit_percent) == 2) { ++ sscanf (optarg, "%f,%d%%", &crit_size, &crit_percent) == 2) { + break; + } + else if (strstr (optarg, "%") && +diff -urN ../nplg/plugins/check_users.c ./plugins/check_users.c +--- ../nplg/plugins/check_users.c 2005-01-05 21:53:22.000000000 +0100 ++++ ./plugins/check_users.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,17 +14,17 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: check_users.c,v 1.19 2004/12/25 23:17:44 opensides Exp $ ++ $Id: check_users.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + + *****************************************************************************/ + + const char *progname = "check_users"; +-const char *revision = "$Revision: 1.19 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" +-#include "popen.h" ++#include "runcmd.h" + #include "utils.h" + + #define possibly_set(a,b) ((a) == 0 ? (b) : 0) +@@ -41,52 +41,28 @@ + { + int users = -1; + int result = STATE_UNKNOWN; +- char input_buffer[MAX_INPUT_BUFFER]; +- char *perf; ++ output chld_out, chld_err; ++ size_t i; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + +- perf = strdup(""); +- + if (process_arguments (argc, argv) == ERROR) + usage4 (_("Could not parse arguments")); + + /* run the command */ +- child_process = spopen (WHO_COMMAND); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), WHO_COMMAND); +- return STATE_UNKNOWN; +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) +- printf (_("Could not open stderr for %s\n"), WHO_COMMAND); +- +- users = 0; +- +- while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { +- +- /* increment 'users' on all lines except total user count */ +- if (input_buffer[0] != '#') { +- users++; +- continue; +- } +- +- /* get total logged in users */ +- if (sscanf (input_buffer, _("# users=%d"), &users) == 1) +- break; +- +- } ++ result = np_runcmd(WHO_COMMAND, &chld_out, &chld_err, 0); ++ if(result != 0) ++ result = STATE_UNKNOWN; ++ ++ /* one user is listed per line, except when it begins with '#' */ ++ users = chld_out.lines; ++ for(i = 0; i < chld_out.lines; i++) ++ if (chld_out.line[0][0] == '#') users--; + + /* check STDERR */ +- if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) +- result = possibly_set (result, STATE_UNKNOWN); +- (void) fclose (child_stderr); +- +- /* close the pipe */ +- if (spclose (child_process)) ++ if(chld_err.buflen > 0) + result = possibly_set (result, STATE_UNKNOWN); + + /* else check the user count against warning and critical thresholds */ +@@ -98,16 +74,12 @@ + result = STATE_OK; + + if (result == STATE_UNKNOWN) +- printf (_("Unable to read output\n")); +- else { +- asprintf(&perf, "%s", perfdata ("users", users, "", +- TRUE, wusers, +- TRUE, cusers, +- TRUE, 0, +- FALSE, 0)); +- printf (_("USERS %s - %d users currently logged in |%s\n"), state_text (result), +- users, perf); +- } ++ die (STATE_UNKNOWN, _("Unable to read output\n")); ++ ++ printf (_("USERS %s - %d users currently logged in |%s\n"), ++ state_text (result), users, ++ perfdata("users", users, "", ++ TRUE, wusers, TRUE, cusers, TRUE, 0, FALSE, 0)); + + return result; + } +@@ -129,8 +101,10 @@ + {0, 0, 0, 0} + }; + +- if (argc < 2) +- usage ("\n"); ++ if (argc < 2) { ++ print_usage (); ++ exit(STATE_UNKNOWN); ++ } + + while (1) { + c = getopt_long (argc, argv, "+hVvc:w:", longopts, &option); +diff -urN ../nplg/plugins/foo ./plugins/foo +--- ../nplg/plugins/foo 1970-01-01 01:00:00.000000000 +0100 ++++ ./plugins/foo 2005-06-10 15:05:25.000000000 +0200 +@@ -0,0 +1,12 @@ ++$Id: check_by_ssh.c,v 1.35 2004/12/25 12:09:19 opensides Exp $ ++$Id: check_dig.c,v 1.40 2005/01/26 21:21:01 tonvoon Exp $ ++$Id: check_dns.c,v 1.47 2004/12/30 00:41:39 opensides Exp $ ++$Id: check_fping.c,v 1.24 2004/12/25 23:17:44 opensides Exp $ ++$Id: check_load.c,v 1.28 2005/05/28 01:21:54 seanius Exp $ ++$Id: check_nagios.c,v 1.26 2005/05/25 00:43:20 seanius Exp $ ++$Id: check_ping.c,v 1.44 2005/05/25 14:25:55 sghosh Exp $ ++$Id: check_procs.c,v 1.45 2005/06/03 13:53:43 seanius Exp $ ++$Id: check_snmp.c,v 1.57 2005/06/01 19:41:01 sghosh Exp $ ++$Id: check_users.c,v 1.19 2004/12/25 23:17:44 opensides Exp $ ++$Id: negate.c,v 1.24 2004/12/25 23:17:44 opensides Exp $ ++$Id: urlize.c,v 1.17 2004/12/25 23:17:44 opensides Exp $ +diff -urN ../nplg/plugins/Makefile.am ./plugins/Makefile.am +--- ../nplg/plugins/Makefile.am 2005-02-15 09:28:36.000000000 +0100 ++++ ./plugins/Makefile.am 2005-06-10 15:01:26.000000000 +0200 +@@ -24,7 +24,8 @@ + check_nagios check_by_ssh check_dns check_nt check_ide_smart \ + check_procs + +-EXTRA_DIST = t utils.c netutils.c popen.c utils.h netutils.h popen.h common.h \ ++EXTRA_DIST = t common.h utils.c utils.h netutils.c netutils.h \ ++ runcmd.c runcmd.h \ + getaddrinfo.c getaddrinfo.h gethostbyname.c gethostbyname.h + + PLUGINHDRS = common.h +@@ -46,85 +47,85 @@ + # the actual targets + + check_dhcp_LDADD = $(NETLIBS) +-check_dig_LDADD = $(NETLIBS) popen.o +-check_disk_LDADD = $(BASEOBJS) popen.o +-check_dns_LDADD = $(NETLIBS) popen.o ++check_dig_LDADD = $(NETLIBS) runcmd.o ++check_disk_LDADD = $(BASEOBJS) runcmd.o ++check_dns_LDADD = $(NETLIBS) runcmd.o + check_dummy_LDADD = $(BASEOBJS) +-check_fping_LDADD = $(NETLIBS) popen.o +-check_game_LDADD = $(BASEOBJS) popen.o ++check_fping_LDADD = $(NETLIBS) runcmd.o ++check_game_LDADD = $(BASEOBJS) runcmd.o + check_http_LDADD = $(NETLIBS) $(SSLLIBS) +-check_hpjd_LDADD = $(NETLIBS) popen.o ++check_hpjd_LDADD = $(NETLIBS) runcmd.o + check_icmp_LDADD = $(SOCKETLIBS) + check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) +-check_load_LDADD = $(BASEOBJS) popen.o ++check_load_LDADD = $(BASEOBJS) runcmd.o + check_mrtg_LDADD = $(BASEOBJS) + check_mrtgtraf_LDADD = $(BASEOBJS) + check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) +-check_nagios_LDADD = $(BASEOBJS) popen.o ++check_nagios_LDADD = $(BASEOBJS) runcmd.o + check_nt_LDADD = $(NETLIBS) + check_nwstat_LDADD = $(NETLIBS) + check_overcr_LDADD = $(NETLIBS) + check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) +-check_ping_LDADD = $(NETLIBS) popen.o +-check_procs_LDADD = $(BASEOBJS) popen.o ++check_ping_LDADD = $(NETLIBS) runcmd.o ++check_procs_LDADD = $(BASEOBJS) runcmd.o + check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) + check_real_LDADD = $(NETLIBS) +-check_snmp_LDADD = $(BASEOBJS) popen.o ++check_snmp_LDADD = $(BASEOBJS) runcmd.o + check_smtp_LDADD = $(NETLIBS) $(SSLLIBS) + check_ssh_LDADD = $(NETLIBS) +-check_swap_LDADD = $(BASEOBJS) popen.o ++check_swap_LDADD = $(BASEOBJS) runcmd.o + check_tcp_LDADD = $(NETLIBS) $(SSLLIBS) + check_time_LDADD = $(NETLIBS) + check_udp_LDADD = $(NETLIBS) + check_ups_LDADD = $(NETLIBS) +-check_users_LDADD = $(BASEOBJS) popen.o +-check_by_ssh_LDADD = $(NETLIBS) popen.o ++check_users_LDADD = $(BASEOBJS) runcmd.o ++check_by_ssh_LDADD = $(NETLIBS) runcmd.o + check_ide_smart_LDADD = $(BASEOBJS) +-negate_LDADD = $(BASEOBJS) popen.o +-urlize_LDADD = $(BASEOBJS) popen.o ++negate_LDADD = $(BASEOBJS) runcmd.o ++urlize_LDADD = $(BASEOBJS) runcmd.o + + check_dhcp_DEPENDENCIES = check_dhcp.c $(NETOBJS) $(DEPLIBS) +-check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) popen.o $(DEPLIBS) +-check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS) +-check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) popen.o $(DEPLIBS) ++check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) runcmd.o $(DEPLIBS) ++check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) runcmd.o $(DEPLIBS) ++check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) runcmd.o $(DEPLIBS) + check_dummy_DEPENDENCIES = check_dummy.c $(DEPLIBS) +-check_fping_DEPENDENCIES = check_fping.c $(NETOBJS) popen.o $(DEPLIBS) ++check_fping_DEPENDENCIES = check_fping.c $(NETOBJS) runcmd.o $(DEPLIBS) + check_game_DEPENDENCIES = check_game.c $(DEPLIBS) + check_http_DEPENDENCIES = check_http.c $(NETOBJS) $(DEPLIBS) +-check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) popen.o $(DEPLIBS) ++check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) runcmd.o $(DEPLIBS) + check_icmp_DEPENDENCIES = check_icmp.c + check_ide_smart_DEPENDENCIES = check_ide_smart.c $(BASEOBJS) $(DEPLIBS) + check_ldap_DEPENDENCIES = check_ldap.c $(NETOBJS) $(DEPLIBS) +-check_load_DEPENDENCIES = check_load.c $(BASEOBJS) popen.o $(DEPLIBS) ++check_load_DEPENDENCIES = check_load.c $(BASEOBJS) runcmd.o $(DEPLIBS) + check_mrtg_DEPENDENCIES = check_mrtg.c $(DEPLIBS) + check_mrtgtraf_DEPENDENCIES = check_mrtgtraf.c $(DEPLIBS) + check_mysql_DEPENDENCIES = check_mysql.c $(NETOBJS) $(DEPLIBS) +-check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) popen.o $(DEPLIBS) ++check_nagios_DEPENDENCIES = check_nagios.c $(BASEOBJS) runcmd.o $(DEPLIBS) + check_nt_DEPENDENCIES = check_nt.c $(NETOBJS) $(DEPLIBS) + check_nwstat_DEPENDENCIES = check_nwstat.c $(NETOBJS) $(DEPLIBS) + check_overcr_DEPENDENCIES = check_overcr.c $(NETOBJS) $(DEPLIBS) + check_pgsql_DEPENDENCIES = check_pgsql.c $(NETOBJS) $(DEPLIBS) +-check_ping_DEPENDENCIES = check_ping.c $(NETOBJS) popen.o $(DEPLIBS) +-check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) popen.o $(DEPLIBS) ++check_ping_DEPENDENCIES = check_ping.c $(NETOBJS) runcmd.o $(DEPLIBS) ++check_procs_DEPENDENCIES = check_procs.c $(BASEOBJS) runcmd.o $(DEPLIBS) + check_radius_DEPENDENCIES = check_radius.c $(NETOBJS) $(DEPLIBS) + check_real_DEPENDENCIES = check_real.c $(NETOBJS) $(DEPLIBS) +-check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) popen.o $(DEPLIBS) ++check_snmp_DEPENDENCIES = check_snmp.c $(BASEOBJS) runcmd.o $(DEPLIBS) + check_smtp_DEPENDENCIES = check_smtp.c $(NETOBJS) $(DEPLIBS) + check_ssh_DEPENDENCIES = check_ssh.c $(NETOBJS) $(DEPLIBS) +-check_swap_DEPENDENCIES = check_swap.c $(BASEOBJS) popen.o $(DEPLIBS) ++check_swap_DEPENDENCIES = check_swap.c $(BASEOBJS) runcmd.o $(DEPLIBS) + check_tcp_DEPENDENCIES = check_tcp.c $(NETOBJS) $(DEPLIBS) + check_time_DEPENDENCIES = check_time.c $(NETOBJS) $(DEPLIBS) + check_udp_DEPENDENCIES = check_udp.c $(NETOBJS) $(DEPLIBS) + check_ups_DEPENDENCIES = check_ups.c $(NETOBJS) $(DEPLIBS) +-check_users_DEPENDENCIES = check_users.c $(BASEOBJS) popen.o $(DEPLIBS) +-check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) popen.o $(DEPLIBS) +-negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS) +-urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS) ++check_users_DEPENDENCIES = check_users.c $(BASEOBJS) runcmd.o $(DEPLIBS) ++check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) runcmd.o $(DEPLIBS) ++negate_DEPENDENCIES = negate.c $(BASEOBJS) runcmd.o $(DEPLIBS) ++urlize_DEPENDENCIES = urlize.c $(BASEOBJS) runcmd.o $(DEPLIBS) + + ############################################################################## + # secondary dependencies + +-popen.o: popen.c popen.h $(PLUGINHDRS) ++runcmd.o: runcmd.c runcmd.h $(PLUGINHDRS) + + utils.o: utils.c utils.h $(PLUGINHDRS) + +diff -urN ../nplg/plugins/negate.c ./plugins/negate.c +--- ../nplg/plugins/negate.c 2005-01-05 21:53:22.000000000 +0100 ++++ ./plugins/negate.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,7 +14,7 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: negate.c,v 1.24 2004/12/25 23:17:44 opensides Exp $ ++ $Id: negate.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + + @@-
+ +@@ -54,7 +54,7 @@ + ******************************************************************************/ + + const char *progname = "negate"; +-const char *revision = "$Revision: 1.24 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "2002-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + +@@ -62,7 +62,7 @@ + + #include "common.h" + #include "utils.h" +-#include "popen.h" ++#include "runcmd.h" + + char *command_line; + +@@ -76,8 +76,9 @@ + int + main (int argc, char **argv) + { +- int found = 0, result = STATE_UNKNOWN; +- char *buf; ++ int result = STATE_UNKNOWN; ++ output chld_out, chld_err; ++ size_t i; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -92,43 +93,26 @@ + + (void) alarm ((unsigned) timeout_interval); + +- child_process = spopen (command_line); +- if (child_process == NULL) +- die (STATE_UNKNOWN, _("Could not open pipe: %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); +- } +- +- buf = malloc(MAX_INPUT_BUFFER); +- while (fgets (buf, MAX_INPUT_BUFFER - 1, child_process)) { +- found++; +- printf ("%s", buf); +- } +- +- if (!found) ++ result = np_runcmd(command_line, &chld_out, &chld_err, 0); ++ if (!chld_out.buflen) + die (STATE_UNKNOWN, + _("%s problem - No data received from host\nCMD: %s\n"),\ + argv[0], command_line); + +- /* close the pipe */ +- result = spclose (child_process); ++ for(i = 0; i < chld_out.lines; i++) ++ printf("%s", chld_out.line[i]); + + /* WARNING if output found on stderr */ +- if (fgets (buf, MAX_INPUT_BUFFER - 1, child_stderr)) ++ if (chld_err.buflen != 0) + result = max_state (result, STATE_WARNING); + +- /* close stderr */ +- (void) fclose (child_stderr); +- + if (result == STATE_OK) + exit (STATE_CRITICAL); +- else if (result == STATE_CRITICAL) ++ ++ if (result == STATE_CRITICAL) + exit (EXIT_SUCCESS); +- else +- exit (result); ++ ++ exit (result); + } + + /****************************************************************************** +diff -urN ../nplg/plugins/runcmd.c ./plugins/runcmd.c +--- ../nplg/plugins/runcmd.c 1970-01-01 01:00:00.000000000 +0100 ++++ ./plugins/runcmd.c 2005-06-10 15:01:26.000000000 +0200 +@@ -0,0 +1,339 @@ ++/* ++ * $Id: runcmd.c,v 1.1 2005/06/05 21:55:26 exon Exp $ ++ * ++ * 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. ++ * ++ */ ++ ++/** includes **/ ++#include "runcmd.h" ++#ifdef HAVE_SYS_WAIT_H ++# include ++#endif ++ ++/** macros **/ ++#ifndef WEXITSTATUS ++# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) ++#endif ++ ++#ifndef WIFEXITED ++# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) ++#endif ++ ++/* 4.3BSD Reno doesn't define SIG_ERR */ ++#if defined(SIG_IGN) && !defined(SIG_ERR) ++# define SIG_ERR ((Sigfunc *)-1) ++#endif ++ ++/* This variable must be global, since there's no way the caller ++ * can forcibly slay a dead or ungainly running program otherwise. ++ * Multithreading apps and plugins can initialize it (via NP_RUNCMD_INIT) ++ * in an async safe manner PRIOR to calling np_runcmd() for the first time. ++ * ++ * The check for initialized values is atomic and can ++ * occur in any number of threads simultaneously. */ ++static pid_t *np_pids = NULL; ++ ++/* If OPEN_MAX isn't defined, we try the sysconf syscall first. ++ * If that fails, we fall back to an educated guess which is accurate ++ * on Linux and some other systems. There's no guarantee that our guess is ++ * adequate and the program will die with SIGSEGV if it isn't and the ++ * upper boundary is breached. */ ++#ifdef OPEN_MAX ++# define maxfd OPEN_MAX ++#else ++# ifndef _SC_OPEN_MAX /* sysconf macro unavailable, so guess */ ++# define maxfd 256 ++# else ++static int maxfd = 0; ++# endif /* _SC_OPEN_MAX */ ++#endif /* OPEN_MAX */ ++ ++ ++/** prototypes **/ ++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_runcmd_close(int); ++ ++/* imported from utils.h */ ++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) ++{ ++#if !defined(OPEN_MAX) && defined(_SC_OPEN_MAX) ++ if(!maxfd) { ++ if((maxfd = sysconf(_SC_OPEN_MAX)) < 0) { ++ /* possibly log or emit a warning here, since there's no ++ * guarantee that our guess at maxfd will be adequate */ ++ maxfd = 256; ++ } ++ } ++#endif ++ ++ 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) ++{ ++ char *env[2]; ++ char *cmd = NULL; ++ char **argv = NULL; ++ char *str; ++ int argc; ++ size_t cmdlen; ++ pid_t pid; ++#ifdef RLIMIT_CORE ++ struct rlimit limit; ++#endif ++ ++ int i = 0; ++ ++ if(!np_pids) NP_RUNCMD_INIT; ++ ++ env[0] = strdup("LC_ALL=C"); ++ env[1] = '\0'; ++ ++ /* if no command was passed, return with no error */ ++ if (cmdstring == NULL) ++ return -1; ++ ++ /* make copy of command string so strtok() doesn't silently modify it */ ++ /* (the calling program may want to access it later) */ ++ cmdlen = strlen(cmdstring); ++ cmd = malloc(cmdlen + 1); ++ if (cmd == NULL) return -1; ++ memcpy(cmd, cmdstring, cmdlen); ++ ++ /* This is not a shell, so we don't handle "???" */ ++ if (strstr (cmdstring, "\"")) return -1; ++ ++ /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ ++ if (strstr (cmdstring, " ' ") || strstr (cmdstring, "'''")) ++ return -1; ++ ++ /* each arg must be whitespace-separated, so args can be a maximum ++ * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ ++ argc = (cmdlen >> 1) + 2; ++ argv = calloc(sizeof(char *), argc); ++ ++ if (argv == NULL) { ++ printf (_("Could not malloc argv array in popen()\n")); ++ return -1; ++ } ++ ++ /* get command arguments (stupidly, but fairly quickly) */ ++ while (cmd) { ++ str = cmd; ++ str += strspn (str, " \t\r\n"); /* trim any leading whitespace */ ++ ++ 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 { ++ cmd = NULL; ++ } ++ } ++ ++ if (cmd && strlen (cmd) == strspn (cmd, " \t\r\n")) ++ cmd = NULL; ++ ++ argv[i++] = str; ++ } ++ ++ if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) ++ return -1; /* errno set by the failing function */ ++ ++ /* child runs exceve() and _exit. */ ++ if (pid == 0) { ++#ifdef RLIMIT_CORE ++ /* the program we execve shouldn't leave core files */ ++ getrlimit (RLIMIT_CORE, &limit); ++ limit.rlim_cur = 0; ++ setrlimit (RLIMIT_CORE, &limit); ++#endif ++ close (pfd[0]); ++ if (pfd[1] != STDOUT_FILENO) { ++ dup2 (pfd[1], STDOUT_FILENO); ++ close (pfd[1]); ++ } ++ close (pfderr[0]); ++ if (pfderr[1] != STDERR_FILENO) { ++ dup2 (pfderr[1], STDERR_FILENO); ++ close (pfderr[1]); ++ } ++ ++ /* close all descriptors in np_pids[] ++ * This is executed in a separate address space (pure child), ++ * so we don't have to worry about async safety */ ++ for (i = 0; i < maxfd; i++) ++ if(np_pids[i] > 0) ++ close (i); ++ ++ execve (argv[0], argv, env); ++ _exit (0); ++ } ++ ++ /* parent picks up execution here */ ++ /* close childs descriptors in our address space */ ++ close(pfd[1]); ++ close(pfderr[1]); ++ ++ /* tag our file's entry in the pid-list and return it */ ++ np_pids[pfd[0]] = pid; ++ ++ return pfd[0]; ++} ++ ++ ++static int ++np_runcmd_close(int fd) ++{ ++ int status; ++ pid_t pid; ++ ++ /* make sure this fd was opened by popen() */ ++ if(fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0) ++ return -1; ++ ++ np_pids[fd] = 0; ++ 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; ++ ++ /* return child's termination status */ ++ return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; ++} ++ ++ ++void ++popen_timeout_alarm_handler (int signo) ++{ ++ size_t i; ++ ++ if (signo == SIGALRM) ++ puts(_("CRITICAL - Plugin timed out while executing system call\n")); ++ ++ if(np_pids) for(i = 0; i < maxfd; i++) { ++ if(np_pids[i] != 0) kill(np_pids[i], SIGKILL); ++ } ++ ++ exit (STATE_CRITICAL); ++} ++ ++ ++static int ++np_fetch_output(int fd, output *op, int flags) ++{ ++ size_t len = 0, i = 0; ++ size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ ++ char *buf = NULL; ++ int ret; ++ char tmpbuf[4096]; ++ ++ op->buf = NULL; ++ op->buflen = 0; ++ while((ret = read(fd, tmpbuf, sizeof(tmpbuf))) > 0) { ++ len = (size_t)ret; ++ op->buf = realloc(op->buf, op->buflen + len + 1); ++ memcpy(op->buf + op->buflen, tmpbuf, len); ++ op->buflen += len; ++ i++; ++ } ++ ++ if(ret < 0) { ++ printf("read() returned %d: %s\n", ret, strerror(errno)); ++ return ret; ++ } ++ ++ if(!op->buf || !op->buflen) return 0; ++ ++ /* some plugins may want to keep output unbroken */ ++ if(flags & RUNCMD_NO_ARRAYS) ++ return op->buflen; ++ ++ /* and some may want both (*sigh*) */ ++ if(flags & RUNCMD_NO_ASSOC) { ++ buf = malloc(op->buflen); ++ memcpy(buf, op->buf, op->buflen); ++ } ++ else buf = op->buf; ++ ++ op->line = NULL; ++ op->lens = NULL; ++ len = i = 0; ++ while(i < op->buflen) { ++ /* make sure we have enough memory */ ++ if(len >= ary_size) { ++ ary_size = op->buflen >> --rsf; ++ op->line = realloc(op->line, ary_size * sizeof(char *)); ++ op->lens = realloc(op->lens, ary_size * sizeof(size_t)); ++ } ++ ++ /* set the pointer to the string */ ++ op->line[len] = &buf[i]; ++ ++ /* hop to next newline or end of buffer */ ++ while(buf[i] != '\n' && i < op->buflen) i++; ++ buf[i] = '\0'; ++ ++ /* calculate the string length using pointer difference */ ++ op->lens[len] = (size_t)&buf[i] - (size_t)op->line[len]; ++ ++ len++; ++ i++; ++ } ++ ++ return len; ++} ++ ++ ++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((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); ++ ++ return np_runcmd_close(fd); ++} +diff -urN ../nplg/plugins/runcmd.h ./plugins/runcmd.h +--- ../nplg/plugins/runcmd.h 1970-01-01 01:00:00.000000000 +0100 ++++ ./plugins/runcmd.h 2005-06-10 15:01:26.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* ++ * $Id: runcmd.h,v 1.1 2005/06/05 21:55:26 exon Exp $ ++ * ++ * Author: Andreas Ericsson ++ * ++ * Copyright: GNU GPL v2 or any later version. ++ * ++ */ ++ ++#ifndef NAGIOSPLUG_RUNCMD_H ++#define NAGIOSPLUG_RUNCMD_H ++ ++#include "common.h" ++ ++/** types **/ ++struct output { ++ char *buf; /* output buffer */ ++ size_t buflen; /* output buffer content length */ ++ char **line; /* array of lines (points to buf) */ ++ size_t *lens; /* string lengths */ ++ size_t lines; /* lines of output */ ++}; ++ ++typedef struct output output; ++ ++/** prototypes **/ ++int np_runcmd(const char *, output *, output *, int); ++void popen_timeout_alarm_handler(int) ++ __attribute__((__noreturn__)); ++ ++/* only multi-threaded plugins need to bother with this */ ++void np_runcmd_init(void); ++#define NP_RUNCMD_INIT np_runcmd_init() ++ ++/* possible flags for np_runcmd()'s fourth argument */ ++#define RUNCMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ ++#define RUNCMD_NO_ASSOC 0x02 /* output.line won't point to buf */ ++ ++#endif /* NAGIOSPLUG_RUNCMD_H */ +diff -urN ../nplg/plugins/urlize.c ./plugins/urlize.c +--- ../nplg/plugins/urlize.c 2005-01-05 21:53:23.000000000 +0100 ++++ ./plugins/urlize.c 2005-06-10 15:01:26.000000000 +0200 +@@ -14,18 +14,18 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +- $Id: urlize.c,v 1.17 2004/12/25 23:17:44 opensides Exp $ ++ $Id: urlize.c,v 1.2 2005/06/05 21:55:26 exon Exp $ + + ******************************************************************************/ + + const char *progname = "urlize"; +-const char *revision = "$Revision: 1.17 $"; ++const char *revision = "$Revision: 1.2 $"; + const char *copyright = "2000-2004"; + const char *email = "nagiosplug-devel@lists.sourceforge.net"; + + #include "common.h" + #include "utils.h" +-#include "popen.h" ++#include "runcmd.h" + + void print_help (void); + void print_usage (void); +@@ -33,10 +33,11 @@ + int + main (int argc, char **argv) + { +- int found = 0, result = STATE_UNKNOWN; ++ int result = STATE_UNKNOWN; + char *url = NULL; + char *cmd; +- char *buf; ++ output chld_out, chld_err; ++ size_t i; + + int c; + int option = 0; +@@ -67,55 +68,37 @@ + exit (EXIT_SUCCESS); + break; + case 'u': +- url = strdup (argv[optind]); ++ url = optarg; + break; + case '?': + default: +- usage2 (_("Unknown argument"), optarg); ++ usage3 (_("Unknown argument"), c); + } + } + +- if (url == NULL) +- url = strdup (argv[optind++]); ++ if (url == NULL && optind < argc - 1) ++ url = argv[optind++]; + + cmd = strdup (argv[optind++]); + for (c = optind; c < argc; c++) { + asprintf (&cmd, "%s %s", cmd, argv[c]); + } + +- child_process = spopen (cmd); +- if (child_process == NULL) { +- printf (_("Could not open pipe: %s\n"), cmd); +- exit (STATE_UNKNOWN); +- } +- +- child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); +- if (child_stderr == NULL) { +- printf (_("Could not open stderr for %s\n"), cmd); +- } ++ result = np_runcmd(cmd, &chld_out, &chld_err, 0); ++ printf ("", url); + +- buf = malloc(MAX_INPUT_BUFFER); +- printf ("", argv[1]); +- while (fgets (buf, MAX_INPUT_BUFFER - 1, child_process)) { +- found++; +- printf ("%s", buf); +- } +- +- if (!found) ++ if (!chld_out.lines) + die (STATE_UNKNOWN, + _("%s UNKNOWN - No data received from host\nCMD: %s\n"), + argv[0], cmd); + +- /* close the pipe */ +- result = spclose (child_process); ++ for(i = 0; i < chld_out.lines; i++) ++ printf("%s", chld_out.line[i]); + + /* WARNING if output found on stderr */ +- if (fgets (buf, MAX_INPUT_BUFFER - 1, child_stderr)) ++ if (chld_err.buflen) + result = max_state (result, STATE_WARNING); + +- /* close stderr */ +- (void) fclose (child_stderr); +- + printf ("\n"); + return result; + } -- cgit v1.2.3-74-g34f1