diff options
Diffstat (limited to 'plugins/check_by_ssh.c')
-rw-r--r-- | plugins/check_by_ssh.c | 150 |
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); |