aboutsummaryrefslogtreecommitdiff
path: root/plugins/check_by_ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_by_ssh.c')
-rw-r--r--plugins/check_by_ssh.c150
1 files changed, 55 insertions, 95 deletions
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c
index 2ceee28f..b777b072 100644
--- a/plugins/check_by_ssh.c
+++ b/plugins/check_by_ssh.c
@@ -26,7 +26,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
#include "common.h"
#include "netutils.h"
#include "utils.h"
-#include "popen.h"
+#include "runcmd.h"
int process_arguments (int, char **);
int validate_arguments (void);
@@ -35,7 +35,7 @@ void print_usage (void);
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 @@ int
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 @@ main (int argc, char **argv)
/* 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);
+ /* 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 */
}
- /* 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;
- }
- }
- (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 @@ process_arguments (int argc, char **argv)
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 @@ process_arguments (int argc, char **argv)
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 @@ process_arguments (int argc, char **argv)
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 @@ process_arguments (int argc, char **argv)
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 @@ process_arguments (int argc, char **argv)
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 @@ process_arguments (int argc, char **argv)
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);