[Nagiosplug-devel] np_runcmd framework
Andreas Ericsson
ae at op5.se
Fri Jun 10 06:33:50 CEST 2005
Just a thought; This patch requires the nagiosplug-common_h-sanity.diff
I sent in a week or so ago. One of the problems of maintaining and
testing with a separate CVS repository, I suppose.
Cheers.
Andreas Ericsson wrote:
> Ahoy.
>
> I've completed the np_runcmd framework and tested it on Linux (FC3 and
> Owl-current) and FreeBSD. It seems to work splendidly, providing a
> slight speedup for some things and quite a bit smaller code.
>
> Also included in this patch is a major cleanup and overhaul for
> check_hpjd. I haven't been able to test it as I don't have a hpjd
> printer, but the theory behind it is sound and I'm confident it will
> work as expected. It reduces the LOC count by about 100 lines (25%) and
> uses more portable and easier to parse snmpget syntax.
>
> As I don't have cvs commit access I was forced to fork this off into a
> repository of my own (hence all the $Id: $ updates in the diff). I will
> keep working on that repository and see what possibilities there are for
> backsyncing with the official project. Sorry about that, but my
> work-description includes fixing and improving on the plugins and the
> number of patches I had to keep track of quickly turned out to be
> unmanagable without an SCM where I could commit things occasionally.
>
> I'll add this to the tracker as well (*sigh*).
>
>
> ------------------------------------------------------------------------
>
> 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 at 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 at 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 <server port>] [-T <query type>]\n\
> - [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\
> - [-a <expected answer address>] [-v]\n", progname);
> + [-w <warning interval>] [-c <critical interval>] [-t <timeout>]\n\
> + [-a <expected answer address>] [-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 at 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 at 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 at 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 at 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 at lists.sourceforge.net";
>
> #include "common.h"
> #include "utils.h"
> -#include "popen.h"
> +#include "runcmd.h"
>
> #ifdef HAVE_SYS_LOADAVG_H
> #include <sys/loadavg.h>
> @@ -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 at 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 at 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 ("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]);
> if (pl == 100)
> - printf (_("PING %s - %sPacket loss = %d%%"), state_text (this_result), warn_text,
> - pl);
> + printf (_("PING %s - %sPacket loss = %d%%"),
> + state_text(this_result), warn_text ? 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 ("</A>");
> 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 at lists.sourceforge.net";
>
> #include "common.h"
> -#include "popen.h"
> +#include "runcmd.h"
> #include "utils.h"
>
> #include <pwd.h>
> @@ -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 at 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 at 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 at 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 at 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 $
>
> @@-<article>
>
> @@ -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 at 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 <sys/wait.h>
> +#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 <signal.h> 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 <ae at op5.se>
> + *
> + * 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 at 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 ("<A href=\"%s\">", url);
>
> - buf = malloc(MAX_INPUT_BUFFER);
> - printf ("<A href=\"%s\">", 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</A>\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 ("</A>\n");
> return result;
> }
--
Andreas Ericsson andreas.ericsson at op5.se
OP5 AB www.op5.se
Lead Developer
More information about the Devel
mailing list