[Nagiosplug-checkins] nagiosplug/plugins Makefile.am,1.56,1.57 check_by_ssh.c,1.35,1.36 check_dig.c,1.40,1.41 check_dns.c,1.47,1.48 check_game.c,1.23,1.24 check_nagios.c,1.26,1.27 netutils.c,1.27,1.28 runcmd.c,1.1,1.2 runcmd.h,1.1,1.2 utils.c,1.41,1.42 utils.h,1.22,1.23

M. Sean Finney seanius at users.sourceforge.net
Mon Oct 24 04:14:26 CEST 2005


Update of /cvsroot/nagiosplug/nagiosplug/plugins
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16704

Modified Files:
	Makefile.am check_by_ssh.c check_dig.c check_dns.c 
	check_game.c check_nagios.c netutils.c runcmd.c runcmd.h 
	utils.c utils.h 
Log Message:
initial merging of ae's np_runcmd code into selected plugins.


Index: utils.h
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/utils.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- utils.h	5 Dec 2004 00:54:09 -0000	1.22
+++ utils.h	24 Oct 2005 11:10:29 -0000	1.23
@@ -1,3 +1,5 @@
+#ifndef NP_UTILS_H
+#define NP_UTILS_H
 /* Header file for nagios plugins utils.c */
 
 /* This file should be included in all plugins */
@@ -77,6 +79,7 @@
 void usage2(const char *, const char *) __attribute__((noreturn));
 void usage3(const char *, int) __attribute__((noreturn));
 void usage4(const char *);
+void usage_va(const char *fmt, ...);
 
 const char *state_text (int);
 
@@ -169,3 +172,5 @@
 The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\
 copies of the plugins under the terms of the GNU General Public License.\n\
 For more information about these matters, see the file named COPYING.\n"
+
+#endif /* NP_UTILS_H */

Index: netutils.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/netutils.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- netutils.c	23 Oct 2005 11:59:43 -0000	1.27
+++ netutils.c	24 Oct 2005 11:10:29 -0000	1.28
@@ -291,6 +291,13 @@
 	return (FALSE);
 }
 
+void
+host_or_die(const char *str)
+{
+	if(!str || (!is_addr(str) && !is_hostname(str)))
+		usage_va(_("Invalid hostname/address - %s"), str);
+}
+
 int
 is_addr (const char *address)
 {

Index: check_dig.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_dig.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- check_dig.c	26 Jan 2005 21:21:01 -0000	1.40
+++ check_dig.c	24 Oct 2005 11:10:29 -0000	1.41
@@ -18,6 +18,12 @@
  
 *****************************************************************************/
 
+/* 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$";
 const char *copyright = "2002-2004";
@@ -26,17 +32,15 @@
 #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,26 +55,25 @@
 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);
 
 	/* Set signal handling and alarm */
 	if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR)
-		usage4 (_("Cannot catch SIGALRM"));
+		usage_va(_("Cannot catch SIGALRM"));
 
 	if (process_arguments (argc, argv) == ERROR)
-		usage4 (_("Could not parse arguments"));
+		usage_va(_("Could not parse arguments"));
 
 	/* get the command to run */
 	asprintf (&command_line, "%s @%s -p %d %s -t %s",
@@ -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(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 && !strstr (input_buffer, ";; ")) 
-					printf ("%s\n", input_buffer); 
+				if (verbose)
+					printf ("%s\n", chld_out.line[i]);
 
-				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;
 }
 
@@ -219,8 +197,6 @@
 			break;
 
 		switch (c) {
-		case '?':									/* help */
-			usage2 (_("Unknown argument"), optarg);
 		case 'h':									/* help */
 			print_help ();
 			exit (STATE_OK);
@@ -228,19 +204,15 @@
 			print_revision (progname, revision);
 			exit (STATE_OK);
 		case 'H':									/* hostname */
-			if (is_host (optarg)) {
-				dns_server = optarg;
-			}
-			else {
-				usage2 (_("Invalid hostname/address"), optarg);
-			}
+			host_or_die(optarg);
+			dns_server = optarg;
 			break;
 		case 'p':                 /* server port */
 			if (is_intpos (optarg)) {
 				server_port = atoi (optarg);
 			}
 			else {
-				usage2 (_("Port must be a positive integer"), optarg);
+				usage_va(_("Port must be a positive integer - %s"), optarg);
 			}
 			break;
 		case 'l':									/* address to lookup */
@@ -251,7 +223,7 @@
 				warning_interval = strtod (optarg, NULL);
 			}
 			else {
-				usage2 (_("Warning interval must be a positive integer"), optarg);
+				usage_va(_("Warning interval must be a positive integer - %s"), optarg);
 			}
 			break;
 		case 'c':									/* critical */
@@ -259,7 +231,7 @@
 				critical_interval = strtod (optarg, NULL);
 			}
 			else {
-				usage2 (_("Critical interval must be a positive integer"), optarg);
+				usage_va(_("Critical interval must be a positive integer - %s"), optarg);
 			}
 			break;
 		case 't':									/* timeout */
@@ -267,7 +239,7 @@
 				timeout_interval = atoi (optarg);
 			}
 			else {
-				usage2 (_("Timeout interval must be a positive integer"), optarg);
+				usage_va(_("Timeout interval must be a positive integer - %s"), optarg);
 			}
 			break;
 		case 'v':									/* verbose */
@@ -279,18 +251,16 @@
 		case 'a':
 			expected_address = optarg;
 			break;
+		default:									/* usage_va */
+			usage_va(_("Unknown argument - %s"), optarg);
 		}
 	}
 
 	c = optind;
 	if (dns_server == NULL) {
 		if (c < argc) {
-			if (is_host (argv[c])) {
-				dns_server = argv[c];
-			}
-			else {
-				usage2 (_("Invalid hostname/address"), argv[c]);
-			}
+			host_or_die(argv[c]);
+			dns_server = argv[c];
 		}
 		else {
 			dns_server = strdup ("127.0.0.1");
@@ -359,6 +329,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);
 }

Index: check_by_ssh.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_by_ssh.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- check_by_ssh.c	25 Dec 2004 12:09:19 -0000	1.35
+++ check_by_ssh.c	24 Oct 2005 11:10:29 -0000	1.36
@@ -26,7 +26,7 @@
 #include "common.h"
 #include "netutils.h"
 #include "utils.h"
-#include "popen.h"
+#include "runcmd.h"
 
 int process_arguments (int, char **);
 int validate_arguments (void);
@@ -35,7 +35,7 @@
 
 int commands = 0;
 int services = 0;
-int skip_lines = 0;
+int skip = 0;
 char *remotecmd = NULL;
 char *comm = NULL;
 char *hostname = NULL;
@@ -49,19 +49,16 @@
 main (int argc, char **argv)
 {
 
-	char input_buffer[MAX_INPUT_BUFFER];
-	char *result_text;
 	char *status_text;
-	char *output;
-	char *eol = NULL;
 	int cresult;
 	int result = STATE_UNKNOWN;
+	int i;
 	time_t local_time;
 	FILE *fp = NULL;
+	struct output chld_out, chld_err;
 
-	remotecmd = strdup ("");
+	remotecmd = "";
 	comm = strdup (SSH_COMMAND);
-	result_text = strdup ("");
 
 	setlocale (LC_ALL, "");
 	bindtextdomain (PACKAGE, LOCALEDIR);
@@ -69,100 +66,62 @@
 
 	/* process arguments */
 	if (process_arguments (argc, argv) == ERROR)
-		usage4 (_("Could not parse arguments"));
+		usage_va(_("Could not parse arguments"));
 
 	/* Set signal handling and alarm timeout */
 	if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
-		usage4 (_("Cannot catch SIGALRM"));
+		usage_va(_("Cannot catch SIGALRM"));
 	}
 	alarm (timeout_interval);
 
 	/* run the command */
-
 	if (verbose)
 		printf ("%s\n", comm);
 
-	child_process = spopen (comm);
-
-	if (child_process == NULL) {
-		printf (_("Could not open pipe: %s\n"), comm);
+	result = np_runcmd(comm, &chld_out, &chld_err, 0);
+	/* UNKNOWN if output found on stderr */
+	if(chld_err.buflen) {
+		printf(_("Remote command execution failed: %s\n"),
+			   chld_err.buflen ? chld_err.buf : _("Unknown error"));
 		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);
-	}
-
-
-	/* 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);
-
-	/* 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;
-		}
+	/* this is simple if we're not supposed to be passive.
+	 * Wrap up quickly and keep the tricks below */
+	if(!passive) {
+		printf ("%s\n", skip < chld_out.lines ? chld_out.line[skip] : chld_out.buf);
+		return result; 	/* return error status from remote command */
 	}
-	(void) fclose (child_stderr);
-	if (result == STATE_WARNING)
-		return result;
 
 
-	/* close the pipe */
-	result = spclose (child_process);
-
+	/*
+	 * Passive mode
+	 */
 
 	/* process output */
-	if (passive) {
+	if (!(fp = fopen (outputfile, "a"))) {
+		printf (_("SSH WARNING: could not open %s\n"), outputfile);
+		exit (STATE_UNKNOWN);
+	}
 
-		if (!(fp = fopen (outputfile, "a"))) {
-			printf (_("SSH WARNING: could not open %s\n"), outputfile);
-			exit (STATE_UNKNOWN);
+	local_time = time (NULL);
+	commands = 0;
+	for(i = skip; chld_out.line[i]; i++) {
+		status_text = strstr (chld_out.line[i], "STATUS CODE: ");
+		if (status_text == NULL) {
+			printf ("%s", chld_out.line[i]);
+			return result;
 		}
-
-		local_time = time (NULL);
-		commands = 0;
-		while (result_text && strlen(result_text) > 0) {
-			status_text = strstr (result_text, "STATUS CODE: ");
-			if (status_text == NULL) {
-				printf ("%s", result_text);
-				return result;
-			}
-			asprintf (&output, "%s", result_text);
-			result_text = strnl (status_text);
-			eol = strpbrk (output, "\r\n");
-			if (eol != NULL)
-				eol[0] = 0;
-			if (service[commands] && status_text
-					&& sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) {
-				fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
-								 (int) local_time, host_shortname, service[commands++], cresult,
-								 output);
-			}
+		if (service[commands] && status_text
+			&& sscanf (status_text, "STATUS CODE: %d", &cresult) == 1)
+		{
+			fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
+			         (int) local_time, host_shortname, service[commands++],
+			         cresult, chld_out.line[i]);
 		}
-
 	}
-
-
-	/* print the first line from the remote command */
-	else {
- 		eol = strpbrk (result_text, "\r\n");
- 		if (eol)
- 			eol[0] = 0;
- 		printf ("%s\n", result_text);
-	}
-
-
-	/* return error status from remote command */	
+	
+	/* force an OK state */
 	return result;
 }
 
@@ -206,14 +165,12 @@
 
 	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;
 
 		switch (c) {
-		case '?':									/* help */
-			usage2 (_("Unknown argument"), optarg);
 		case 'V':									/* version */
 			print_revision (progname, revision);
 			exit (STATE_OK);
@@ -225,18 +182,17 @@
 			break;
 		case 't':									/* timeout period */
 			if (!is_integer (optarg))
-				usage2 (_("Timeout interval must be a positive integer"), optarg);
+				usage_va(_("Timeout interval must be a positive integer"));
 			else
 				timeout_interval = atoi (optarg);
 			break;
 		case 'H':									/* host */
-			if (!is_host (optarg))
-				usage2 (_("Invalid hostname/address"), optarg);
+			host_or_die(optarg);
 			hostname = optarg;
 			break;
 		case 'p': /* port number */
 			if (!is_integer (optarg))
-				usage2 (_("Port must be a positive integer"), optarg);
+				usage_va(_("Port must be a positive integer"));
 			asprintf (&comm,"%s -p %s", comm, optarg);
 			break;
 		case 'O':									/* output file */
@@ -244,25 +200,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 */
@@ -278,10 +236,12 @@
 			break;
 		case 'S':									/* Skip n lines in the output to ignore system banner */
 			if (!is_integer (optarg))
-				usage2 (_("skip lines must be an integer"), optarg);
+				usage_va(_("skip lines must be an integer"));
 			else
-				skip_lines = atoi (optarg);
+				skip = atoi (optarg);
 			break;
+		default:									/* help */
+			usage_va(_("Unknown argument - %s"), optarg);
 		}
 	}
 
@@ -289,8 +249,8 @@
 	if (hostname == NULL) {
 		if (c <= argc) {
 			die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname);
-		} else if (!is_host (argv[c]))
-			die (STATE_UNKNOWN, "%s: %s %s\n", progname, _("Invalid hostname/address"), argv[c]);
+		}
+		host_or_die(argv[c]);
 		hostname = argv[c++];
 	}
 
@@ -306,7 +266,7 @@
 		asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd);
 
 	if (remotecmd == NULL || strlen (remotecmd) <= 1)
-		usage4 (_("No remotecmd"));
+		usage_va(_("No remotecmd"));
 
 	asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd);
 

Index: utils.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/utils.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- utils.c	25 Dec 2004 23:17:44 -0000	1.41
+++ utils.c	24 Oct 2005 11:10:29 -0000	1.42
@@ -58,6 +58,17 @@
 	exit (STATE_UNKNOWN);
 }
 
+void usage_va (const char *fmt, ...)
+{
+	va_list ap;
+	printf("%s: ", progname);
+	va_start(ap, fmt);
+	vprintf(fmt, ap);
+	va_end(ap);
+	printf("\n");
+	exit (STATE_UNKNOWN);
+}
+
 void usage2(const char *msg, const char *arg)
 {
 	printf ("%s: %s - %s\n",progname,msg,arg);

Index: Makefile.am
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/Makefile.am,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- Makefile.am	23 Oct 2005 11:59:43 -0000	1.56
+++ Makefile.am	24 Oct 2005 11:10:29 -0000	1.57
@@ -26,7 +26,7 @@
 
 EXTRA_DIST = t utils.c netutils.c sslutils.c popen.c utils.h netutils.h \
 	popen.h common.h getaddrinfo.c getaddrinfo.h \
-	gethostbyname.c gethostbyname.h
+	gethostbyname.c gethostbyname.h runcmd.c runcmd.h
 
 PLUGINHDRS = common.h
 
@@ -47,12 +47,12 @@
 ##############################################################################
 # the actual targets
 
-check_dig_LDADD = $(NETLIBS) popen.o 
+check_dig_LDADD = $(NETLIBS) runcmd.o 
 check_disk_LDADD = $(BASEOBJS) popen.o
-check_dns_LDADD = $(NETLIBS) popen.o
+check_dns_LDADD = $(NETLIBS) runcmd.o
 check_dummy_LDADD = $(BASEOBJS)
 check_fping_LDADD = $(NETLIBS) popen.o
-check_game_LDADD = $(BASEOBJS) popen.o
+check_game_LDADD = $(BASEOBJS) runcmd.o
 check_http_LDADD = $(SSLOBJS) $(NETLIBS)
 check_hpjd_LDADD = $(NETLIBS) popen.o
 check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS)
@@ -60,7 +60,7 @@
 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)
@@ -78,17 +78,17 @@
 check_udp_LDADD = $(SSLOBJS) $(NETLIBS)
 check_ups_LDADD = $(NETLIBS)
 check_users_LDADD = $(BASEOBJS) popen.o
-check_by_ssh_LDADD = $(NETLIBS) popen.o
+check_by_ssh_LDADD = $(NETLIBS) runcmd.o
 check_ide_smart_LDADD = $(BASEOBJS)
 negate_LDADD = $(BASEOBJS) popen.o
 urlize_LDADD = $(BASEOBJS) popen.o
 
-check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) popen.o $(DEPLIBS)
+check_dig_DEPENDENCIES = check_dig.c $(NETOBJS) runcmd.o $(DEPLIBS)
 check_disk_DEPENDENCIES = check_disk.c $(BASEOBJS) popen.o $(DEPLIBS)
-check_dns_DEPENDENCIES = check_dns.c $(NETOBJS) popen.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_game_DEPENDENCIES = check_game.c  $(DEPLIBS)
+check_game_DEPENDENCIES = check_game.c  $(DEPLIBS) runcmd.o
 check_http_DEPENDENCIES = check_http.c $(SSLOBJS) $(NETOBJS) $(DEPLIBS)
 check_hpjd_DEPENDENCIES = check_hpjd.c $(NETOBJS) popen.o $(DEPLIBS)
 check_ide_smart_DEPENDENCIES = check_ide_smart.c $(BASEOBJS) $(DEPLIBS)
@@ -97,7 +97,7 @@
 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)
@@ -115,7 +115,7 @@
 check_udp_DEPENDENCIES = check_udp.c $(SSLOBJS) $(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)
+check_by_ssh_DEPENDENCIES = check_by_ssh.c $(NETOBJS) runcmd.o $(DEPLIBS)
 negate_DEPENDENCIES = negate.c $(BASEOBJS) popen.o $(DEPLIBS)
 urlize_DEPENDENCIES = urlize.c $(BASEOBJS) popen.o $(DEPLIBS)
 
@@ -124,6 +124,8 @@
 
 popen.o: popen.c popen.h $(PLUGINHDRS)
 
+runcmd.o: runcmd.c runcmd.h $(PLUGINHDRS)
+
 utils.o: utils.c utils.h $(PLUGINHDRS)
 
 netutils.o: netutils.c netutils.h $(PLUGINHDRS)

Index: runcmd.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/runcmd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- runcmd.c	29 Jun 2005 04:11:29 -0000	1.1
+++ runcmd.c	24 Oct 2005 11:10:29 -0000	1.2
@@ -16,6 +16,8 @@
  *
  */
 
+#define NAGIOSPLUG_API_C 1
+
 /** includes **/
 #include "runcmd.h"
 #ifdef HAVE_SYS_WAIT_H
@@ -45,20 +47,17 @@
  * 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
+/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
+ * If that fails and the macro isn't defined, we fall back to an educated
+ * guess. 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 _SC_OPEN_MAX
+static long maxfd = 0;
+#elif defined(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 */
+#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
+# define maxfd 256
+#endif
 
 
 /** prototypes **/
@@ -70,7 +69,7 @@
 
 static int np_runcmd_close(int);
 
-/* imported from utils.h */
+/* prototype imported from utils.h */
 extern void die (int, const char *, ...)
 	__attribute__((__noreturn__,__format__(__printf__, 2, 3)));
 
@@ -80,13 +79,11 @@
  * 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;
-		}
+#ifndef maxfd
+	if(!maxfd && (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
 
@@ -123,9 +120,9 @@
 	/* 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;
+	if((cmd = malloc(cmdlen + 1)) == NULL) return -1;
 	memcpy(cmd, cmdstring, cmdlen);
+	cmd[cmdlen] = '\0';
 
 	/* This is not a shell, so we don't handle "???" */
 	if (strstr (cmdstring, "\"")) return -1;
@@ -257,7 +254,7 @@
 static int
 np_fetch_output(int fd, output *op, int flags)
 {
-	size_t len = 0, i = 0;
+	size_t len = 0, i = 0, lineno = 0;
 	size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */
 	char *buf = NULL;
 	int ret;
@@ -278,13 +275,12 @@
 		return ret;
 	}
 
-	if(!op->buf || !op->buflen) return 0;
-
-	/* some plugins may want to keep output unbroken */
-	if(flags & RUNCMD_NO_ARRAYS)
+	/* some plugins may want to keep output unbroken, and some commands
+	 * will yield no output, so return here for those */
+	if(flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen)
 		return op->buflen;
 
-	/* and some may want both (*sigh*) */
+	/* and some may want both */
 	if(flags & RUNCMD_NO_ASSOC) {
 		buf = malloc(op->buflen);
 		memcpy(buf, op->buf, op->buflen);
@@ -293,30 +289,34 @@
 
 	op->line = NULL;
 	op->lens = NULL;
-	len = i = 0;
+	i = 0;
 	while(i < op->buflen) {
 		/* make sure we have enough memory */
-		if(len >= ary_size) {
-			ary_size = op->buflen >> --rsf;
+		if(lineno >= ary_size) {
+			/* ary_size must never be zero */
+			do {
+				ary_size = op->buflen >> --rsf;
+			} while(!ary_size);
+
 			op->line = realloc(op->line, ary_size * sizeof(char *));
 			op->lens = realloc(op->lens, ary_size * sizeof(size_t));
 		}
 
 		/* set the pointer to the string */
-		op->line[len] = &buf[i];
+		op->line[lineno] = &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++;
+		op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno];
+
+		lineno++;
 		i++;
 	}
 
-	return len;
+	return lineno;
 }
 
 

Index: check_nagios.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_nagios.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- check_nagios.c	25 May 2005 00:43:20 -0000	1.26
+++ check_nagios.c	24 Oct 2005 11:10:29 -0000	1.27
@@ -24,7 +24,7 @@
 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,17 +64,19 @@
 	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);
 	textdomain (PACKAGE);
 
 	if (process_arguments (argc, argv) == ERROR)
-		usage4 (_("Could not parse arguments"));
+		usage_va(_("Could not parse arguments"));
 
 	/* Set signal handling and alarm timeout */
 	if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
-		usage4 (_("Cannot catch SIGALRM"));
+		usage_va(_("Cannot catch SIGALRM"));
 	}
 
 	/* handle timeouts gracefully... */
@@ -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 */
@@ -219,8 +206,6 @@
 			break;
 
 		switch (c) {
-		case '?':									/* print short usage statement if args not parsable */
-			usage2 (_("Unknown argument"), optarg);
 		case 'h':									/* help */
 			print_help ();
 			exit (STATE_OK);
@@ -243,16 +228,17 @@
 		case 'v':
 			verbose++;
 			break;
+		default:									/* print short usage_va statement if args not parsable */
+			usage_va(_("Unknown argument - %s"), optarg);
 		}
 	}
 
 
 	if (status_log == NULL)
-		die (STATE_UNKNOWN,
-		     _("You must provide the status_log\n"));
-	else if (process_string == NULL)
-		die (STATE_UNKNOWN,
-							 _("You must provide a process string\n"));
+		die (STATE_UNKNOWN, _("You must provide the status_log\n"));
+
+	if (process_string == NULL)
+		die (STATE_UNKNOWN, _("You must provide a process string\n"));
 
 	return OK;
 }

Index: check_game.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_game.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- check_game.c	13 Oct 2005 10:16:02 -0000	1.23
+++ check_game.c	24 Oct 2005 11:10:29 -0000	1.24
@@ -23,8 +23,8 @@
 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,16 +57,16 @@
 	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);
 	textdomain (PACKAGE);
 	
 	if (process_arguments (argc, argv) == ERROR)
-		usage4 (_("Could not parse arguments"));
+		usage_va(_("Could not parse arguments"));
 
 	result = STATE_OK;
 
@@ -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;
 }
 
@@ -197,8 +181,6 @@
 			break;
 
 		switch (c) {
-		case '?': /* args not parsable */
-			usage2 (_("Unknown argument"), optarg);
 		case 'h': /* help */
 			print_help ();
 			exit (STATE_OK);
@@ -251,6 +233,8 @@
 			if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
 				return ERROR;
 			break;
+		default: /* args not parsable */
+			usage_va(_("Unknown argument - %s"), optarg);
 		}
 	}
 
@@ -328,8 +312,8 @@
 print_usage (void)
 {
 	printf ("\
-Usage: %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field]\n\
-                  [-p ping_field] [-G game-time] [-H hostname] <game> <ip_address>\n", progname);
+Usage: %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field]\n\
+                  [-pf ping_field]\n", progname);
 }
 
 /******************************************************************************

Index: check_dns.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_dns.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- check_dns.c	30 Dec 2004 00:41:39 -0000	1.47
+++ check_dns.c	24 Oct 2005 11:10:29 -0000	1.48
@@ -27,9 +27,9 @@
 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);
@@ -68,11 +70,11 @@
 
 	/* Set signal handling and alarm */
 	if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
-		usage4 (_("Cannot catch SIGALRM"));
+		usage_va(_("Cannot catch SIGALRM"));
 	}
 
 	if (process_arguments (argc, argv) == ERROR) {
-		usage4 (_("Could not parse arguments"));
+		usage_va(_("Could not parse arguments"));
 	}
 
 	/* get the command to run */
@@ -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);
+			puts(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);
+			puts(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);
@@ -200,19 +184,19 @@
 			multi_address = TRUE;
 
 		printf ("DNS %s: ", _("OK"));
-		printf (ngettext("%.3f second response time ", "%.3f seconds response time ", elapsed_time), elapsed_time);
-		printf (_("%s returns %s"), query_address, address);
+		printf (ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time);
+		printf (_(". %s returns %s"), query_address, address);
 		printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
 	}
 	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;
 }
@@ -311,8 +295,6 @@
 			break;
 
 		switch (c) {
-		case '?': /* args not parsable */
-			usage2 (_("Unknown argument"), optarg);
 		case 'h': /* help */
 			print_help ();
 			exit (STATE_OK);
@@ -331,20 +313,16 @@
 			strcpy (query_address, optarg);
 			break;
 		case 's': /* server name */
-			/* TODO: this is_host check is probably unnecessary. */
-			/* Better to confirm nslookup response matches */
-			if (is_host (optarg) == FALSE) {
-				usage2 (_("Invalid hostname/address"), optarg);
-			}
+			/* TODO: this host_or_die check is probably unnecessary.
+			 * Better to confirm nslookup response matches */
+			host_or_die(optarg);
 			if (strlen (optarg) >= ADDRESS_LENGTH)
 				die (STATE_UNKNOWN, _("Input buffer overflow\n"));
 			strcpy (dns_server, optarg);
 			break;
 		case 'r': /* reverse server name */
-			/* TODO: Is this is_host necessary? */
-			if (is_host (optarg) == FALSE) {
-				usage2 (_("Invalid hostname/address"), optarg);
-			}
+			/* TODO: Is this host_or_die necessary? */
+			host_or_die(optarg);
 			if (strlen (optarg) >= ADDRESS_LENGTH)
 				die (STATE_UNKNOWN, _("Input buffer overflow\n"));
 			strcpy (ptr_server, optarg);
@@ -358,6 +336,8 @@
 		case 'A': /* expect authority */
 			expect_authority = TRUE;
 			break;
+		default: /* args not parsable */
+			usage_va(_("Unknown argument - %s"), optarg);
 		}
 	}
 
@@ -370,10 +350,7 @@
 
 	if (strlen(dns_server)==0 && c<argc) {
 		/* TODO: See -s option */
-		if (is_host(argv[c]) == FALSE) {
-			printf (_("Invalid hostname/address: %s\n\n"), argv[c]);
-			return ERROR;
-		}
+		host_or_die(argv[c]);
 		if (strlen(argv[c]) >= ADDRESS_LENGTH)
 			die (STATE_UNKNOWN, _("Input buffer overflow\n"));
 		strcpy (dns_server, argv[c++]);
@@ -388,8 +365,8 @@
 {
 	if (query_address[0] == 0)
 		return ERROR;
-	else
-		return OK;
+
+	return OK;
 }
 
 






More information about the Commits mailing list