summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_apt.c4
-rw-r--r--plugins/check_fping.c78
-rw-r--r--plugins/check_http.c185
-rw-r--r--plugins/check_ide_smart.c109
-rw-r--r--plugins/check_mysql.c154
-rw-r--r--plugins/check_pgsql.c236
-rw-r--r--plugins/check_procs.c76
-rw-r--r--plugins/check_snmp.c41
-rw-r--r--plugins/common.h8
-rw-r--r--plugins/netutils.h2
-rw-r--r--plugins/sslutils.c12
-rw-r--r--plugins/t/check_apt.t4
-rw-r--r--plugins/t/check_http.t32
-rw-r--r--plugins/t/check_procs.t6
-rwxr-xr-xplugins/tests/check_http.t13
15 files changed, 839 insertions, 121 deletions
diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index 433055b5..daeb7578 100644
--- a/plugins/check_apt.c
+++ b/plugins/check_apt.c
@@ -112,8 +112,8 @@ int main (int argc, char **argv) {
112 result = max_state(result, STATE_CRITICAL); 112 result = max_state(result, STATE_CRITICAL);
113 } else if(packages_available > 0){ 113 } else if(packages_available > 0){
114 result = max_state(result, STATE_WARNING); 114 result = max_state(result, STATE_WARNING);
115 } else { 115 } else if(result > STATE_UNKNOWN){
116 result = max_state(result, STATE_OK); 116 result = STATE_UNKNOWN;
117 } 117 }
118 118
119 printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"), 119 printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"),
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index 675a547c..c7cce97d 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -52,6 +52,8 @@ void print_help (void);
52void print_usage (void); 52void print_usage (void);
53 53
54char *server_name = NULL; 54char *server_name = NULL;
55char *sourceip = NULL;
56char *sourceif = NULL;
55int packet_size = PACKET_SIZE; 57int packet_size = PACKET_SIZE;
56int packet_count = PACKET_COUNT; 58int packet_count = PACKET_COUNT;
57int target_timeout = 0; 59int target_timeout = 0;
@@ -72,6 +74,8 @@ main (int argc, char **argv)
72/* normaly should be int result = STATE_UNKNOWN; */ 74/* normaly should be int result = STATE_UNKNOWN; */
73 75
74 int status = STATE_UNKNOWN; 76 int status = STATE_UNKNOWN;
77 int result = 0;
78 char *fping_prog = NULL;
75 char *server = NULL; 79 char *server = NULL;
76 char *command_line = NULL; 80 char *command_line = NULL;
77 char *input_buffer = NULL; 81 char *input_buffer = NULL;
@@ -95,8 +99,21 @@ main (int argc, char **argv)
95 xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); 99 xasprintf(&option_string, "%s-t %d ", option_string, target_timeout);
96 if (packet_interval) 100 if (packet_interval)
97 xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); 101 xasprintf(&option_string, "%s-p %d ", option_string, packet_interval);
98 102 if (sourceip)
99 xasprintf (&command_line, "%s %s-b %d -c %d %s", PATH_TO_FPING, 103 xasprintf(&option_string, "%s-S %s ", option_string, sourceip);
104 if (sourceif)
105 xasprintf(&option_string, "%s-I %s ", option_string, sourceif);
106
107#ifdef PATH_TO_FPING6
108 if (address_family == AF_INET6)
109 fping_prog = strdup(PATH_TO_FPING6);
110 else
111 fping_prog = strdup(PATH_TO_FPING);
112#else
113 fping_prog = strdup(PATH_TO_FPING);
114#endif
115
116 xasprintf (&command_line, "%s %s-b %d -c %d %s", fping_prog,
100 option_string, packet_size, packet_count, server); 117 option_string, packet_size, packet_count, server);
101 118
102 if (verbose) 119 if (verbose)
@@ -130,10 +147,24 @@ main (int argc, char **argv)
130 (void) fclose (child_stderr); 147 (void) fclose (child_stderr);
131 148
132 /* close the pipe */ 149 /* close the pipe */
133 if (spclose (child_process)) 150 if (result = spclose (child_process))
134 /* need to use max_state not max */ 151 /* need to use max_state not max */
135 status = max_state (status, STATE_WARNING); 152 status = max_state (status, STATE_WARNING);
136 153
154 if (result > 1 ) {
155 status = max_state (status, STATE_UNKNOWN);
156 if (result == 2) {
157 die (STATE_UNKNOWN, _("FPING UNKNOWN - IP address not found\n"));
158 }
159 if (result == 3) {
160 die (STATE_UNKNOWN, _("FPING UNKNOWN - invalid commandline argument\n"));
161 }
162 if (result == 4) {
163 die (STATE_UNKNOWN, _("FPING UNKNOWN - failed system call\n"));
164 }
165
166 }
167
137 printf ("FPING %s - %s\n", state_text (status), server_name); 168 printf ("FPING %s - %s\n", state_text (status), server_name);
138 169
139 return status; 170 return status;
@@ -159,6 +190,10 @@ textscan (char *buf)
159 "host"); 190 "host");
160 191
161 } 192 }
193 else if (strstr (buf, "Operation not permitted") || strstr (buf, "No such device") ) {
194 die (STATE_UNKNOWN, _("FPING UNKNOWN - %s parameter error\n"),
195 "host");
196 }
162 else if (strstr (buf, "is down")) { 197 else if (strstr (buf, "is down")) {
163 die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); 198 die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
164 199
@@ -232,6 +267,8 @@ process_arguments (int argc, char **argv)
232 int option = 0; 267 int option = 0;
233 static struct option longopts[] = { 268 static struct option longopts[] = {
234 {"hostname", required_argument, 0, 'H'}, 269 {"hostname", required_argument, 0, 'H'},
270 {"sourceip", required_argument, 0, 'S'},
271 {"sourceif", required_argument, 0, 'I'},
235 {"critical", required_argument, 0, 'c'}, 272 {"critical", required_argument, 0, 'c'},
236 {"warning", required_argument, 0, 'w'}, 273 {"warning", required_argument, 0, 'w'},
237 {"bytes", required_argument, 0, 'b'}, 274 {"bytes", required_argument, 0, 'b'},
@@ -241,6 +278,8 @@ process_arguments (int argc, char **argv)
241 {"verbose", no_argument, 0, 'v'}, 278 {"verbose", no_argument, 0, 'v'},
242 {"version", no_argument, 0, 'V'}, 279 {"version", no_argument, 0, 'V'},
243 {"help", no_argument, 0, 'h'}, 280 {"help", no_argument, 0, 'h'},
281 {"use-ipv4", no_argument, 0, '4'},
282 {"use-ipv6", no_argument, 0, '6'},
244 {0, 0, 0, 0} 283 {0, 0, 0, 0}
245 }; 284 };
246 285
@@ -258,7 +297,7 @@ process_arguments (int argc, char **argv)
258 } 297 }
259 298
260 while (1) { 299 while (1) {
261 c = getopt_long (argc, argv, "+hVvH:c:w:b:n:T:i:", longopts, &option); 300 c = getopt_long (argc, argv, "+hVvH:S:c:w:b:n:T:i:I:46", longopts, &option);
262 301
263 if (c == -1 || c == EOF || c == 1) 302 if (c == -1 || c == EOF || c == 1)
264 break; 303 break;
@@ -281,6 +320,24 @@ process_arguments (int argc, char **argv)
281 } 320 }
282 server_name = strscpy (server_name, optarg); 321 server_name = strscpy (server_name, optarg);
283 break; 322 break;
323 case 'S': /* sourceip */
324 if (is_host (optarg) == FALSE) {
325 usage2 (_("Invalid hostname/address"), optarg);
326 }
327 sourceip = strscpy (sourceip, optarg);
328 break;
329 case 'I': /* sourceip */
330 sourceif = strscpy (sourceif, optarg);
331 case '4': /* IPv4 only */
332 address_family = AF_INET;
333 break;
334 case '6': /* IPv6 only */
335#ifdef USE_IPV6
336 address_family = AF_INET6;
337#else
338 usage (_("IPv6 support not available\n"));
339#endif
340 break;
284 case 'c': 341 case 'c':
285 get_threshold (optarg, rv); 342 get_threshold (optarg, rv);
286 if (rv[RTA]) { 343 if (rv[RTA]) {
@@ -402,6 +459,8 @@ print_help (void)
402 printf (UT_HELP_VRSN); 459 printf (UT_HELP_VRSN);
403 printf (UT_EXTRA_OPTS); 460 printf (UT_EXTRA_OPTS);
404 461
462 printf (UT_IPv46);
463
405 printf (" %s\n", "-H, --hostname=HOST"); 464 printf (" %s\n", "-H, --hostname=HOST");
406 printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)")); 465 printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)"));
407 printf (" %s\n", "-w, --warning=THRESHOLD"); 466 printf (" %s\n", "-w, --warning=THRESHOLD");
@@ -413,15 +472,22 @@ print_help (void)
413 printf (" %s\n", "-n, --number=INTEGER"); 472 printf (" %s\n", "-n, --number=INTEGER");
414 printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT); 473 printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT);
415 printf (" %s\n", "-T, --target-timeout=INTEGER"); 474 printf (" %s\n", "-T, --target-timeout=INTEGER");
416 printf (" %s (default: fping's default for -t)\n", _("Target timeout (ms)"),PACKET_COUNT); 475 printf (" %s (default: fping's default for -t)\n", _("Target timeout (ms)"));
417 printf (" %s\n", "-i, --interval=INTEGER"); 476 printf (" %s\n", "-i, --interval=INTEGER");
418 printf (" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets"),PACKET_COUNT); 477 printf (" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets"));
478 printf (" %s\n", "-S, --sourceip=HOST");
479 printf (" %s\n", _("name or IP Address of sourceip"));
480 printf (" %s\n", "-I, --sourceif=IF");
481 printf (" %s\n", _("source interface name"));
419 printf (UT_VERBOSE); 482 printf (UT_VERBOSE);
420 printf ("\n"); 483 printf ("\n");
421 printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); 484 printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
422 printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of")); 485 printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
423 printf (" %s\n", _("packet loss to trigger an alarm state.")); 486 printf (" %s\n", _("packet loss to trigger an alarm state."));
424 487
488 printf ("\n");
489 printf (" %s\n", _("IPv4 is used by default. Specify -6 to use IPv6."));
490
425 printf (UT_SUPPORT); 491 printf (UT_SUPPORT);
426} 492}
427 493
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 9231a559..1576601b 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -1,40 +1,40 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Nagios check_http plugin 3* Nagios check_http plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2008 Nagios Plugins Development Team 6* Copyright (c) 1999-2013 Nagios Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_http plugin 10* This file contains the check_http plugin
11* 11*
12* This plugin tests the HTTP service on the specified host. It can test 12* This plugin tests the HTTP service on the specified host. It can test
13* normal (http) and secure (https) servers, follow redirects, search for 13* normal (http) and secure (https) servers, follow redirects, search for
14* strings and regular expressions, check connection times, and report on 14* strings and regular expressions, check connection times, and report on
15* certificate expiration times. 15* certificate expiration times.
16* 16*
17* 17*
18* This program is free software: you can redistribute it and/or modify 18* This program is free software: you can redistribute it and/or modify
19* it under the terms of the GNU General Public License as published by 19* it under the terms of the GNU General Public License as published by
20* the Free Software Foundation, either version 3 of the License, or 20* the Free Software Foundation, either version 3 of the License, or
21* (at your option) any later version. 21* (at your option) any later version.
22* 22*
23* This program is distributed in the hope that it will be useful, 23* This program is distributed in the hope that it will be useful,
24* but WITHOUT ANY WARRANTY; without even the implied warranty of 24* but WITHOUT ANY WARRANTY; without even the implied warranty of
25* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26* GNU General Public License for more details. 26* GNU General Public License for more details.
27* 27*
28* You should have received a copy of the GNU General Public License 28* You should have received a copy of the GNU General Public License
29* along with this program. If not, see <http://www.gnu.org/licenses/>. 29* along with this program. If not, see <http://www.gnu.org/licenses/>.
30* 30*
31* 31*
32*****************************************************************************/ 32*****************************************************************************/
33 33
34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */ 34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */
35 35
36const char *progname = "check_http"; 36const char *progname = "check_http";
37const char *copyright = "1999-2011"; 37const char *copyright = "1999-2013";
38const char *email = "nagiosplug-devel@lists.sourceforge.net"; 38const char *email = "nagiosplug-devel@lists.sourceforge.net";
39 39
40#include "common.h" 40#include "common.h"
@@ -43,7 +43,6 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
43#include "base64.h" 43#include "base64.h"
44#include <ctype.h> 44#include <ctype.h>
45 45
46#define INPUT_DELIMITER ";"
47#define STICKY_NONE 0 46#define STICKY_NONE 0
48#define STICKY_HOST 1 47#define STICKY_HOST 1
49#define STICKY_PORT 2 48#define STICKY_PORT 2
@@ -85,6 +84,7 @@ int errcode;
85int invert_regex = 0; 84int invert_regex = 0;
86 85
87struct timeval tv; 86struct timeval tv;
87struct timeval tv_temp;
88 88
89#define HTTP_URL "/" 89#define HTTP_URL "/"
90#define CRLF "\r\n" 90#define CRLF "\r\n"
@@ -100,7 +100,9 @@ char *user_agent;
100int server_url_length; 100int server_url_length;
101int server_expect_yn = 0; 101int server_expect_yn = 0;
102char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; 102char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
103char header_expect[MAX_INPUT_BUFFER] = "";
103char string_expect[MAX_INPUT_BUFFER] = ""; 104char string_expect[MAX_INPUT_BUFFER] = "";
105char output_header_search[30] = "";
104char output_string_search[30] = ""; 106char output_string_search[30] = "";
105char *warning_thresholds = NULL; 107char *warning_thresholds = NULL;
106char *critical_thresholds = NULL; 108char *critical_thresholds = NULL;
@@ -115,6 +117,7 @@ int followsticky = STICKY_NONE;
115int use_ssl = FALSE; 117int use_ssl = FALSE;
116int use_sni = FALSE; 118int use_sni = FALSE;
117int verbose = FALSE; 119int verbose = FALSE;
120int show_extended_perfdata = FALSE;
118int sd; 121int sd;
119int min_page_len = 0; 122int min_page_len = 0;
120int max_page_len = 0; 123int max_page_len = 0;
@@ -124,6 +127,8 @@ char *http_method;
124char *http_post_data; 127char *http_post_data;
125char *http_content_type; 128char *http_content_type;
126char buffer[MAX_INPUT_BUFFER]; 129char buffer[MAX_INPUT_BUFFER];
130char *client_cert = NULL;
131char *client_privkey = NULL;
127 132
128int process_arguments (int, char **); 133int process_arguments (int, char **);
129int check_http (void); 134int check_http (void);
@@ -131,6 +136,11 @@ void redir (char *pos, char *status_line);
131int server_type_check(const char *type); 136int server_type_check(const char *type);
132int server_port_check(int ssl_flag); 137int server_port_check(int ssl_flag);
133char *perfd_time (double microsec); 138char *perfd_time (double microsec);
139char *perfd_time_connect (double microsec);
140char *perfd_time_ssl (double microsec);
141char *perfd_time_firstbyte (double microsec);
142char *perfd_time_headers (double microsec);
143char *perfd_time_transfer (double microsec);
134char *perfd_size (int page_len); 144char *perfd_size (int page_len);
135void print_help (void); 145void print_help (void);
136void print_usage (void); 146void print_usage (void);
@@ -170,7 +180,14 @@ main (int argc, char **argv)
170 return result; 180 return result;
171} 181}
172 182
173 183/* check whether a file exists */
184void
185test_file (char *path)
186{
187 if (access(path, R_OK) == 0)
188 return;
189 usage2 (_("file does not exist or is not readable"), path);
190}
174 191
175/* process command-line arguments */ 192/* process command-line arguments */
176int 193int
@@ -199,6 +216,7 @@ process_arguments (int argc, char **argv)
199 {"port", required_argument, 0, 'p'}, 216 {"port", required_argument, 0, 'p'},
200 {"authorization", required_argument, 0, 'a'}, 217 {"authorization", required_argument, 0, 'a'},
201 {"proxy_authorization", required_argument, 0, 'b'}, 218 {"proxy_authorization", required_argument, 0, 'b'},
219 {"header-string", required_argument, 0, 'd'},
202 {"string", required_argument, 0, 's'}, 220 {"string", required_argument, 0, 's'},
203 {"expect", required_argument, 0, 'e'}, 221 {"expect", required_argument, 0, 'e'},
204 {"regex", required_argument, 0, 'r'}, 222 {"regex", required_argument, 0, 'r'},
@@ -207,6 +225,8 @@ process_arguments (int argc, char **argv)
207 {"linespan", no_argument, 0, 'l'}, 225 {"linespan", no_argument, 0, 'l'},
208 {"onredirect", required_argument, 0, 'f'}, 226 {"onredirect", required_argument, 0, 'f'},
209 {"certificate", required_argument, 0, 'C'}, 227 {"certificate", required_argument, 0, 'C'},
228 {"client-cert", required_argument, 0, 'J'},
229 {"private-key", required_argument, 0, 'K'},
210 {"useragent", required_argument, 0, 'A'}, 230 {"useragent", required_argument, 0, 'A'},
211 {"header", required_argument, 0, 'k'}, 231 {"header", required_argument, 0, 'k'},
212 {"no-body", no_argument, 0, 'N'}, 232 {"no-body", no_argument, 0, 'N'},
@@ -216,6 +236,7 @@ process_arguments (int argc, char **argv)
216 {"invert-regex", no_argument, NULL, INVERT_REGEX}, 236 {"invert-regex", no_argument, NULL, INVERT_REGEX},
217 {"use-ipv4", no_argument, 0, '4'}, 237 {"use-ipv4", no_argument, 0, '4'},
218 {"use-ipv6", no_argument, 0, '6'}, 238 {"use-ipv6", no_argument, 0, '6'},
239 {"extended-perfdata", no_argument, 0, 'E'},
219 {0, 0, 0, 0} 240 {0, 0, 0, 0}
220 }; 241 };
221 242
@@ -236,7 +257,7 @@ process_arguments (int argc, char **argv)
236 } 257 }
237 258
238 while (1) { 259 while (1) {
239 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:nlLS::m:M:N", longopts, &option); 260 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:N:E", longopts, &option);
240 if (c == -1 || c == EOF) 261 if (c == -1 || c == EOF)
241 break; 262 break;
242 263
@@ -301,10 +322,23 @@ process_arguments (int argc, char **argv)
301 days_till_exp_warn = atoi (optarg); 322 days_till_exp_warn = atoi (optarg);
302 } 323 }
303 check_cert = TRUE; 324 check_cert = TRUE;
304 /* Fall through to -S option */ 325 goto enable_ssl;
326#endif
327 case 'J': /* use client certificate */
328#ifdef HAVE_SSL
329 test_file(optarg);
330 client_cert = optarg;
331 goto enable_ssl;
332#endif
333 case 'K': /* use client private key */
334#ifdef HAVE_SSL
335 test_file(optarg);
336 client_privkey = optarg;
337 goto enable_ssl;
305#endif 338#endif
306 case 'S': /* use SSL */ 339 case 'S': /* use SSL */
307#ifdef HAVE_SSL 340#ifdef HAVE_SSL
341 enable_ssl:
308 use_ssl = TRUE; 342 use_ssl = TRUE;
309 if (optarg == NULL || c != 'S') 343 if (optarg == NULL || c != 'S')
310 ssl_version = 0; 344 ssl_version = 0;
@@ -316,6 +350,7 @@ process_arguments (int argc, char **argv)
316 if (specify_port == FALSE) 350 if (specify_port == FALSE)
317 server_port = HTTPS_PORT; 351 server_port = HTTPS_PORT;
318#else 352#else
353 /* -C -J and -K fall through to here without SSL */
319 usage4 (_("Invalid option - SSL is not available")); 354 usage4 (_("Invalid option - SSL is not available"));
320#endif 355#endif
321 break; 356 break;
@@ -385,6 +420,10 @@ process_arguments (int argc, char **argv)
385 free(http_method); 420 free(http_method);
386 http_method = strdup (optarg); 421 http_method = strdup (optarg);
387 break; 422 break;
423 case 'd': /* string or substring */
424 strncpy (header_expect, optarg, MAX_INPUT_BUFFER - 1);
425 header_expect[MAX_INPUT_BUFFER - 1] = 0;
426 break;
388 case 's': /* string or substring */ 427 case 's': /* string or substring */
389 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); 428 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1);
390 string_expect[MAX_INPUT_BUFFER - 1] = 0; 429 string_expect[MAX_INPUT_BUFFER - 1] = 0;
@@ -471,6 +510,9 @@ process_arguments (int argc, char **argv)
471 } 510 }
472 } 511 }
473 break; 512 break;
513 case 'E': /* show extended perfdata */
514 show_extended_perfdata = TRUE;
515 break;
474 } 516 }
475 } 517 }
476 518
@@ -497,6 +539,9 @@ process_arguments (int argc, char **argv)
497 if (http_method == NULL) 539 if (http_method == NULL)
498 http_method = strdup ("GET"); 540 http_method = strdup ("GET");
499 541
542 if (client_cert && !client_privkey)
543 usage4 (_("If you use a client certificate you must also specify a private key file"));
544
500 return TRUE; 545 return TRUE;
501} 546}
502 547
@@ -812,17 +857,33 @@ check_http (void)
812 char *pos; 857 char *pos;
813 long microsec; 858 long microsec;
814 double elapsed_time; 859 double elapsed_time;
860 long microsec_connect;
861 double elapsed_time_connect;
862 long microsec_ssl;
863 double elapsed_time_ssl;
864 long microsec_firstbyte;
865 double elapsed_time_firstbyte;
866 long microsec_headers;
867 double elapsed_time_headers;
868 long microsec_transfer;
869 double elapsed_time_transfer;
815 int page_len = 0; 870 int page_len = 0;
816 int result = STATE_OK; 871 int result = STATE_OK;
817 872
818 /* try to connect to the host at the given port number */ 873 /* try to connect to the host at the given port number */
874 gettimeofday (&tv_temp, NULL);
819 if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) 875 if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
820 die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n")); 876 die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n"));
877 microsec_connect = deltime (tv_temp);
821#ifdef HAVE_SSL 878#ifdef HAVE_SSL
879 elapsed_time_connect = (double)microsec_connect / 1.0e6;
822 if (use_ssl == TRUE) { 880 if (use_ssl == TRUE) {
823 result = np_net_ssl_init_with_hostname_and_version(sd, (use_sni ? host_name : NULL), ssl_version); 881 gettimeofday (&tv_temp, NULL);
882 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
824 if (result != STATE_OK) 883 if (result != STATE_OK)
825 return result; 884 return result;
885 microsec_ssl = deltime (tv_temp);
886 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
826 if (check_cert == TRUE) { 887 if (check_cert == TRUE) {
827 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 888 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
828 np_net_ssl_cleanup(); 889 np_net_ssl_cleanup();
@@ -854,8 +915,7 @@ check_http (void)
854 /* optionally send any other header tag */ 915 /* optionally send any other header tag */
855 if (http_opt_headers_count) { 916 if (http_opt_headers_count) {
856 for (i = 0; i < http_opt_headers_count ; i++) { 917 for (i = 0; i < http_opt_headers_count ; i++) {
857 for ((pos = strtok(http_opt_headers[i], INPUT_DELIMITER)); pos; (pos = strtok(NULL, INPUT_DELIMITER))) 918 xasprintf (&buf, "%s%s\r\n", buf, http_opt_headers[i]);
858 xasprintf (&buf, "%s%s\r\n", buf, pos);
859 } 919 }
860 /* This cannot be free'd here because a redirection will then try to access this and segfault */ 920 /* This cannot be free'd here because a redirection will then try to access this and segfault */
861 /* Covered in a testcase in tests/check_http.t */ 921 /* Covered in a testcase in tests/check_http.t */
@@ -891,11 +951,19 @@ check_http (void)
891 } 951 }
892 952
893 if (verbose) printf ("%s\n", buf); 953 if (verbose) printf ("%s\n", buf);
954 gettimeofday (&tv_temp, NULL);
894 my_send (buf, strlen (buf)); 955 my_send (buf, strlen (buf));
956 microsec_headers = deltime (tv_temp);
957 elapsed_time_headers = (double)microsec_headers / 1.0e6;
895 958
896 /* fetch the page */ 959 /* fetch the page */
897 full_page = strdup(""); 960 full_page = strdup("");
961 gettimeofday (&tv_temp, NULL);
898 while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) { 962 while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) {
963 if ((i >= 1) && (elapsed_time_firstbyte <= 0.000001)) {
964 microsec_firstbyte = deltime (tv_temp);
965 elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6;
966 }
899 buffer[i] = '\0'; 967 buffer[i] = '\0';
900 xasprintf (&full_page_new, "%s%s", full_page, buffer); 968 xasprintf (&full_page_new, "%s%s", full_page, buffer);
901 free (full_page); 969 free (full_page);
@@ -907,6 +975,8 @@ check_http (void)
907 break; 975 break;
908 } 976 }
909 } 977 }
978 microsec_transfer = deltime (tv_temp);
979 elapsed_time_transfer = (double)microsec_transfer / 1.0e6;
910 980
911 if (i < 0 && errno != ECONNRESET) { 981 if (i < 0 && errno != ECONNRESET) {
912#ifdef HAVE_SSL 982#ifdef HAVE_SSL
@@ -1050,6 +1120,17 @@ check_http (void)
1050 } 1120 }
1051 1121
1052 /* Page and Header content checks go here */ 1122 /* Page and Header content checks go here */
1123 if (strlen (header_expect)) {
1124 if (!strstr (header, header_expect)) {
1125 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search));
1126 if(output_header_search[sizeof(output_header_search)-1]!='\0') {
1127 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4);
1128 }
1129 xasprintf (&msg, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url);
1130 result = STATE_CRITICAL;
1131 }
1132 }
1133
1053 1134
1054 if (strlen (string_expect)) { 1135 if (strlen (string_expect)) {
1055 if (!strstr (page, string_expect)) { 1136 if (!strstr (page, string_expect)) {
@@ -1108,11 +1189,25 @@ check_http (void)
1108 msg[strlen(msg)-3] = '\0'; 1189 msg[strlen(msg)-3] = '\0';
1109 1190
1110 /* check elapsed time */ 1191 /* check elapsed time */
1111 xasprintf (&msg, 1192 if (show_extended_perfdata)
1112 _("%s - %d bytes in %.3f second response time %s|%s %s"), 1193 xasprintf (&msg,
1113 msg, page_len, elapsed_time, 1194 _("%s - %d bytes in %.3f second response time %s|%s %s %s %s %s %s %s"),
1114 (display_html ? "</A>" : ""), 1195 msg, page_len, elapsed_time,
1115 perfd_time (elapsed_time), perfd_size (page_len)); 1196 (display_html ? "</A>" : ""),
1197 perfd_time (elapsed_time),
1198 perfd_size (page_len),
1199 perfd_time_connect (elapsed_time_connect),
1200 use_ssl == TRUE ? perfd_time_ssl (elapsed_time_ssl) : "",
1201 perfd_time_headers (elapsed_time_headers),
1202 perfd_time_firstbyte (elapsed_time_firstbyte),
1203 perfd_time_transfer (elapsed_time_transfer));
1204 else
1205 xasprintf (&msg,
1206 _("%s - %d bytes in %.3f second response time %s|%s %s"),
1207 msg, page_len, elapsed_time,
1208 (display_html ? "</A>" : ""),
1209 perfd_time (elapsed_time),
1210 perfd_size (page_len));
1116 1211
1117 result = max_state_alt(get_status(elapsed_time, thlds), result); 1212 result = max_state_alt(get_status(elapsed_time, thlds), result);
1118 1213
@@ -1301,7 +1396,30 @@ char *perfd_time (double elapsed_time)
1301 TRUE, 0, FALSE, 0); 1396 TRUE, 0, FALSE, 0);
1302} 1397}
1303 1398
1399char *perfd_time_connect (double elapsed_time_connect)
1400{
1401 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1402}
1403
1404char *perfd_time_ssl (double elapsed_time_ssl)
1405{
1406 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1407}
1408
1409char *perfd_time_headers (double elapsed_time_headers)
1410{
1411 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1412}
1413
1414char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1415{
1416 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1417}
1304 1418
1419char *perfd_time_transfer (double elapsed_time_transfer)
1420{
1421 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0);
1422}
1305 1423
1306char *perfd_size (int page_len) 1424char *perfd_size (int page_len)
1307{ 1425{
@@ -1354,7 +1472,13 @@ print_help (void)
1354 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1472 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1355 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1473 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1356 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1474 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1357 printf (" %s\n", _("(when this option is used the URL is not checked.)\n")); 1475 printf (" %s\n", _("(when this option is used the URL is not checked.)"));
1476 printf (" %s\n", "-J, --client-cert=FILE");
1477 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1478 printf (" %s\n", _("to be used in establishing the SSL session"));
1479 printf (" %s\n", "-K, --private-key=FILE");
1480 printf (" %s\n", _("Name of file containing the private key (PEM format)"));
1481 printf (" %s\n", _("matching the client certificate"));
1358#endif 1482#endif
1359 1483
1360 printf (" %s\n", "-e, --expect=STRING"); 1484 printf (" %s\n", "-e, --expect=STRING");
@@ -1362,6 +1486,8 @@ print_help (void)
1362 printf (" %s", _("the first (status) line of the server response (default: ")); 1486 printf (" %s", _("the first (status) line of the server response (default: "));
1363 printf ("%s)\n", HTTP_EXPECT); 1487 printf ("%s)\n", HTTP_EXPECT);
1364 printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); 1488 printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"));
1489 printf (" %s\n", "-d, --header-string=STRING");
1490 printf (" %s\n", _("String to expect in the response headers"));
1365 printf (" %s\n", "-s, --string=STRING"); 1491 printf (" %s\n", "-s, --string=STRING");
1366 printf (" %s\n", _("String to expect in the content")); 1492 printf (" %s\n", _("String to expect in the content"));
1367 printf (" %s\n", "-u, --url=PATH"); 1493 printf (" %s\n", "-u, --url=PATH");
@@ -1396,6 +1522,8 @@ print_help (void)
1396 printf (" %s\n", _("String to be sent in http header as \"User Agent\"")); 1522 printf (" %s\n", _("String to be sent in http header as \"User Agent\""));
1397 printf (" %s\n", "-k, --header=STRING"); 1523 printf (" %s\n", "-k, --header=STRING");
1398 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); 1524 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers"));
1525 printf (" %s\n", "-E, --extended-perfdata");
1526 printf (" %s\n", _("Print additional performance data"));
1399 printf (" %s\n", "-L, --link"); 1527 printf (" %s\n", "-L, --link");
1400 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); 1528 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)"));
1401 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); 1529 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>");
@@ -1461,9 +1589,10 @@ print_usage (void)
1461{ 1589{
1462 printf ("%s\n", _("Usage:")); 1590 printf ("%s\n", _("Usage:"));
1463 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); 1591 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
1464 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-a auth]\n"); 1592 printf (" [-J <client certificate file>] [-K <private key>]\n");
1593 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
1465 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); 1594 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n");
1466 printf (" [-e <expect>] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 1595 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
1467 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 1596 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1468 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n"); 1597 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n");
1469 printf (" [-T <content-type>] [-j method]\n"); 1598 printf (" [-T <content-type>] [-j method]\n");
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index b942461b..ee6bf7bd 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -46,8 +46,29 @@ void print_usage (void);
46#include <sys/stat.h> 46#include <sys/stat.h>
47#include <sys/ioctl.h> 47#include <sys/ioctl.h>
48#include <fcntl.h> 48#include <fcntl.h>
49#ifdef __linux__
49#include <linux/hdreg.h> 50#include <linux/hdreg.h>
50#include <linux/types.h> 51#include <linux/types.h>
52
53#define OPEN_MODE O_RDONLY
54#endif /* __linux__ */
55#ifdef __NetBSD__
56#include <sys/device.h>
57#include <sys/param.h>
58#include <sys/sysctl.h>
59#include <sys/videoio.h> /* for __u8 and friends */
60#include <sys/scsiio.h>
61#include <sys/ataio.h>
62#include <dev/ata/atareg.h>
63#include <dev/ic/wdcreg.h>
64
65#define SMART_ENABLE WDSM_ENABLE_OPS
66#define SMART_DISABLE WDSM_DISABLE_OPS
67#define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM
68#define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */
69
70#define OPEN_MODE O_RDWR
71#endif /* __NetBSD__ */
51#include <errno.h> 72#include <errno.h>
52 73
53#define NR_ATTRIBUTES 30 74#define NR_ATTRIBUTES 30
@@ -223,7 +244,7 @@ main (int argc, char *argv[])
223 return STATE_OK; 244 return STATE_OK;
224 } 245 }
225 246
226 fd = open (device, O_RDONLY); 247 fd = open (device, OPEN_MODE);
227 248
228 if (fd < 0) { 249 if (fd < 0) {
229 printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno)); 250 printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno));
@@ -284,6 +305,7 @@ get_offline_text (int status)
284int 305int
285smart_read_values (int fd, values_t * values) 306smart_read_values (int fd, values_t * values)
286{ 307{
308#ifdef __linux__
287 int e; 309 int e;
288 __u8 args[4 + 512]; 310 __u8 args[4 + 512];
289 args[0] = WIN_SMART; 311 args[0] = WIN_SMART;
@@ -296,6 +318,35 @@ smart_read_values (int fd, values_t * values)
296 return e; 318 return e;
297 } 319 }
298 memcpy (values, args + 4, 512); 320 memcpy (values, args + 4, 512);
321#endif /* __linux__ */
322#ifdef __NetBSD__
323 struct atareq req;
324 unsigned char inbuf[DEV_BSIZE];
325
326 memset(&req, 0, sizeof(req));
327 req.timeout = 1000;
328 memset(&inbuf, 0, sizeof(inbuf));
329
330 req.flags = ATACMD_READ;
331 req.features = WDSM_RD_DATA;
332 req.command = WDCC_SMART;
333 req.databuf = (char *)inbuf;
334 req.datalen = sizeof(inbuf);
335 req.cylinder = WDSMART_CYL;
336
337 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
338 if (req.retsts != ATACMD_OK)
339 errno = ENODEV;
340 }
341
342 if (errno != 0) {
343 int e = errno;
344 printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno));
345 return e;
346 }
347
348 (void)memcpy(values, inbuf, 512);
349#endif /* __NetBSD__ */
299 return 0; 350 return 0;
300} 351}
301 352
@@ -439,6 +490,7 @@ int
439smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error) 490smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error)
440{ 491{
441 int e = 0; 492 int e = 0;
493#ifdef __linux__
442 __u8 args[4]; 494 __u8 args[4];
443 args[0] = WIN_SMART; 495 args[0] = WIN_SMART;
444 args[1] = val0; 496 args[1] = val0;
@@ -450,6 +502,31 @@ smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error)
450 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno)); 502 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
451 } 503 }
452 } 504 }
505#endif /* __linux__ */
506#ifdef __NetBSD__
507 struct atareq req;
508
509 memset(&req, 0, sizeof(req));
510 req.timeout = 1000;
511 req.flags = ATACMD_READREG;
512 req.features = smart_command[command].value;
513 req.command = WDCC_SMART;
514 req.cylinder = WDSMART_CYL;
515 req.sec_count = val0;
516
517 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
518 if (req.retsts != ATACMD_OK)
519 errno = ENODEV;
520 if (req.cylinder != WDSMART_CYL)
521 errno = ENODEV;
522 }
523
524 if (errno != 0) {
525 e = errno;
526 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
527 return e;
528 }
529#endif /* __NetBSD__ */
453 return e; 530 return e;
454} 531}
455 532
@@ -458,6 +535,7 @@ smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, char show_error)
458int 535int
459smart_read_thresholds (int fd, thresholds_t * thresholds) 536smart_read_thresholds (int fd, thresholds_t * thresholds)
460{ 537{
538#ifdef __linux__
461 int e; 539 int e;
462 __u8 args[4 + 512]; 540 __u8 args[4 + 512];
463 args[0] = WIN_SMART; 541 args[0] = WIN_SMART;
@@ -470,6 +548,35 @@ smart_read_thresholds (int fd, thresholds_t * thresholds)
470 return e; 548 return e;
471 } 549 }
472 memcpy (thresholds, args + 4, 512); 550 memcpy (thresholds, args + 4, 512);
551#endif /* __linux__ */
552#ifdef __NetBSD__
553 struct atareq req;
554 unsigned char inbuf[DEV_BSIZE];
555
556 memset(&req, 0, sizeof(req));
557 req.timeout = 1000;
558 memset(&inbuf, 0, sizeof(inbuf));
559
560 req.flags = ATACMD_READ;
561 req.features = WDSM_RD_THRESHOLDS;
562 req.command = WDCC_SMART;
563 req.databuf = (char *)inbuf;
564 req.datalen = sizeof(inbuf);
565 req.cylinder = WDSMART_CYL;
566
567 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
568 if (req.retsts != ATACMD_OK)
569 errno = ENODEV;
570 }
571
572 if (errno != 0) {
573 int e = errno;
574 printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno));
575 return e;
576 }
577
578 (void)memcpy(thresholds, inbuf, 512);
579#endif /* __NetBSD__ */
473 return 0; 580 return 0;
474} 581}
475 582
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 51579c2a..db670e2d 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -49,10 +49,44 @@ char *db_host = NULL;
49char *db_socket = NULL; 49char *db_socket = NULL;
50char *db_pass = NULL; 50char *db_pass = NULL;
51char *db = NULL; 51char *db = NULL;
52char *ca_cert = NULL;
53char *ca_dir = NULL;
54char *cert = NULL;
55char *key = NULL;
56char *ciphers = NULL;
57bool ssl = false;
58char *opt_file = NULL;
59char *opt_group = NULL;
52unsigned int db_port = MYSQL_PORT; 60unsigned int db_port = MYSQL_PORT;
53int check_slave = 0, warn_sec = 0, crit_sec = 0; 61int check_slave = 0, warn_sec = 0, crit_sec = 0;
54int verbose = 0; 62int verbose = 0;
55 63
64static double warning_time = 0;
65static double critical_time = 0;
66
67#define LENGTH_METRIC_UNIT 6
68static const char *metric_unit[LENGTH_METRIC_UNIT] = {
69 "Open_files",
70 "Open_tables",
71 "Qcache_free_memory",
72 "Qcache_queries_in_cache",
73 "Threads_connected",
74 "Threads_running"
75};
76
77#define LENGTH_METRIC_COUNTER 9
78static const char *metric_counter[LENGTH_METRIC_COUNTER] = {
79 "Connections",
80 "Qcache_hits",
81 "Qcache_inserts",
82 "Qcache_lowmem_prunes",
83 "Qcache_not_cached",
84 "Queries",
85 "Questions",
86 "Table_locks_waited",
87 "Uptime"
88};
89
56thresholds *my_threshold = NULL; 90thresholds *my_threshold = NULL;
57 91
58int process_arguments (int, char **); 92int process_arguments (int, char **);
@@ -73,6 +107,9 @@ main (int argc, char **argv)
73 char *result = NULL; 107 char *result = NULL;
74 char *error = NULL; 108 char *error = NULL;
75 char slaveresult[SLAVERESULTSIZE]; 109 char slaveresult[SLAVERESULTSIZE];
110 char* perf;
111
112 perf = strdup ("");
76 113
77 setlocale (LC_ALL, ""); 114 setlocale (LC_ALL, "");
78 bindtextdomain (PACKAGE, LOCALEDIR); 115 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -86,9 +123,17 @@ main (int argc, char **argv)
86 123
87 /* initialize mysql */ 124 /* initialize mysql */
88 mysql_init (&mysql); 125 mysql_init (&mysql);
126
127 if (opt_file != NULL)
128 mysql_options(&mysql,MYSQL_READ_DEFAULT_FILE,opt_file);
89 129
90 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client"); 130 if (opt_group != NULL)
131 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,opt_group);
132 else
133 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
91 134
135 if (ssl)
136 mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers);
92 /* establish a connection to the server and error checking */ 137 /* establish a connection to the server and error checking */
93 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) { 138 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) {
94 if (mysql_errno (&mysql) == CR_UNKNOWN_HOST) 139 if (mysql_errno (&mysql) == CR_UNKNOWN_HOST)
@@ -118,6 +163,37 @@ main (int argc, char **argv)
118 die (STATE_CRITICAL, "%s\n", mysql_error (&mysql)); 163 die (STATE_CRITICAL, "%s\n", mysql_error (&mysql));
119 } 164 }
120 165
166 /* try to fetch some perf data */
167 if (mysql_query (&mysql, "show global status") == 0) {
168 if ( (res = mysql_store_result (&mysql)) == NULL) {
169 error = strdup(mysql_error(&mysql));
170 mysql_close (&mysql);
171 die (STATE_CRITICAL, _("status store_result error: %s\n"), error);
172 }
173
174 while ( (row = mysql_fetch_row (res)) != NULL) {
175 int i;
176
177 for(i = 0; i < LENGTH_METRIC_UNIT; i++) {
178 if (strcmp(row[0], metric_unit[i]) == 0) {
179 xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i],
180 atol(row[1]), "", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0));
181 continue;
182 }
183 }
184 for(i = 0; i < LENGTH_METRIC_COUNTER; i++) {
185 if (strcmp(row[0], metric_counter[i]) == 0) {
186 xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i],
187 atol(row[1]), "c", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0));
188 continue;
189 }
190 }
191 }
192 /* remove trailing space */
193 if (strlen(perf) > 0)
194 perf[strlen(perf) - 1] = '\0';
195 }
196
121 if(check_slave) { 197 if(check_slave) {
122 /* check the slave status */ 198 /* check the slave status */
123 if (mysql_query (&mysql, "show slave status") != 0) { 199 if (mysql_query (&mysql, "show slave status") != 0) {
@@ -210,11 +286,17 @@ main (int argc, char **argv)
210 286
211 status = get_status(value, my_threshold); 287 status = get_status(value, my_threshold);
212 288
289 xasprintf (&perf, "%s %s", perf, fperfdata ("seconds behind master", value, "s",
290 TRUE, (double) warning_time,
291 TRUE, (double) critical_time,
292 FALSE, 0,
293 FALSE, 0));
294
213 if (status == STATE_WARNING) { 295 if (status == STATE_WARNING) {
214 printf("SLOW_SLAVE %s: %s\n", _("WARNING"), slaveresult); 296 printf("SLOW_SLAVE %s: %s|%s\n", _("WARNING"), slaveresult, perf);
215 exit(STATE_WARNING); 297 exit(STATE_WARNING);
216 } else if (status == STATE_CRITICAL) { 298 } else if (status == STATE_CRITICAL) {
217 printf("SLOW_SLAVE %s: %s\n", _("CRITICAL"), slaveresult); 299 printf("SLOW_SLAVE %s: %s|%s\n", _("CRITICAL"), slaveresult, perf);
218 exit(STATE_CRITICAL); 300 exit(STATE_CRITICAL);
219 } 301 }
220 } 302 }
@@ -229,9 +311,9 @@ main (int argc, char **argv)
229 311
230 /* print out the result of stats */ 312 /* print out the result of stats */
231 if (check_slave) { 313 if (check_slave) {
232 printf ("%s %s\n", result, slaveresult); 314 printf ("%s %s|%s\n", result, slaveresult, perf);
233 } else { 315 } else {
234 printf ("%s\n", result); 316 printf ("%s|%s\n", result, perf);
235 } 317 }
236 318
237 return STATE_OK; 319 return STATE_OK;
@@ -253,6 +335,8 @@ process_arguments (int argc, char **argv)
253 {"database", required_argument, 0, 'd'}, 335 {"database", required_argument, 0, 'd'},
254 {"username", required_argument, 0, 'u'}, 336 {"username", required_argument, 0, 'u'},
255 {"password", required_argument, 0, 'p'}, 337 {"password", required_argument, 0, 'p'},
338 {"file", required_argument, 0, 'f'},
339 {"group", required_argument, 0, 'g'},
256 {"port", required_argument, 0, 'P'}, 340 {"port", required_argument, 0, 'P'},
257 {"critical", required_argument, 0, 'c'}, 341 {"critical", required_argument, 0, 'c'},
258 {"warning", required_argument, 0, 'w'}, 342 {"warning", required_argument, 0, 'w'},
@@ -260,6 +344,12 @@ process_arguments (int argc, char **argv)
260 {"verbose", no_argument, 0, 'v'}, 344 {"verbose", no_argument, 0, 'v'},
261 {"version", no_argument, 0, 'V'}, 345 {"version", no_argument, 0, 'V'},
262 {"help", no_argument, 0, 'h'}, 346 {"help", no_argument, 0, 'h'},
347 {"ssl", no_argument, 0, 'l'},
348 {"ca-cert", optional_argument, 0, 'C'},
349 {"key", required_argument,0,'k'},
350 {"cert", required_argument,0,'a'},
351 {"ca-dir", required_argument, 0, 'D'},
352 {"ciphers", required_argument, 0, 'L'},
263 {0, 0, 0, 0} 353 {0, 0, 0, 0}
264 }; 354 };
265 355
@@ -267,7 +357,7 @@ process_arguments (int argc, char **argv)
267 return ERROR; 357 return ERROR;
268 358
269 while (1) { 359 while (1) {
270 c = getopt_long (argc, argv, "hvVSP:p:u:d:H:s:c:w:", longopts, &option); 360 c = getopt_long (argc, argv, "hlvVSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option);
271 361
272 if (c == -1 || c == EOF) 362 if (c == -1 || c == EOF)
273 break; 363 break;
@@ -287,6 +377,24 @@ process_arguments (int argc, char **argv)
287 case 'd': /* database */ 377 case 'd': /* database */
288 db = optarg; 378 db = optarg;
289 break; 379 break;
380 case 'l':
381 ssl = true;
382 break;
383 case 'C':
384 ca_cert = optarg;
385 break;
386 case 'a':
387 cert = optarg;
388 break;
389 case 'k':
390 key = optarg;
391 break;
392 case 'D':
393 ca_dir = optarg;
394 break;
395 case 'L':
396 ciphers = optarg;
397 break;
290 case 'u': /* username */ 398 case 'u': /* username */
291 db_user = optarg; 399 db_user = optarg;
292 break; 400 break;
@@ -299,6 +407,12 @@ process_arguments (int argc, char **argv)
299 optarg++; 407 optarg++;
300 } 408 }
301 break; 409 break;
410 case 'f': /* client options file */
411 opt_file = optarg;
412 break;
413 case 'g': /* client options group */
414 opt_group = optarg;
415 break;
302 case 'P': /* critical time threshold */ 416 case 'P': /* critical time threshold */
303 db_port = atoi (optarg); 417 db_port = atoi (optarg);
304 break; 418 break;
@@ -307,9 +421,11 @@ process_arguments (int argc, char **argv)
307 break; 421 break;
308 case 'w': 422 case 'w':
309 warning = optarg; 423 warning = optarg;
424 warning_time = strtod (warning, NULL);
310 break; 425 break;
311 case 'c': 426 case 'c':
312 critical = optarg; 427 critical = optarg;
428 critical_time = strtod (critical, NULL);
313 break; 429 break;
314 case 'V': /* version */ 430 case 'V': /* version */
315 print_revision (progname, NP_VERSION); 431 print_revision (progname, NP_VERSION);
@@ -360,6 +476,12 @@ validate_arguments (void)
360 if (db_user == NULL) 476 if (db_user == NULL)
361 db_user = strdup(""); 477 db_user = strdup("");
362 478
479 if (opt_file == NULL)
480 opt_file = strdup("");
481
482 if (opt_group == NULL)
483 opt_group = strdup("");
484
363 if (db_host == NULL) 485 if (db_host == NULL)
364 db_host = strdup(""); 486 db_host = strdup("");
365 487
@@ -395,6 +517,10 @@ print_help (void)
395 517
396 printf (" %s\n", "-d, --database=STRING"); 518 printf (" %s\n", "-d, --database=STRING");
397 printf (" %s\n", _("Check database with indicated name")); 519 printf (" %s\n", _("Check database with indicated name"));
520 printf (" %s\n", "-f, --file=STRING");
521 printf (" %s\n", _("Read from the specified client options file"));
522 printf (" %s\n", "-g, --group=STRING");
523 printf (" %s\n", _("Use a client options group"));
398 printf (" %s\n", "-u, --username=STRING"); 524 printf (" %s\n", "-u, --username=STRING");
399 printf (" %s\n", _("Connect using the indicated username")); 525 printf (" %s\n", _("Connect using the indicated username"));
400 printf (" %s\n", "-p, --password=STRING"); 526 printf (" %s\n", "-p, --password=STRING");
@@ -409,6 +535,19 @@ print_help (void)
409 printf (" %s\n", "-c, --critical"); 535 printf (" %s\n", "-c, --critical");
410 printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds")); 536 printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds"));
411 printf (" %s\n", _("behind master")); 537 printf (" %s\n", _("behind master"));
538 printf (" %s\n", "-l, --ssl");
539 printf (" %s\n", _("Use ssl encryptation"));
540 printf (" %s\n", "-C, --ca-cert=STRING");
541 printf (" %s\n", _("Path to CA signing the cert"));
542 printf (" %s\n", "-a, --cert=STRING");
543 printf (" %s\n", _("Path to SSL certificate"));
544 printf (" %s\n", "-k, --key=STRING");
545 printf (" %s\n", _("Path to private SSL key"));
546 printf (" %s\n", "-D, --ca-dir=STRING");
547 printf (" %s\n", _("Path to CA directory"));
548 printf (" %s\n", "-L, --ciphers=STRING");
549 printf (" %s\n", _("List of valid SSL ciphers"));
550
412 551
413 printf ("\n"); 552 printf ("\n");
414 printf (" %s\n", _("There are no required arguments. By default, the local database is checked")); 553 printf (" %s\n", _("There are no required arguments. By default, the local database is checked"));
@@ -429,5 +568,6 @@ print_usage (void)
429{ 568{
430 printf ("%s\n", _("Usage:")); 569 printf ("%s\n", _("Usage:"));
431 printf (" %s [-d database] [-H host] [-P port] [-s socket]\n",progname); 570 printf (" %s [-d database] [-H host] [-P port] [-s socket]\n",progname);
432 printf (" [-u user] [-p password] [-S]\n"); 571 printf (" [-u user] [-p password] [-S] [-l] [-a cert] [-k key]\n");
572 printf (" [-C ca-cert] [-D ca-dir] [-L ciphers] [-f optfile] [-g group]\n");
433} 573}
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 8b0769f1..8d60701f 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -3,7 +3,7 @@
3* Nagios check_pgsql plugin 3* Nagios check_pgsql plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2007 Nagios Plugins Development Team 6* Copyright (c) 1999-2011 Nagios Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
@@ -29,7 +29,7 @@
29*****************************************************************************/ 29*****************************************************************************/
30 30
31const char *progname = "check_pgsql"; 31const char *progname = "check_pgsql";
32const char *copyright = "1999-2007"; 32const char *copyright = "1999-2011";
33const char *email = "nagiosplug-devel@lists.sourceforge.net"; 33const char *email = "nagiosplug-devel@lists.sourceforge.net";
34 34
35#include "common.h" 35#include "common.h"
@@ -42,6 +42,20 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
42#define DEFAULT_DB "template1" 42#define DEFAULT_DB "template1"
43#define DEFAULT_HOST "127.0.0.1" 43#define DEFAULT_HOST "127.0.0.1"
44 44
45/* return the PSQL server version as a 3-tuple */
46#define PSQL_SERVER_VERSION3(server_version) \
47 (server_version) / 10000, \
48 (server_version) / 100 - (int)((server_version) / 10000) * 100, \
49 (server_version) - (int)((server_version) / 100) * 100
50/* return true if the given host is a UNIX domain socket */
51#define PSQL_IS_UNIX_DOMAIN_SOCKET(host) \
52 ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host)))
53/* return a 3-tuple identifying a host/port independent of the socket type */
54#define PSQL_SOCKET3(host, port) \
55 ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \
56 PSQL_IS_UNIX_DOMAIN_SOCKET (host) ? "/.s.PGSQL." : ":", \
57 port
58
45enum { 59enum {
46 DEFAULT_PORT = 5432, 60 DEFAULT_PORT = 5432,
47 DEFAULT_WARN = 2, 61 DEFAULT_WARN = 2,
@@ -56,6 +70,7 @@ void print_usage (void);
56void print_help (void); 70void print_help (void);
57int is_pg_dbname (char *); 71int is_pg_dbname (char *);
58int is_pg_logname (char *); 72int is_pg_logname (char *);
73int do_query (PGconn *, char *);
59 74
60char *pghost = NULL; /* host name of the backend server */ 75char *pghost = NULL; /* host name of the backend server */
61char *pgport = NULL; /* port of the backend server */ 76char *pgport = NULL; /* port of the backend server */
@@ -65,14 +80,15 @@ char *pgtty = NULL;
65char dbName[NAMEDATALEN] = DEFAULT_DB; 80char dbName[NAMEDATALEN] = DEFAULT_DB;
66char *pguser = NULL; 81char *pguser = NULL;
67char *pgpasswd = NULL; 82char *pgpasswd = NULL;
83char *pgparams = NULL;
68double twarn = (double)DEFAULT_WARN; 84double twarn = (double)DEFAULT_WARN;
69double tcrit = (double)DEFAULT_CRIT; 85double tcrit = (double)DEFAULT_CRIT;
86char *pgquery = NULL;
87char *query_warning = NULL;
88char *query_critical = NULL;
89thresholds *qthresholds = NULL;
70int verbose = 0; 90int verbose = 0;
71 91
72PGconn *conn;
73/*PGresult *res;*/
74
75
76/****************************************************************************** 92/******************************************************************************
77 93
78The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ 94The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
@@ -115,10 +131,6 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
115<sect2> 131<sect2>
116<title>Future Enhancements</title> 132<title>Future Enhancements</title>
117<para>ToDo List</para> 133<para>ToDo List</para>
118<itemizedlist>
119<listitem>Add option to get password from a secured file rather than the command line</listitem>
120<listitem>Add option to specify the query to execute</listitem>
121</itemizedlist>
122</sect2> 134</sect2>
123 135
124 136
@@ -132,8 +144,14 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
132int 144int
133main (int argc, char **argv) 145main (int argc, char **argv)
134{ 146{
135 int elapsed_time; 147 PGconn *conn;
148 char *conninfo = NULL;
149
150 struct timeval start_timeval;
151 struct timeval end_timeval;
152 double elapsed_time;
136 int status = STATE_UNKNOWN; 153 int status = STATE_UNKNOWN;
154 int query_status = STATE_UNKNOWN;
137 155
138 /* begin, by setting the parameters for a backend connection if the 156 /* begin, by setting the parameters for a backend connection if the
139 * parameters are null, then the system will try to use reasonable 157 * parameters are null, then the system will try to use reasonable
@@ -161,20 +179,41 @@ main (int argc, char **argv)
161 } 179 }
162 alarm (timeout_interval); 180 alarm (timeout_interval);
163 181
164 if (verbose) 182 if (pgparams)
165 printf("Connecting to database:\n DB: %s\n User: %s\n Host: %s\n Port: %d\n", dbName, 183 asprintf (&conninfo, "%s ", pgparams);
166 (pguser != NULL) ? pguser : "unspecified", 184
167 (pghost != NULL) ? pghost : "unspecified", 185 asprintf (&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName);
168 (pgport != NULL) ? atoi(pgport) : DEFAULT_PORT); 186 if (pghost)
187 asprintf (&conninfo, "%s host = '%s'", conninfo, pghost);
188 if (pgport)
189 asprintf (&conninfo, "%s port = '%s'", conninfo, pgport);
190 if (pgoptions)
191 asprintf (&conninfo, "%s options = '%s'", conninfo, pgoptions);
192 /* if (pgtty) -- ignored by PQconnectdb */
193 if (pguser)
194 asprintf (&conninfo, "%s user = '%s'", conninfo, pguser);
195
196 if (verbose) /* do not include password (see right below) in output */
197 printf ("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo,
198 pgpasswd ? " password = <hidden>" : "");
199
200 if (pgpasswd)
201 asprintf (&conninfo, "%s password = '%s'", conninfo, pgpasswd);
169 202
170 /* make a connection to the database */ 203 /* make a connection to the database */
171 time (&start_time); 204 gettimeofday (&start_timeval, NULL);
172 conn = 205 conn = PQconnectdb (conninfo);
173 PQsetdbLogin (pghost, pgport, pgoptions, pgtty, dbName, pguser, pgpasswd); 206 gettimeofday (&end_timeval, NULL);
174 time (&end_time); 207
175 elapsed_time = (int) (end_time - start_time); 208 while (start_timeval.tv_usec > end_timeval.tv_usec) {
209 --end_timeval.tv_sec;
210 end_timeval.tv_usec += 1000000;
211 }
212 elapsed_time = (double)(end_timeval.tv_sec - start_timeval.tv_sec)
213 + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
214
176 if (verbose) 215 if (verbose)
177 printf("Time elapsed: %d\n", elapsed_time); 216 printf("Time elapsed: %f\n", elapsed_time);
178 217
179 /* check to see that the backend connection was successfully made */ 218 /* check to see that the backend connection was successfully made */
180 if (verbose) 219 if (verbose)
@@ -194,14 +233,32 @@ main (int argc, char **argv)
194 else { 233 else {
195 status = STATE_OK; 234 status = STATE_OK;
196 } 235 }
236
237 if (verbose) {
238 char *server_host = PQhost (conn);
239 int server_version = PQserverVersion (conn);
240
241 printf ("Successfully connected to database %s (user %s) "
242 "at server %s%s%s (server version: %d.%d.%d, "
243 "protocol version: %d, pid: %d)\n",
244 PQdb (conn), PQuser (conn),
245 PSQL_SOCKET3 (server_host, PQport (conn)),
246 PSQL_SERVER_VERSION3 (server_version),
247 PQprotocolVersion (conn), PQbackendPID (conn));
248 }
249
250 printf (_(" %s - database %s (%f sec.)|%s\n"),
251 state_text(status), dbName, elapsed_time,
252 fperfdata("time", elapsed_time, "s",
253 !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, TRUE, 0, FALSE,0));
254
255 if (pgquery)
256 query_status = do_query (conn, pgquery);
257
197 if (verbose) 258 if (verbose)
198 printf("Closing connection\n"); 259 printf("Closing connection\n");
199 PQfinish (conn); 260 PQfinish (conn);
200 printf (_(" %s - database %s (%d sec.)|%s\n"), 261 return (query_status > status) ? query_status : status;
201 state_text(status), dbName, elapsed_time,
202 fperfdata("time", elapsed_time, "s",
203 (int)twarn, twarn, (int)tcrit, tcrit, TRUE, 0, FALSE,0));
204 return status;
205} 262}
206 263
207 264
@@ -225,12 +282,16 @@ process_arguments (int argc, char **argv)
225 {"authorization", required_argument, 0, 'a'}, 282 {"authorization", required_argument, 0, 'a'},
226 {"port", required_argument, 0, 'P'}, 283 {"port", required_argument, 0, 'P'},
227 {"database", required_argument, 0, 'd'}, 284 {"database", required_argument, 0, 'd'},
285 {"option", required_argument, 0, 'o'},
286 {"query", required_argument, 0, 'q'},
287 {"query_critical", required_argument, 0, 'C'},
288 {"query_warning", required_argument, 0, 'W'},
228 {"verbose", no_argument, 0, 'v'}, 289 {"verbose", no_argument, 0, 'v'},
229 {0, 0, 0, 0} 290 {0, 0, 0, 0}
230 }; 291 };
231 292
232 while (1) { 293 while (1) {
233 c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:v", 294 c = getopt_long (argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v",
234 longopts, &option); 295 longopts, &option);
235 296
236 if (c == EOF) 297 if (c == EOF)
@@ -263,8 +324,14 @@ process_arguments (int argc, char **argv)
263 else 324 else
264 twarn = strtod (optarg, NULL); 325 twarn = strtod (optarg, NULL);
265 break; 326 break;
327 case 'C': /* critical query threshold */
328 query_critical = optarg;
329 break;
330 case 'W': /* warning query threshold */
331 query_warning = optarg;
332 break;
266 case 'H': /* host */ 333 case 'H': /* host */
267 if (!is_host (optarg)) 334 if ((*optarg != '/') && (!is_host (optarg)))
268 usage2 (_("Invalid hostname/address"), optarg); 335 usage2 (_("Invalid hostname/address"), optarg);
269 else 336 else
270 pghost = optarg; 337 pghost = optarg;
@@ -291,12 +358,23 @@ process_arguments (int argc, char **argv)
291 case 'a': 358 case 'a':
292 pgpasswd = optarg; 359 pgpasswd = optarg;
293 break; 360 break;
361 case 'o':
362 if (pgparams)
363 asprintf (&pgparams, "%s %s", pgparams, optarg);
364 else
365 asprintf (&pgparams, "%s", optarg);
366 break;
367 case 'q':
368 pgquery = optarg;
369 break;
294 case 'v': 370 case 'v':
295 verbose++; 371 verbose++;
296 break; 372 break;
297 } 373 }
298 } 374 }
299 375
376 set_thresholds (&qthresholds, query_warning, query_critical);
377
300 return validate_arguments (); 378 return validate_arguments ();
301} 379}
302 380
@@ -434,8 +512,6 @@ print_help (void)
434 512
435 printf (UT_HOST_PORT, 'P', myport); 513 printf (UT_HOST_PORT, 'P', myport);
436 514
437 printf (UT_IPv46);
438
439 printf (" %s\n", "-d, --database=STRING"); 515 printf (" %s\n", "-d, --database=STRING");
440 printf (" %s", _("Database to check ")); 516 printf (" %s", _("Database to check "));
441 printf (_("(default: %s)"), DEFAULT_DB); 517 printf (_("(default: %s)"), DEFAULT_DB);
@@ -443,11 +519,20 @@ print_help (void)
443 printf (" %s\n", _("Login name of user")); 519 printf (" %s\n", _("Login name of user"));
444 printf (" %s\n", "-p, --password = STRING"); 520 printf (" %s\n", "-p, --password = STRING");
445 printf (" %s\n", _("Password (BIG SECURITY ISSUE)")); 521 printf (" %s\n", _("Password (BIG SECURITY ISSUE)"));
522 printf (" %s\n", "-o, --option = STRING");
523 printf (" %s\n", _("Connection parameters (keyword = value), see below"));
446 524
447 printf (UT_WARN_CRIT); 525 printf (UT_WARN_CRIT);
448 526
449 printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 527 printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
450 528
529 printf (" %s\n", "-q, --query=STRING");
530 printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
531 printf (" %s\n", "-W, --query-warning=RANGE");
532 printf (" %s\n", _("SQL query value to result in warning status (double)"));
533 printf (" %s\n", "-C, --query-critical=RANGE");
534 printf (" %s\n", _("SQL query value to result in critical status (double)"));
535
451 printf (UT_VERBOSE); 536 printf (UT_VERBOSE);
452 537
453 printf ("\n"); 538 printf ("\n");
@@ -458,6 +543,22 @@ print_help (void)
458 printf (" %s\n", _("connects to the template1 database, which is present in every functioning")); 543 printf (" %s\n", _("connects to the template1 database, which is present in every functioning"));
459 printf (" %s\n\n", _("PostgreSQL DBMS.")); 544 printf (" %s\n\n", _("PostgreSQL DBMS."));
460 545
546 printf (" %s\n", _("If a query is specified using the -q option, it will be executed after"));
547 printf (" %s\n", _("connecting to the server. The result from the query has to be numeric."));
548 printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
549 printf (" %s\n", _("of the last command is taken into account only. The value of the first"));
550 printf (" %s\n\n", _("column in the first row is used as the check result."));
551
552 printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
553 printf (" %s\n\n", _("for details about how to access internal statistics of the database server."));
554
555 printf (" %s\n", _("For a list of available connection parameters which may be used with the -o"));
556 printf (" %s\n", _("command line option, see the documentation for PQconnectdb() in the chapter"));
557 printf (" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be"));
558 printf (" %s\n", _("used to specify a service name in pg_service.conf to be used for additional"));
559 printf (" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:"));
560 printf (" %s\n\n", _("-o 'sslmode=require'."));
561
461 printf (" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To")); 562 printf (" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To"));
462 printf (" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP")); 563 printf (" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP"));
463 printf (" %s\n\n", _("connections (start the postmaster with the -i option).")); 564 printf (" %s\n\n", _("connections (start the postmaster with the -i option)."));
@@ -475,6 +576,75 @@ void
475print_usage (void) 576print_usage (void)
476{ 577{
477 printf ("%s\n", _("Usage:")); 578 printf ("%s\n", _("Usage:"));
478 printf ("%s [-H <host>] [-4|-6] [-P <port>] [-c <critical time>] [-w <warning time>]\n", progname); 579 printf ("%s [-H <host>] [-P <port>] [-c <critical time>] [-w <warning time>]\n", progname);
479 printf (" [-t <timeout>] [-d <database>] [-l <logname>] [-p <password>]\n"); 580 printf (" [-t <timeout>] [-d <database>] [-l <logname>] [-p <password>]\n"
581 "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
480} 582}
583
584int
585do_query (PGconn *conn, char *query)
586{
587 PGresult *res;
588
589 char *val_str;
590 double value;
591
592 char *endptr = NULL;
593
594 int my_status = STATE_UNKNOWN;
595
596 if (verbose)
597 printf ("Executing SQL query \"%s\".\n", query);
598 res = PQexec (conn, query);
599
600 if (PGRES_TUPLES_OK != PQresultStatus (res)) {
601 printf (_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"),
602 PQerrorMessage (conn));
603 return STATE_CRITICAL;
604 }
605
606 if (PQntuples (res) < 1) {
607 printf ("QUERY %s - %s.\n", _("WARNING"), _("No rows returned"));
608 return STATE_WARNING;
609 }
610
611 if (PQnfields (res) < 1) {
612 printf ("QUERY %s - %s.\n", _("WARNING"), _("No columns returned"));
613 return STATE_WARNING;
614 }
615
616 val_str = PQgetvalue (res, 0, 0);
617 if (! val_str) {
618 printf ("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned"));
619 return STATE_CRITICAL;
620 }
621
622 value = strtod (val_str, &endptr);
623 if (verbose)
624 printf ("Query result: %f\n", value);
625
626 if (endptr == val_str) {
627 printf ("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
628 return STATE_CRITICAL;
629 }
630 else if ((endptr != NULL) && (*endptr != '\0')) {
631 if (verbose)
632 printf ("Garbage after value: %s.\n", endptr);
633 }
634
635 my_status = get_status (value, qthresholds);
636 printf ("QUERY %s - ",
637 (my_status == STATE_OK)
638 ? _("OK")
639 : (my_status == STATE_WARNING)
640 ? _("WARNING")
641 : (my_status == STATE_CRITICAL)
642 ? _("CRITICAL")
643 : _("UNKNOWN"));
644 printf (_("'%s' returned %f"), query, value);
645 printf ("|query=%f;%s;%s;;\n", value,
646 query_warning ? query_warning : "",
647 query_critical ? query_critical : "");
648 return my_status;
649}
650
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 6acedc70..d09bd8b6 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -42,6 +42,11 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
42#include "regex.h" 42#include "regex.h"
43 43
44#include <pwd.h> 44#include <pwd.h>
45#include <errno.h>
46
47#ifdef HAVE_SYS_STAT_H
48#include <sys/stat.h>
49#endif
45 50
46int process_arguments (int, char **); 51int process_arguments (int, char **);
47int validate_arguments (void); 52int validate_arguments (void);
@@ -65,6 +70,10 @@ int options = 0; /* bitmask of filter criteria to test against */
65#define PCPU 256 70#define PCPU 256
66#define ELAPSED 512 71#define ELAPSED 512
67#define EREG_ARGS 1024 72#define EREG_ARGS 1024
73
74#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
75 ppid of procs are compared to pid of this proc*/
76
68/* Different metrics */ 77/* Different metrics */
69char *metric_name; 78char *metric_name;
70enum metric { 79enum metric {
@@ -90,9 +99,21 @@ regex_t re_args;
90char *fmt; 99char *fmt;
91char *fails; 100char *fails;
92char tmp[MAX_INPUT_BUFFER]; 101char tmp[MAX_INPUT_BUFFER];
102int kthread_filter = 0;
103int usepid = 0; /* whether to test for pid or /proc/pid/exe */
93 104
94FILE *ps_input = NULL; 105FILE *ps_input = NULL;
95 106
107static int
108stat_exe (const pid_t pid, struct stat *buf) {
109 char *path;
110 int ret;
111 xasprintf(&path, "/proc/%d/exe", pid);
112 ret = stat(path, buf);
113 free(path);
114 return ret;
115}
116
96 117
97int 118int
98main (int argc, char **argv) 119main (int argc, char **argv)
@@ -102,9 +123,13 @@ main (int argc, char **argv)
102 char *procprog; 123 char *procprog;
103 124
104 pid_t mypid = 0; 125 pid_t mypid = 0;
126 struct stat statbuf;
127 dev_t mydev = 0;
128 ino_t myino = 0;
105 int procuid = 0; 129 int procuid = 0;
106 pid_t procpid = 0; 130 pid_t procpid = 0;
107 pid_t procppid = 0; 131 pid_t procppid = 0;
132 pid_t kthread_ppid = 0;
108 int procvsz = 0; 133 int procvsz = 0;
109 int procrss = 0; 134 int procrss = 0;
110 int procseconds = 0; 135 int procseconds = 0;
@@ -125,6 +150,7 @@ main (int argc, char **argv)
125 int crit = 0; /* number of processes in crit state */ 150 int crit = 0; /* number of processes in crit state */
126 int i = 0, j = 0; 151 int i = 0, j = 0;
127 int result = STATE_UNKNOWN; 152 int result = STATE_UNKNOWN;
153 int ret;
128 output chld_out, chld_err; 154 output chld_out, chld_err;
129 155
130 setlocale (LC_ALL, ""); 156 setlocale (LC_ALL, "");
@@ -144,8 +170,16 @@ main (int argc, char **argv)
144 if (process_arguments (argc, argv) == ERROR) 170 if (process_arguments (argc, argv) == ERROR)
145 usage4 (_("Could not parse arguments")); 171 usage4 (_("Could not parse arguments"));
146 172
147 /* get our pid */ 173 /* find ourself */
148 mypid = getpid(); 174 mypid = getpid();
175 if (usepid || stat_exe(mypid, &statbuf) == -1) {
176 /* usepid might have been set by -T */
177 usepid = 1;
178 } else {
179 usepid = 0;
180 mydev = statbuf.st_dev;
181 myino = statbuf.st_ino;
182 }
149 183
150 /* Set signal handling and alarm timeout */ 184 /* Set signal handling and alarm timeout */
151 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 185 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
@@ -200,7 +234,28 @@ main (int argc, char **argv)
200 procetime, procprog, procargs); 234 procetime, procprog, procargs);
201 235
202 /* Ignore self */ 236 /* Ignore self */
203 if (mypid == procpid) continue; 237 if ((usepid && mypid == procpid) ||
238 (!usepid && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino) ||
239 (ret == -1 && errno == ENOENT))) {
240 if (verbose >= 3)
241 printf("not considering - is myself or gone\n");
242 continue;
243 }
244
245 /* filter kernel threads (childs of KTHREAD_PARENT)*/
246 /* TODO adapt for other OSes than GNU/Linux
247 sorry for not doing that, but I've no other OSes to test :-( */
248 if (kthread_filter == 1) {
249 /* get pid KTHREAD_PARENT */
250 if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) )
251 kthread_ppid = procpid;
252
253 if (kthread_ppid == procppid) {
254 if (verbose >= 2)
255 printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs);
256 continue;
257 }
258 }
204 259
205 if ((options & STAT) && (strstr (statopts, procstat))) 260 if ((options & STAT) && (strstr (statopts, procstat)))
206 resultsum |= STAT; 261 resultsum |= STAT;
@@ -344,6 +399,8 @@ process_arguments (int argc, char **argv)
344 {"verbose", no_argument, 0, 'v'}, 399 {"verbose", no_argument, 0, 'v'},
345 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, 400 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
346 {"input-file", required_argument, 0, CHAR_MAX+2}, 401 {"input-file", required_argument, 0, CHAR_MAX+2},
402 {"no-kthreads", required_argument, 0, 'k'},
403 {"traditional-filter", no_argument, 0, 'T'},
347 {0, 0, 0, 0} 404 {0, 0, 0, 0}
348 }; 405 };
349 406
@@ -352,7 +409,7 @@ process_arguments (int argc, char **argv)
352 strcpy (argv[c], "-t"); 409 strcpy (argv[c], "-t");
353 410
354 while (1) { 411 while (1) {
355 c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:", 412 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T",
356 longopts, &option); 413 longopts, &option);
357 414
358 if (c == -1 || c == EOF) 415 if (c == -1 || c == EOF)
@@ -496,9 +553,15 @@ process_arguments (int argc, char **argv)
496 } 553 }
497 554
498 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); 555 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
556 case 'k': /* linux kernel thread filter */
557 kthread_filter = 1;
558 break;
499 case 'v': /* command */ 559 case 'v': /* command */
500 verbose++; 560 verbose++;
501 break; 561 break;
562 case 'T':
563 usepid = 1;
564 break;
502 case CHAR_MAX+2: 565 case CHAR_MAX+2:
503 input_filename = optarg; 566 input_filename = optarg;
504 break; 567 break;
@@ -649,6 +712,9 @@ print_help (void)
649 printf (" %s\n", "-v, --verbose"); 712 printf (" %s\n", "-v, --verbose");
650 printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); 713 printf (" %s\n", _("Extra information. Up to 3 verbosity levels"));
651 714
715 printf (" %s\n", "-T, --traditional");
716 printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe"));
717
652 printf ("\n"); 718 printf ("\n");
653 printf ("%s\n", "Filters:"); 719 printf ("%s\n", "Filters:");
654 printf (" %s\n", "-s, --state=STATUSFLAGS"); 720 printf (" %s\n", "-s, --state=STATUSFLAGS");
@@ -671,6 +737,8 @@ print_help (void)
671 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); 737 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
672 printf (" %s\n", "-C, --command=COMMAND"); 738 printf (" %s\n", "-C, --command=COMMAND");
673 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); 739 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
740 printf (" %s\n", "-k, --no-kthreads");
741 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
674 742
675 printf(_("\n\ 743 printf(_("\n\
676RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ 744RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
@@ -705,5 +773,5 @@ print_usage (void)
705 printf ("%s\n", _("Usage:")); 773 printf ("%s\n", _("Usage:"));
706 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); 774 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
707 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); 775 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
708 printf (" [-C command] [-t timeout] [-v]\n"); 776 printf (" [-C command] [-k] [-t timeout] [-v]\n");
709} 777}
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 7c5d0ec5..7c3bc4b9 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -63,6 +63,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
63#define L_CALCULATE_RATE CHAR_MAX+1 63#define L_CALCULATE_RATE CHAR_MAX+1
64#define L_RATE_MULTIPLIER CHAR_MAX+2 64#define L_RATE_MULTIPLIER CHAR_MAX+2
65#define L_INVERT_SEARCH CHAR_MAX+3 65#define L_INVERT_SEARCH CHAR_MAX+3
66#define L_OFFSET CHAR_MAX+4
66 67
67/* Gobble to string - stop incrementing c when c[0] match one of the 68/* Gobble to string - stop incrementing c when c[0] match one of the
68 * characters in s */ 69 * characters in s */
@@ -138,6 +139,7 @@ char *output_delim;
138char *miblist = NULL; 139char *miblist = NULL;
139int needmibs = FALSE; 140int needmibs = FALSE;
140int calculate_rate = 0; 141int calculate_rate = 0;
142double offset = 0.0;
141int rate_multiplier = 1; 143int rate_multiplier = 1;
142state_data *previous_state; 144state_data *previous_state;
143double previous_value[MAX_OIDS]; 145double previous_value[MAX_OIDS];
@@ -274,35 +276,36 @@ main (int argc, char **argv)
274 snmpcmd = strdup (PATH_TO_SNMPGET); 276 snmpcmd = strdup (PATH_TO_SNMPGET);
275 } 277 }
276 278
277 /* 9 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */ 279 /* 10 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */
278 command_line = calloc (9 + numauthpriv + 1 + numoids + 1, sizeof (char *)); 280 command_line = calloc (10 + numauthpriv + 1 + numoids + 1, sizeof (char *));
279 command_line[0] = snmpcmd; 281 command_line[0] = snmpcmd;
280 command_line[1] = strdup ("-t"); 282 command_line[1] = strdup ("-Le");
281 xasprintf (&command_line[2], "%d", timeout_interval); 283 command_line[2] = strdup ("-t");
282 command_line[3] = strdup ("-r"); 284 xasprintf (&command_line[3], "%d", timeout_interval);
283 xasprintf (&command_line[4], "%d", retries); 285 command_line[4] = strdup ("-r");
284 command_line[5] = strdup ("-m"); 286 xasprintf (&command_line[5], "%d", retries);
285 command_line[6] = strdup (miblist); 287 command_line[6] = strdup ("-m");
286 command_line[7] = "-v"; 288 command_line[7] = strdup (miblist);
287 command_line[8] = strdup (proto); 289 command_line[8] = "-v";
290 command_line[9] = strdup (proto);
288 291
289 for (i = 0; i < numauthpriv; i++) { 292 for (i = 0; i < numauthpriv; i++) {
290 command_line[9 + i] = authpriv[i]; 293 command_line[10 + i] = authpriv[i];
291 } 294 }
292 295
293 xasprintf (&command_line[9 + numauthpriv], "%s:%s", server_address, port); 296 xasprintf (&command_line[10 + numauthpriv], "%s:%s", server_address, port);
294 297
295 /* This is just for display purposes, so it can remain a string */ 298 /* This is just for display purposes, so it can remain a string */
296 xasprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s", 299 xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s %s %s:%s",
297 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[authpriv]", 300 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[authpriv]",
298 server_address, port); 301 server_address, port);
299 302
300 for (i = 0; i < numoids; i++) { 303 for (i = 0; i < numoids; i++) {
301 command_line[9 + numauthpriv + 1 + i] = oids[i]; 304 command_line[10 + numauthpriv + 1 + i] = oids[i];
302 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); 305 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
303 } 306 }
304 307
305 command_line[9 + numauthpriv + 1 + numoids] = NULL; 308 command_line[10 + numauthpriv + 1 + numoids] = NULL;
306 309
307 if (verbose) 310 if (verbose)
308 printf ("%s\n", cl_hidden_auth); 311 printf ("%s\n", cl_hidden_auth);
@@ -429,7 +432,7 @@ main (int argc, char **argv)
429 ptr = strpbrk (show, "0123456789"); 432 ptr = strpbrk (show, "0123456789");
430 if (ptr == NULL) 433 if (ptr == NULL)
431 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); 434 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show);
432 response_value[i] = strtod (ptr, NULL); 435 response_value[i] = strtod (ptr, NULL) + offset;
433 436
434 if(calculate_rate) { 437 if(calculate_rate) {
435 if (previous_state!=NULL) { 438 if (previous_state!=NULL) {
@@ -618,6 +621,7 @@ process_arguments (int argc, char **argv)
618 {"next", no_argument, 0, 'n'}, 621 {"next", no_argument, 0, 'n'},
619 {"rate", no_argument, 0, L_CALCULATE_RATE}, 622 {"rate", no_argument, 0, L_CALCULATE_RATE},
620 {"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER}, 623 {"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER},
624 {"offset", required_argument, 0, L_OFFSET},
621 {"invert-search", no_argument, 0, L_INVERT_SEARCH}, 625 {"invert-search", no_argument, 0, L_INVERT_SEARCH},
622 {"perf-oids", no_argument, 0, 'O'}, 626 {"perf-oids", no_argument, 0, 'O'},
623 {0, 0, 0, 0} 627 {0, 0, 0, 0}
@@ -832,6 +836,9 @@ process_arguments (int argc, char **argv)
832 if(!is_integer(optarg)||((rate_multiplier=atoi(optarg))<=0)) 836 if(!is_integer(optarg)||((rate_multiplier=atoi(optarg))<=0))
833 usage2(_("Rate multiplier must be a positive integer"),optarg); 837 usage2(_("Rate multiplier must be a positive integer"),optarg);
834 break; 838 break;
839 case L_OFFSET:
840 offset=strtod(optarg,NULL);
841 break;
835 case L_INVERT_SEARCH: 842 case L_INVERT_SEARCH:
836 invert_search=1; 843 invert_search=1;
837 break; 844 break;
@@ -1080,6 +1087,8 @@ print_help (void)
1080 printf (" %s\n", _("Enable rate calculation. See 'Rate Calculation' below")); 1087 printf (" %s\n", _("Enable rate calculation. See 'Rate Calculation' below"));
1081 printf (" %s\n", "--rate-multiplier"); 1088 printf (" %s\n", "--rate-multiplier");
1082 printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute")); 1089 printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute"));
1090 printf (" %s\n", "--offset=OFFSET");
1091 printf (" %s\n", _("Add/substract the specified OFFSET to numeric sensor data"));
1083 1092
1084 /* Tests Against Strings */ 1093 /* Tests Against Strings */
1085 printf (" %s\n", "-s, --string=STRING"); 1094 printf (" %s\n", "-s, --string=STRING");
diff --git a/plugins/common.h b/plugins/common.h
index c0dc2f41..8f05c158 100644
--- a/plugins/common.h
+++ b/plugins/common.h
@@ -82,10 +82,12 @@
82 getting that data 82 getting that data
83 Will return -1 if cannot get data 83 Will return -1 if cannot get data
84*/ 84*/
85#ifdef HAVE_SYSCONF__SC_NPROCESSORS_CONF 85#if defined(HAVE_SYSCONF__SC_NPROCESSORS_ONLN)
86#define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF) 86# define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_ONLN)
87#elif defined (HAVE_SYSCONF__SC_NPROCESSORS_CONF)
88# define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF)
87#else 89#else
88#define GET_NUMBER_OF_CPUS() -1 90# define GET_NUMBER_OF_CPUS() -1
89#endif 91#endif
90 92
91#ifdef TIME_WITH_SYS_TIME 93#ifdef TIME_WITH_SYS_TIME
diff --git a/plugins/netutils.h b/plugins/netutils.h
index 21017f1f..5a495c91 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -100,6 +100,8 @@ extern int address_family;
100/* maybe this could be merged with the above np_net_connect, via some flags */ 100/* maybe this could be merged with the above np_net_connect, via some flags */
101int np_net_ssl_init(int sd); 101int np_net_ssl_init(int sd);
102int np_net_ssl_init_with_hostname(int sd, char *host_name); 102int np_net_ssl_init_with_hostname(int sd, char *host_name);
103int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version);
104int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey);
103void np_net_ssl_cleanup(); 105void np_net_ssl_cleanup();
104int np_net_ssl_write(const void *buf, int num); 106int np_net_ssl_write(const void *buf, int num);
105int np_net_ssl_read(void *buf, int num); 107int np_net_ssl_read(void *buf, int num);
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index a1ce560d..78317f83 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -45,6 +45,10 @@ int np_net_ssl_init_with_hostname(int sd, char *host_name) {
45} 45}
46 46
47int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { 47int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) {
48 return np_net_ssl_init_with_hostname_version_and_cert(sd, host_name, version, NULL, NULL);
49}
50
51int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) {
48 const SSL_METHOD *method = NULL; 52 const SSL_METHOD *method = NULL;
49 53
50 switch (version) { 54 switch (version) {
@@ -80,6 +84,14 @@ int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int versi
80 printf("%s\n", _("CRITICAL - Cannot create SSL context.")); 84 printf("%s\n", _("CRITICAL - Cannot create SSL context."));
81 return STATE_CRITICAL; 85 return STATE_CRITICAL;
82 } 86 }
87 if (cert && privkey) {
88 SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM);
89 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
90 if (!SSL_CTX_check_private_key(c)) {
91 printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
92 return STATE_CRITICAL;
93 }
94 }
83#ifdef SSL_OP_NO_TICKET 95#ifdef SSL_OP_NO_TICKET
84 SSL_CTX_set_options(c, SSL_OP_NO_TICKET); 96 SSL_CTX_set_options(c, SSL_OP_NO_TICKET);
85#endif 97#endif
diff --git a/plugins/t/check_apt.t b/plugins/t/check_apt.t
index 71230979..9ba0ff8e 100644
--- a/plugins/t/check_apt.t
+++ b/plugins/t/check_apt.t
@@ -18,8 +18,8 @@ sub make_result_regexp {
18 } else { 18 } else {
19 $status = "CRITICAL"; 19 $status = "CRITICAL";
20 } 20 }
21 return sprintf('/^APT %s: %d packages available for upgrade \(%d critical updates\).\s*$/', 21 return sprintf('/^APT %s: %d packages available for upgrade \(%d critical updates\)\. |available_upgrades=%d;;;0 critical_updates=%d;;;0$/',
22 $status, $warning, $critical); 22 $status, $warning, $critical, $warning, $critical);
23} 23}
24 24
25if (-x "./check_apt") { 25if (-x "./check_apt") {
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index 0a25c775..9948c539 100644
--- a/plugins/t/check_http.t
+++ b/plugins/t/check_http.t
@@ -8,22 +8,22 @@ use strict;
8use Test::More; 8use Test::More;
9use NPTest; 9use NPTest;
10 10
11plan tests => 28; 11plan tests => 30;
12 12
13my $successOutput = '/OK.*HTTP.*second/'; 13my $successOutput = '/OK.*HTTP.*second/';
14 14
15my $res; 15my $res;
16 16
17my $host_tcp_http = getTestParameter( "NP_HOST_TCP_HTTP", 17my $host_tcp_http = getTestParameter( "NP_HOST_TCP_HTTP",
18 "A host providing the HTTP Service (a web server)", 18 "A host providing the HTTP Service (a web server)",
19 "localhost" ); 19 "localhost" );
20 20
21my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE", 21my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE",
22 "The hostname of system not responsive to network requests", 22 "The hostname of system not responsive to network requests",
23 "10.0.0.1" ); 23 "10.0.0.1" );
24 24
25my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", 25my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID",
26 "An invalid (not known to DNS) hostname", 26 "An invalid (not known to DNS) hostname",
27 "nosuchhost"); 27 "nosuchhost");
28 28
29my $internet_access = getTestParameter( "NP_INTERNET_ACCESS", 29my $internet_access = getTestParameter( "NP_INTERNET_ACCESS",
@@ -32,8 +32,8 @@ my $internet_access = getTestParameter( "NP_INTERNET_ACCESS",
32 32
33my $host_tcp_http2; 33my $host_tcp_http2;
34if ($internet_access eq "no") { 34if ($internet_access eq "no") {
35 $host_tcp_http2 = getTestParameter( "NP_HOST_TCP_HTTP2", 35 $host_tcp_http2 = getTestParameter( "NP_HOST_TCP_HTTP2",
36 "A host providing an index page containing the string 'nagios'", 36 "A host providing an index page containing the string 'nagios'",
37 "www.nagios.com" ); 37 "www.nagios.com" );
38} 38}
39 39
@@ -45,14 +45,9 @@ cmp_ok( $res->return_code, '==', 0, "Webserver $host_tcp_http responded" );
45like( $res->output, $successOutput, "Output OK" ); 45like( $res->output, $successOutput, "Output OK" );
46 46
47$res = NPTest->testCmd( 47$res = NPTest->testCmd(
48 "./check_http $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there;fred:here'" 48 "./check_http $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there' -k 'carl:frown'"
49 ); 49 );
50like( $res->output, '/bob:there\r\nfred:here\r\n/', "Got headers, delimited with ';'" ); 50like( $res->output, '/bob:there\r\ncarl:frown\r\n/', "Got headers with multiple -k options" );
51
52$res = NPTest->testCmd(
53 "./check_http $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there;fred:here' -k 'carl:frown'"
54 );
55like( $res->output, '/bob:there\r\nfred:here\r\ncarl:frown\r\n/', "Got headers with multiple -k options" );
56 51
57$res = NPTest->testCmd( 52$res = NPTest->testCmd(
58 "./check_http $host_nonresponsive -wt 1 -ct 2" 53 "./check_http $host_nonresponsive -wt 1 -ct 2"
@@ -123,6 +118,10 @@ SKIP: {
123 $res = NPTest->testCmd( "./check_http www.verisign.com -C 1" ); 118 $res = NPTest->testCmd( "./check_http www.verisign.com -C 1" );
124 cmp_ok( $res->output, 'eq', $saved_cert_output, "Old syntax for cert checking still works"); 119 cmp_ok( $res->output, 'eq', $saved_cert_output, "Old syntax for cert checking still works");
125 120
121 $res = NPTest->testCmd( "./check_http --ssl www.verisign.com -E" );
122 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
123 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' );
124
126 $res = NPTest->testCmd( 125 $res = NPTest->testCmd(
127 "./check_http --ssl www.e-paycobalt.com" 126 "./check_http --ssl www.e-paycobalt.com"
128 ); 127 );
@@ -131,4 +130,7 @@ SKIP: {
131 130
132 $res = NPTest->testCmd( "./check_http -H www.mozilla.com -u /firefox -f follow" ); 131 $res = NPTest->testCmd( "./check_http -H www.mozilla.com -u /firefox -f follow" );
133 is( $res->return_code, 0, "Redirection based on location is okay"); 132 is( $res->return_code, 0, "Redirection based on location is okay");
133
134 $res = NPTest->testCmd( "./check_http -H www.mozilla.com --extended-perfdata" );
135 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
134} 136}
diff --git a/plugins/t/check_procs.t b/plugins/t/check_procs.t
index 30f02488..a1a28836 100644
--- a/plugins/t/check_procs.t
+++ b/plugins/t/check_procs.t
@@ -20,7 +20,7 @@ my $result;
20 20
21$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000" ); 21$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000" );
22is( $result->return_code, 0, "Checking less than 10000 processes" ); 22is( $result->return_code, 0, "Checking less than 10000 processes" );
23like( $result->output, '/^PROCS OK: [0-9]+ process(es)?$/', "Output correct" ); 23like( $result->output, '/^PROCS OK: [0-9]+ process(es)? | procs=[0-9]+;100000;100000;0;$/', "Output correct" );
24 24
25$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000 -s Z" ); 25$result = NPTest->testCmd( "./check_procs -w 100000 -c 100000 -s Z" );
26is( $result->return_code, 0, "Checking less than 100000 zombie processes" ); 26is( $result->return_code, 0, "Checking less than 100000 zombie processes" );
@@ -28,11 +28,11 @@ like( $result->output, '/^PROCS OK: [0-9]+ process(es)? with /', "Output correct
28 28
29$result = NPTest->testCmd( "./check_procs -w 0 -c 100000" ); 29$result = NPTest->testCmd( "./check_procs -w 0 -c 100000" );
30is( $result->return_code, 1, "Checking warning if processes > 0" ); 30is( $result->return_code, 1, "Checking warning if processes > 0" );
31like( $result->output, '/^PROCS WARNING: [0-9]+ process(es)?$/', "Output correct" ); 31like( $result->output, '/^PROCS WARNING: [0-9]+ process(es)? | procs=[0-9]+;0;100000;0;$/', "Output correct" );
32 32
33$result = NPTest->testCmd( "./check_procs -w 0 -c 0" ); 33$result = NPTest->testCmd( "./check_procs -w 0 -c 0" );
34is( $result->return_code, 2, "Checking critical if processes > 0" ); 34is( $result->return_code, 2, "Checking critical if processes > 0" );
35like( $result->output, '/^PROCS CRITICAL: [0-9]+ process(es)?$/', "Output correct" ); 35like( $result->output, '/^PROCS CRITICAL: [0-9]+ process(es)? | procs=[0-9]+;0;0;0;$/', "Output correct" );
36 36
37$result = NPTest->testCmd( "./check_procs -w 0 -c 0 -s S" ); 37$result = NPTest->testCmd( "./check_procs -w 0 -c 0 -s S" );
38is( $result->return_code, 2, "Checking critical if sleeping processes" ); 38is( $result->return_code, 2, "Checking critical if sleeping processes" );
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 9f97abdc..c3085e13 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -17,7 +17,7 @@ use Test::More;
17use NPTest; 17use NPTest;
18use FindBin qw($Bin); 18use FindBin qw($Bin);
19 19
20my $common_tests = 66; 20my $common_tests = 70;
21my $ssl_only_tests = 8; 21my $ssl_only_tests = 8;
22# Check that all dependent modules are available 22# Check that all dependent modules are available
23eval { 23eval {
@@ -151,6 +151,10 @@ sub run_server {
151 unshift @persist, $c; 151 unshift @persist, $c;
152 delete($persist[1000]); 152 delete($persist[1000]);
153 next MAINLOOP; 153 next MAINLOOP;
154 } elsif ($r->url->path eq "/header_check") {
155 $c->send_basic_header;
156 $c->send_header('foo');
157 $c->send_crlf;
154 } else { 158 } else {
155 $c->send_error(HTTP::Status->RC_FORBIDDEN); 159 $c->send_error(HTTP::Status->RC_FORBIDDEN);
156 } 160 }
@@ -223,6 +227,13 @@ sub run_common_tests {
223 is( $result->return_code, 2, "Missing string check"); 227 is( $result->return_code, 2, "Missing string check");
224 like( $result->output, qr%HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location"); 228 like( $result->output, qr%HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location");
225 229
230 $result = NPTest->testCmd( "$command -u /header_check -d foo" );
231 is( $result->return_code, 0, "header_check search for string");
232 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 96 bytes in [\d\.]+ second/', "Output correct" );
233
234 $result = NPTest->testCmd( "$command -u /header_check -d bar" );
235 is( $result->return_code, 2, "Missing header string check");
236 like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location");
226 237
227 my $cmd; 238 my $cmd;
228 $cmd = "$command -u /slow"; 239 $cmd = "$command -u /slow";