diff options
| author | M. Sean Finney <seanius@users.sourceforge.net> | 2005-10-24 11:10:29 +0000 |
|---|---|---|
| committer | M. Sean Finney <seanius@users.sourceforge.net> | 2005-10-24 11:10:29 +0000 |
| commit | ceebd58040b1688749d58dd76963af639cf8c803 (patch) | |
| tree | 972deca448413addc597ce7ba3a1a4edefa8c5a5 /plugins/check_by_ssh.c | |
| parent | 19100c883d72e6ebfd3f15b3171ade2a78345c73 (diff) | |
| download | monitoring-plugins-ceebd58040b1688749d58dd76963af639cf8c803.tar.gz | |
initial merging of ae's np_runcmd code into selected plugins.
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1260 f882894a-f735-0410-b71e-b25c423dba1c
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"; | |||
| 26 | #include "common.h" | 26 | #include "common.h" |
| 27 | #include "netutils.h" | 27 | #include "netutils.h" |
| 28 | #include "utils.h" | 28 | #include "utils.h" |
| 29 | #include "popen.h" | 29 | #include "runcmd.h" |
| 30 | 30 | ||
| 31 | int process_arguments (int, char **); | 31 | int process_arguments (int, char **); |
| 32 | int validate_arguments (void); | 32 | int validate_arguments (void); |
| @@ -35,7 +35,7 @@ void print_usage (void); | |||
| 35 | 35 | ||
| 36 | int commands = 0; | 36 | int commands = 0; |
| 37 | int services = 0; | 37 | int services = 0; |
| 38 | int skip_lines = 0; | 38 | int skip = 0; |
| 39 | char *remotecmd = NULL; | 39 | char *remotecmd = NULL; |
| 40 | char *comm = NULL; | 40 | char *comm = NULL; |
| 41 | char *hostname = NULL; | 41 | char *hostname = NULL; |
| @@ -49,19 +49,16 @@ int | |||
| 49 | main (int argc, char **argv) | 49 | main (int argc, char **argv) |
| 50 | { | 50 | { |
| 51 | 51 | ||
| 52 | char input_buffer[MAX_INPUT_BUFFER]; | ||
| 53 | char *result_text; | ||
| 54 | char *status_text; | 52 | char *status_text; |
| 55 | char *output; | ||
| 56 | char *eol = NULL; | ||
| 57 | int cresult; | 53 | int cresult; |
| 58 | int result = STATE_UNKNOWN; | 54 | int result = STATE_UNKNOWN; |
| 55 | int i; | ||
| 59 | time_t local_time; | 56 | time_t local_time; |
| 60 | FILE *fp = NULL; | 57 | FILE *fp = NULL; |
| 58 | struct output chld_out, chld_err; | ||
| 61 | 59 | ||
| 62 | remotecmd = strdup (""); | 60 | remotecmd = ""; |
| 63 | comm = strdup (SSH_COMMAND); | 61 | comm = strdup (SSH_COMMAND); |
| 64 | result_text = strdup (""); | ||
| 65 | 62 | ||
| 66 | setlocale (LC_ALL, ""); | 63 | setlocale (LC_ALL, ""); |
| 67 | bindtextdomain (PACKAGE, LOCALEDIR); | 64 | bindtextdomain (PACKAGE, LOCALEDIR); |
| @@ -69,100 +66,62 @@ main (int argc, char **argv) | |||
| 69 | 66 | ||
| 70 | /* process arguments */ | 67 | /* process arguments */ |
| 71 | if (process_arguments (argc, argv) == ERROR) | 68 | if (process_arguments (argc, argv) == ERROR) |
| 72 | usage4 (_("Could not parse arguments")); | 69 | usage_va(_("Could not parse arguments")); |
| 73 | 70 | ||
| 74 | /* Set signal handling and alarm timeout */ | 71 | /* Set signal handling and alarm timeout */ |
| 75 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { | 72 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { |
| 76 | usage4 (_("Cannot catch SIGALRM")); | 73 | usage_va(_("Cannot catch SIGALRM")); |
| 77 | } | 74 | } |
| 78 | alarm (timeout_interval); | 75 | alarm (timeout_interval); |
| 79 | 76 | ||
| 80 | /* run the command */ | 77 | /* run the command */ |
| 81 | |||
| 82 | if (verbose) | 78 | if (verbose) |
| 83 | printf ("%s\n", comm); | 79 | printf ("%s\n", comm); |
| 84 | 80 | ||
| 85 | child_process = spopen (comm); | 81 | result = np_runcmd(comm, &chld_out, &chld_err, 0); |
| 86 | 82 | /* UNKNOWN if output found on stderr */ | |
| 87 | if (child_process == NULL) { | 83 | if(chld_err.buflen) { |
| 88 | printf (_("Could not open pipe: %s\n"), comm); | 84 | printf(_("Remote command execution failed: %s\n"), |
| 85 | chld_err.buflen ? chld_err.buf : _("Unknown error")); | ||
| 89 | return STATE_UNKNOWN; | 86 | return STATE_UNKNOWN; |
| 90 | } | 87 | } |
| 91 | 88 | ||
| 92 | 89 | /* this is simple if we're not supposed to be passive. | |
| 93 | /* open STDERR for spopen */ | 90 | * Wrap up quickly and keep the tricks below */ |
| 94 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | 91 | if(!passive) { |
| 95 | if (child_stderr == NULL) { | 92 | printf ("%s\n", skip < chld_out.lines ? chld_out.line[skip] : chld_out.buf); |
| 96 | printf (_("Could not open stderr for %s\n"), SSH_COMMAND); | 93 | return result; /* return error status from remote command */ |
| 97 | } | 94 | } |
| 98 | 95 | ||
| 99 | 96 | ||
| 100 | /* build up results from remote command in result_text */ | 97 | /* |
| 101 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) | 98 | * Passive mode |
| 102 | asprintf (&result_text, "%s%s", result_text, input_buffer); | 99 | */ |
| 103 | |||
| 104 | /* WARNING if output found on stderr */ | ||
| 105 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | ||
| 106 | if (skip_lines > 0) { | ||
| 107 | if (input_buffer[strlen(input_buffer)-1] == '\n') { | ||
| 108 | skip_lines--; | ||
| 109 | } | ||
| 110 | } else { | ||
| 111 | printf ("%s", input_buffer); | ||
| 112 | result = STATE_WARNING; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | (void) fclose (child_stderr); | ||
| 116 | if (result == STATE_WARNING) | ||
| 117 | return result; | ||
| 118 | |||
| 119 | |||
| 120 | /* close the pipe */ | ||
| 121 | result = spclose (child_process); | ||
| 122 | |||
| 123 | 100 | ||
| 124 | /* process output */ | 101 | /* process output */ |
| 125 | if (passive) { | 102 | if (!(fp = fopen (outputfile, "a"))) { |
| 103 | printf (_("SSH WARNING: could not open %s\n"), outputfile); | ||
| 104 | exit (STATE_UNKNOWN); | ||
| 105 | } | ||
| 126 | 106 | ||
| 127 | if (!(fp = fopen (outputfile, "a"))) { | 107 | local_time = time (NULL); |
| 128 | printf (_("SSH WARNING: could not open %s\n"), outputfile); | 108 | commands = 0; |
| 129 | exit (STATE_UNKNOWN); | 109 | for(i = skip; chld_out.line[i]; i++) { |
| 110 | status_text = strstr (chld_out.line[i], "STATUS CODE: "); | ||
| 111 | if (status_text == NULL) { | ||
| 112 | printf ("%s", chld_out.line[i]); | ||
| 113 | return result; | ||
| 130 | } | 114 | } |
| 131 | 115 | if (service[commands] && status_text | |
| 132 | local_time = time (NULL); | 116 | && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) |
| 133 | commands = 0; | 117 | { |
| 134 | while (result_text && strlen(result_text) > 0) { | 118 | fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", |
| 135 | status_text = strstr (result_text, "STATUS CODE: "); | 119 | (int) local_time, host_shortname, service[commands++], |
| 136 | if (status_text == NULL) { | 120 | cresult, chld_out.line[i]); |
| 137 | printf ("%s", result_text); | ||
| 138 | return result; | ||
| 139 | } | ||
| 140 | asprintf (&output, "%s", result_text); | ||
| 141 | result_text = strnl (status_text); | ||
| 142 | eol = strpbrk (output, "\r\n"); | ||
| 143 | if (eol != NULL) | ||
| 144 | eol[0] = 0; | ||
| 145 | if (service[commands] && status_text | ||
| 146 | && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) { | ||
| 147 | fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", | ||
| 148 | (int) local_time, host_shortname, service[commands++], cresult, | ||
| 149 | output); | ||
| 150 | } | ||
| 151 | } | 121 | } |
| 152 | |||
| 153 | } | ||
| 154 | |||
| 155 | |||
| 156 | /* print the first line from the remote command */ | ||
| 157 | else { | ||
| 158 | eol = strpbrk (result_text, "\r\n"); | ||
| 159 | if (eol) | ||
| 160 | eol[0] = 0; | ||
| 161 | printf ("%s\n", result_text); | ||
| 162 | } | 122 | } |
| 163 | 123 | ||
| 164 | 124 | /* force an OK state */ | |
| 165 | /* return error status from remote command */ | ||
| 166 | return result; | 125 | return result; |
| 167 | } | 126 | } |
| 168 | 127 | ||
| @@ -206,14 +165,12 @@ process_arguments (int argc, char **argv) | |||
| 206 | 165 | ||
| 207 | while (1) { | 166 | while (1) { |
| 208 | c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts, | 167 | c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts, |
| 209 | &option); | 168 | &option); |
| 210 | 169 | ||
| 211 | if (c == -1 || c == EOF) | 170 | if (c == -1 || c == EOF) |
| 212 | break; | 171 | break; |
| 213 | 172 | ||
| 214 | switch (c) { | 173 | switch (c) { |
| 215 | case '?': /* help */ | ||
| 216 | usage2 (_("Unknown argument"), optarg); | ||
| 217 | case 'V': /* version */ | 174 | case 'V': /* version */ |
| 218 | print_revision (progname, revision); | 175 | print_revision (progname, revision); |
| 219 | exit (STATE_OK); | 176 | exit (STATE_OK); |
| @@ -225,18 +182,17 @@ process_arguments (int argc, char **argv) | |||
| 225 | break; | 182 | break; |
| 226 | case 't': /* timeout period */ | 183 | case 't': /* timeout period */ |
| 227 | if (!is_integer (optarg)) | 184 | if (!is_integer (optarg)) |
| 228 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 185 | usage_va(_("Timeout interval must be a positive integer")); |
| 229 | else | 186 | else |
| 230 | timeout_interval = atoi (optarg); | 187 | timeout_interval = atoi (optarg); |
| 231 | break; | 188 | break; |
| 232 | case 'H': /* host */ | 189 | case 'H': /* host */ |
| 233 | if (!is_host (optarg)) | 190 | host_or_die(optarg); |
| 234 | usage2 (_("Invalid hostname/address"), optarg); | ||
| 235 | hostname = optarg; | 191 | hostname = optarg; |
| 236 | break; | 192 | break; |
| 237 | case 'p': /* port number */ | 193 | case 'p': /* port number */ |
| 238 | if (!is_integer (optarg)) | 194 | if (!is_integer (optarg)) |
| 239 | usage2 (_("Port must be a positive integer"), optarg); | 195 | usage_va(_("Port must be a positive integer")); |
| 240 | asprintf (&comm,"%s -p %s", comm, optarg); | 196 | asprintf (&comm,"%s -p %s", comm, optarg); |
| 241 | break; | 197 | break; |
| 242 | case 'O': /* output file */ | 198 | case 'O': /* output file */ |
| @@ -244,25 +200,27 @@ process_arguments (int argc, char **argv) | |||
| 244 | passive = TRUE; | 200 | passive = TRUE; |
| 245 | break; | 201 | break; |
| 246 | case 's': /* description of service to check */ | 202 | case 's': /* description of service to check */ |
| 247 | service = realloc (service, (++services) * sizeof(char *)); | ||
| 248 | p1 = optarg; | 203 | p1 = optarg; |
| 204 | service = realloc (service, (++services) * sizeof(char *)); | ||
| 249 | while ((p2 = index (p1, ':'))) { | 205 | while ((p2 = index (p1, ':'))) { |
| 250 | *p2 = '\0'; | 206 | *p2 = '\0'; |
| 251 | asprintf (&service[services-1], "%s", p1); | 207 | service[services - 1] = p1; |
| 252 | service = realloc (service, (++services) * sizeof(char *)); | 208 | service = realloc (service, (++services) * sizeof(char *)); |
| 253 | p1 = p2 + 1; | 209 | p1 = p2 + 1; |
| 254 | } | 210 | } |
| 255 | asprintf (&service[services-1], "%s", p1); | 211 | service[services - 1] = p1; |
| 256 | break; | 212 | break; |
| 257 | case 'n': /* short name of host in nagios configuration */ | 213 | case 'n': /* short name of host in nagios configuration */ |
| 258 | host_shortname = optarg; | 214 | host_shortname = optarg; |
| 259 | break; | 215 | break; |
| 216 | |||
| 260 | case 'u': | 217 | case 'u': |
| 261 | c = 'l'; | 218 | c = 'l'; |
| 262 | case 'l': /* login name */ | 219 | case 'l': /* login name */ |
| 263 | case 'i': /* identity */ | 220 | case 'i': /* identity */ |
| 264 | asprintf (&comm, "%s -%c %s", comm, c, optarg); | 221 | asprintf (&comm, "%s -%c %s", comm, c, optarg); |
| 265 | break; | 222 | break; |
| 223 | |||
| 266 | case '1': /* Pass these switches directly to ssh */ | 224 | case '1': /* Pass these switches directly to ssh */ |
| 267 | case '2': /* 1 to force version 1, 2 to force version 2 */ | 225 | case '2': /* 1 to force version 1, 2 to force version 2 */ |
| 268 | case '4': /* -4 for IPv4 */ | 226 | case '4': /* -4 for IPv4 */ |
| @@ -278,10 +236,12 @@ process_arguments (int argc, char **argv) | |||
| 278 | break; | 236 | break; |
| 279 | case 'S': /* Skip n lines in the output to ignore system banner */ | 237 | case 'S': /* Skip n lines in the output to ignore system banner */ |
| 280 | if (!is_integer (optarg)) | 238 | if (!is_integer (optarg)) |
| 281 | usage2 (_("skip lines must be an integer"), optarg); | 239 | usage_va(_("skip lines must be an integer")); |
| 282 | else | 240 | else |
| 283 | skip_lines = atoi (optarg); | 241 | skip = atoi (optarg); |
| 284 | break; | 242 | break; |
| 243 | default: /* help */ | ||
| 244 | usage_va(_("Unknown argument - %s"), optarg); | ||
| 285 | } | 245 | } |
| 286 | } | 246 | } |
| 287 | 247 | ||
| @@ -289,8 +249,8 @@ process_arguments (int argc, char **argv) | |||
| 289 | if (hostname == NULL) { | 249 | if (hostname == NULL) { |
| 290 | if (c <= argc) { | 250 | if (c <= argc) { |
| 291 | die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); | 251 | die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); |
| 292 | } else if (!is_host (argv[c])) | 252 | } |
| 293 | die (STATE_UNKNOWN, "%s: %s %s\n", progname, _("Invalid hostname/address"), argv[c]); | 253 | host_or_die(argv[c]); |
| 294 | hostname = argv[c++]; | 254 | hostname = argv[c++]; |
| 295 | } | 255 | } |
| 296 | 256 | ||
| @@ -306,7 +266,7 @@ process_arguments (int argc, char **argv) | |||
| 306 | asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); | 266 | asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); |
| 307 | 267 | ||
| 308 | if (remotecmd == NULL || strlen (remotecmd) <= 1) | 268 | if (remotecmd == NULL || strlen (remotecmd) <= 1) |
| 309 | usage4 (_("No remotecmd")); | 269 | usage_va(_("No remotecmd")); |
| 310 | 270 | ||
| 311 | asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd); | 271 | asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd); |
| 312 | 272 | ||
