summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am4
-rw-r--r--plugins/check_apt.c72
-rw-r--r--plugins/check_curl.c264
-rw-r--r--plugins/check_disk.c116
-rw-r--r--plugins/check_fping.c2
-rw-r--r--plugins/check_http.c313
-rw-r--r--plugins/check_procs.c47
-rw-r--r--plugins/check_radius.c4
-rw-r--r--plugins/check_snmp.c107
-rw-r--r--plugins/check_swap.c3
-rw-r--r--plugins/sslutils.c34
-rw-r--r--plugins/t/check_disk.t27
-rw-r--r--plugins/t/check_http.t2
-rwxr-xr-xplugins/tests/check_curl.t21
-rwxr-xr-xplugins/tests/check_http.t85
-rwxr-xr-xplugins/tests/check_procs.t8
-rwxr-xr-xplugins/tests/check_snmp.t22
-rw-r--r--plugins/tests/check_snmp_agent.pl8
18 files changed, 827 insertions, 312 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 3fde54d6..ab59eb73 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -51,10 +51,10 @@ noinst_LIBRARIES = libnpcommon.a
51libnpcommon_a_SOURCES = utils.c netutils.c sslutils.c runcmd.c \ 51libnpcommon_a_SOURCES = utils.c netutils.c sslutils.c runcmd.c \
52 popen.c utils.h netutils.h popen.h common.h runcmd.c runcmd.h 52 popen.c utils.h netutils.h popen.h common.h runcmd.c runcmd.h
53 53
54BASEOBJS = libnpcommon.a ../lib/libmonitoringplug.a ../gl/libgnu.a 54BASEOBJS = libnpcommon.a ../lib/libmonitoringplug.a ../gl/libgnu.a $(LIB_CRYPTO)
55NETOBJS = $(BASEOBJS) $(EXTRA_NETOBLS) 55NETOBJS = $(BASEOBJS) $(EXTRA_NETOBLS)
56NETLIBS = $(NETOBJS) $(SOCKETLIBS) 56NETLIBS = $(NETOBJS) $(SOCKETLIBS)
57SSLOBJS = $(BASEOBJS) $(NETLIBS) $(SSLLIBS) 57SSLOBJS = $(BASEOBJS) $(NETLIBS) $(SSLLIBS) $(LIB_CRYPTO)
58 58
59TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir) 59TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir)
60 60
diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index d7be5750..fa982ae3 100644
--- a/plugins/check_apt.c
+++ b/plugins/check_apt.c
@@ -1,32 +1,32 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_apt plugin 3* Monitoring check_apt plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2006-2008 Monitoring Plugins Development Team 6* Copyright (c) 2006-2008 Monitoring Plugins Development Team
7* 7*
8* Original author: Sean Finney 8* Original author: Sean Finney
9* 9*
10* Description: 10* Description:
11* 11*
12* This file contains the check_apt plugin 12* This file contains the check_apt plugin
13* 13*
14* Check for available updates in apt package management systems 14* Check for available updates in apt package management systems
15* 15*
16* 16*
17* This program is free software: you can redistribute it and/or modify 17* This program is free software: you can redistribute it and/or modify
18* it under the terms of the GNU General Public License as published by 18* it under the terms of the GNU General Public License as published by
19* the Free Software Foundation, either version 3 of the License, or 19* the Free Software Foundation, either version 3 of the License, or
20* (at your option) any later version. 20* (at your option) any later version.
21* 21*
22* This program is distributed in the hope that it will be useful, 22* This program is distributed in the hope that it will be useful,
23* but WITHOUT ANY WARRANTY; without even the implied warranty of 23* but WITHOUT ANY WARRANTY; without even the implied warranty of
24* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25* GNU General Public License for more details. 25* GNU General Public License for more details.
26* 26*
27* You should have received a copy of the GNU General Public License 27* You should have received a copy of the GNU General Public License
28* along with this program. If not, see <http://www.gnu.org/licenses/>. 28* along with this program. If not, see <http://www.gnu.org/licenses/>.
29* 29*
30*****************************************************************************/ 30*****************************************************************************/
31 31
32const char *progname = "check_apt"; 32const char *progname = "check_apt";
@@ -76,9 +76,9 @@ int cmpstringp(const void *p1, const void *p2);
76 76
77/* configuration variables */ 77/* configuration variables */
78static int verbose = 0; /* -v */ 78static int verbose = 0; /* -v */
79static int list = 0; /* list packages available for upgrade */ 79static bool list = false; /* list packages available for upgrade */
80static int do_update = 0; /* whether to call apt-get update */ 80static bool do_update = false; /* whether to call apt-get update */
81static int only_critical = 0; /* whether to warn about non-critical updates */ 81static bool only_critical = false; /* whether to warn about non-critical updates */
82static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ 82static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
83static char *upgrade_opts = NULL; /* options to override defaults for upgrade */ 83static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
84static char *update_opts = NULL; /* options to override defaults for update */ 84static char *update_opts = NULL; /* options to override defaults for update */
@@ -119,7 +119,7 @@ int main (int argc, char **argv) {
119 119
120 if(sec_count > 0){ 120 if(sec_count > 0){
121 result = max_state(result, STATE_CRITICAL); 121 result = max_state(result, STATE_CRITICAL);
122 } else if(packages_available >= packages_warning && only_critical == 0){ 122 } else if(packages_available >= packages_warning && only_critical == false){
123 result = max_state(result, STATE_WARNING); 123 result = max_state(result, STATE_WARNING);
124 } else if(result > STATE_UNKNOWN){ 124 } else if(result > STATE_UNKNOWN){
125 result = STATE_UNKNOWN; 125 result = STATE_UNKNOWN;
@@ -144,7 +144,7 @@ int main (int argc, char **argv) {
144 144
145 for(i = 0; i < sec_count; i++) 145 for(i = 0; i < sec_count; i++)
146 printf("%s (security)\n", secpackages_list[i]); 146 printf("%s (security)\n", secpackages_list[i]);
147 if (only_critical == 0) { 147 if (only_critical == false) {
148 for(i = 0; i < packages_available - sec_count; i++) 148 for(i = 0; i < packages_available - sec_count; i++)
149 printf("%s\n", packages_list[i]); 149 printf("%s\n", packages_list[i]);
150 } 150 }
@@ -166,7 +166,7 @@ int process_arguments (int argc, char **argv) {
166 {"upgrade", optional_argument, 0, 'U'}, 166 {"upgrade", optional_argument, 0, 'U'},
167 {"no-upgrade", no_argument, 0, 'n'}, 167 {"no-upgrade", no_argument, 0, 'n'},
168 {"dist-upgrade", optional_argument, 0, 'd'}, 168 {"dist-upgrade", optional_argument, 0, 'd'},
169 {"list", no_argument, 0, 'l'}, 169 {"list", no_argument, false, 'l'},
170 {"include", required_argument, 0, 'i'}, 170 {"include", required_argument, 0, 'i'},
171 {"exclude", required_argument, 0, 'e'}, 171 {"exclude", required_argument, 0, 'e'},
172 {"critical", required_argument, 0, 'c'}, 172 {"critical", required_argument, 0, 'c'},
@@ -212,14 +212,14 @@ int process_arguments (int argc, char **argv) {
212 upgrade=NO_UPGRADE; 212 upgrade=NO_UPGRADE;
213 break; 213 break;
214 case 'u': 214 case 'u':
215 do_update=1; 215 do_update=true;
216 if(optarg!=NULL){ 216 if(optarg!=NULL){
217 update_opts=strdup(optarg); 217 update_opts=strdup(optarg);
218 if(update_opts==NULL) die(STATE_UNKNOWN, "strdup failed"); 218 if(update_opts==NULL) die(STATE_UNKNOWN, "strdup failed");
219 } 219 }
220 break; 220 break;
221 case 'l': 221 case 'l':
222 list=1; 222 list=true;
223 break; 223 break;
224 case 'i': 224 case 'i':
225 do_include=add_to_regexp(do_include, optarg); 225 do_include=add_to_regexp(do_include, optarg);
@@ -231,7 +231,7 @@ int process_arguments (int argc, char **argv) {
231 do_critical=add_to_regexp(do_critical, optarg); 231 do_critical=add_to_regexp(do_critical, optarg);
232 break; 232 break;
233 case 'o': 233 case 'o':
234 only_critical=1; 234 only_critical=true;
235 break; 235 break;
236 case INPUT_FILE_OPT: 236 case INPUT_FILE_OPT:
237 input_filename = optarg; 237 input_filename = optarg;
@@ -269,7 +269,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg
269 die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); 269 die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf);
270 } 270 }
271 } 271 }
272 272
273 if(do_exclude!=NULL){ 273 if(do_exclude!=NULL){
274 regres=regcomp(&ereg, do_exclude, REG_EXTENDED); 274 regres=regcomp(&ereg, do_exclude, REG_EXTENDED);
275 if(regres!=0) { 275 if(regres!=0) {
@@ -278,7 +278,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg
278 progname, rerrbuf); 278 progname, rerrbuf);
279 } 279 }
280 } 280 }
281 281
282 const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; 282 const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE;
283 regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); 283 regres=regcomp(&sreg, crit_ptr, REG_EXTENDED);
284 if(regres!=0) { 284 if(regres!=0) {
@@ -295,7 +295,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg
295 /* run the upgrade */ 295 /* run the upgrade */
296 result = np_runcmd(cmdline, &chld_out, &chld_err, 0); 296 result = np_runcmd(cmdline, &chld_out, &chld_err, 0);
297 } 297 }
298 298
299 /* apt-get upgrade only changes exit status if there is an 299 /* apt-get upgrade only changes exit status if there is an
300 * internal error when run in dry-run mode. therefore we will 300 * internal error when run in dry-run mode. therefore we will
301 * treat such an error as UNKNOWN */ 301 * treat such an error as UNKNOWN */
@@ -371,7 +371,7 @@ int run_update(void){
371 struct output chld_out, chld_err; 371 struct output chld_out, chld_err;
372 char *cmdline; 372 char *cmdline;
373 373
374 /* run the upgrade */ 374 /* run the update */
375 cmdline = construct_cmdline(NO_UPGRADE, update_opts); 375 cmdline = construct_cmdline(NO_UPGRADE, update_opts);
376 result = np_runcmd(cmdline, &chld_out, &chld_err, 0); 376 result = np_runcmd(cmdline, &chld_out, &chld_err, 0);
377 /* apt-get update changes exit status if it can't fetch packages. 377 /* apt-get update changes exit status if it can't fetch packages.
@@ -501,16 +501,6 @@ print_help (void)
501 501
502 printf(UT_PLUG_TIMEOUT, timeout_interval); 502 printf(UT_PLUG_TIMEOUT, timeout_interval);
503 503
504 printf (" %s\n", "-U, --upgrade=OPTS");
505 printf (" %s\n", _("[Default] Perform an upgrade. If an optional OPTS argument is provided,"));
506 printf (" %s\n", _("apt-get will be run with these command line options instead of the"));
507 printf (" %s", _("default "));
508 printf ("(%s).\n", UPGRADE_DEFAULT_OPTS);
509 printf (" %s\n", _("Note that you may be required to have root privileges if you do not use"));
510 printf (" %s\n", _("the default options."));
511 printf (" %s\n", "-d, --dist-upgrade=OPTS");
512 printf (" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS"));
513 printf (" %s\n", _("can be provided to override the default options."));
514 printf (" %s\n", "-n, --no-upgrade"); 504 printf (" %s\n", "-n, --no-upgrade");
515 printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); 505 printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least)."));
516 printf (" %s\n", "-l, --list"); 506 printf (" %s\n", "-l, --list");
@@ -530,7 +520,7 @@ print_help (void)
530 printf (" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified")); 520 printf (" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified"));
531 printf (" %s\n", _("multiple times like above. Default is a regexp matching security")); 521 printf (" %s\n", _("multiple times like above. Default is a regexp matching security"));
532 printf (" %s\n", _("upgrades for Debian and Ubuntu:")); 522 printf (" %s\n", _("upgrades for Debian and Ubuntu:"));
533 printf (" \t\%s\n", SECURITY_RE); 523 printf (" \t%s\n", SECURITY_RE);
534 printf (" %s\n", _("Note that the package must first match the include list before its")); 524 printf (" %s\n", _("Note that the package must first match the include list before its"));
535 printf (" %s\n", _("information is compared against the critical list.")); 525 printf (" %s\n", _("information is compared against the critical list."));
536 printf (" %s\n", "-o, --only-critical"); 526 printf (" %s\n", "-o, --only-critical");
@@ -538,7 +528,7 @@ print_help (void)
538 printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); 528 printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause"));
539 printf (" %s\n", _("the plugin to return WARNING status.")); 529 printf (" %s\n", _("the plugin to return WARNING status."));
540 printf (" %s\n", "-w, --packages-warning"); 530 printf (" %s\n", "-w, --packages-warning");
541 printf (" %s\n", _("Minumum number of packages available for upgrade to return WARNING status.")); 531 printf (" %s\n", _("Minimum number of packages available for upgrade to return WARNING status."));
542 printf (" %s\n\n", _("Default is 1 package.")); 532 printf (" %s\n\n", _("Default is 1 package."));
543 533
544 printf ("%s\n\n", _("The following options require root privileges and should be used with care:")); 534 printf ("%s\n\n", _("The following options require root privileges and should be used with care:"));
@@ -547,6 +537,16 @@ print_help (void)
547 printf (" %s\n", _("the default options. Note: you may also need to adjust the global")); 537 printf (" %s\n", _("the default options. Note: you may also need to adjust the global"));
548 printf (" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get")); 538 printf (" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get"));
549 printf (" %s\n", _("upgrade is expected to take longer than the default timeout.")); 539 printf (" %s\n", _("upgrade is expected to take longer than the default timeout."));
540 printf (" %s\n", "-U, --upgrade=OPTS");
541 printf (" %s\n", _("Perform an upgrade. If an optional OPTS argument is provided,"));
542 printf (" %s\n", _("apt-get will be run with these command line options instead of the"));
543 printf (" %s", _("default "));
544 printf ("(%s).\n", UPGRADE_DEFAULT_OPTS);
545 printf (" %s\n", _("Note that you may be required to have root privileges if you do not use"));
546 printf (" %s\n", _("the default options, which will only run a simulation and NOT perform the upgrade"));
547 printf (" %s\n", "-d, --dist-upgrade=OPTS");
548 printf (" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS"));
549 printf (" %s\n", _("can be provided to override the default options."));
550 550
551 printf(UT_SUPPORT); 551 printf(UT_SUPPORT);
552} 552}
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 2ad373c0..c51914a9 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -37,6 +37,7 @@ const char *progname = "check_curl";
37const char *copyright = "2006-2019"; 37const char *copyright = "2006-2019";
38const char *email = "devel@monitoring-plugins.org"; 38const char *email = "devel@monitoring-plugins.org";
39 39
40#include <stdbool.h>
40#include <ctype.h> 41#include <ctype.h>
41 42
42#include "common.h" 43#include "common.h"
@@ -54,6 +55,7 @@ const char *email = "devel@monitoring-plugins.org";
54#include "uriparser/Uri.h" 55#include "uriparser/Uri.h"
55 56
56#include <arpa/inet.h> 57#include <arpa/inet.h>
58#include <netinet/in.h>
57 59
58#if defined(HAVE_SSL) && defined(USE_OPENSSL) 60#if defined(HAVE_SSL) && defined(USE_OPENSSL)
59#include <openssl/opensslv.h> 61#include <openssl/opensslv.h>
@@ -131,14 +133,14 @@ regmatch_t pmatch[REGS];
131char regexp[MAX_RE_SIZE]; 133char regexp[MAX_RE_SIZE];
132int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; 134int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE;
133int errcode; 135int errcode;
134int invert_regex = 0; 136bool invert_regex = false;
135 137
136char *server_address = NULL; 138char *server_address = NULL;
137char *host_name = NULL; 139char *host_name = NULL;
138char *server_url = 0; 140char *server_url = 0;
139char server_ip[DEFAULT_BUFFER_SIZE]; 141char server_ip[DEFAULT_BUFFER_SIZE];
140struct curl_slist *server_ips = NULL; 142struct curl_slist *server_ips = NULL;
141int specify_port = FALSE; 143bool specify_port = false;
142unsigned short server_port = HTTP_PORT; 144unsigned short server_port = HTTP_PORT;
143unsigned short virtual_port = 0; 145unsigned short virtual_port = 0;
144int host_name_length; 146int host_name_length;
@@ -150,8 +152,8 @@ int days_till_exp_warn, days_till_exp_crit;
150thresholds *thlds; 152thresholds *thlds;
151char user_agent[DEFAULT_BUFFER_SIZE]; 153char user_agent[DEFAULT_BUFFER_SIZE];
152int verbose = 0; 154int verbose = 0;
153int show_extended_perfdata = FALSE; 155bool show_extended_perfdata = false;
154int show_body = FALSE; 156bool show_body = false;
155int min_page_len = 0; 157int min_page_len = 0;
156int max_page_len = 0; 158int max_page_len = 0;
157int redir_depth = 0; 159int redir_depth = 0;
@@ -160,10 +162,16 @@ char *http_method = NULL;
160char *http_post_data = NULL; 162char *http_post_data = NULL;
161char *http_content_type = NULL; 163char *http_content_type = NULL;
162CURL *curl; 164CURL *curl;
165bool curl_global_initialized = false;
166bool curl_easy_initialized = false;
163struct curl_slist *header_list = NULL; 167struct curl_slist *header_list = NULL;
168bool body_buf_initialized = false;
164curlhelp_write_curlbuf body_buf; 169curlhelp_write_curlbuf body_buf;
170bool header_buf_initialized = false;
165curlhelp_write_curlbuf header_buf; 171curlhelp_write_curlbuf header_buf;
172bool status_line_initialized = false;
166curlhelp_statusline status_line; 173curlhelp_statusline status_line;
174bool put_buf_initialized = false;
167curlhelp_read_curlbuf put_buf; 175curlhelp_read_curlbuf put_buf;
168char http_header[DEFAULT_BUFFER_SIZE]; 176char http_header[DEFAULT_BUFFER_SIZE];
169long code; 177long code;
@@ -173,7 +181,7 @@ double time_connect;
173double time_appconnect; 181double time_appconnect;
174double time_headers; 182double time_headers;
175double time_firstbyte; 183double time_firstbyte;
176char errbuf[CURL_ERROR_SIZE+1]; 184char errbuf[MAX_INPUT_BUFFER];
177CURLcode res; 185CURLcode res;
178char url[DEFAULT_BUFFER_SIZE]; 186char url[DEFAULT_BUFFER_SIZE];
179char msg[DEFAULT_BUFFER_SIZE]; 187char msg[DEFAULT_BUFFER_SIZE];
@@ -186,14 +194,14 @@ char user_auth[MAX_INPUT_BUFFER] = "";
186char proxy_auth[MAX_INPUT_BUFFER] = ""; 194char proxy_auth[MAX_INPUT_BUFFER] = "";
187char **http_opt_headers; 195char **http_opt_headers;
188int http_opt_headers_count = 0; 196int http_opt_headers_count = 0;
189int display_html = FALSE; 197bool display_html = false;
190int onredirect = STATE_OK; 198int onredirect = STATE_OK;
191int followmethod = FOLLOW_HTTP_CURL; 199int followmethod = FOLLOW_HTTP_CURL;
192int followsticky = STICKY_NONE; 200int followsticky = STICKY_NONE;
193int use_ssl = FALSE; 201bool use_ssl = false;
194int use_sni = TRUE; 202bool use_sni = true;
195int check_cert = FALSE; 203bool check_cert = false;
196int continue_after_check_cert = FALSE; 204bool continue_after_check_cert = false;
197typedef union { 205typedef union {
198 struct curl_slist* to_info; 206 struct curl_slist* to_info;
199 struct curl_certinfo* to_certinfo; 207 struct curl_certinfo* to_certinfo;
@@ -203,19 +211,20 @@ int ssl_version = CURL_SSLVERSION_DEFAULT;
203char *client_cert = NULL; 211char *client_cert = NULL;
204char *client_privkey = NULL; 212char *client_privkey = NULL;
205char *ca_cert = NULL; 213char *ca_cert = NULL;
206int verify_peer_and_host = FALSE; 214bool verify_peer_and_host = false;
207int is_openssl_callback = FALSE; 215bool is_openssl_callback = false;
208#if defined(HAVE_SSL) && defined(USE_OPENSSL) 216#if defined(HAVE_SSL) && defined(USE_OPENSSL)
209X509 *cert = NULL; 217X509 *cert = NULL;
210#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ 218#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */
211int no_body = FALSE; 219bool no_body = false;
212int maximum_age = -1; 220int maximum_age = -1;
213int address_family = AF_UNSPEC; 221int address_family = AF_UNSPEC;
214curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; 222curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN;
215int curl_http_version = CURL_HTTP_VERSION_NONE; 223int curl_http_version = CURL_HTTP_VERSION_NONE;
216int automatic_decompression = FALSE; 224bool automatic_decompression = false;
225char *cookie_jar_file = NULL;
217 226
218int process_arguments (int, char**); 227bool process_arguments (int, char**);
219void handle_curl_option_return_code (CURLcode res, const char* option); 228void handle_curl_option_return_code (CURLcode res, const char* option);
220int check_http (void); 229int check_http (void);
221void redir (curlhelp_write_curlbuf*); 230void redir (curlhelp_write_curlbuf*);
@@ -269,10 +278,10 @@ main (int argc, char **argv)
269 progname, NP_VERSION, VERSION, curl_version()); 278 progname, NP_VERSION, VERSION, curl_version());
270 279
271 /* parse arguments */ 280 /* parse arguments */
272 if (process_arguments (argc, argv) == ERROR) 281 if (process_arguments (argc, argv) == false)
273 usage4 (_("Could not parse arguments")); 282 usage4 (_("Could not parse arguments"));
274 283
275 if (display_html == TRUE) 284 if (display_html)
276 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 285 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">",
277 use_ssl ? "https" : "http", 286 use_ssl ? "https" : "http",
278 host_name ? host_name : server_address, 287 host_name ? host_name : server_address,
@@ -376,8 +385,11 @@ int
376lookup_host (const char *host, char *buf, size_t buflen) 385lookup_host (const char *host, char *buf, size_t buflen)
377{ 386{
378 struct addrinfo hints, *res, *result; 387 struct addrinfo hints, *res, *result;
388 char addrstr[100];
389 size_t addrstr_len;
379 int errcode; 390 int errcode;
380 void *ptr; 391 void *ptr;
392 size_t buflen_remaining = buflen - 1;
381 393
382 memset (&hints, 0, sizeof (hints)); 394 memset (&hints, 0, sizeof (hints));
383 hints.ai_family = address_family; 395 hints.ai_family = address_family;
@@ -387,31 +399,62 @@ lookup_host (const char *host, char *buf, size_t buflen)
387 errcode = getaddrinfo (host, NULL, &hints, &result); 399 errcode = getaddrinfo (host, NULL, &hints, &result);
388 if (errcode != 0) 400 if (errcode != 0)
389 return errcode; 401 return errcode;
390 402
403 strcpy(buf, "");
391 res = result; 404 res = result;
392 405
393 while (res) { 406 while (res) {
394 inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen); 407 switch (res->ai_family) {
395 switch (res->ai_family) { 408 case AF_INET:
396 case AF_INET: 409 ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
397 ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; 410 break;
398 break; 411 case AF_INET6:
399 case AF_INET6: 412 ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
400 ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; 413 break;
401 break;
402 } 414 }
403 inet_ntop (res->ai_family, ptr, buf, buflen); 415
404 if (verbose >= 1) 416 inet_ntop (res->ai_family, ptr, addrstr, 100);
417 if (verbose >= 1) {
405 printf ("* getaddrinfo IPv%d address: %s\n", 418 printf ("* getaddrinfo IPv%d address: %s\n",
406 res->ai_family == PF_INET6 ? 6 : 4, buf); 419 res->ai_family == PF_INET6 ? 6 : 4, addrstr);
420 }
421
422 // Append all IPs to buf as a comma-separated string
423 addrstr_len = strlen(addrstr);
424 if (buflen_remaining > addrstr_len + 1) {
425 if (buf[0] != '\0') {
426 strncat(buf, ",", buflen_remaining);
427 buflen_remaining -= 1;
428 }
429 strncat(buf, addrstr, buflen_remaining);
430 buflen_remaining -= addrstr_len;
431 }
432
407 res = res->ai_next; 433 res = res->ai_next;
408 } 434 }
409 435
410 freeaddrinfo(result); 436 freeaddrinfo(result);
411 437
412 return 0; 438 return 0;
413} 439}
414 440
441static void
442cleanup (void)
443{
444 if (status_line_initialized) curlhelp_free_statusline(&status_line);
445 status_line_initialized = false;
446 if (curl_easy_initialized) curl_easy_cleanup (curl);
447 curl_easy_initialized = false;
448 if (curl_global_initialized) curl_global_cleanup ();
449 curl_global_initialized = false;
450 if (body_buf_initialized) curlhelp_freewritebuffer (&body_buf);
451 body_buf_initialized = false;
452 if (header_buf_initialized) curlhelp_freewritebuffer (&header_buf);
453 header_buf_initialized = false;
454 if (put_buf_initialized) curlhelp_freereadbuffer (&put_buf);
455 put_buf_initialized = false;
456}
457
415int 458int
416check_http (void) 459check_http (void)
417{ 460{
@@ -420,18 +463,24 @@ check_http (void)
420 int i; 463 int i;
421 char *force_host_header = NULL; 464 char *force_host_header = NULL;
422 struct curl_slist *host = NULL; 465 struct curl_slist *host = NULL;
423 char addrstr[100]; 466 char addrstr[DEFAULT_BUFFER_SIZE/2];
424 char dnscache[DEFAULT_BUFFER_SIZE]; 467 char dnscache[DEFAULT_BUFFER_SIZE];
425 468
426 /* initialize curl */ 469 /* initialize curl */
427 if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK) 470 if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK)
428 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); 471 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n");
472 curl_global_initialized = true;
429 473
430 if ((curl = curl_easy_init()) == NULL) 474 if ((curl = curl_easy_init()) == NULL) {
431 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); 475 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n");
476 }
477 curl_easy_initialized = true;
432 478
479 /* register cleanup function to shut down libcurl properly */
480 atexit (cleanup);
481
433 if (verbose >= 1) 482 if (verbose >= 1)
434 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE), "CURLOPT_VERBOSE"); 483 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE");
435 484
436 /* print everything on stdout like check_http would do */ 485 /* print everything on stdout like check_http would do */
437 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR"); 486 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR");
@@ -446,12 +495,14 @@ check_http (void)
446 /* initialize buffer for body of the answer */ 495 /* initialize buffer for body of the answer */
447 if (curlhelp_initwritebuffer(&body_buf) < 0) 496 if (curlhelp_initwritebuffer(&body_buf) < 0)
448 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); 497 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n");
498 body_buf_initialized = true;
449 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_WRITEFUNCTION"); 499 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_WRITEFUNCTION");
450 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA"); 500 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA");
451 501
452 /* initialize buffer for header of the answer */ 502 /* initialize buffer for header of the answer */
453 if (curlhelp_initwritebuffer( &header_buf ) < 0) 503 if (curlhelp_initwritebuffer( &header_buf ) < 0)
454 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" ); 504 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" );
505 header_buf_initialized = true;
455 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_HEADERFUNCTION"); 506 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_HEADERFUNCTION");
456 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER"); 507 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER");
457 508
@@ -464,7 +515,7 @@ check_http (void)
464 515
465 // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy 516 // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy
466 if(use_ssl && host_name != NULL) { 517 if(use_ssl && host_name != NULL) {
467 if ( (res=lookup_host (server_address, addrstr, 100)) != 0) { 518 if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) {
468 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), 519 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"),
469 server_address, res, gai_strerror (res)); 520 server_address, res, gai_strerror (res));
470 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 521 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
@@ -491,7 +542,7 @@ check_http (void)
491 /* compose URL: use the address we want to connect to, set Host: header later */ 542 /* compose URL: use the address we want to connect to, set Host: header later */
492 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", 543 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s",
493 use_ssl ? "https" : "http", 544 use_ssl ? "https" : "http",
494 use_ssl & host_name != NULL ? host_name : server_address, 545 ( use_ssl & ( host_name != NULL ) ) ? host_name : server_address,
495 server_port, 546 server_port,
496 server_url 547 server_url
497 ); 548 );
@@ -512,7 +563,7 @@ check_http (void)
512 563
513 /* disable body for HEAD request */ 564 /* disable body for HEAD request */
514 if (http_method && !strcmp (http_method, "HEAD" )) { 565 if (http_method && !strcmp (http_method, "HEAD" )) {
515 no_body = TRUE; 566 no_body = true;
516 } 567 }
517 568
518 /* set HTTP protocol version */ 569 /* set HTTP protocol version */
@@ -609,7 +660,7 @@ check_http (void)
609#ifdef USE_OPENSSL 660#ifdef USE_OPENSSL
610 /* libcurl and monitoring plugins built with OpenSSL, good */ 661 /* libcurl and monitoring plugins built with OpenSSL, good */
611 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); 662 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION");
612 is_openssl_callback = TRUE; 663 is_openssl_callback = true;
613#else /* USE_OPENSSL */ 664#else /* USE_OPENSSL */
614#endif /* USE_OPENSSL */ 665#endif /* USE_OPENSSL */
615 /* libcurl is built with OpenSSL, monitoring plugins, so falling 666 /* libcurl is built with OpenSSL, monitoring plugins, so falling
@@ -688,9 +739,11 @@ check_http (void)
688 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS"); 739 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS");
689 740
690 /* for now allow only http and https (we are a http(s) check plugin in the end) */ 741 /* for now allow only http and https (we are a http(s) check plugin in the end) */
691#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) 742#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0)
743 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"), "CURLOPT_REDIR_PROTOCOLS_STR");
744#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4)
692 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS"); 745 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS");
693#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) */ 746#endif
694 747
695 /* TODO: handle the following aspects of redirection, make them 748 /* TODO: handle the following aspects of redirection, make them
696 * command line options too later: 749 * command line options too later:
@@ -734,11 +787,19 @@ check_http (void)
734 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS"); 787 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS");
735 } else if (!strcmp(http_method, "PUT")) { 788 } else if (!strcmp(http_method, "PUT")) {
736 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), "CURLOPT_READFUNCTION"); 789 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), "CURLOPT_READFUNCTION");
737 curlhelp_initreadbuffer (&put_buf, http_post_data, strlen (http_post_data)); 790 if (curlhelp_initreadbuffer (&put_buf, http_post_data, strlen (http_post_data)) < 0)
791 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating read buffer for PUT\n");
792 put_buf_initialized = true;
738 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA"); 793 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA");
739 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE"); 794 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE");
740 } 795 }
741 } 796 }
797
798 /* cookie handling */
799 if (cookie_jar_file != NULL) {
800 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEJAR, cookie_jar_file), "CURLOPT_COOKIEJAR");
801 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEFILE, cookie_jar_file), "CURLOPT_COOKIEFILE");
802 }
742 803
743 /* do the request */ 804 /* do the request */
744 res = curl_easy_perform(curl); 805 res = curl_easy_perform(curl);
@@ -749,6 +810,9 @@ check_http (void)
749 /* free header and server IP resolve lists, we don't need it anymore */ 810 /* free header and server IP resolve lists, we don't need it anymore */
750 curl_slist_free_all (header_list); header_list = NULL; 811 curl_slist_free_all (header_list); header_list = NULL;
751 curl_slist_free_all (server_ips); server_ips = NULL; 812 curl_slist_free_all (server_ips); server_ips = NULL;
813 if (host) {
814 curl_slist_free_all (host); host = NULL;
815 }
752 816
753 /* Curl errors, result in critical Nagios state */ 817 /* Curl errors, result in critical Nagios state */
754 if (res != CURLE_OK) { 818 if (res != CURLE_OK) {
@@ -759,15 +823,15 @@ check_http (void)
759 823
760 /* certificate checks */ 824 /* certificate checks */
761#ifdef LIBCURL_FEATURE_SSL 825#ifdef LIBCURL_FEATURE_SSL
762 if (use_ssl == TRUE) { 826 if (use_ssl) {
763 if (check_cert == TRUE) { 827 if (check_cert) {
764 if (is_openssl_callback) { 828 if (is_openssl_callback) {
765#ifdef USE_OPENSSL 829#ifdef USE_OPENSSL
766 /* check certificate with OpenSSL functions, curl has been built against OpenSSL 830 /* check certificate with OpenSSL functions, curl has been built against OpenSSL
767 * and we actually have OpenSSL in the monitoring tools 831 * and we actually have OpenSSL in the monitoring tools
768 */ 832 */
769 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 833 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
770 if (continue_after_check_cert == FALSE) { 834 if (!continue_after_check_cert) {
771 return result; 835 return result;
772 } 836 }
773#else /* USE_OPENSSL */ 837#else /* USE_OPENSSL */
@@ -809,7 +873,7 @@ GOT_FIRST_CERT:
809 } 873 }
810 BIO_free (cert_BIO); 874 BIO_free (cert_BIO);
811 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 875 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
812 if (continue_after_check_cert == FALSE) { 876 if (!continue_after_check_cert) {
813 return result; 877 return result;
814 } 878 }
815#else /* USE_OPENSSL */ 879#else /* USE_OPENSSL */
@@ -817,7 +881,7 @@ GOT_FIRST_CERT:
817 * so we use the libcurl CURLINFO data 881 * so we use the libcurl CURLINFO data
818 */ 882 */
819 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); 883 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit);
820 if (continue_after_check_cert == FALSE) { 884 if (!continue_after_check_cert) {
821 return result; 885 return result;
822 } 886 }
823#endif /* USE_OPENSSL */ 887#endif /* USE_OPENSSL */
@@ -845,7 +909,7 @@ GOT_FIRST_CERT:
845 perfd_time(total_time), 909 perfd_time(total_time),
846 perfd_size(page_len), 910 perfd_size(page_len),
847 perfd_time_connect(time_connect), 911 perfd_time_connect(time_connect),
848 use_ssl == TRUE ? perfd_time_ssl (time_appconnect-time_connect) : "", 912 use_ssl ? perfd_time_ssl (time_appconnect-time_connect) : "",
849 perfd_time_headers(time_headers - time_appconnect), 913 perfd_time_headers(time_headers - time_appconnect),
850 perfd_time_firstbyte(time_firstbyte - time_headers), 914 perfd_time_firstbyte(time_firstbyte - time_headers),
851 perfd_time_transfer(total_time-time_firstbyte) 915 perfd_time_transfer(total_time-time_firstbyte)
@@ -868,6 +932,7 @@ GOT_FIRST_CERT:
868 /* we cannot know the major/minor version here for sure as we cannot parse the first line */ 932 /* we cannot know the major/minor version here for sure as we cannot parse the first line */
869 die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); 933 die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg);
870 } 934 }
935 status_line_initialized = true;
871 936
872 /* get result code from cURL */ 937 /* get result code from cURL */
873 handle_curl_option_return_code (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE"); 938 handle_curl_option_return_code (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE");
@@ -980,12 +1045,12 @@ GOT_FIRST_CERT:
980 1045
981 if (strlen (regexp)) { 1046 if (strlen (regexp)) {
982 errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0); 1047 errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0);
983 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1048 if ((errcode == 0 && !invert_regex) || (errcode == REG_NOMATCH && invert_regex)) {
984 /* OK - No-op to avoid changing the logic around it */ 1049 /* OK - No-op to avoid changing the logic around it */
985 result = max_state_alt(STATE_OK, result); 1050 result = max_state_alt(STATE_OK, result);
986 } 1051 }
987 else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { 1052 else if ((errcode == REG_NOMATCH && !invert_regex) || (errcode == 0 && invert_regex)) {
988 if (invert_regex == 0) 1053 if (!invert_regex)
989 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg); 1054 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg);
990 else 1055 else
991 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg); 1056 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg);
@@ -1017,7 +1082,7 @@ GOT_FIRST_CERT:
1017 else 1082 else
1018 msg[strlen(msg)-3] = '\0'; 1083 msg[strlen(msg)-3] = '\0';
1019 } 1084 }
1020 1085
1021 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ 1086 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */
1022 die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", 1087 die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s",
1023 state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), 1088 state_text(result), string_statuscode (status_line.http_major, status_line.http_minor),
@@ -1029,16 +1094,6 @@ GOT_FIRST_CERT:
1029 (show_body ? body_buf.buf : ""), 1094 (show_body ? body_buf.buf : ""),
1030 (show_body ? "\n" : "") ); 1095 (show_body ? "\n" : "") );
1031 1096
1032 /* proper cleanup after die? */
1033 curlhelp_free_statusline(&status_line);
1034 curl_easy_cleanup (curl);
1035 curl_global_cleanup ();
1036 curlhelp_freewritebuffer (&body_buf);
1037 curlhelp_freewritebuffer (&header_buf);
1038 if (!strcmp (http_method, "PUT")) {
1039 curlhelp_freereadbuffer (&put_buf);
1040 }
1041
1042 return result; 1097 return result;
1043} 1098}
1044 1099
@@ -1134,7 +1189,10 @@ redir (curlhelp_write_curlbuf* header_buf)
1134 } 1189 }
1135 } 1190 }
1136 1191
1137 use_ssl = !uri_strcmp (uri.scheme, "https"); 1192 if (!uri_strcmp (uri.scheme, "https"))
1193 use_ssl = true;
1194 else
1195 use_ssl = false;
1138 1196
1139 /* we do a sloppy test here only, because uriparser would have failed 1197 /* we do a sloppy test here only, because uriparser would have failed
1140 * above, if the port would be invalid, we just check for MAX_PORT 1198 * above, if the port would be invalid, we just check for MAX_PORT
@@ -1209,6 +1267,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1209 * attached to the URL in Location 1267 * attached to the URL in Location
1210 */ 1268 */
1211 1269
1270 cleanup ();
1212 check_http (); 1271 check_http ();
1213} 1272}
1214 1273
@@ -1221,7 +1280,7 @@ test_file (char *path)
1221 usage2 (_("file does not exist or is not readable"), path); 1280 usage2 (_("file does not exist or is not readable"), path);
1222} 1281}
1223 1282
1224int 1283bool
1225process_arguments (int argc, char **argv) 1284process_arguments (int argc, char **argv)
1226{ 1285{
1227 char *p; 1286 char *p;
@@ -1235,7 +1294,8 @@ process_arguments (int argc, char **argv)
1235 CONTINUE_AFTER_CHECK_CERT, 1294 CONTINUE_AFTER_CHECK_CERT,
1236 CA_CERT_OPTION, 1295 CA_CERT_OPTION,
1237 HTTP_VERSION_OPTION, 1296 HTTP_VERSION_OPTION,
1238 AUTOMATIC_DECOMPRESSION 1297 AUTOMATIC_DECOMPRESSION,
1298 COOKIE_JAR
1239 }; 1299 };
1240 1300
1241 int option = 0; 1301 int option = 0;
@@ -1281,11 +1341,12 @@ process_arguments (int argc, char **argv)
1281 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION}, 1341 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
1282 {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, 1342 {"http-version", required_argument, 0, HTTP_VERSION_OPTION},
1283 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, 1343 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION},
1344 {"cookie-jar", required_argument, 0, COOKIE_JAR},
1284 {0, 0, 0, 0} 1345 {0, 0, 0, 0}
1285 }; 1346 };
1286 1347
1287 if (argc < 2) 1348 if (argc < 2)
1288 return ERROR; 1349 return false;
1289 1350
1290 /* support check_http compatible arguments */ 1351 /* support check_http compatible arguments */
1291 for (c = 1; c < argc; c++) { 1352 for (c = 1; c < argc; c++) {
@@ -1365,7 +1426,7 @@ process_arguments (int argc, char **argv)
1365 if( strtol(optarg, NULL, 10) > MAX_PORT) 1426 if( strtol(optarg, NULL, 10) > MAX_PORT)
1366 usage2 (_("Invalid port number, supplied port number is too big"), optarg); 1427 usage2 (_("Invalid port number, supplied port number is too big"), optarg);
1367 server_port = (unsigned short)strtol(optarg, NULL, 10); 1428 server_port = (unsigned short)strtol(optarg, NULL, 10);
1368 specify_port = TRUE; 1429 specify_port = true;
1369 } 1430 }
1370 break; 1431 break;
1371 case 'a': /* authorization info */ 1432 case 'a': /* authorization info */
@@ -1399,10 +1460,10 @@ process_arguments (int argc, char **argv)
1399 http_opt_headers[http_opt_headers_count - 1] = optarg; 1460 http_opt_headers[http_opt_headers_count - 1] = optarg;
1400 break; 1461 break;
1401 case 'L': /* show html link */ 1462 case 'L': /* show html link */
1402 display_html = TRUE; 1463 display_html = true;
1403 break; 1464 break;
1404 case 'n': /* do not show html link */ 1465 case 'n': /* do not show html link */
1405 display_html = FALSE; 1466 display_html = false;
1406 break; 1467 break;
1407 case 'C': /* Check SSL cert validity */ 1468 case 'C': /* Check SSL cert validity */
1408#ifdef LIBCURL_FEATURE_SSL 1469#ifdef LIBCURL_FEATURE_SSL
@@ -1423,12 +1484,12 @@ process_arguments (int argc, char **argv)
1423 usage2 (_("Invalid certificate expiration period"), optarg); 1484 usage2 (_("Invalid certificate expiration period"), optarg);
1424 days_till_exp_warn = atoi (optarg); 1485 days_till_exp_warn = atoi (optarg);
1425 } 1486 }
1426 check_cert = TRUE; 1487 check_cert = true;
1427 goto enable_ssl; 1488 goto enable_ssl;
1428#endif 1489#endif
1429 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */ 1490 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
1430#ifdef HAVE_SSL 1491#ifdef HAVE_SSL
1431 continue_after_check_cert = TRUE; 1492 continue_after_check_cert = true;
1432 break; 1493 break;
1433#endif 1494#endif
1434 case 'J': /* use client certificate */ 1495 case 'J': /* use client certificate */
@@ -1451,13 +1512,13 @@ process_arguments (int argc, char **argv)
1451#endif 1512#endif
1452#ifdef LIBCURL_FEATURE_SSL 1513#ifdef LIBCURL_FEATURE_SSL
1453 case 'D': /* verify peer certificate & host */ 1514 case 'D': /* verify peer certificate & host */
1454 verify_peer_and_host = TRUE; 1515 verify_peer_and_host = true;
1455 break; 1516 break;
1456#endif 1517#endif
1457 case 'S': /* use SSL */ 1518 case 'S': /* use SSL */
1458#ifdef LIBCURL_FEATURE_SSL 1519#ifdef LIBCURL_FEATURE_SSL
1459 enable_ssl: 1520 enable_ssl:
1460 use_ssl = TRUE; 1521 use_ssl = true;
1461 /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default. 1522 /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default.
1462 * Only set if it's non-zero. This helps when we include multiple 1523 * Only set if it's non-zero. This helps when we include multiple
1463 * parameters, like -S and -C combinations */ 1524 * parameters, like -S and -C combinations */
@@ -1531,15 +1592,15 @@ process_arguments (int argc, char **argv)
1531#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ 1592#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */
1532 if (verbose >= 2) 1593 if (verbose >= 2)
1533 printf(_("* Set SSL/TLS version to %d\n"), ssl_version); 1594 printf(_("* Set SSL/TLS version to %d\n"), ssl_version);
1534 if (specify_port == FALSE) 1595 if (!specify_port)
1535 server_port = HTTPS_PORT; 1596 server_port = HTTPS_PORT;
1536 break; 1597 break;
1537#else /* LIBCURL_FEATURE_SSL */ 1598#else /* LIBCURL_FEATURE_SSL */
1538 /* -C -J and -K fall through to here without SSL */ 1599 /* -C -J and -K fall through to here without SSL */
1539 usage4 (_("Invalid option - SSL is not available")); 1600 usage4 (_("Invalid option - SSL is not available"));
1540 break; 1601 break;
1541 case SNI_OPTION: /* --sni is parsed, but ignored, the default is TRUE with libcurl */ 1602 case SNI_OPTION: /* --sni is parsed, but ignored, the default is true with libcurl */
1542 use_sni = TRUE; 1603 use_sni = true;
1543 break; 1604 break;
1544#endif /* LIBCURL_FEATURE_SSL */ 1605#endif /* LIBCURL_FEATURE_SSL */
1545 case MAX_REDIRS_OPTION: 1606 case MAX_REDIRS_OPTION:
@@ -1600,11 +1661,11 @@ process_arguments (int argc, char **argv)
1600 if (errcode != 0) { 1661 if (errcode != 0) {
1601 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 1662 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
1602 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 1663 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
1603 return ERROR; 1664 return false;
1604 } 1665 }
1605 break; 1666 break;
1606 case INVERT_REGEX: 1667 case INVERT_REGEX:
1607 invert_regex = 1; 1668 invert_regex = true;
1608 break; 1669 break;
1609 case '4': 1670 case '4':
1610 address_family = AF_INET; 1671 address_family = AF_INET;
@@ -1639,7 +1700,7 @@ process_arguments (int argc, char **argv)
1639 break; 1700 break;
1640 } 1701 }
1641 case 'N': /* no-body */ 1702 case 'N': /* no-body */
1642 no_body = TRUE; 1703 no_body = true;
1643 break; 1704 break;
1644 case 'M': /* max-age */ 1705 case 'M': /* max-age */
1645 { 1706 {
@@ -1662,10 +1723,10 @@ process_arguments (int argc, char **argv)
1662 } 1723 }
1663 break; 1724 break;
1664 case 'E': /* show extended perfdata */ 1725 case 'E': /* show extended perfdata */
1665 show_extended_perfdata = TRUE; 1726 show_extended_perfdata = true;
1666 break; 1727 break;
1667 case 'B': /* print body content after status line */ 1728 case 'B': /* print body content after status line */
1668 show_body = TRUE; 1729 show_body = true;
1669 break; 1730 break;
1670 case HTTP_VERSION_OPTION: 1731 case HTTP_VERSION_OPTION:
1671 curl_http_version = CURL_HTTP_VERSION_NONE; 1732 curl_http_version = CURL_HTTP_VERSION_NONE;
@@ -1680,12 +1741,15 @@ process_arguments (int argc, char **argv)
1680 curl_http_version = CURL_HTTP_VERSION_NONE; 1741 curl_http_version = CURL_HTTP_VERSION_NONE;
1681#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */ 1742#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */
1682 } else { 1743 } else {
1683 fprintf (stderr, "unkown http-version parameter: %s\n", optarg); 1744 fprintf (stderr, "unknown http-version parameter: %s\n", optarg);
1684 exit (STATE_WARNING); 1745 exit (STATE_WARNING);
1685 } 1746 }
1686 break; 1747 break;
1687 case AUTOMATIC_DECOMPRESSION: 1748 case AUTOMATIC_DECOMPRESSION:
1688 automatic_decompression = TRUE; 1749 automatic_decompression = true;
1750 break;
1751 case COOKIE_JAR:
1752 cookie_jar_file = optarg;
1689 break; 1753 break;
1690 case '?': 1754 case '?':
1691 /* print short usage statement if args not parsable */ 1755 /* print short usage statement if args not parsable */
@@ -1726,52 +1790,52 @@ process_arguments (int argc, char **argv)
1726 virtual_port = server_port; 1790 virtual_port = server_port;
1727 else { 1791 else {
1728 if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT)) 1792 if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT))
1729 if(specify_port == FALSE) 1793 if(!specify_port)
1730 server_port = virtual_port; 1794 server_port = virtual_port;
1731 } 1795 }
1732 1796
1733 return TRUE; 1797 return true;
1734} 1798}
1735 1799
1736char *perfd_time (double elapsed_time) 1800char *perfd_time (double elapsed_time)
1737{ 1801{
1738 return fperfdata ("time", elapsed_time, "s", 1802 return fperfdata ("time", elapsed_time, "s",
1739 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1803 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1740 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1804 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1741 TRUE, 0, TRUE, socket_timeout); 1805 true, 0, true, socket_timeout);
1742} 1806}
1743 1807
1744char *perfd_time_connect (double elapsed_time_connect) 1808char *perfd_time_connect (double elapsed_time_connect)
1745{ 1809{
1746 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1810 return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1747} 1811}
1748 1812
1749char *perfd_time_ssl (double elapsed_time_ssl) 1813char *perfd_time_ssl (double elapsed_time_ssl)
1750{ 1814{
1751 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1815 return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1752} 1816}
1753 1817
1754char *perfd_time_headers (double elapsed_time_headers) 1818char *perfd_time_headers (double elapsed_time_headers)
1755{ 1819{
1756 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1820 return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1757} 1821}
1758 1822
1759char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1823char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1760{ 1824{
1761 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1825 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1762} 1826}
1763 1827
1764char *perfd_time_transfer (double elapsed_time_transfer) 1828char *perfd_time_transfer (double elapsed_time_transfer)
1765{ 1829{
1766 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1830 return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1767} 1831}
1768 1832
1769char *perfd_size (int page_len) 1833char *perfd_size (int page_len)
1770{ 1834{
1771 return perfdata ("size", page_len, "B", 1835 return perfdata ("size", page_len, "B",
1772 (min_page_len>0?TRUE:FALSE), min_page_len, 1836 (min_page_len>0?true:false), min_page_len,
1773 (min_page_len>0?TRUE:FALSE), 0, 1837 (min_page_len>0?true:false), 0,
1774 TRUE, 0, FALSE, 0); 1838 true, 0, false, 0);
1775} 1839}
1776 1840
1777void 1841void
@@ -1906,6 +1970,8 @@ print_help (void)
1906 printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); 1970 printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)"));
1907 printf (" %s\n", "--enable-automatic-decompression"); 1971 printf (" %s\n", "--enable-automatic-decompression");
1908 printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); 1972 printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING)."));
1973 printf (" %s\n", "---cookie-jar=FILE");
1974 printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested."));
1909 printf ("\n"); 1975 printf ("\n");
1910 1976
1911 printf (UT_WARN_CRIT); 1977 printf (UT_WARN_CRIT);
@@ -1990,7 +2056,8 @@ print_usage (void)
1990 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 2056 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1991 printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); 2057 printf (" [-A string] [-k string] [-S <version>] [--sni]\n");
1992 printf (" [-T <content-type>] [-j method]\n"); 2058 printf (" [-T <content-type>] [-j method]\n");
1993 printf (" [--http-version=<version>]\n"); 2059 printf (" [--http-version=<version>] [--enable-automatic-decompression]\n");
2060 printf (" [--cookie-jar=<cookie jar file>\n");
1994 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname); 2061 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname);
1995 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n"); 2062 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n");
1996 printf ("\n"); 2063 printf ("\n");
@@ -2024,9 +2091,12 @@ curlhelp_buffer_write_callback (void *buffer, size_t size, size_t nmemb, void *s
2024 curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; 2091 curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream;
2025 2092
2026 while (buf->bufsize < buf->buflen + size * nmemb + 1) { 2093 while (buf->bufsize < buf->buflen + size * nmemb + 1) {
2027 buf->bufsize *= buf->bufsize * 2; 2094 buf->bufsize = buf->bufsize * 2;
2028 buf->buf = (char *)realloc (buf->buf, buf->bufsize); 2095 buf->buf = (char *)realloc (buf->buf, buf->bufsize);
2029 if (buf->buf == NULL) return -1; 2096 if (buf->buf == NULL) {
2097 fprintf(stderr, "malloc failed (%d) %s\n", errno, strerror(errno));
2098 return -1;
2099 }
2030 } 2100 }
2031 2101
2032 memcpy (buf->buf + buf->buflen, buffer, size * nmemb); 2102 memcpy (buf->buf + buf->buflen, buffer, size * nmemb);
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 7018c6fd..bd84c825 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -112,11 +112,12 @@ enum
112{ 112{
113 SYNC_OPTION = CHAR_MAX + 1, 113 SYNC_OPTION = CHAR_MAX + 1,
114 NO_SYNC_OPTION, 114 NO_SYNC_OPTION,
115 BLOCK_SIZE_OPTION 115 BLOCK_SIZE_OPTION,
116 IGNORE_MISSING
116}; 117};
117 118
118#ifdef _AIX 119#ifdef _AIX
119 #pragma alloca 120#pragma alloca
120#endif 121#endif
121 122
122int process_arguments (int, char **); 123int process_arguments (int, char **);
@@ -126,7 +127,7 @@ int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, ch
126void print_help (void); 127void print_help (void);
127void print_usage (void); 128void print_usage (void);
128double calculate_percent(uintmax_t, uintmax_t); 129double calculate_percent(uintmax_t, uintmax_t);
129void stat_path (struct parameter_list *p); 130bool stat_path (struct parameter_list *p);
130void get_stats (struct parameter_list *p, struct fs_usage *fsp); 131void get_stats (struct parameter_list *p, struct fs_usage *fsp);
131void get_path_stats (struct parameter_list *p, struct fs_usage *fsp); 132void get_path_stats (struct parameter_list *p, struct fs_usage *fsp);
132 133
@@ -140,6 +141,7 @@ int verbose = 0;
140int erronly = FALSE; 141int erronly = FALSE;
141int display_mntp = FALSE; 142int display_mntp = FALSE;
142int exact_match = FALSE; 143int exact_match = FALSE;
144bool ignore_missing = false;
143int freespace_ignore_reserved = FALSE; 145int freespace_ignore_reserved = FALSE;
144int display_inodes_perfdata = FALSE; 146int display_inodes_perfdata = FALSE;
145char *warn_freespace_units = NULL; 147char *warn_freespace_units = NULL;
@@ -155,6 +157,7 @@ char *crit_usedinodes_percent = NULL;
155char *warn_freeinodes_percent = NULL; 157char *warn_freeinodes_percent = NULL;
156char *crit_freeinodes_percent = NULL; 158char *crit_freeinodes_percent = NULL;
157int path_selected = FALSE; 159int path_selected = FALSE;
160bool path_ignored = false;
158char *group = NULL; 161char *group = NULL;
159struct stat *stat_buf; 162struct stat *stat_buf;
160struct name_list *seen = NULL; 163struct name_list *seen = NULL;
@@ -166,10 +169,12 @@ main (int argc, char **argv)
166 int result = STATE_UNKNOWN; 169 int result = STATE_UNKNOWN;
167 int disk_result = STATE_UNKNOWN; 170 int disk_result = STATE_UNKNOWN;
168 char *output; 171 char *output;
172 char *ignored;
169 char *details; 173 char *details;
170 char *perf; 174 char *perf;
171 char *perf_ilabel; 175 char *perf_ilabel;
172 char *preamble; 176 char *preamble = " - free space:";
177 char *ignored_preamble = " - ignored paths:";
173 char *flag_header; 178 char *flag_header;
174 int temp_result; 179 int temp_result;
175 180
@@ -181,8 +186,8 @@ main (int argc, char **argv)
181 char mountdir[32]; 186 char mountdir[32];
182#endif 187#endif
183 188
184 preamble = strdup (" - free space:");
185 output = strdup (""); 189 output = strdup ("");
190 ignored = strdup ("");
186 details = strdup (""); 191 details = strdup ("");
187 perf = strdup (""); 192 perf = strdup ("");
188 perf_ilabel = strdup (""); 193 perf_ilabel = strdup ("");
@@ -203,7 +208,7 @@ main (int argc, char **argv)
203 /* If a list of paths has not been selected, find entire 208 /* If a list of paths has not been selected, find entire
204 mount list and create list of paths 209 mount list and create list of paths
205 */ 210 */
206 if (path_selected == FALSE) { 211 if (path_selected == FALSE && path_ignored == false) {
207 for (me = mount_list; me; me = me->me_next) { 212 for (me = mount_list; me; me = me->me_next) {
208 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { 213 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
209 path = np_add_parameter(&path_select_list, me->me_mountdir); 214 path = np_add_parameter(&path_select_list, me->me_mountdir);
@@ -213,17 +218,40 @@ main (int argc, char **argv)
213 set_all_thresholds(path); 218 set_all_thresholds(path);
214 } 219 }
215 } 220 }
216 np_set_best_match(path_select_list, mount_list, exact_match); 221
222 if (path_ignored == false) {
223 np_set_best_match(path_select_list, mount_list, exact_match);
224 }
217 225
218 /* Error if no match found for specified paths */ 226 /* Error if no match found for specified paths */
219 temp_list = path_select_list; 227 temp_list = path_select_list;
220 228
221 while (temp_list) { 229 while (path_select_list) {
222 if (! temp_list->best_match) { 230 if (! path_select_list->best_match && ignore_missing == true) {
223 die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name); 231 /* If the first element will be deleted, the temp_list must be updated with the new start address as well */
232 if (path_select_list == temp_list) {
233 temp_list = path_select_list->name_next;
234 }
235 /* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */
236 xasprintf (&ignored, "%s %s;", ignored, path_select_list->name);
237 /* Delete the path from the list so that it is not stat-checked later in the code. */
238 path_select_list = np_del_parameter(path_select_list, path_select_list->name_prev);
239 } else if (! path_select_list->best_match) {
240 /* Without --ignore-missing option, exit with Critical state. */
241 die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), path_select_list->name);
242 } else {
243 /* Continue jumping through the list */
244 path_select_list = path_select_list->name_next;
224 } 245 }
246 }
247
248 path_select_list = temp_list;
225 249
226 temp_list = temp_list->name_next; 250 if (! path_select_list && ignore_missing == true) {
251 result = STATE_OK;
252 if (verbose >= 2) {
253 printf ("None of the provided paths were found\n");
254 }
227 } 255 }
228 256
229 /* Process for every path in list */ 257 /* Process for every path in list */
@@ -242,6 +270,10 @@ main (int argc, char **argv)
242 270
243 me = path->best_match; 271 me = path->best_match;
244 272
273 if (!me) {
274 continue;
275 }
276
245#ifdef __CYGWIN__ 277#ifdef __CYGWIN__
246 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) 278 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
247 continue; 279 continue;
@@ -260,8 +292,12 @@ main (int argc, char **argv)
260 if (path->group == NULL) { 292 if (path->group == NULL) {
261 /* Skip remote filesystems if we're not interested in them */ 293 /* Skip remote filesystems if we're not interested in them */
262 if (me->me_remote && show_local_fs) { 294 if (me->me_remote && show_local_fs) {
263 if (stat_remote_fs) 295 if (stat_remote_fs) {
264 stat_path(path); 296 if (!stat_path(path) && ignore_missing == true) {
297 result = STATE_OK;
298 xasprintf (&ignored, "%s %s;", ignored, path->name);
299 }
300 }
265 continue; 301 continue;
266 /* Skip pseudo fs's if we haven't asked for all fs's */ 302 /* Skip pseudo fs's if we haven't asked for all fs's */
267 } else if (me->me_dummy && !show_all_fs) { 303 } else if (me->me_dummy && !show_all_fs) {
@@ -280,7 +316,13 @@ main (int argc, char **argv)
280 } 316 }
281 } 317 }
282 318
283 stat_path(path); 319 if (!stat_path(path)) {
320 if (ignore_missing == true) {
321 result = STATE_OK;
322 xasprintf (&ignored, "%s %s;", ignored, path->name);
323 }
324 continue;
325 }
284 get_fs_usage (me->me_mountdir, me->me_devname, &fsp); 326 get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
285 327
286 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { 328 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
@@ -411,8 +453,12 @@ main (int argc, char **argv)
411 if (verbose >= 2) 453 if (verbose >= 2)
412 xasprintf (&output, "%s%s", output, details); 454 xasprintf (&output, "%s%s", output, details);
413 455
456 if (strcmp(output, "") == 0 && ! erronly) {
457 preamble = "";
458 xasprintf (&output, " - No disks were found for provided parameters;");
459 }
414 460
415 printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf); 461 printf ("DISK %s%s%s%s%s|%s\n", state_text (result), ((erronly && result==STATE_OK)) ? "" : preamble, output, (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf);
416 return result; 462 return result;
417} 463}
418 464
@@ -481,6 +527,7 @@ process_arguments (int argc, char **argv)
481 {"ignore-ereg-partition", required_argument, 0, 'i'}, 527 {"ignore-ereg-partition", required_argument, 0, 'i'},
482 {"ignore-eregi-path", required_argument, 0, 'I'}, 528 {"ignore-eregi-path", required_argument, 0, 'I'},
483 {"ignore-eregi-partition", required_argument, 0, 'I'}, 529 {"ignore-eregi-partition", required_argument, 0, 'I'},
530 {"ignore-missing", no_argument, 0, IGNORE_MISSING},
484 {"local", no_argument, 0, 'l'}, 531 {"local", no_argument, 0, 'l'},
485 {"stat-remote-fs", no_argument, 0, 'L'}, 532 {"stat-remote-fs", no_argument, 0, 'L'},
486 {"iperfdata", no_argument, 0, 'P'}, 533 {"iperfdata", no_argument, 0, 'P'},
@@ -632,12 +679,19 @@ process_arguments (int argc, char **argv)
632 /* add parameter if not found. overwrite thresholds if path has already been added */ 679 /* add parameter if not found. overwrite thresholds if path has already been added */
633 if (! (se = np_find_parameter(path_select_list, optarg))) { 680 if (! (se = np_find_parameter(path_select_list, optarg))) {
634 se = np_add_parameter(&path_select_list, optarg); 681 se = np_add_parameter(&path_select_list, optarg);
682
683 if (stat(optarg, &stat_buf[0]) && ignore_missing == true) {
684 path_ignored = true;
685 break;
686 }
635 } 687 }
636 se->group = group; 688 se->group = group;
637 set_all_thresholds(se); 689 set_all_thresholds(se);
638 690
639 /* With autofs, it is required to stat() the path before re-populating the mount_list */ 691 /* With autofs, it is required to stat() the path before re-populating the mount_list */
640 stat_path(se); 692 if (!stat_path(se)) {
693 break;
694 }
641 /* NB: We can't free the old mount_list "just like that": both list pointers and struct 695 /* NB: We can't free the old mount_list "just like that": both list pointers and struct
642 * pointers are copied around. One of the reason it wasn't done yet is that other parts 696 * pointers are copied around. One of the reason it wasn't done yet is that other parts
643 * of check_disk need the same kind of cleanup so it'd better be done as a whole */ 697 * of check_disk need the same kind of cleanup so it'd better be done as a whole */
@@ -718,6 +772,9 @@ process_arguments (int argc, char **argv)
718 cflags = default_cflags; 772 cflags = default_cflags;
719 break; 773 break;
720 774
775 case IGNORE_MISSING:
776 ignore_missing = true;
777 break;
721 case 'A': 778 case 'A':
722 optarg = strdup(".*"); 779 optarg = strdup(".*");
723 // Intentional fallthrough 780 // Intentional fallthrough
@@ -753,7 +810,11 @@ process_arguments (int argc, char **argv)
753 } 810 }
754 } 811 }
755 812
756 if (!fnd) 813 if (!fnd && ignore_missing == true) {
814 path_ignored = true;
815 /* path_selected = TRUE;*/
816 break;
817 } else if (!fnd)
757 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), 818 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"),
758 _("Regular expression did not match any path or disk"), optarg); 819 _("Regular expression did not match any path or disk"), optarg);
759 820
@@ -923,6 +984,9 @@ print_help (void)
923 printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); 984 printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)"));
924 printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); 985 printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION");
925 printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); 986 printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)"));
987 printf (" %s\n", "--ignore-missing");
988 printf (" %s\n", _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible."));
989 printf (" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)"));
926 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 990 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
927 printf (" %s\n", "-u, --units=STRING"); 991 printf (" %s\n", "-u, --units=STRING");
928 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); 992 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
@@ -951,12 +1015,12 @@ void
951print_usage (void) 1015print_usage (void)
952{ 1016{
953 printf ("%s\n", _("Usage:")); 1017 printf ("%s\n", _("Usage:"));
954 printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); 1018 printf (" %s {-w absolute_limit |-w percentage_limit% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit% | -K inode_percentage_limit } {-p path | -x device}\n", progname);
955 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); 1019 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
956 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); 1020 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
957} 1021}
958 1022
959void 1023bool
960stat_path (struct parameter_list *p) 1024stat_path (struct parameter_list *p)
961{ 1025{
962 /* Stat entry to check that dir exists and is accessible */ 1026 /* Stat entry to check that dir exists and is accessible */
@@ -965,9 +1029,14 @@ stat_path (struct parameter_list *p)
965 if (stat (p->name, &stat_buf[0])) { 1029 if (stat (p->name, &stat_buf[0])) {
966 if (verbose >= 3) 1030 if (verbose >= 3)
967 printf("stat failed on %s\n", p->name); 1031 printf("stat failed on %s\n", p->name);
968 printf("DISK %s - ", _("CRITICAL")); 1032 if (ignore_missing == true) {
969 die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); 1033 return false;
1034 } else {
1035 printf("DISK %s - ", _("CRITICAL"));
1036 die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
1037 }
970 } 1038 }
1039 return true;
971} 1040}
972 1041
973 1042
@@ -987,7 +1056,8 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
987 continue; 1056 continue;
988#endif 1057#endif
989 if (p_list->group && ! (strcmp(p_list->group, p->group))) { 1058 if (p_list->group && ! (strcmp(p_list->group, p->group))) {
990 stat_path(p_list); 1059 if (! stat_path(p_list))
1060 continue;
991 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); 1061 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
992 get_path_stats(p_list, &tmpfsp); 1062 get_path_stats(p_list, &tmpfsp);
993 if (verbose >= 3) 1063 if (verbose >= 3)
@@ -1056,7 +1126,7 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1056 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1126 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
1057 p->dtotal_units = p->total*fsp->fsu_blocksize/mult; 1127 p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
1058 /* Free file nodes. Not sure the workaround is required, but in case...*/ 1128 /* Free file nodes. Not sure the workaround is required, but in case...*/
1059 p->inodes_free = fsp->fsu_favail > fsp->fsu_ffree ? 0 : fsp->fsu_favail; 1129 p->inodes_free = fsp->fsu_ffree;
1060 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ 1130 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
1061 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; 1131 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
1062 if (freespace_ignore_reserved) { 1132 if (freespace_ignore_reserved) {
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index be9362ad..db433162 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -492,7 +492,7 @@ void print_help (void) {
492 printf (" %s\n", "-c, --critical=THRESHOLD"); 492 printf (" %s\n", "-c, --critical=THRESHOLD");
493 printf (" %s\n", _("critical threshold pair")); 493 printf (" %s\n", _("critical threshold pair"));
494 printf (" %s\n", "-a, --alive"); 494 printf (" %s\n", "-a, --alive");
495 printf (" %s\n", _("Return OK after first successfull reply")); 495 printf (" %s\n", _("Return OK after first successful reply"));
496 printf (" %s\n", "-b, --bytes=INTEGER"); 496 printf (" %s\n", "-b, --bytes=INTEGER");
497 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE); 497 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE);
498 printf (" %s\n", "-n, --number=INTEGER"); 498 printf (" %s\n", "-n, --number=INTEGER");
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 41d47816..8dda046f 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -31,13 +31,14 @@
31* 31*
32*****************************************************************************/ 32*****************************************************************************/
33 33
34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */
35
36const char *progname = "check_http"; 34const char *progname = "check_http";
37const char *copyright = "1999-2013"; 35const char *copyright = "1999-2022";
38const char *email = "devel@monitoring-plugins.org"; 36const char *email = "devel@monitoring-plugins.org";
39 37
38// Do NOT sort those headers, it will break the build
39// TODO: Fix this
40#include "common.h" 40#include "common.h"
41#include "base64.h"
41#include "netutils.h" 42#include "netutils.h"
42#include "utils.h" 43#include "utils.h"
43#include "base64.h" 44#include "base64.h"
@@ -57,8 +58,8 @@ enum {
57}; 58};
58 59
59#ifdef HAVE_SSL 60#ifdef HAVE_SSL
60int check_cert = FALSE; 61bool check_cert = false;
61int continue_after_check_cert = FALSE; 62bool continue_after_check_cert = false;
62int ssl_version = 0; 63int ssl_version = 0;
63int days_till_exp_warn, days_till_exp_crit; 64int days_till_exp_warn, days_till_exp_crit;
64char *randbuff; 65char *randbuff;
@@ -69,7 +70,7 @@ X509 *server_cert;
69# define my_recv(buf, len) read(sd, buf, len) 70# define my_recv(buf, len) read(sd, buf, len)
70# define my_send(buf, len) send(sd, buf, len, 0) 71# define my_send(buf, len) send(sd, buf, len, 0)
71#endif /* HAVE_SSL */ 72#endif /* HAVE_SSL */
72int no_body = FALSE; 73bool no_body = false;
73int maximum_age = -1; 74int maximum_age = -1;
74 75
75enum { 76enum {
@@ -91,7 +92,7 @@ struct timeval tv_temp;
91#define HTTP_URL "/" 92#define HTTP_URL "/"
92#define CRLF "\r\n" 93#define CRLF "\r\n"
93 94
94int specify_port = FALSE; 95bool specify_port = false;
95int server_port = HTTP_PORT; 96int server_port = HTTP_PORT;
96int virtual_port = 0; 97int virtual_port = 0;
97char server_port_text[6] = ""; 98char server_port_text[6] = "";
@@ -106,23 +107,21 @@ int server_expect_yn = 0;
106char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; 107char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
107char header_expect[MAX_INPUT_BUFFER] = ""; 108char header_expect[MAX_INPUT_BUFFER] = "";
108char string_expect[MAX_INPUT_BUFFER] = ""; 109char string_expect[MAX_INPUT_BUFFER] = "";
109char output_header_search[30] = "";
110char output_string_search[30] = "";
111char *warning_thresholds = NULL; 110char *warning_thresholds = NULL;
112char *critical_thresholds = NULL; 111char *critical_thresholds = NULL;
113thresholds *thlds; 112thresholds *thlds;
114char user_auth[MAX_INPUT_BUFFER] = ""; 113char user_auth[MAX_INPUT_BUFFER] = "";
115char proxy_auth[MAX_INPUT_BUFFER] = ""; 114char proxy_auth[MAX_INPUT_BUFFER] = "";
116int display_html = FALSE; 115bool display_html = false;
117char **http_opt_headers; 116char **http_opt_headers;
118int http_opt_headers_count = 0; 117int http_opt_headers_count = 0;
119int onredirect = STATE_OK; 118int onredirect = STATE_OK;
120int followsticky = STICKY_NONE; 119int followsticky = STICKY_NONE;
121int use_ssl = FALSE; 120bool use_ssl = false;
122int use_sni = FALSE; 121bool use_sni = false;
123int verbose = FALSE; 122bool verbose = false;
124int show_extended_perfdata = FALSE; 123bool show_extended_perfdata = false;
125int show_body = FALSE; 124bool show_body = false;
126int sd; 125int sd;
127int min_page_len = 0; 126int min_page_len = 0;
128int max_page_len = 0; 127int max_page_len = 0;
@@ -136,10 +135,11 @@ char buffer[MAX_INPUT_BUFFER];
136char *client_cert = NULL; 135char *client_cert = NULL;
137char *client_privkey = NULL; 136char *client_privkey = NULL;
138 137
139int process_arguments (int, char **); 138// Forward function declarations
139bool process_arguments (int, char **);
140int check_http (void); 140int check_http (void);
141void redir (char *pos, char *status_line); 141void redir (char *pos, char *status_line);
142int server_type_check(const char *type); 142bool server_type_check(const char *type);
143int server_port_check(int ssl_flag); 143int server_port_check(int ssl_flag);
144char *perfd_time (double microsec); 144char *perfd_time (double microsec);
145char *perfd_time_connect (double microsec); 145char *perfd_time_connect (double microsec);
@@ -150,6 +150,7 @@ char *perfd_time_transfer (double microsec);
150char *perfd_size (int page_len); 150char *perfd_size (int page_len);
151void print_help (void); 151void print_help (void);
152void print_usage (void); 152void print_usage (void);
153char *unchunk_content(const char *content);
153 154
154int 155int
155main (int argc, char **argv) 156main (int argc, char **argv)
@@ -169,10 +170,10 @@ main (int argc, char **argv)
169 /* Parse extra opts if any */ 170 /* Parse extra opts if any */
170 argv=np_extra_opts (&argc, argv, progname); 171 argv=np_extra_opts (&argc, argv, progname);
171 172
172 if (process_arguments (argc, argv) == ERROR) 173 if (process_arguments (argc, argv) == false)
173 usage4 (_("Could not parse arguments")); 174 usage4 (_("Could not parse arguments"));
174 175
175 if (display_html == TRUE) 176 if (display_html == true)
176 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 177 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">",
177 use_ssl ? "https" : "http", host_name ? host_name : server_address, 178 use_ssl ? "https" : "http", host_name ? host_name : server_address,
178 server_port, server_url); 179 server_port, server_url);
@@ -195,9 +196,11 @@ test_file (char *path)
195 usage2 (_("file does not exist or is not readable"), path); 196 usage2 (_("file does not exist or is not readable"), path);
196} 197}
197 198
198/* process command-line arguments */ 199/*
199int 200 * process command-line arguments
200process_arguments (int argc, char **argv) 201 * returns true on succes, false otherwise
202 */
203bool process_arguments (int argc, char **argv)
201{ 204{
202 int c = 1; 205 int c = 1;
203 char *p; 206 char *p;
@@ -252,7 +255,7 @@ process_arguments (int argc, char **argv)
252 }; 255 };
253 256
254 if (argc < 2) 257 if (argc < 2)
255 return ERROR; 258 return false;
256 259
257 for (c = 1; c < argc; c++) { 260 for (c = 1; c < argc; c++) {
258 if (strcmp ("-to", argv[c]) == 0) 261 if (strcmp ("-to", argv[c]) == 0)
@@ -308,10 +311,10 @@ process_arguments (int argc, char **argv)
308 /* xasprintf (&http_opt_headers, "%s", optarg); */ 311 /* xasprintf (&http_opt_headers, "%s", optarg); */
309 break; 312 break;
310 case 'L': /* show html link */ 313 case 'L': /* show html link */
311 display_html = TRUE; 314 display_html = true;
312 break; 315 break;
313 case 'n': /* do not show html link */ 316 case 'n': /* do not show html link */
314 display_html = FALSE; 317 display_html = false;
315 break; 318 break;
316 case 'C': /* Check SSL cert validity */ 319 case 'C': /* Check SSL cert validity */
317#ifdef HAVE_SSL 320#ifdef HAVE_SSL
@@ -332,12 +335,12 @@ process_arguments (int argc, char **argv)
332 usage2 (_("Invalid certificate expiration period"), optarg); 335 usage2 (_("Invalid certificate expiration period"), optarg);
333 days_till_exp_warn = atoi (optarg); 336 days_till_exp_warn = atoi (optarg);
334 } 337 }
335 check_cert = TRUE; 338 check_cert = true;
336 goto enable_ssl; 339 goto enable_ssl;
337#endif 340#endif
338 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */ 341 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
339#ifdef HAVE_SSL 342#ifdef HAVE_SSL
340 continue_after_check_cert = TRUE; 343 continue_after_check_cert = true;
341 break; 344 break;
342#endif 345#endif
343 case 'J': /* use client certificate */ 346 case 'J': /* use client certificate */
@@ -357,7 +360,7 @@ process_arguments (int argc, char **argv)
357 enable_ssl: 360 enable_ssl:
358 /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple 361 /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple
359 parameters, like -S and -C combinations */ 362 parameters, like -S and -C combinations */
360 use_ssl = TRUE; 363 use_ssl = true;
361 if (c=='S' && optarg != NULL) { 364 if (c=='S' && optarg != NULL) {
362 int got_plus = strchr(optarg, '+') != NULL; 365 int got_plus = strchr(optarg, '+') != NULL;
363 366
@@ -374,7 +377,7 @@ process_arguments (int argc, char **argv)
374 else 377 else
375 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); 378 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)"));
376 } 379 }
377 if (specify_port == FALSE) 380 if (specify_port == false)
378 server_port = HTTPS_PORT; 381 server_port = HTTPS_PORT;
379#else 382#else
380 /* -C -J and -K fall through to here without SSL */ 383 /* -C -J and -K fall through to here without SSL */
@@ -382,7 +385,7 @@ process_arguments (int argc, char **argv)
382#endif 385#endif
383 break; 386 break;
384 case SNI_OPTION: 387 case SNI_OPTION:
385 use_sni = TRUE; 388 use_sni = true;
386 break; 389 break;
387 case MAX_REDIRS_OPTION: 390 case MAX_REDIRS_OPTION:
388 if (!is_intnonneg (optarg)) 391 if (!is_intnonneg (optarg))
@@ -420,7 +423,7 @@ process_arguments (int argc, char **argv)
420 host_name_length = strlen (host_name) - strlen (p) - 1; 423 host_name_length = strlen (host_name) - strlen (p) - 1;
421 free (host_name); 424 free (host_name);
422 host_name = strndup (optarg, host_name_length); 425 host_name = strndup (optarg, host_name_length);
423 if (specify_port == FALSE) 426 if (specify_port == false)
424 server_port = virtual_port; 427 server_port = virtual_port;
425 } 428 }
426 } else if ((p = strchr (host_name, ':')) != NULL 429 } else if ((p = strchr (host_name, ':')) != NULL
@@ -430,7 +433,7 @@ process_arguments (int argc, char **argv)
430 host_name_length = strlen (host_name) - strlen (p) - 1; 433 host_name_length = strlen (host_name) - strlen (p) - 1;
431 free (host_name); 434 free (host_name);
432 host_name = strndup (optarg, host_name_length); 435 host_name = strndup (optarg, host_name_length);
433 if (specify_port == FALSE) 436 if (specify_port == false)
434 server_port = virtual_port; 437 server_port = virtual_port;
435 } 438 }
436 break; 439 break;
@@ -446,7 +449,7 @@ process_arguments (int argc, char **argv)
446 usage2 (_("Invalid port number"), optarg); 449 usage2 (_("Invalid port number"), optarg);
447 else { 450 else {
448 server_port = atoi (optarg); 451 server_port = atoi (optarg);
449 specify_port = TRUE; 452 specify_port = true;
450 } 453 }
451 break; 454 break;
452 case 'a': /* authorization info */ 455 case 'a': /* authorization info */
@@ -502,7 +505,7 @@ process_arguments (int argc, char **argv)
502 if (errcode != 0) { 505 if (errcode != 0) {
503 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 506 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
504 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 507 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
505 return ERROR; 508 return false;
506 } 509 }
507 break; 510 break;
508 case INVERT_REGEX: 511 case INVERT_REGEX:
@@ -519,7 +522,7 @@ process_arguments (int argc, char **argv)
519#endif 522#endif
520 break; 523 break;
521 case 'v': /* verbose */ 524 case 'v': /* verbose */
522 verbose = TRUE; 525 verbose = true;
523 break; 526 break;
524 case 'm': /* min_page_length */ 527 case 'm': /* min_page_length */
525 { 528 {
@@ -544,7 +547,7 @@ process_arguments (int argc, char **argv)
544 break; 547 break;
545 } 548 }
546 case 'N': /* no-body */ 549 case 'N': /* no-body */
547 no_body = TRUE; 550 no_body = true;
548 break; 551 break;
549 case 'M': /* max-age */ 552 case 'M': /* max-age */
550 { 553 {
@@ -565,10 +568,10 @@ process_arguments (int argc, char **argv)
565 } 568 }
566 break; 569 break;
567 case 'E': /* show extended perfdata */ 570 case 'E': /* show extended perfdata */
568 show_extended_perfdata = TRUE; 571 show_extended_perfdata = true;
569 break; 572 break;
570 case 'B': /* print body content after status line */ 573 case 'B': /* print body content after status line */
571 show_body = TRUE; 574 show_body = true;
572 break; 575 break;
573 } 576 }
574 } 577 }
@@ -605,7 +608,7 @@ process_arguments (int argc, char **argv)
605 if (virtual_port == 0) 608 if (virtual_port == 0)
606 virtual_port = server_port; 609 virtual_port = server_port;
607 610
608 return TRUE; 611 return true;
609} 612}
610 613
611 614
@@ -945,7 +948,7 @@ check_http (void)
945 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */ 948 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */
946 949
947 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 950 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
948 && host_name != NULL && use_ssl == TRUE) { 951 && host_name != NULL && use_ssl == true) {
949 952
950 if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT); 953 if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT);
951 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent); 954 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent);
@@ -979,7 +982,7 @@ check_http (void)
979 } 982 }
980#ifdef HAVE_SSL 983#ifdef HAVE_SSL
981 elapsed_time_connect = (double)microsec_connect / 1.0e6; 984 elapsed_time_connect = (double)microsec_connect / 1.0e6;
982 if (use_ssl == TRUE) { 985 if (use_ssl == true) {
983 gettimeofday (&tv_temp, NULL); 986 gettimeofday (&tv_temp, NULL);
984 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); 987 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
985 if (verbose) printf ("SSL initialized\n"); 988 if (verbose) printf ("SSL initialized\n");
@@ -987,9 +990,9 @@ check_http (void)
987 die (STATE_CRITICAL, NULL); 990 die (STATE_CRITICAL, NULL);
988 microsec_ssl = deltime (tv_temp); 991 microsec_ssl = deltime (tv_temp);
989 elapsed_time_ssl = (double)microsec_ssl / 1.0e6; 992 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
990 if (check_cert == TRUE) { 993 if (check_cert == true) {
991 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 994 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
992 if (continue_after_check_cert == FALSE) { 995 if (continue_after_check_cert == false) {
993 if (sd) close(sd); 996 if (sd) close(sd);
994 np_net_ssl_cleanup(); 997 np_net_ssl_cleanup();
995 return result; 998 return result;
@@ -999,7 +1002,7 @@ check_http (void)
999#endif /* HAVE_SSL */ 1002#endif /* HAVE_SSL */
1000 1003
1001 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 1004 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
1002 && host_name != NULL && use_ssl == TRUE) 1005 && host_name != NULL && use_ssl == true)
1003 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1006 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
1004 else 1007 else
1005 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1008 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
@@ -1027,10 +1030,10 @@ check_http (void)
1027 * 14.23). Some server applications/configurations cause trouble if the 1030 * 14.23). Some server applications/configurations cause trouble if the
1028 * (default) port is explicitly specified in the "Host:" header line. 1031 * (default) port is explicitly specified in the "Host:" header line.
1029 */ 1032 */
1030 if ((use_ssl == FALSE && virtual_port == HTTP_PORT) || 1033 if ((use_ssl == false && virtual_port == HTTP_PORT) ||
1031 (use_ssl == TRUE && virtual_port == HTTPS_PORT) || 1034 (use_ssl == true && virtual_port == HTTPS_PORT) ||
1032 (server_address != NULL && strcmp(http_method, "CONNECT") == 0 1035 (server_address != NULL && strcmp(http_method, "CONNECT") == 0
1033 && host_name != NULL && use_ssl == TRUE)) 1036 && host_name != NULL && use_ssl == true))
1034 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name); 1037 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name);
1035 else 1038 else
1036 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port); 1039 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port);
@@ -1095,9 +1098,14 @@ check_http (void)
1095 *pos = ' '; 1098 *pos = ' ';
1096 } 1099 }
1097 buffer[i] = '\0'; 1100 buffer[i] = '\0';
1098 xasprintf (&full_page_new, "%s%s", full_page, buffer); 1101
1099 free (full_page); 1102 if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL)
1103 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n"));
1104
1105 memmove(&full_page_new[pagesize], buffer, i + 1);
1106
1100 full_page = full_page_new; 1107 full_page = full_page_new;
1108
1101 pagesize += i; 1109 pagesize += i;
1102 1110
1103 if (no_body && document_headers_done (full_page)) { 1111 if (no_body && document_headers_done (full_page)) {
@@ -1109,25 +1117,7 @@ check_http (void)
1109 elapsed_time_transfer = (double)microsec_transfer / 1.0e6; 1117 elapsed_time_transfer = (double)microsec_transfer / 1.0e6;
1110 1118
1111 if (i < 0 && errno != ECONNRESET) { 1119 if (i < 0 && errno != ECONNRESET) {
1112#ifdef HAVE_SSL 1120 die(STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1113 /*
1114 if (use_ssl) {
1115 sslerr=SSL_get_error(ssl, i);
1116 if ( sslerr == SSL_ERROR_SSL ) {
1117 die (STATE_WARNING, _("HTTP WARNING - Client Certificate Required\n"));
1118 } else {
1119 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1120 }
1121 }
1122 else {
1123 */
1124#endif
1125 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1126#ifdef HAVE_SSL
1127 /* XXX
1128 }
1129 */
1130#endif
1131 } 1121 }
1132 1122
1133 /* return a CRITICAL status if we couldn't read any data */ 1123 /* return a CRITICAL status if we couldn't read any data */
@@ -1252,32 +1242,73 @@ check_http (void)
1252 } 1242 }
1253 1243
1254 /* Page and Header content checks go here */ 1244 /* Page and Header content checks go here */
1255 if (strlen (header_expect)) { 1245 if (strlen(header_expect) > 0) {
1256 if (!strstr (header, header_expect)) { 1246 if (strstr(header, header_expect) == NULL) {
1257 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); 1247 // We did not find the header, the rest is for building the output and setting the state
1258 if(output_header_search[sizeof(output_header_search)-1]!='\0') { 1248 char output_header_search[30] = "";
1259 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); 1249
1250 strncpy(&output_header_search[0], header_expect,
1251 sizeof(output_header_search));
1252
1253 if (output_header_search[sizeof(output_header_search) - 1] != '\0') {
1254 bcopy("...",
1255 &output_header_search[sizeof(output_header_search) - 4],
1256 4);
1260 } 1257 }
1261 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); 1258
1259 xasprintf (&msg,
1260 _("%sheader '%s' not found on '%s://%s:%d%s', "),
1261 msg,
1262 output_header_search, use_ssl ? "https" : "http",
1263 host_name ? host_name : server_address, server_port,
1264 server_url);
1265
1262 result = STATE_CRITICAL; 1266 result = STATE_CRITICAL;
1263 } 1267 }
1264 } 1268 }
1265 1269
1270 // At this point we should test if the content is chunked and unchunk it, so
1271 // it can be searched (and possibly printed)
1272 const char *chunked_header_regex_string = "Transfer-Encoding: *chunked *";
1273 regex_t chunked_header_regex;
1266 1274
1267 if (strlen (string_expect)) { 1275 if (regcomp(&chunked_header_regex, chunked_header_regex_string, REG_ICASE)) {
1268 if (!strstr (page, string_expect)) { 1276 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to compile chunked_header_regex regex");
1269 strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); 1277 }
1270 if(output_string_search[sizeof(output_string_search)-1]!='\0') { 1278
1271 bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); 1279 regmatch_t chre_pmatch[1]; // We actually do not care about this, since we only want to know IF it was found
1280
1281 if (regexec(&chunked_header_regex, header, 1, chre_pmatch, 0) == 0) {
1282 if (verbose) {
1283 printf("Found chunked content\n");
1284 }
1285 // We actually found the chunked header
1286 char *tmp = unchunk_content(page);
1287 if (tmp == NULL) {
1288 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to unchunk message body");
1289 }
1290 page = tmp;
1291 }
1292
1293 if (strlen(string_expect) > 0) {
1294 if (!strstr(page, string_expect)) {
1295 // We found the string the body, the rest is for building the output
1296 char output_string_search[30] = "";
1297 strncpy(&output_string_search[0], string_expect,
1298 sizeof(output_string_search));
1299 if (output_string_search[sizeof(output_string_search) - 1] != '\0') {
1300 bcopy("...", &output_string_search[sizeof(output_string_search) - 4],
1301 4);
1272 } 1302 }
1273 xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1303 xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url);
1274 result = STATE_CRITICAL; 1304 result = STATE_CRITICAL;
1275 } 1305 }
1276 } 1306 }
1277 1307
1278 if (strlen (regexp)) { 1308 if (strlen(regexp) > 0) {
1279 errcode = regexec (&preg, page, REGS, pmatch, 0); 1309 errcode = regexec(&preg, page, REGS, pmatch, 0);
1280 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1310 if ((errcode == 0 && invert_regex == 0) ||
1311 (errcode == REG_NOMATCH && invert_regex == 1)) {
1281 /* OK - No-op to avoid changing the logic around it */ 1312 /* OK - No-op to avoid changing the logic around it */
1282 result = max_state_alt(STATE_OK, result); 1313 result = max_state_alt(STATE_OK, result);
1283 } 1314 }
@@ -1329,7 +1360,7 @@ check_http (void)
1329 perfd_time (elapsed_time), 1360 perfd_time (elapsed_time),
1330 perfd_size (page_len), 1361 perfd_size (page_len),
1331 perfd_time_connect (elapsed_time_connect), 1362 perfd_time_connect (elapsed_time_connect),
1332 use_ssl == TRUE ? perfd_time_ssl (elapsed_time_ssl) : "", 1363 use_ssl == true ? perfd_time_ssl (elapsed_time_ssl) : "",
1333 perfd_time_headers (elapsed_time_headers), 1364 perfd_time_headers (elapsed_time_headers),
1334 perfd_time_firstbyte (elapsed_time_firstbyte), 1365 perfd_time_firstbyte (elapsed_time_firstbyte),
1335 perfd_time_transfer (elapsed_time_transfer)); 1366 perfd_time_transfer (elapsed_time_transfer));
@@ -1351,7 +1382,95 @@ check_http (void)
1351 return STATE_UNKNOWN; 1382 return STATE_UNKNOWN;
1352} 1383}
1353 1384
1385/* Receivces a pointer to the beginning of the body of a HTTP message
1386 * which is chunked and returns a pointer to a freshly allocated memory
1387 * region containing the unchunked body or NULL if something failed.
1388 * The result must be freed by the caller.
1389 */
1390char *unchunk_content(const char *content) {
1391 // https://en.wikipedia.org/wiki/Chunked_transfer_encoding
1392 // https://www.rfc-editor.org/rfc/rfc7230#section-4.1
1393 char *result = NULL;
1394 size_t content_length = strlen(content);
1395 char *start_of_chunk;
1396 char* end_of_chunk;
1397 long size_of_chunk;
1398 const char *pointer = content;
1399 char *endptr;
1400 long length_of_chunk = 0;
1401 size_t overall_size = 0;
1402
1403 while (true) {
1404 size_of_chunk = strtol(pointer, &endptr, 16);
1405 if (size_of_chunk == LONG_MIN || size_of_chunk == LONG_MAX) {
1406 // Apparently underflow or overflow, should not happen
1407 if (verbose) {
1408 printf("Got an underflow or overflow from strtol at: %u\n", __LINE__);
1409 }
1410 return NULL;
1411 }
1412 if (endptr == pointer) {
1413 // Apparently this was not a number
1414 if (verbose) {
1415 printf("Chunked content did not start with a number at all (Line: %u)\n", __LINE__);
1416 }
1417 return NULL;
1418 }
1419
1420 // So, we got the length of the chunk
1421 if (*endptr == ';') {
1422 // Chunk extension starts here
1423 while (*endptr != '\r') {
1424 endptr++;
1425 }
1426 }
1427
1428 start_of_chunk = endptr + 2;
1429 end_of_chunk = start_of_chunk + size_of_chunk;
1430 length_of_chunk = (long)(end_of_chunk - start_of_chunk);
1431 pointer = end_of_chunk + 2; //Next number should be here
1432
1433 if (length_of_chunk == 0) {
1434 // Chunk length is 0, so this is the last one
1435 break;
1436 }
1437
1438 overall_size += length_of_chunk;
1439
1440 if (result == NULL) {
1441 // Size of the chunk plus the ending NULL byte
1442 result = (char *)malloc(length_of_chunk +1);
1443 if (result == NULL) {
1444 if (verbose) {
1445 printf("Failed to allocate memory for unchunked body\n");
1446 }
1447 return NULL;
1448 }
1449 } else {
1450 // Enlarge memory to the new size plus the ending NULL byte
1451 void *tmp = realloc(result, overall_size +1);
1452 if (tmp == NULL) {
1453 if (verbose) {
1454 printf("Failed to allocate memory for unchunked body\n");
1455 }
1456 return NULL;
1457 } else {
1458 result = tmp;
1459 }
1460 }
1354 1461
1462 memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk);
1463 }
1464
1465 if (overall_size == 0 && result == NULL) {
1466 // We might just have received the end chunk without previous content, so result is never allocated
1467 result = calloc(1, sizeof(char));
1468 // No error handling here, we can only return NULL anyway
1469 } else {
1470 result[overall_size] = '\0';
1471 }
1472 return result;
1473}
1355 1474
1356/* per RFC 2396 */ 1475/* per RFC 2396 */
1357#define URI_HTTP "%5[HTPShtps]" 1476#define URI_HTTP "%5[HTPShtps]"
@@ -1524,13 +1643,13 @@ redir (char *pos, char *status_line)
1524} 1643}
1525 1644
1526 1645
1527int 1646bool
1528server_type_check (const char *type) 1647server_type_check (const char *type)
1529{ 1648{
1530 if (strcmp (type, "https")) 1649 if (strcmp (type, "https"))
1531 return FALSE; 1650 return false;
1532 else 1651 else
1533 return TRUE; 1652 return true;
1534} 1653}
1535 1654
1536int 1655int
@@ -1545,42 +1664,42 @@ server_port_check (int ssl_flag)
1545char *perfd_time (double elapsed_time) 1664char *perfd_time (double elapsed_time)
1546{ 1665{
1547 return fperfdata ("time", elapsed_time, "s", 1666 return fperfdata ("time", elapsed_time, "s",
1548 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1667 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1549 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1668 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1550 TRUE, 0, TRUE, socket_timeout); 1669 true, 0, true, socket_timeout);
1551} 1670}
1552 1671
1553char *perfd_time_connect (double elapsed_time_connect) 1672char *perfd_time_connect (double elapsed_time_connect)
1554{ 1673{
1555 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1674 return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1556} 1675}
1557 1676
1558char *perfd_time_ssl (double elapsed_time_ssl) 1677char *perfd_time_ssl (double elapsed_time_ssl)
1559{ 1678{
1560 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1679 return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1561} 1680}
1562 1681
1563char *perfd_time_headers (double elapsed_time_headers) 1682char *perfd_time_headers (double elapsed_time_headers)
1564{ 1683{
1565 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1684 return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1566} 1685}
1567 1686
1568char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1687char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1569{ 1688{
1570 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1689 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1571} 1690}
1572 1691
1573char *perfd_time_transfer (double elapsed_time_transfer) 1692char *perfd_time_transfer (double elapsed_time_transfer)
1574{ 1693{
1575 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1694 return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1576} 1695}
1577 1696
1578char *perfd_size (int page_len) 1697char *perfd_size (int page_len)
1579{ 1698{
1580 return perfdata ("size", page_len, "B", 1699 return perfdata ("size", page_len, "B",
1581 (min_page_len>0?TRUE:FALSE), min_page_len, 1700 (min_page_len>0?true:false), min_page_len,
1582 (min_page_len>0?TRUE:FALSE), 0, 1701 (min_page_len>0?true:false), 0,
1583 TRUE, 0, FALSE, 0); 1702 true, 0, false, 0);
1584} 1703}
1585 1704
1586void 1705void
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index a025ee89..d672dd44 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -70,6 +70,7 @@ int options = 0; /* bitmask of filter criteria to test against */
70#define PCPU 256 70#define PCPU 256
71#define ELAPSED 512 71#define ELAPSED 512
72#define EREG_ARGS 1024 72#define EREG_ARGS 1024
73#define EXCLUDE_PROGS 2048
73 74
74#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: 75#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
75 ppid of procs are compared to pid of this proc*/ 76 ppid of procs are compared to pid of this proc*/
@@ -93,6 +94,9 @@ int rss;
93float pcpu; 94float pcpu;
94char *statopts; 95char *statopts;
95char *prog; 96char *prog;
97char *exclude_progs;
98char **exclude_progs_arr = NULL;
99char exclude_progs_counter = 0;
96char *args; 100char *args;
97char *input_filename = NULL; 101char *input_filename = NULL;
98regex_t re_args; 102regex_t re_args;
@@ -250,6 +254,25 @@ main (int argc, char **argv)
250 continue; 254 continue;
251 } 255 }
252 256
257 /* Ignore excluded processes by name */
258 if(options & EXCLUDE_PROGS) {
259 int found = 0;
260 int i = 0;
261
262 for(i=0; i < (exclude_progs_counter); i++) {
263 if(!strcmp(procprog, exclude_progs_arr[i])) {
264 found = 1;
265 }
266 }
267 if(found == 0) {
268 resultsum |= EXCLUDE_PROGS;
269 } else
270 {
271 if(verbose >= 3)
272 printf("excluding - by ignorelist\n");
273 }
274 }
275
253 /* filter kernel threads (childs of KTHREAD_PARENT)*/ 276 /* filter kernel threads (childs of KTHREAD_PARENT)*/
254 /* TODO adapt for other OSes than GNU/Linux 277 /* TODO adapt for other OSes than GNU/Linux
255 sorry for not doing that, but I've no other OSes to test :-( */ 278 sorry for not doing that, but I've no other OSes to test :-( */
@@ -409,6 +432,7 @@ process_arguments (int argc, char **argv)
409 {"input-file", required_argument, 0, CHAR_MAX+2}, 432 {"input-file", required_argument, 0, CHAR_MAX+2},
410 {"no-kthreads", required_argument, 0, 'k'}, 433 {"no-kthreads", required_argument, 0, 'k'},
411 {"traditional-filter", no_argument, 0, 'T'}, 434 {"traditional-filter", no_argument, 0, 'T'},
435 {"exclude-process", required_argument, 0, 'X'},
412 {0, 0, 0, 0} 436 {0, 0, 0, 0}
413 }; 437 };
414 438
@@ -417,7 +441,7 @@ process_arguments (int argc, char **argv)
417 strcpy (argv[c], "-t"); 441 strcpy (argv[c], "-t");
418 442
419 while (1) { 443 while (1) {
420 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T", 444 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:",
421 longopts, &option); 445 longopts, &option);
422 446
423 if (c == -1 || c == EOF) 447 if (c == -1 || c == EOF)
@@ -490,6 +514,23 @@ process_arguments (int argc, char **argv)
490 prog); 514 prog);
491 options |= PROG; 515 options |= PROG;
492 break; 516 break;
517 case 'X':
518 if(exclude_progs)
519 break;
520 else
521 exclude_progs = optarg;
522 xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
523 exclude_progs);
524 char *p = strtok(exclude_progs, ",");
525
526 while(p){
527 exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter);
528 exclude_progs_arr[exclude_progs_counter-1] = p;
529 p = strtok(NULL, ",");
530 }
531
532 options |= EXCLUDE_PROGS;
533 break;
493 case 'a': /* args (full path name with args) */ 534 case 'a': /* args (full path name with args) */
494 /* TODO: allow this to be passed in with --metric */ 535 /* TODO: allow this to be passed in with --metric */
495 if (args) 536 if (args)
@@ -745,6 +786,8 @@ print_help (void)
745 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); 786 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
746 printf (" %s\n", "-C, --command=COMMAND"); 787 printf (" %s\n", "-C, --command=COMMAND");
747 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); 788 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
789 printf (" %s\n", "-X, --exclude-process");
790 printf (" %s\n", _("Exclude processes which match this comma seperated list"));
748 printf (" %s\n", "-k, --no-kthreads"); 791 printf (" %s\n", "-k, --no-kthreads");
749 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); 792 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
750 793
@@ -786,5 +829,5 @@ print_usage (void)
786 printf ("%s\n", _("Usage:")); 829 printf ("%s\n", _("Usage:"));
787 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); 830 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
788 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); 831 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
789 printf (" [-C command] [-k] [-t timeout] [-v]\n"); 832 printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
790} 833}
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index be1001b4..96a95553 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -155,7 +155,11 @@ main (int argc, char **argv)
155{ 155{
156 struct sockaddr_storage ss; 156 struct sockaddr_storage ss;
157 char name[HOST_NAME_MAX]; 157 char name[HOST_NAME_MAX];
158#ifdef RC_BUFFER_LEN
159 char msg[RC_BUFFER_LEN];
160#else
158 char msg[BUFFER_LEN]; 161 char msg[BUFFER_LEN];
162#endif
159 SEND_DATA data; 163 SEND_DATA data;
160 int result = STATE_UNKNOWN; 164 int result = STATE_UNKNOWN;
161 uint32_t client_id, service; 165 uint32_t client_id, service;
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 2601ccd8..d3968a27 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -1,31 +1,31 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_snmp plugin 3* Monitoring check_snmp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2007 Monitoring Plugins Development Team 6* Copyright (c) 1999-2007 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_snmp plugin 10* This file contains the check_snmp plugin
11* 11*
12* Check status of remote machines and obtain system information via SNMP 12* Check status of remote machines and obtain system information via SNMP
13* 13*
14* 14*
15* This program is free software: you can redistribute it and/or modify 15* This program is free software: you can redistribute it and/or modify
16* it under the terms of the GNU General Public License as published by 16* it under the terms of the GNU General Public License as published by
17* the Free Software Foundation, either version 3 of the License, or 17* the Free Software Foundation, either version 3 of the License, or
18* (at your option) any later version. 18* (at your option) any later version.
19* 19*
20* This program is distributed in the hope that it will be useful, 20* This program is distributed in the hope that it will be useful,
21* but WITHOUT ANY WARRANTY; without even the implied warranty of 21* but WITHOUT ANY WARRANTY; without even the implied warranty of
22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23* GNU General Public License for more details. 23* GNU General Public License for more details.
24* 24*
25* You should have received a copy of the GNU General Public License 25* You should have received a copy of the GNU General Public License
26* along with this program. If not, see <http://www.gnu.org/licenses/>. 26* along with this program. If not, see <http://www.gnu.org/licenses/>.
27* 27*
28* 28*
29*****************************************************************************/ 29*****************************************************************************/
30 30
31const char *progname = "check_snmp"; 31const char *progname = "check_snmp";
@@ -90,6 +90,7 @@ char *thisarg (char *str);
90char *nextarg (char *str); 90char *nextarg (char *str);
91void print_usage (void); 91void print_usage (void);
92void print_help (void); 92void print_help (void);
93char *multiply (char *str);
93 94
94#include "regex.h" 95#include "regex.h"
95char regex_expect[MAX_INPUT_BUFFER] = ""; 96char regex_expect[MAX_INPUT_BUFFER] = "";
@@ -154,6 +155,8 @@ double *previous_value;
154size_t previous_size = OID_COUNT_STEP; 155size_t previous_size = OID_COUNT_STEP;
155int perf_labels = 1; 156int perf_labels = 1;
156char* ip_version = ""; 157char* ip_version = "";
158double multiplier = 1.0;
159char *fmtstr = "";
157 160
158static char *fix_snmp_range(char *th) 161static char *fix_snmp_range(char *th)
159{ 162{
@@ -316,7 +319,7 @@ main (int argc, char **argv)
316 for (i = 0; i < numcontext; i++) { 319 for (i = 0; i < numcontext; i++) {
317 command_line[10 + i] = contextargs[i]; 320 command_line[10 + i] = contextargs[i];
318 } 321 }
319 322
320 for (i = 0; i < numauthpriv; i++) { 323 for (i = 0; i < numauthpriv; i++) {
321 command_line[10 + numcontext + i] = authpriv[i]; 324 command_line[10 + numcontext + i] = authpriv[i];
322 } 325 }
@@ -330,7 +333,7 @@ main (int argc, char **argv)
330 333
331 for (i = 0; i < numoids; i++) { 334 for (i = 0; i < numoids; i++) {
332 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i]; 335 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i];
333 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); 336 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
334 } 337 }
335 338
336 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL; 339 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL;
@@ -398,15 +401,15 @@ main (int argc, char **argv)
398 is_counter=0; 401 is_counter=0;
399 /* We strip out the datatype indicator for PHBs */ 402 /* We strip out the datatype indicator for PHBs */
400 if (strstr (response, "Gauge: ")) { 403 if (strstr (response, "Gauge: ")) {
401 show = strstr (response, "Gauge: ") + 7; 404 show = multiply (strstr (response, "Gauge: ") + 7);
402 } 405 }
403 else if (strstr (response, "Gauge32: ")) { 406 else if (strstr (response, "Gauge32: ")) {
404 show = strstr (response, "Gauge32: ") + 9; 407 show = multiply (strstr (response, "Gauge32: ") + 9);
405 } 408 }
406 else if (strstr (response, "Counter32: ")) { 409 else if (strstr (response, "Counter32: ")) {
407 show = strstr (response, "Counter32: ") + 11; 410 show = strstr (response, "Counter32: ") + 11;
408 is_counter=1; 411 is_counter=1;
409 if(!calculate_rate) 412 if(!calculate_rate)
410 strcpy(type, "c"); 413 strcpy(type, "c");
411 } 414 }
412 else if (strstr (response, "Counter64: ")) { 415 else if (strstr (response, "Counter64: ")) {
@@ -416,7 +419,10 @@ main (int argc, char **argv)
416 strcpy(type, "c"); 419 strcpy(type, "c");
417 } 420 }
418 else if (strstr (response, "INTEGER: ")) { 421 else if (strstr (response, "INTEGER: ")) {
419 show = strstr (response, "INTEGER: ") + 9; 422 show = multiply (strstr (response, "INTEGER: ") + 9);
423 if (fmtstr != "") {
424 conv = fmtstr;
425 }
420 } 426 }
421 else if (strstr (response, "OID: ")) { 427 else if (strstr (response, "OID: ")) {
422 show = strstr (response, "OID: ") + 5; 428 show = strstr (response, "OID: ") + 5;
@@ -616,7 +622,7 @@ main (int argc, char **argv)
616 state_string=malloc(string_length); 622 state_string=malloc(string_length);
617 if(state_string==NULL) 623 if(state_string==NULL)
618 die(STATE_UNKNOWN, _("Cannot malloc")); 624 die(STATE_UNKNOWN, _("Cannot malloc"));
619 625
620 current_length=0; 626 current_length=0;
621 for(i=0; i<total_oids; i++) { 627 for(i=0; i<total_oids; i++) {
622 xasprintf(&temp_string,"%.0f",response_value[i]); 628 xasprintf(&temp_string,"%.0f",response_value[i]);
@@ -638,7 +644,7 @@ main (int argc, char **argv)
638 state_string[--current_length]='\0'; 644 state_string[--current_length]='\0';
639 if (verbose > 2) 645 if (verbose > 2)
640 printf("State string=%s\n",state_string); 646 printf("State string=%s\n",state_string);
641 647
642 /* This is not strictly the same as time now, but any subtle variations will cancel out */ 648 /* This is not strictly the same as time now, but any subtle variations will cancel out */
643 np_state_write_string(current_time, state_string ); 649 np_state_write_string(current_time, state_string );
644 if(previous_state==NULL) { 650 if(previous_state==NULL) {
@@ -698,6 +704,8 @@ process_arguments (int argc, char **argv)
698 {"perf-oids", no_argument, 0, 'O'}, 704 {"perf-oids", no_argument, 0, 'O'},
699 {"ipv4", no_argument, 0, '4'}, 705 {"ipv4", no_argument, 0, '4'},
700 {"ipv6", no_argument, 0, '6'}, 706 {"ipv6", no_argument, 0, '6'},
707 {"multiplier", required_argument, 0, 'M'},
708 {"fmtstr", required_argument, 0, 'f'},
701 {0, 0, 0, 0} 709 {0, 0, 0, 0}
702 }; 710 };
703 711
@@ -715,7 +723,7 @@ process_arguments (int argc, char **argv)
715 } 723 }
716 724
717 while (1) { 725 while (1) {
718 c = getopt_long (argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:z:", 726 c = getopt_long (argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:M:f:z:",
719 longopts, &option); 727 longopts, &option);
720 728
721 if (c == -1 || c == EOF) 729 if (c == -1 || c == EOF)
@@ -953,6 +961,16 @@ process_arguments (int argc, char **argv)
953 if(verbose>2) 961 if(verbose>2)
954 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n"); 962 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n");
955 break; 963 break;
964 case 'M':
965 if ( strspn( optarg, "0123456789.," ) == strlen( optarg ) ) {
966 multiplier=strtod(optarg,NULL);
967 }
968 break;
969 case 'f':
970 if (multiplier != 1.0) {
971 fmtstr=optarg;
972 }
973 break;
956 } 974 }
957 } 975 }
958 976
@@ -1022,7 +1040,7 @@ validate_arguments ()
1022 contextargs[0] = strdup ("-n"); 1040 contextargs[0] = strdup ("-n");
1023 contextargs[1] = strdup (context); 1041 contextargs[1] = strdup (context);
1024 } 1042 }
1025 1043
1026 if (seclevel == NULL) 1044 if (seclevel == NULL)
1027 xasprintf(&seclevel, "noAuthNoPriv"); 1045 xasprintf(&seclevel, "noAuthNoPriv");
1028 1046
@@ -1143,6 +1161,44 @@ nextarg (char *str)
1143 1161
1144 1162
1145 1163
1164/* multiply result (values 0 < n < 1 work as divider) */
1165char *
1166multiply (char *str)
1167{
1168 char *endptr;
1169 double val;
1170 char *conv = "%f";
1171
1172 if(verbose>2)
1173 printf(" multiply input: %s\n", str);
1174
1175 val = strtod (str, &endptr);
1176 if ((val == 0.0) && (endptr == str)) {
1177 if(multiplier != 1) {
1178 die(STATE_UNKNOWN, _("multiplier set (%.1f), but input is not a number: %s"), multiplier, str);
1179 }
1180 return str;
1181 }
1182
1183 if(verbose>2)
1184 printf(" multiply extracted double: %f\n", val);
1185 val *= multiplier;
1186 if (fmtstr != "") {
1187 conv = fmtstr;
1188 }
1189 if (val == (int)val) {
1190 sprintf(str, "%.0f", val);
1191 } else {
1192 if(verbose>2)
1193 printf(" multiply using format: %s\n", conv);
1194 sprintf(str, conv, val);
1195 }
1196 if(verbose>2)
1197 printf(" multiply result: %s\n", str);
1198 return str;
1199}
1200
1201
1146void 1202void
1147print_help (void) 1203print_help (void)
1148{ 1204{
@@ -1235,6 +1291,10 @@ print_help (void)
1235 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.').")); 1291 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.')."));
1236 printf (" %s\n", "-D, --output-delimiter=STRING"); 1292 printf (" %s\n", "-D, --output-delimiter=STRING");
1237 printf (" %s\n", _("Separates output on multiple OID requests")); 1293 printf (" %s\n", _("Separates output on multiple OID requests"));
1294 printf (" %s\n", "-M, --multiplier=FLOAT");
1295 printf (" %s\n", _("Multiplies current value, 0 < n < 1 works as divider, defaults to 1"));
1296 printf (" %s\n", "-f, --fmtstr=STRING");
1297 printf (" %s\n", _("C-style format string for float values (see option -M)"));
1238 1298
1239 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1299 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
1240 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5")); 1300 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5"));
@@ -1287,4 +1347,5 @@ print_usage (void)
1287 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n"); 1347 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");
1288 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n"); 1348 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n");
1289 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n"); 1349 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n");
1350 printf ("[-M multiplier [-f format]]\n");
1290} 1351}
diff --git a/plugins/check_swap.c b/plugins/check_swap.c
index a607da1e..25d5f21d 100644
--- a/plugins/check_swap.c
+++ b/plugins/check_swap.c
@@ -34,9 +34,6 @@ const char *email = "devel@monitoring-plugins.org";
34#include "common.h" 34#include "common.h"
35#include "popen.h" 35#include "popen.h"
36#include "utils.h" 36#include "utils.h"
37#include <string.h>
38#include <math.h>
39#include <libintl.h>
40 37
41#ifdef HAVE_DECL_SWAPCTL 38#ifdef HAVE_DECL_SWAPCTL
42# ifdef HAVE_SYS_PARAM_H 39# ifdef HAVE_SYS_PARAM_H
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index 286273f6..666a0120 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -134,7 +134,16 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
134 return STATE_CRITICAL; 134 return STATE_CRITICAL;
135 } 135 }
136 if (cert && privkey) { 136 if (cert && privkey) {
137 SSL_CTX_use_certificate_chain_file(c, cert); 137#ifdef USE_OPENSSL
138 if (!SSL_CTX_use_certificate_chain_file(c, cert)) {
139#elif USE_GNUTLS
140 if (!SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM)) {
141#else
142#error Unported for unknown SSL library
143#endif
144 printf ("%s\n", _("CRITICAL - Unable to open certificate chain file!\n"));
145 return STATE_CRITICAL;
146 }
138 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); 147 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
139#ifdef USE_OPENSSL 148#ifdef USE_OPENSSL
140 if (!SSL_CTX_check_private_key(c)) { 149 if (!SSL_CTX_check_private_key(c)) {
@@ -191,17 +200,6 @@ int np_net_ssl_read(void *buf, int num) {
191 return SSL_read(s, buf, num); 200 return SSL_read(s, buf, num);
192} 201}
193 202
194int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
195# ifdef USE_OPENSSL
196 X509 *certificate = NULL;
197 certificate=SSL_get_peer_certificate(s);
198 return(np_net_ssl_check_certificate(certificate, days_till_exp_warn, days_till_exp_crit));
199# else /* ifndef USE_OPENSSL */
200 printf("%s\n", _("WARNING - Plugin does not support checking certificates."));
201 return STATE_WARNING;
202# endif /* USE_OPENSSL */
203}
204
205int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit){ 203int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit){
206# ifdef USE_OPENSSL 204# ifdef USE_OPENSSL
207 X509_NAME *subj=NULL; 205 X509_NAME *subj=NULL;
@@ -328,4 +326,16 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int
328# endif /* USE_OPENSSL */ 326# endif /* USE_OPENSSL */
329} 327}
330 328
329int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
330# ifdef USE_OPENSSL
331 X509 *certificate = NULL;
332 certificate=SSL_get_peer_certificate(s);
333 return(np_net_ssl_check_certificate(certificate, days_till_exp_warn, days_till_exp_crit));
334# else /* ifndef USE_OPENSSL */
335 printf("%s\n", _("WARNING - Plugin does not support checking certificates."));
336 return STATE_WARNING;
337# endif /* USE_OPENSSL */
338}
339
340
331#endif /* HAVE_SSL */ 341#endif /* HAVE_SSL */
diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t
index ec527e7f..c8f08f51 100644
--- a/plugins/t/check_disk.t
+++ b/plugins/t/check_disk.t
@@ -23,7 +23,7 @@ my $mountpoint2_valid = getTestParameter( "NP_MOUNTPOINT2_VALID", "Path to anoth
23if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { 23if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") {
24 plan skip_all => "Need 2 mountpoints to test"; 24 plan skip_all => "Need 2 mountpoints to test";
25} else { 25} else {
26 plan tests => 78; 26 plan tests => 88;
27} 27}
28 28
29$result = NPTest->testCmd( 29$result = NPTest->testCmd(
@@ -351,3 +351,28 @@ unlike( $result->output, qr/$mountpoint2_valid/, "output data does not have $mou
351$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '^barbazJodsf\$'"); 351$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '^barbazJodsf\$'");
352like( $result->output, qr/$mountpoint_valid/, "ignore: output data does have $mountpoint_valid when regex doesn't match"); 352like( $result->output, qr/$mountpoint_valid/, "ignore: output data does have $mountpoint_valid when regex doesn't match");
353like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mountpoint2_valid when regex doesn't match"); 353like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mountpoint2_valid when regex doesn't match");
354
355# ignore-missing: exit okay, when fs is not accessible
356$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p /bob");
357cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for not existing filesystem /bob");
358like( $result->output, '/^DISK OK - No disks were found for provided parameters; - ignored paths: /bob;.*$/', 'Output OK');
359
360# ignore-missing: exit okay, when regex does not match
361$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r /bob");
362cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching");
363like( $result->output, '/^DISK OK - No disks were found for provided parameters;.*$/', 'Output OK');
364
365# ignore-missing: exit okay, when fs with exact match (-E) is not found
366$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -E -p /etc");
367cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay when exact match does not find fs");
368like( $result->output, '/^DISK OK - No disks were found for provided parameters; - ignored paths: /etc;.*$/', 'Output OK');
369
370# ignore-missing: exit okay, when checking one existing fs and one non-existing fs (regex)
371$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r '/bob' -r '^/\$'");
372cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching");
373like( $result->output, '/^DISK OK - free space: \/ .*$/', 'Output OK');
374
375# ignore-missing: exit okay, when checking one existing fs and one non-existing fs (path)
376$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p '/bob' -p '/'");
377cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching");
378like( $result->output, '/^DISK OK - free space: / .*; - ignored paths: /bob;.*$/', 'Output OK'); \ No newline at end of file
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index 0c866229..1ca52f61 100644
--- a/plugins/t/check_http.t
+++ b/plugins/t/check_http.t
@@ -103,7 +103,7 @@ SKIP: {
103 cmp_ok( $res->return_code, "==", 0, "And also when not found"); 103 cmp_ok( $res->return_code, "==", 0, "And also when not found");
104} 104}
105SKIP: { 105SKIP: {
106 skip "No internet access", 23 if $internet_access eq "no"; 106 skip "No internet access", 22 if $internet_access eq "no";
107 107
108 $res = NPTest->testCmd( 108 $res = NPTest->testCmd(
109 "./$plugin --ssl $host_tls_http" 109 "./$plugin --ssl $host_tls_http"
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t
index aa72ef67..72f2b7c2 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -21,7 +21,7 @@ use FindBin qw($Bin);
21 21
22$ENV{'LC_TIME'} = "C"; 22$ENV{'LC_TIME'} = "C";
23 23
24my $common_tests = 72; 24my $common_tests = 73;
25my $ssl_only_tests = 8; 25my $ssl_only_tests = 8;
26# Check that all dependent modules are available 26# Check that all dependent modules are available
27eval "use HTTP::Daemon 6.01;"; 27eval "use HTTP::Daemon 6.01;";
@@ -200,6 +200,14 @@ sub run_server {
200 $c->send_basic_header; 200 $c->send_basic_header;
201 $c->send_crlf; 201 $c->send_crlf;
202 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host'))); 202 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
203 } elsif ($r->url->path eq "/chunked") {
204 my $chunks = ["chunked", "encoding", "test\n"];
205 $c->send_response(HTTP::Response->new( 200, 'OK', undef, sub {
206 my $chunk = shift @{$chunks};
207 return unless $chunk;
208 sleep(1);
209 return($chunk);
210 }));
203 } else { 211 } else {
204 $c->send_error(HTTP::Status->RC_FORBIDDEN); 212 $c->send_error(HTTP::Status->RC_FORBIDDEN);
205 } 213 }
@@ -472,7 +480,8 @@ sub run_common_tests {
472 local $SIG{ALRM} = sub { die "alarm\n" }; 480 local $SIG{ALRM} = sub { die "alarm\n" };
473 alarm(2); 481 alarm(2);
474 $result = NPTest->testCmd( $cmd ); 482 $result = NPTest->testCmd( $cmd );
475 alarm(0); }; 483 };
484 alarm(0);
476 isnt( $@, "alarm\n", $cmd ); 485 isnt( $@, "alarm\n", $cmd );
477 is( $result->return_code, 0, $cmd ); 486 is( $result->return_code, 0, $cmd );
478 487
@@ -482,7 +491,8 @@ sub run_common_tests {
482 local $SIG{ALRM} = sub { die "alarm\n" }; 491 local $SIG{ALRM} = sub { die "alarm\n" };
483 alarm(2); 492 alarm(2);
484 $result = NPTest->testCmd( $cmd ); 493 $result = NPTest->testCmd( $cmd );
485 alarm(0); }; 494 };
495 alarm(0);
486 isnt( $@, "alarm\n", $cmd ); 496 isnt( $@, "alarm\n", $cmd );
487 isnt( $result->return_code, 0, $cmd ); 497 isnt( $result->return_code, 0, $cmd );
488 498
@@ -508,4 +518,9 @@ sub run_common_tests {
508 }; 518 };
509 is( $@, "", $cmd ); 519 is( $@, "", $cmd );
510 520
521 $cmd = "$command -u /chunked -s 'chunkedencodingtest' -d 'Transfer-Encoding: chunked'";
522 eval {
523 $result = NPTest->testCmd( $cmd, 5 );
524 };
525 is( $@, "", $cmd );
511} 526}
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index ea11b2ac..6078b274 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -9,12 +9,14 @@ use strict;
9use Test::More; 9use Test::More;
10use NPTest; 10use NPTest;
11use FindBin qw($Bin); 11use FindBin qw($Bin);
12use IO::Socket::INET;
12 13
13$ENV{'LC_TIME'} = "C"; 14$ENV{'LC_TIME'} = "C";
14 15
15my $common_tests = 70; 16my $common_tests = 71;
16my $virtual_port_tests = 8; 17my $virtual_port_tests = 8;
17my $ssl_only_tests = 12; 18my $ssl_only_tests = 12;
19my $chunked_encoding_special_tests = 1;
18# Check that all dependent modules are available 20# Check that all dependent modules are available
19eval "use HTTP::Daemon 6.01;"; 21eval "use HTTP::Daemon 6.01;";
20plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; 22plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@;
@@ -30,7 +32,7 @@ if ($@) {
30 plan skip_all => "Missing required module for test: $@"; 32 plan skip_all => "Missing required module for test: $@";
31} else { 33} else {
32 if (-x "./$plugin") { 34 if (-x "./$plugin") {
33 plan tests => $common_tests * 2 + $ssl_only_tests + $virtual_port_tests; 35 plan tests => $common_tests * 2 + $ssl_only_tests + $virtual_port_tests + $chunked_encoding_special_tests;
34 } else { 36 } else {
35 plan skip_all => "No $plugin compiled"; 37 plan skip_all => "No $plugin compiled";
36 } 38 }
@@ -51,6 +53,7 @@ my $port_http = 50000 + int(rand(1000));
51my $port_https = $port_http + 1; 53my $port_https = $port_http + 1;
52my $port_https_expired = $port_http + 2; 54my $port_https_expired = $port_http + 2;
53my $port_https_clientcert = $port_http + 3; 55my $port_https_clientcert = $port_http + 3;
56my $port_hacked_http = $port_http + 4;
54 57
55# This array keeps sockets around for implementing timeouts 58# This array keeps sockets around for implementing timeouts
56my @persist; 59my @persist;
@@ -72,6 +75,28 @@ if (!$pid) {
72} 75}
73push @pids, $pid; 76push @pids, $pid;
74 77
78# Fork the hacked HTTP server
79undef $pid;
80$pid = fork;
81defined $pid or die "Failed to fork";
82if (!$pid) {
83 # this is the fork
84 undef @pids;
85 my $socket = new IO::Socket::INET (
86 LocalHost => '0.0.0.0',
87 LocalPort => $port_hacked_http,
88 Proto => 'tcp',
89 Listen => 5,
90 Reuse => 1
91 );
92 die "cannot create socket $!n" unless $socket;
93 my $local_sock = $socket->sockport();
94 print "server waiting for client connection on port $local_sock\n";
95 run_hacked_http_server ( $socket );
96 die "hacked http server stopped";
97}
98push @pids, $pid;
99
75if (exists $servers->{https}) { 100if (exists $servers->{https}) {
76 # Fork a normal HTTPS server 101 # Fork a normal HTTPS server
77 $pid = fork; 102 $pid = fork;
@@ -190,6 +215,14 @@ sub run_server {
190 $c->send_basic_header; 215 $c->send_basic_header;
191 $c->send_crlf; 216 $c->send_crlf;
192 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host'))); 217 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
218 } elsif ($r->url->path eq "/chunked") {
219 my $chunks = ["chunked", "encoding", "test\n"];
220 $c->send_response(HTTP::Response->new( 200, 'OK', undef, sub {
221 my $chunk = shift @{$chunks};
222 return unless $chunk;
223 sleep(1);
224 return($chunk);
225 }));
193 } else { 226 } else {
194 $c->send_error(HTTP::Status->RC_FORBIDDEN); 227 $c->send_error(HTTP::Status->RC_FORBIDDEN);
195 } 228 }
@@ -199,6 +232,37 @@ sub run_server {
199 } 232 }
200} 233}
201 234
235sub run_hacked_http_server {
236 my $socket = shift;
237
238 # auto-flush on socket
239 $| = 1;
240
241
242 while(1)
243 {
244 # waiting for a new client connection
245 my $client_socket = $socket->accept();
246
247 # get information about a newly connected client
248 my $client_address = $client_socket->peerhost();
249 my $client_portn = $client_socket->peerport();
250 print "connection from $client_address:$client_portn";
251
252 # read up to 1024 characters from the connected client
253 my $data = "";
254 $client_socket->recv($data, 1024);
255 print "received data: $data";
256
257 # write response data to the connected client
258 $data = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n";
259 $client_socket->send($data);
260
261 # notify client that response has been sent
262 shutdown($client_socket, 1);
263 }
264}
265
202END { 266END {
203 foreach my $pid (@pids) { 267 foreach my $pid (@pids) {
204 if ($pid) { print "Killing $pid\n"; kill "INT", $pid } 268 if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
@@ -214,6 +278,7 @@ if ($ARGV[0] && $ARGV[0] eq "-d") {
214my $result; 278my $result;
215my $command = "./$plugin -H 127.0.0.1"; 279my $command = "./$plugin -H 127.0.0.1";
216 280
281run_chunked_encoding_special_test( {command => "$command -p $port_hacked_http"});
217run_common_tests( { command => "$command -p $port_http" } ); 282run_common_tests( { command => "$command -p $port_http" } );
218SKIP: { 283SKIP: {
219 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 284 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
@@ -497,4 +562,20 @@ sub run_common_tests {
497 }; 562 };
498 is( $@, "", $cmd ); 563 is( $@, "", $cmd );
499 564
565 $cmd = "$command -u /chunked -s 'chunkedencodingtest' -d 'Transfer-Encoding: chunked'";
566 eval {
567 $result = NPTest->testCmd( $cmd, 5 );
568 };
569 is( $@, "", $cmd );
570}
571
572sub run_chunked_encoding_special_test {
573 my ($opts) = @_;
574 my $command = $opts->{command};
575
576 $cmd = "$command -u / -s 'ChunkedEncodingSpecialTest'";
577 eval {
578 $result = NPTest->testCmd( $cmd, 5 );
579 };
580 is( $@, "", $cmd );
500} 581}
diff --git a/plugins/tests/check_procs.t b/plugins/tests/check_procs.t
index 3af218f5..b3a0a301 100755
--- a/plugins/tests/check_procs.t
+++ b/plugins/tests/check_procs.t
@@ -8,7 +8,7 @@ use Test::More;
8use NPTest; 8use NPTest;
9 9
10if (-x "./check_procs") { 10if (-x "./check_procs") {
11 plan tests => 52; 11 plan tests => 54;
12} else { 12} else {
13 plan skip_all => "No check_procs compiled"; 13 plan skip_all => "No check_procs compiled";
14} 14}
@@ -34,9 +34,13 @@ is( $result->return_code, 0, "Checking no threshold breeched" );
34is( $result->output, "PROCS OK: 95 processes | procs=95;100;200;0;", "Output correct" ); 34is( $result->output, "PROCS OK: 95 processes | procs=95;100;200;0;", "Output correct" );
35 35
36$result = NPTest->testCmd( "$command -C launchd -c 5" ); 36$result = NPTest->testCmd( "$command -C launchd -c 5" );
37is( $result->return_code, 2, "Checking processes filtered by command name" ); 37is( $result->return_code, 2, "Checking processes matched by command name" );
38is( $result->output, "PROCS CRITICAL: 6 processes with command name 'launchd' | procs=6;;5;0;", "Output correct" ); 38is( $result->output, "PROCS CRITICAL: 6 processes with command name 'launchd' | procs=6;;5;0;", "Output correct" );
39 39
40$result = NPTest->testCmd( "$command -X bash -c 5" );
41is( $result->return_code, 2, "Checking processes excluded by command name" );
42is( $result->output, "PROCS CRITICAL: 95 processes with exclude progs 'bash' | procs=95;;5;0;", "Output correct" );
43
40SKIP: { 44SKIP: {
41 skip 'user with uid 501 required', 4 unless getpwuid(501); 45 skip 'user with uid 501 required', 4 unless getpwuid(501);
42 46
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t
index 0a77fa8a..bc03ec60 100755
--- a/plugins/tests/check_snmp.t
+++ b/plugins/tests/check_snmp.t
@@ -9,7 +9,7 @@ use NPTest;
9use FindBin qw($Bin); 9use FindBin qw($Bin);
10use POSIX qw/strftime/; 10use POSIX qw/strftime/;
11 11
12my $tests = 73; 12my $tests = 81;
13# Check that all dependent modules are available 13# Check that all dependent modules are available
14eval { 14eval {
15 require NetSNMP::OID; 15 require NetSNMP::OID;
@@ -57,9 +57,9 @@ if ($pid) {
57 exec("snmpd -c tests/conf/snmpd.conf -C -f -r udp:$port_snmp"); 57 exec("snmpd -c tests/conf/snmpd.conf -C -f -r udp:$port_snmp");
58} 58}
59 59
60END { 60END {
61 foreach my $pid (@pids) { 61 foreach my $pid (@pids) {
62 if ($pid) { print "Killing $pid\n"; kill "INT", $pid } 62 if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
63 } 63 }
64}; 64};
65 65
@@ -268,3 +268,19 @@ like($res->output, '/SNMP WARNING - \d+ \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d
268$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" ); 268$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" );
269is($res->return_code, 2, "Multiple OIDs with some thresholds" ); 269is($res->return_code, 2, "Multiple OIDs with some thresholds" );
270like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" ); 270like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" );
271
272$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19");
273is($res->return_code, 0, "Test plain .1.3.6.1.4.1.8072.3.2.67.6 RC" );
274is($res->output,'SNMP OK - 42 | iso.3.6.1.4.1.8072.3.2.67.19=42 ', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" );
275
276$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 -M .1");
277is($res->return_code, 0, "Test multiply RC" );
278is($res->output,'SNMP OK - 4.200000 | iso.3.6.1.4.1.8072.3.2.67.19=4.200000 ' , "Test multiply .1 output" );
279
280$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' ");
281is($res->return_code, 0, "Test multiply RC + format" );
282is($res->output, 'SNMP OK - 4.20 | iso.3.6.1.4.1.8072.3.2.67.19=4.20 ', "Test multiply .1 output + format" );
283
284$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' -w 1");
285is($res->return_code, 1, "Test multiply RC + format + thresholds" );
286is($res->output, 'SNMP WARNING - *4.20* | iso.3.6.1.4.1.8072.3.2.67.19=4.20;1 ', "Test multiply .1 output + format + thresholds" );
diff --git a/plugins/tests/check_snmp_agent.pl b/plugins/tests/check_snmp_agent.pl
index 0e41d575..38912e98 100644
--- a/plugins/tests/check_snmp_agent.pl
+++ b/plugins/tests/check_snmp_agent.pl
@@ -32,11 +32,11 @@ my $multilin5 = 'And now have fun with with this: "C:\\"
32because we\'re not done yet!'; 32because we\'re not done yet!';
33 33
34# Next are arrays of indexes (Type, initial value and increments) 34# Next are arrays of indexes (Type, initial value and increments)
35# 0..16 <---- please update comment when adding/removing fields 35# 0..19 <---- please update comment when adding/removing fields
36my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR ); 36my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER );
37my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6' ); 37my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6', 42 );
38# undef increments are randomized 38# undef increments are randomized
39my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef ); 39my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef, 0 );
40 40
41# Number of elements in our OID 41# Number of elements in our OID
42my $oidelts; 42my $oidelts;