summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am3
-rw-r--r--plugins/check_by_ssh.c34
-rw-r--r--plugins/check_curl.c90
-rw-r--r--plugins/check_curl.d/check_curl_helpers.c34
-rw-r--r--plugins/check_curl.d/check_curl_helpers.h2
-rw-r--r--plugins/check_curl.d/config.h6
-rw-r--r--plugins/check_dbi.c4
-rw-r--r--plugins/check_disk.c10
-rw-r--r--plugins/check_http.c6
-rw-r--r--plugins/check_ide_smart.c259
-rw-r--r--plugins/check_ide_smart.d/config.h15
-rw-r--r--plugins/check_ldap.c12
-rw-r--r--plugins/check_mrtg.c8
-rw-r--r--plugins/check_mysql.c4
-rw-r--r--plugins/check_mysql_query.c4
-rw-r--r--plugins/check_ntp_peer.c20
-rw-r--r--plugins/check_ntp_time.c20
-rw-r--r--plugins/check_pgsql.c8
-rw-r--r--plugins/check_ping.c4
-rw-r--r--plugins/check_procs.c2
-rw-r--r--plugins/check_real.c318
-rw-r--r--plugins/check_real.d/config.h23
-rw-r--r--plugins/check_smtp.c21
-rw-r--r--plugins/check_snmp.d/check_snmp_helpers.c14
-rw-r--r--plugins/check_snmp.d/check_snmp_helpers.h4
-rw-r--r--plugins/check_ssh.c16
-rw-r--r--plugins/check_tcp.c16
-rw-r--r--plugins/check_time.c2
-rw-r--r--plugins/check_users.c4
-rw-r--r--plugins/netutils.c10
-rw-r--r--plugins/netutils.h4
-rw-r--r--plugins/t/check_disk.t15
-rwxr-xr-xplugins/tests/check_curl.t184
-rw-r--r--plugins/utils.c1
-rw-r--r--plugins/utils.h2
35 files changed, 774 insertions, 405 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index d098fa8a..a35f273e 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -66,6 +66,7 @@ EXTRA_DIST = t \
66 check_hpjd.d \ 66 check_hpjd.d \
67 check_game.d \ 67 check_game.d \
68 check_radius.d \ 68 check_radius.d \
69 check_ide_smart.d \
69 check_curl.d \ 70 check_curl.d \
70 check_disk.d \ 71 check_disk.d \
71 check_time.d \ 72 check_time.d \
@@ -164,7 +165,7 @@ check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS)
164check_real_LDADD = $(NETLIBS) 165check_real_LDADD = $(NETLIBS)
165check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c 166check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c
166check_snmp_LDADD = $(BASEOBJS) 167check_snmp_LDADD = $(BASEOBJS)
167check_snmp_LDFLAGS = $(AM_LDFLAGS) `net-snmp-config --libs` 168check_snmp_LDFLAGS = $(AM_LDFLAGS) -lm `net-snmp-config --libs`
168check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags` 169check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags`
169check_smtp_LDADD = $(SSLOBJS) 170check_smtp_LDADD = $(SSLOBJS)
170check_ssh_LDADD = $(NETLIBS) 171check_ssh_LDADD = $(NETLIBS)
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c
index df8907d9..7ffa0ded 100644
--- a/plugins/check_by_ssh.c
+++ b/plugins/check_by_ssh.c
@@ -98,7 +98,7 @@ int main(int argc, char **argv) {
98 if (child_result.cmd_error_code == 255 && config.unknown_timeout) { 98 if (child_result.cmd_error_code == 255 && config.unknown_timeout) {
99 mp_subcheck sc_ssh_execution = mp_subcheck_init(); 99 mp_subcheck sc_ssh_execution = mp_subcheck_init();
100 xasprintf(&sc_ssh_execution.output, "SSH connection failed: %s", 100 xasprintf(&sc_ssh_execution.output, "SSH connection failed: %s",
101 child_result.stderr.lines > 0 ? child_result.stderr.line[0] 101 child_result.err.lines > 0 ? child_result.err.line[0]
102 : "(no error output)"); 102 : "(no error output)");
103 103
104 sc_ssh_execution = mp_set_subcheck_state(sc_ssh_execution, STATE_UNKNOWN); 104 sc_ssh_execution = mp_set_subcheck_state(sc_ssh_execution, STATE_UNKNOWN);
@@ -107,34 +107,34 @@ int main(int argc, char **argv) {
107 } 107 }
108 108
109 if (verbose) { 109 if (verbose) {
110 for (size_t i = 0; i < child_result.stdout.lines; i++) { 110 for (size_t i = 0; i < child_result.out.lines; i++) {
111 printf("stdout: %s\n", child_result.stdout.line[i]); 111 printf("stdout: %s\n", child_result.out.line[i]);
112 } 112 }
113 for (size_t i = 0; i < child_result.stderr.lines; i++) { 113 for (size_t i = 0; i < child_result.err.lines; i++) {
114 printf("stderr: %s\n", child_result.stderr.line[i]); 114 printf("stderr: %s\n", child_result.err.line[i]);
115 } 115 }
116 } 116 }
117 117
118 size_t skip_stdout = 0; 118 size_t skip_stdout = 0;
119 if (config.skip_stdout) { /* --skip-stdout specified without argument */ 119 if (config.skip_stdout) { /* --skip-stdout specified without argument */
120 skip_stdout = child_result.stdout.lines; 120 skip_stdout = child_result.out.lines;
121 } else { 121 } else {
122 skip_stdout = config.stdout_lines_to_ignore; 122 skip_stdout = config.stdout_lines_to_ignore;
123 } 123 }
124 124
125 size_t skip_stderr = 0; 125 size_t skip_stderr = 0;
126 if (config.skip_stderr) { /* --skip-stderr specified without argument */ 126 if (config.skip_stderr) { /* --skip-stderr specified without argument */
127 skip_stderr = child_result.stderr.lines; 127 skip_stderr = child_result.err.lines;
128 } else { 128 } else {
129 skip_stderr = config.sterr_lines_to_ignore; 129 skip_stderr = config.sterr_lines_to_ignore;
130 } 130 }
131 131
132 /* Allow UNKNOWN or WARNING state for (non-skipped) output found on stderr */ 132 /* Allow UNKNOWN or WARNING state for (non-skipped) output found on stderr */
133 if (child_result.stderr.lines > skip_stderr && 133 if (child_result.err.lines > skip_stderr &&
134 (config.unknown_on_stderr || config.warn_on_stderr)) { 134 (config.unknown_on_stderr || config.warn_on_stderr)) {
135 mp_subcheck sc_stderr = mp_subcheck_init(); 135 mp_subcheck sc_stderr = mp_subcheck_init();
136 xasprintf(&sc_stderr.output, "remote command execution failed: %s", 136 xasprintf(&sc_stderr.output, "remote command execution failed: %s",
137 child_result.stderr.line[skip_stderr]); 137 child_result.err.line[skip_stderr]);
138 138
139 if (config.unknown_on_stderr) { 139 if (config.unknown_on_stderr) {
140 sc_stderr = mp_set_subcheck_state(sc_stderr, STATE_UNKNOWN); 140 sc_stderr = mp_set_subcheck_state(sc_stderr, STATE_UNKNOWN);
@@ -154,10 +154,10 @@ int main(int argc, char **argv) {
154 mp_subcheck sc_active_check = mp_subcheck_init(); 154 mp_subcheck sc_active_check = mp_subcheck_init();
155 xasprintf(&sc_active_check.output, "command stdout:"); 155 xasprintf(&sc_active_check.output, "command stdout:");
156 156
157 if (child_result.stdout.lines > skip_stdout) { 157 if (child_result.out.lines > skip_stdout) {
158 for (size_t i = skip_stdout; i < child_result.stdout.lines; i++) { 158 for (size_t i = skip_stdout; i < child_result.out.lines; i++) {
159 xasprintf(&sc_active_check.output, "%s\n%s", sc_active_check.output, 159 xasprintf(&sc_active_check.output, "%s\n%s", sc_active_check.output,
160 child_result.stdout.line[i]); 160 child_result.out.line[i]);
161 } 161 }
162 } else { 162 } else {
163 xasprintf(&sc_active_check.output, "remote command '%s' returned status %d", 163 xasprintf(&sc_active_check.output, "remote command '%s' returned status %d",
@@ -209,10 +209,10 @@ int main(int argc, char **argv) {
209 char *status_text; 209 char *status_text;
210 int cresult; 210 int cresult;
211 mp_subcheck sc_parse_passive = mp_subcheck_init(); 211 mp_subcheck sc_parse_passive = mp_subcheck_init();
212 for (size_t i = skip_stdout; i < child_result.stdout.lines; i++) { 212 for (size_t i = skip_stdout; i < child_result.out.lines; i++) {
213 status_text = child_result.stdout.line[i++]; 213 status_text = child_result.out.line[i++];
214 if (i == child_result.stdout.lines || 214 if (i == child_result.out.lines ||
215 strstr(child_result.stdout.line[i], "STATUS CODE: ") == NULL) { 215 strstr(child_result.out.line[i], "STATUS CODE: ") == NULL) {
216 216
217 sc_parse_passive = mp_set_subcheck_state(sc_parse_passive, STATE_UNKNOWN); 217 sc_parse_passive = mp_set_subcheck_state(sc_parse_passive, STATE_UNKNOWN);
218 xasprintf(&sc_parse_passive.output, "failed to parse output"); 218 xasprintf(&sc_parse_passive.output, "failed to parse output");
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
221 } 221 }
222 222
223 if (config.service[commands] && status_text && 223 if (config.service[commands] && status_text &&
224 sscanf(child_result.stdout.line[i], "STATUS CODE: %d", &cresult) == 1) { 224 sscanf(child_result.out.line[i], "STATUS CODE: %d", &cresult) == 1) {
225 fprintf(output_file, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, 225 fprintf(output_file, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time,
226 config.host_shortname, config.service[commands++], cresult, status_text); 226 config.host_shortname, config.service[commands++], cresult, status_text);
227 } 227 }
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index e3e514ff..d7d68de5 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -92,16 +92,16 @@ typedef struct {
92static check_curl_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); 92static check_curl_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
93 93
94static mp_subcheck check_http(check_curl_config /*config*/, check_curl_working_state workingState, 94static mp_subcheck check_http(check_curl_config /*config*/, check_curl_working_state workingState,
95 int redir_depth); 95 long redir_depth);
96 96
97typedef struct { 97typedef struct {
98 int redir_depth; 98 long redir_depth;
99 check_curl_working_state working_state; 99 check_curl_working_state working_state;
100 int error_code; 100 int error_code;
101 check_curl_global_state curl_state; 101 check_curl_global_state curl_state;
102} redir_wrapper; 102} redir_wrapper;
103static redir_wrapper redir(curlhelp_write_curlbuf * /*header_buf*/, check_curl_config /*config*/, 103static redir_wrapper redir(curlhelp_write_curlbuf * /*header_buf*/, check_curl_config /*config*/,
104 int redir_depth, check_curl_working_state working_state); 104 long redir_depth, check_curl_working_state working_state);
105 105
106static void print_help(void); 106static void print_help(void);
107void print_usage(void); 107void print_usage(void);
@@ -120,6 +120,14 @@ mp_state_enum np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_
120#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ 120#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */
121 121
122int main(int argc, char **argv) { 122int main(int argc, char **argv) {
123#ifdef __OpenBSD__
124 /* - rpath is required to read --extra-opts, CA and/or client certs
125 * - wpath is required to write --cookie-jar (possibly given up later)
126 * - inet is required for sockets
127 * - dns is required for name lookups */
128 pledge("stdio rpath wpath inet dns", NULL);
129#endif // __OpenBSD__
130
123 setlocale(LC_ALL, ""); 131 setlocale(LC_ALL, "");
124 bindtextdomain(PACKAGE, LOCALEDIR); 132 bindtextdomain(PACKAGE, LOCALEDIR);
125 textdomain(PACKAGE); 133 textdomain(PACKAGE);
@@ -135,6 +143,15 @@ int main(int argc, char **argv) {
135 143
136 const check_curl_config config = tmp_config.config; 144 const check_curl_config config = tmp_config.config;
137 145
146#ifdef __OpenBSD__
147 if (!config.curl_config.cookie_jar_file) {
148 if (verbose >= 2) {
149 printf(_("* No \"--cookie-jar\" is used, giving up \"wpath\" pledge(2)\n"));
150 }
151 pledge("stdio rpath inet dns", NULL);
152 }
153#endif // __OpenBSD__
154
138 if (config.output_format_is_set) { 155 if (config.output_format_is_set) {
139 mp_set_format(config.output_format); 156 mp_set_format(config.output_format);
140 } 157 }
@@ -198,7 +215,7 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) {
198#endif /* HAVE_SSL */ 215#endif /* HAVE_SSL */
199 216
200mp_subcheck check_http(const check_curl_config config, check_curl_working_state workingState, 217mp_subcheck check_http(const check_curl_config config, check_curl_working_state workingState,
201 int redir_depth) { 218 long redir_depth) {
202 219
203 // ======================= 220 // =======================
204 // Initialisation for curl 221 // Initialisation for curl
@@ -441,19 +458,19 @@ mp_subcheck check_http(const check_curl_config config, check_curl_working_state
441 "CURLINFO_REDIRECT_COUNT"); 458 "CURLINFO_REDIRECT_COUNT");
442 459
443 if (verbose >= 2) { 460 if (verbose >= 2) {
444 printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth); 461 printf(_("* curl LIBINFO_REDIRECT_COUNT is %ld\n"), redir_depth);
445 } 462 }
446 463
447 mp_subcheck sc_redir_depth = mp_subcheck_init(); 464 mp_subcheck sc_redir_depth = mp_subcheck_init();
448 if (redir_depth > config.max_depth) { 465 if (redir_depth > config.max_depth) {
449 xasprintf(&sc_redir_depth.output, 466 xasprintf(&sc_redir_depth.output,
450 "maximum redirection depth %d exceeded in libcurl", 467 "maximum redirection depth %ld exceeded in libcurl",
451 config.max_depth); 468 config.max_depth);
452 sc_redir_depth = mp_set_subcheck_state(sc_redir_depth, STATE_CRITICAL); 469 sc_redir_depth = mp_set_subcheck_state(sc_redir_depth, STATE_CRITICAL);
453 mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); 470 mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth);
454 return sc_result; 471 return sc_result;
455 } 472 }
456 xasprintf(&sc_redir_depth.output, "redirection depth %d (of a maximum %d)", 473 xasprintf(&sc_redir_depth.output, "redirection depth %ld (of a maximum %ld)",
457 redir_depth, config.max_depth); 474 redir_depth, config.max_depth);
458 mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); 475 mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth);
459 476
@@ -653,7 +670,7 @@ char *uri_string(const UriTextRangeA range, char *buf, size_t buflen) {
653} 670}
654 671
655redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config, 672redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config,
656 int redir_depth, check_curl_working_state working_state) { 673 long redir_depth, check_curl_working_state working_state) {
657 curlhelp_statusline status_line; 674 curlhelp_statusline status_line;
658 struct phr_header headers[255]; 675 struct phr_header headers[255];
659 size_t msglen; 676 size_t msglen;
@@ -678,7 +695,7 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
678 } 695 }
679 696
680 if (++redir_depth > config.max_depth) { 697 if (++redir_depth > config.max_depth) {
681 die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %d exceeded - %s\n"), 698 die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %ld exceeded - %s\n"),
682 config.max_depth, location); 699 config.max_depth, location);
683 } 700 }
684 701
@@ -761,7 +778,7 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
761 } 778 }
762 779
763 /* compose new path */ 780 /* compose new path */
764 /* TODO: handle fragments and query part of URL */ 781 /* TODO: handle fragments of URL */
765 char *new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE); 782 char *new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE);
766 if (uri.pathHead) { 783 if (uri.pathHead) {
767 for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment; 784 for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment;
@@ -772,6 +789,29 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
772 } 789 }
773 } 790 }
774 791
792 /* missing components have null,null in their UriTextRangeA
793 * add query parameters if they exist.
794 */
795 if (uri.query.first && uri.query.afterLast) {
796 // Ensure we have space for '?' + query_str + '\0' ahead of time, instead of calling strncat
797 // twice
798 size_t current_len = strlen(new_url);
799 size_t remaining_space = DEFAULT_BUFFER_SIZE - current_len - 1;
800
801 const char *query_str = uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE);
802 size_t query_str_len = strlen(query_str);
803
804 if (remaining_space >= query_str_len + 1) {
805 strcat(new_url, "?");
806 strcat(new_url, query_str);
807 } else {
808 die(STATE_UNKNOWN,
809 _("HTTP UNKNOWN - No space to add query part of size %zu to the buffer, buffer has "
810 "remaining size %zu"),
811 query_str_len, current_len);
812 }
813 }
814
775 if (working_state.serverPort == new_port && 815 if (working_state.serverPort == new_port &&
776 !strncmp(working_state.server_address, new_host, MAX_IPV4_HOSTLENGTH) && 816 !strncmp(working_state.server_address, new_host, MAX_IPV4_HOSTLENGTH) &&
777 (working_state.host_name && 817 (working_state.host_name &&
@@ -950,7 +990,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
950 case 'c': /* critical time threshold */ 990 case 'c': /* critical time threshold */
951 { 991 {
952 mp_range_parsed critical_range = mp_parse_range_string(optarg); 992 mp_range_parsed critical_range = mp_parse_range_string(optarg);
953 if (critical_range.error != MP_PARSING_SUCCES) { 993 if (critical_range.error != MP_PARSING_SUCCESS) {
954 die(STATE_UNKNOWN, "failed to parse critical threshold: %s", optarg); 994 die(STATE_UNKNOWN, "failed to parse critical threshold: %s", optarg);
955 } 995 }
956 result.config.thlds = mp_thresholds_set_crit(result.config.thlds, critical_range.range); 996 result.config.thlds = mp_thresholds_set_crit(result.config.thlds, critical_range.range);
@@ -959,7 +999,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
959 { 999 {
960 mp_range_parsed warning_range = mp_parse_range_string(optarg); 1000 mp_range_parsed warning_range = mp_parse_range_string(optarg);
961 1001
962 if (warning_range.error != MP_PARSING_SUCCES) { 1002 if (warning_range.error != MP_PARSING_SUCCESS) {
963 die(STATE_UNKNOWN, "failed to parse warning threshold: %s", optarg); 1003 die(STATE_UNKNOWN, "failed to parse warning threshold: %s", optarg);
964 } 1004 }
965 result.config.thlds = mp_thresholds_set_warn(result.config.thlds, warning_range.range); 1005 result.config.thlds = mp_thresholds_set_warn(result.config.thlds, warning_range.range);
@@ -1225,7 +1265,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1225 result.config.curl_config.sin_family = AF_INET; 1265 result.config.curl_config.sin_family = AF_INET;
1226 break; 1266 break;
1227 case '6': 1267 case '6':
1228#if defined(USE_IPV6) && defined(LIBCURL_FEATURE_IPV6) 1268#if defined(LIBCURL_FEATURE_IPV6)
1229 result.config.curl_config.sin_family = AF_INET6; 1269 result.config.curl_config.sin_family = AF_INET6;
1230#else 1270#else
1231 usage4(_("IPv6 support not available")); 1271 usage4(_("IPv6 support not available"));
@@ -1235,7 +1275,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1235 { 1275 {
1236 mp_range_parsed foo = mp_parse_range_string(optarg); 1276 mp_range_parsed foo = mp_parse_range_string(optarg);
1237 1277
1238 if (foo.error != MP_PARSING_SUCCES) { 1278 if (foo.error != MP_PARSING_SUCCESS) {
1239 die(STATE_CRITICAL, "failed to parse page size limits: %s", optarg); 1279 die(STATE_CRITICAL, "failed to parse page size limits: %s", optarg);
1240 } 1280 }
1241 1281
@@ -1400,7 +1440,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1400 } 1440 }
1401#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ 1441#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */
1402 if (verbose >= 2) { 1442 if (verbose >= 2) {
1403 printf(_("* Set SSL/TLS version to %d\n"), result.config.curl_config.ssl_version); 1443 printf(_("* Set SSL/TLS version to %ld\n"), result.config.curl_config.ssl_version);
1404 } 1444 }
1405 if (!specify_port) { 1445 if (!specify_port) {
1406 result.config.initial_config.serverPort = HTTPS_PORT; 1446 result.config.initial_config.serverPort = HTTPS_PORT;
@@ -1482,8 +1522,8 @@ void print_help(void) {
1482 printf(" %s\n", "-I, --IP-address=ADDRESS"); 1522 printf(" %s\n", "-I, --IP-address=ADDRESS");
1483 printf(" %s\n", 1523 printf(" %s\n",
1484 "IP address or name (use numeric address if possible to bypass DNS lookup)."); 1524 "IP address or name (use numeric address if possible to bypass DNS lookup).");
1485 printf(" %s\n", 1525 printf(" %s\n", "This overwrites the network address of the target while leaving everything "
1486 "This overwrites the network address of the target while leaving everything else (HTTP headers) as they are"); 1526 "else (HTTP headers) as they are");
1487 printf(" %s\n", "-p, --port=INTEGER"); 1527 printf(" %s\n", "-p, --port=INTEGER");
1488 printf(" %s", _("Port number (default: ")); 1528 printf(" %s", _("Port number (default: "));
1489 printf("%d)\n", HTTP_PORT); 1529 printf("%d)\n", HTTP_PORT);
@@ -1547,7 +1587,8 @@ void print_help(void) {
1547 printf(" %s\n", _("String to expect in the content")); 1587 printf(" %s\n", _("String to expect in the content"));
1548 printf(" %s\n", "-u, --url=PATH"); 1588 printf(" %s\n", "-u, --url=PATH");
1549 printf(" %s\n", _("URL to GET or POST (default: /)")); 1589 printf(" %s\n", _("URL to GET or POST (default: /)"));
1550 printf(" %s\n", _("This is the part after the address in a URL, so for \"https://example.com/index.html\" it would be '-u /index.html'")); 1590 printf(" %s\n", _("This is the part after the address in a URL, so for "
1591 "\"https://example.com/index.html\" it would be '-u /index.html'"));
1551 printf(" %s\n", "-P, --post=STRING"); 1592 printf(" %s\n", "-P, --post=STRING");
1552 printf(" %s\n", _("URL decoded http POST data")); 1593 printf(" %s\n", _("URL decoded http POST data"));
1553 printf(" %s\n", 1594 printf(" %s\n",
@@ -1648,6 +1689,8 @@ void print_help(void) {
1648 printf(" %s\n", _("certificate matches the hostname of the server, or if the certificate")); 1689 printf(" %s\n", _("certificate matches the hostname of the server, or if the certificate"));
1649 printf(" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); 1690 printf(" %s\n", _("has a valid chain of trust to one of the locally installed CAs."));
1650 printf("\n"); 1691 printf("\n");
1692 printf(" %s\n", _("To also verify certificates, please set --verify-cert."));
1693 printf("\n");
1651 printf("%s\n", _("Examples:")); 1694 printf("%s\n", _("Examples:"));
1652 printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com"); 1695 printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com");
1653 printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); 1696 printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,"));
@@ -1657,16 +1700,18 @@ void print_help(void) {
1657 _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); 1700 _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,"));
1658 printf(" %s\n", _("a STATE_CRITICAL will be returned.")); 1701 printf(" %s\n", _("a STATE_CRITICAL will be returned."));
1659 printf("\n"); 1702 printf("\n");
1660 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14"); 1703 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14 -D");
1661 printf(" %s\n", 1704 printf(" %s\n",
1662 _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); 1705 _("When the certificate of 'www.verisign.com' is valid for more than 14 days,"));
1663 printf(" %s\n", 1706 printf(" %s\n",
1664 _("a STATE_OK is returned. When the certificate is still valid, but for less than")); 1707 _("a STATE_OK is returned. When the certificate is still valid, but for less than"));
1665 printf(" %s\n", 1708 printf(" %s\n",
1666 _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); 1709 _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when"));
1667 printf(" %s\n\n", _("the certificate is expired.")); 1710 printf(" %s\n", _("the certificate is expired."));
1711 printf("\n");
1712 printf(" %s\n", _("The -D flag enforces a certificate validation beyond expiration time."));
1668 printf("\n"); 1713 printf("\n");
1669 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14"); 1714 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14 -D");
1670 printf(" %s\n", 1715 printf(" %s\n",
1671 _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); 1716 _("When the certificate of 'www.verisign.com' is valid for more than 30 days,"));
1672 printf(" %s\n", 1717 printf(" %s\n",
@@ -1689,7 +1734,8 @@ void print_help(void) {
1689 printf(" %s\n", _("It is recommended to use an environment proxy like:")); 1734 printf(" %s\n", _("It is recommended to use an environment proxy like:"));
1690 printf(" %s\n", 1735 printf(" %s\n",
1691 _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S")); 1736 _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S"));
1692 printf(" %s\n", _("legacy proxy requests in check_http style might still work, but are frowned upon, so DONT:")); 1737 printf(" %s\n", _("legacy proxy requests in check_http style might still work, but are frowned "
1738 "upon, so DONT:"));
1693 printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j " 1739 printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j "
1694 "CONNECT -H www.verisign.com ")); 1740 "CONNECT -H www.verisign.com "));
1695 printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> " 1741 printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> "
diff --git a/plugins/check_curl.d/check_curl_helpers.c b/plugins/check_curl.d/check_curl_helpers.c
index e4e7bef6..ad31b847 100644
--- a/plugins/check_curl.d/check_curl_helpers.c
+++ b/plugins/check_curl.d/check_curl_helpers.c
@@ -19,7 +19,7 @@ bool add_sslctx_verify_fun = false;
19check_curl_configure_curl_wrapper 19check_curl_configure_curl_wrapper
20check_curl_configure_curl(const check_curl_static_curl_config config, 20check_curl_configure_curl(const check_curl_static_curl_config config,
21 check_curl_working_state working_state, bool check_cert, 21 check_curl_working_state working_state, bool check_cert,
22 bool on_redirect_dependent, int follow_method, int max_depth) { 22 bool on_redirect_dependent, int follow_method, long max_depth) {
23 check_curl_configure_curl_wrapper result = { 23 check_curl_configure_curl_wrapper result = {
24 .errorcode = OK, 24 .errorcode = OK,
25 .curl_state = 25 .curl_state =
@@ -57,7 +57,7 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
57 result.curl_state.curl_easy_initialized = true; 57 result.curl_state.curl_easy_initialized = true;
58 58
59 if (verbose >= 1) { 59 if (verbose >= 1) {
60 handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_VERBOSE, 1), 60 handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_VERBOSE, 1L),
61 "CURLOPT_VERBOSE"); 61 "CURLOPT_VERBOSE");
62 } 62 }
63 63
@@ -214,10 +214,10 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
214 if (working_state.http_method) { 214 if (working_state.http_method) {
215 if (!strcmp(working_state.http_method, "POST")) { 215 if (!strcmp(working_state.http_method, "POST")) {
216 handle_curl_option_return_code( 216 handle_curl_option_return_code(
217 curl_easy_setopt(result.curl_state.curl, CURLOPT_POST, 1), "CURLOPT_POST"); 217 curl_easy_setopt(result.curl_state.curl, CURLOPT_POST, 1L), "CURLOPT_POST");
218 } else if (!strcmp(working_state.http_method, "PUT")) { 218 } else if (!strcmp(working_state.http_method, "PUT")) {
219 handle_curl_option_return_code( 219 handle_curl_option_return_code(
220 curl_easy_setopt(result.curl_state.curl, CURLOPT_UPLOAD, 1), "CURLOPT_UPLOAD"); 220 curl_easy_setopt(result.curl_state.curl, CURLOPT_UPLOAD, 1L), "CURLOPT_UPLOAD");
221 } else { 221 } else {
222 handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, 222 handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl,
223 CURLOPT_CUSTOMREQUEST, 223 CURLOPT_CUSTOMREQUEST,
@@ -300,10 +300,10 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
300 /* per default if we have a CA verify both the peer and the 300 /* per default if we have a CA verify both the peer and the
301 * hostname in the certificate, can be switched off later */ 301 * hostname in the certificate, can be switched off later */
302 handle_curl_option_return_code( 302 handle_curl_option_return_code(
303 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYPEER, 1), 303 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYPEER, 1L),
304 "CURLOPT_SSL_VERIFYPEER"); 304 "CURLOPT_SSL_VERIFYPEER");
305 handle_curl_option_return_code( 305 handle_curl_option_return_code(
306 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYHOST, 2), 306 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYHOST, 2L),
307 "CURLOPT_SSL_VERIFYHOST"); 307 "CURLOPT_SSL_VERIFYHOST");
308 } else { 308 } else {
309 /* backward-compatible behaviour, be tolerant in checks 309 /* backward-compatible behaviour, be tolerant in checks
@@ -311,10 +311,10 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
311 * to be less tolerant about ssl verfications 311 * to be less tolerant about ssl verfications
312 */ 312 */
313 handle_curl_option_return_code( 313 handle_curl_option_return_code(
314 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYPEER, 0), 314 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYPEER, 0L),
315 "CURLOPT_SSL_VERIFYPEER"); 315 "CURLOPT_SSL_VERIFYPEER");
316 handle_curl_option_return_code( 316 handle_curl_option_return_code(
317 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYHOST, 0), 317 curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYHOST, 0L),
318 "CURLOPT_SSL_VERIFYHOST"); 318 "CURLOPT_SSL_VERIFYHOST");
319 } 319 }
320 320
@@ -438,7 +438,7 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
438 if (on_redirect_dependent) { 438 if (on_redirect_dependent) {
439 if (follow_method == FOLLOW_LIBCURL) { 439 if (follow_method == FOLLOW_LIBCURL) {
440 handle_curl_option_return_code( 440 handle_curl_option_return_code(
441 curl_easy_setopt(result.curl_state.curl, CURLOPT_FOLLOWLOCATION, 1), 441 curl_easy_setopt(result.curl_state.curl, CURLOPT_FOLLOWLOCATION, 1L),
442 "CURLOPT_FOLLOWLOCATION"); 442 "CURLOPT_FOLLOWLOCATION");
443 443
444 /* default -1 is infinite, not good, could lead to zombie plugins! 444 /* default -1 is infinite, not good, could lead to zombie plugins!
@@ -474,7 +474,7 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
474 } 474 }
475 /* no-body */ 475 /* no-body */
476 if (working_state.no_body) { 476 if (working_state.no_body) {
477 handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_NOBODY, 1), 477 handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_NOBODY, 1L),
478 "CURLOPT_NOBODY"); 478 "CURLOPT_NOBODY");
479 } 479 }
480 480
@@ -488,7 +488,7 @@ check_curl_configure_curl(const check_curl_static_curl_config config,
488 curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4), 488 curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4),
489 "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V4)"); 489 "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V4)");
490 } 490 }
491#if defined(USE_IPV6) && defined(LIBCURL_FEATURE_IPV6) 491#if defined(LIBCURL_FEATURE_IPV6)
492 else if (config.sin_family == AF_INET6) { 492 else if (config.sin_family == AF_INET6) {
493 handle_curl_option_return_code( 493 handle_curl_option_return_code(
494 curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6), 494 curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6),
@@ -796,15 +796,17 @@ mp_subcheck check_document_dates(const curlhelp_write_curlbuf *header_buf, const
796 ((float)last_modified) / (60 * 60 * 24)); 796 ((float)last_modified) / (60 * 60 * 24));
797 sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); 797 sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL);
798 } else { 798 } else {
799 xasprintf(&sc_document_dates.output, _("Last modified %ld:%02ld:%02ld ago"), 799 xasprintf(&sc_document_dates.output, _("Last modified %lld:%02d:%02d ago"),
800 last_modified / (60 * 60), (last_modified / 60) % 60, last_modified % 60); 800 (long long)last_modified / (60 * 60), (int)(last_modified / 60) % 60,
801 (int)last_modified % 60);
801 sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); 802 sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL);
802 } 803 }
803 } else { 804 } else {
804 // TODO is this the OK case? 805 // TODO is this the OK case?
805 time_t last_modified = (srv_data - doc_data); 806 time_t last_modified = (srv_data - doc_data);
806 xasprintf(&sc_document_dates.output, _("Last modified %ld:%02ld:%02ld ago"), 807 xasprintf(&sc_document_dates.output, _("Last modified %lld:%02d:%02d ago"),
807 last_modified / (60 * 60), (last_modified / 60) % 60, last_modified % 60); 808 (long long)last_modified / (60 * 60), (int)(last_modified / 60) % 60,
809 (int)last_modified % 60);
808 sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_OK); 810 sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_OK);
809 } 811 }
810 } 812 }
@@ -1212,7 +1214,7 @@ mp_subcheck check_curl_certificate_checks(CURL *curl, X509 *cert, int warn_days_
1212 1214
1213 cert_ptr_union cert_ptr = {0}; 1215 cert_ptr_union cert_ptr = {0};
1214 cert_ptr.to_info = NULL; 1216 cert_ptr.to_info = NULL;
1215 CURLcode res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &cert_ptr.to_info); 1217 CURLcode res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &cert_ptr.to_certinfo);
1216 if (!res && cert_ptr.to_info) { 1218 if (!res && cert_ptr.to_info) {
1217# ifdef USE_OPENSSL 1219# ifdef USE_OPENSSL
1218 /* We have no OpenSSL in libcurl, but we can use OpenSSL for X509 cert 1220 /* We have no OpenSSL in libcurl, but we can use OpenSSL for X509 cert
diff --git a/plugins/check_curl.d/check_curl_helpers.h b/plugins/check_curl.d/check_curl_helpers.h
index e7b80f7e..e77b763b 100644
--- a/plugins/check_curl.d/check_curl_helpers.h
+++ b/plugins/check_curl.d/check_curl_helpers.h
@@ -80,7 +80,7 @@ check_curl_configure_curl_wrapper check_curl_configure_curl(check_curl_static_cu
80 check_curl_working_state working_state, 80 check_curl_working_state working_state,
81 bool check_cert, 81 bool check_cert,
82 bool on_redirect_dependent, 82 bool on_redirect_dependent,
83 int follow_method, int max_depth); 83 int follow_method, long max_depth);
84 84
85void handle_curl_option_return_code(CURLcode res, const char *option); 85void handle_curl_option_return_code(CURLcode res, const char *option);
86 86
diff --git a/plugins/check_curl.d/config.h b/plugins/check_curl.d/config.h
index f51b2ee9..61067d46 100644
--- a/plugins/check_curl.d/config.h
+++ b/plugins/check_curl.d/config.h
@@ -57,10 +57,10 @@ typedef struct {
57 bool haproxy_protocol; 57 bool haproxy_protocol;
58 long socket_timeout; 58 long socket_timeout;
59 sa_family_t sin_family; 59 sa_family_t sin_family;
60 int curl_http_version; 60 long curl_http_version;
61 char **http_opt_headers; 61 char **http_opt_headers;
62 size_t http_opt_headers_count; 62 size_t http_opt_headers_count;
63 int ssl_version; 63 long ssl_version;
64 char *client_cert; 64 char *client_cert;
65 char *client_privkey; 65 char *client_privkey;
66 char *ca_cert; 66 char *ca_cert;
@@ -76,7 +76,7 @@ typedef struct {
76 check_curl_working_state initial_config; 76 check_curl_working_state initial_config;
77 77
78 check_curl_static_curl_config curl_config; 78 check_curl_static_curl_config curl_config;
79 int max_depth; 79 long max_depth;
80 int followmethod; 80 int followmethod;
81 int followsticky; 81 int followsticky;
82 82
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index 81d92952..dd466d00 100644
--- a/plugins/check_dbi.c
+++ b/plugins/check_dbi.c
@@ -470,7 +470,7 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) {
470 470
471 case 'c': /* critical range */ { 471 case 'c': /* critical range */ {
472 mp_range_parsed tmp = mp_parse_range_string(optarg); 472 mp_range_parsed tmp = mp_parse_range_string(optarg);
473 if (tmp.error != MP_PARSING_SUCCES) { 473 if (tmp.error != MP_PARSING_SUCCESS) {
474 die(STATE_UNKNOWN, "failed to parse critical threshold"); 474 die(STATE_UNKNOWN, "failed to parse critical threshold");
475 } 475 }
476 result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range); 476 result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range);
@@ -478,7 +478,7 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) {
478 } break; 478 } break;
479 case 'w': /* warning range */ { 479 case 'w': /* warning range */ {
480 mp_range_parsed tmp = mp_parse_range_string(optarg); 480 mp_range_parsed tmp = mp_parse_range_string(optarg);
481 if (tmp.error != MP_PARSING_SUCCES) { 481 if (tmp.error != MP_PARSING_SUCCESS) {
482 die(STATE_UNKNOWN, "failed to parse warning threshold"); 482 die(STATE_UNKNOWN, "failed to parse warning threshold");
483 } 483 }
484 result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range); 484 result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range);
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index d42b5486..0d941f25 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -838,7 +838,7 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) {
838 } 838 }
839 char *range = argv[index++]; 839 char *range = argv[index++];
840 mp_range_parsed tmp = mp_parse_range_string(range); 840 mp_range_parsed tmp = mp_parse_range_string(range);
841 if (tmp.error != MP_PARSING_SUCCES) { 841 if (tmp.error != MP_PARSING_SUCCESS) {
842 die(STATE_UNKNOWN, "failed to parse warning threshold"); 842 die(STATE_UNKNOWN, "failed to parse warning threshold");
843 } 843 }
844 844
@@ -859,7 +859,7 @@ check_disk_config_wrapper process_arguments(int argc, char **argv) {
859 } 859 }
860 char *range = argv[index++]; 860 char *range = argv[index++];
861 mp_range_parsed tmp = mp_parse_range_string(range); 861 mp_range_parsed tmp = mp_parse_range_string(range);
862 if (tmp.error != MP_PARSING_SUCCES) { 862 if (tmp.error != MP_PARSING_SUCCESS) {
863 die(STATE_UNKNOWN, "failed to parse warning threshold"); 863 die(STATE_UNKNOWN, "failed to parse warning threshold");
864 } 864 }
865 865
@@ -1262,6 +1262,10 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_
1262 double free_inode_percentage = 1262 double free_inode_percentage =
1263 calculate_percent(measurement_unit.inodes_free, measurement_unit.inodes_total); 1263 calculate_percent(measurement_unit.inodes_free, measurement_unit.inodes_total);
1264 1264
1265 mp_perfdata inode_percentage_pd = perfdata_init();
1266 inode_percentage_pd = mp_set_pd_value(inode_percentage_pd, free_inode_percentage);
1267 inode_percentage_pd = mp_pd_set_thresholds(inode_percentage_pd, measurement_unit.freeinodes_percent_thresholds);
1268
1265 if (verbose > 0) { 1269 if (verbose > 0) {
1266 printf("free inode percentage computed: %g\n", free_inode_percentage); 1270 printf("free inode percentage computed: %g\n", free_inode_percentage);
1267 } 1271 }
@@ -1293,7 +1297,7 @@ mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_
1293 inodes_pd = mp_pd_set_thresholds(inodes_pd, absolut_inode_thresholds); 1297 inodes_pd = mp_pd_set_thresholds(inodes_pd, absolut_inode_thresholds);
1294 1298
1295 freeindodes_percent_sc = 1299 freeindodes_percent_sc =
1296 mp_set_subcheck_state(freeindodes_percent_sc, mp_get_pd_status(inodes_pd)); 1300 mp_set_subcheck_state(freeindodes_percent_sc, mp_get_pd_status(inode_percentage_pd));
1297 if (display_inodes_perfdata) { 1301 if (display_inodes_perfdata) {
1298 mp_add_perfdata_to_subcheck(&freeindodes_percent_sc, inodes_pd); 1302 mp_add_perfdata_to_subcheck(&freeindodes_percent_sc, inodes_pd);
1299 } 1303 }
diff --git a/plugins/check_http.c b/plugins/check_http.c
index d264b95d..71f94b91 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -544,11 +544,7 @@ bool process_arguments(int argc, char **argv) {
544 address_family = AF_INET; 544 address_family = AF_INET;
545 break; 545 break;
546 case '6': 546 case '6':
547#ifdef USE_IPV6
548 address_family = AF_INET6; 547 address_family = AF_INET6;
549#else
550 usage4(_("IPv6 support not available"));
551#endif
552 break; 548 break;
553 case 'v': /* verbose */ 549 case 'v': /* verbose */
554 verbose = true; 550 verbose = true;
@@ -1036,7 +1032,7 @@ int check_http(void) {
1036 printf("SSL initialized\n"); 1032 printf("SSL initialized\n");
1037 } 1033 }
1038 if (result != STATE_OK) { 1034 if (result != STATE_OK) {
1039 die(STATE_CRITICAL, NULL); 1035 die(STATE_CRITICAL, _("HTTP CRITICAL - SSL error\n"));
1040 } 1036 }
1041 microsec_ssl = deltime(tv_temp); 1037 microsec_ssl = deltime(tv_temp);
1042 elapsed_time_ssl = (double)microsec_ssl / 1.0e6; 1038 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index 16fe3d01..c1325cf9 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -39,6 +39,8 @@ const char *email = "devel@monitoring-plugins.org";
39 39
40#include "common.h" 40#include "common.h"
41#include "utils.h" 41#include "utils.h"
42#include "check_ide_smart.d/config.h"
43#include "states.h"
42 44
43static void print_help(void); 45static void print_help(void);
44void print_usage(void); 46void print_usage(void);
@@ -46,6 +48,7 @@ void print_usage(void);
46#include <sys/stat.h> 48#include <sys/stat.h>
47#include <sys/ioctl.h> 49#include <sys/ioctl.h>
48#include <fcntl.h> 50#include <fcntl.h>
51
49#ifdef __linux__ 52#ifdef __linux__
50# include <linux/hdreg.h> 53# include <linux/hdreg.h>
51# include <linux/types.h> 54# include <linux/types.h>
@@ -77,30 +80,30 @@ void print_usage(void);
77#define OPERATIONAL 0 80#define OPERATIONAL 0
78#define UNKNOWN -1 81#define UNKNOWN -1
79 82
80typedef struct threshold_s { 83typedef struct {
81 uint8_t id; 84 uint8_t id;
82 uint8_t threshold; 85 uint8_t threshold;
83 uint8_t reserved[10]; 86 uint8_t reserved[10];
84} __attribute__((packed)) threshold_t; 87} __attribute__((packed)) smart_threshold;
85 88
86typedef struct thresholds_s { 89typedef struct {
87 uint16_t revision; 90 uint16_t revision;
88 threshold_t thresholds[NR_ATTRIBUTES]; 91 smart_threshold thresholds[NR_ATTRIBUTES];
89 uint8_t reserved[18]; 92 uint8_t reserved[18];
90 uint8_t vendor[131]; 93 uint8_t vendor[131];
91 uint8_t checksum; 94 uint8_t checksum;
92} __attribute__((packed)) thresholds_t; 95} __attribute__((packed)) smart_thresholds;
93 96
94typedef struct value_s { 97typedef struct {
95 uint8_t id; 98 uint8_t id;
96 uint16_t status; 99 uint16_t status;
97 uint8_t value; 100 uint8_t value;
98 uint8_t vendor[8]; 101 uint8_t vendor[8];
99} __attribute__((packed)) value_t; 102} __attribute__((packed)) smart_value;
100 103
101typedef struct values_s { 104typedef struct {
102 uint16_t revision; 105 uint16_t revision;
103 value_t values[NR_ATTRIBUTES]; 106 smart_value values[NR_ATTRIBUTES];
104 uint8_t offline_status; 107 uint8_t offline_status;
105 uint8_t vendor1; 108 uint8_t vendor1;
106 uint16_t offline_timeout; 109 uint16_t offline_timeout;
@@ -110,7 +113,7 @@ typedef struct values_s {
110 uint8_t reserved[16]; 113 uint8_t reserved[16];
111 uint8_t vendor[125]; 114 uint8_t vendor[125];
112 uint8_t checksum; 115 uint8_t checksum;
113} __attribute__((packed)) values_t; 116} __attribute__((packed)) smart_values;
114 117
115static struct { 118static struct {
116 uint8_t value; 119 uint8_t value;
@@ -133,25 +136,20 @@ enum SmartCommand {
133 SMART_CMD_AUTO_OFFLINE 136 SMART_CMD_AUTO_OFFLINE
134}; 137};
135 138
136static char *get_offline_text(int); 139static char *get_offline_text(int /*status*/);
137static int smart_read_values(int, values_t *); 140static int smart_read_values(int /*fd*/, smart_values * /*values*/);
138static int nagios(values_t *, thresholds_t *); 141static mp_state_enum compare_values_and_thresholds(smart_values * /*p*/, smart_thresholds * /*t*/);
139static void print_value(value_t *, threshold_t *); 142static void print_value(smart_value * /*p*/, smart_threshold * /*t*/);
140static void print_values(values_t *, thresholds_t *); 143static void print_values(smart_values * /*p*/, smart_thresholds * /*t*/);
141static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); 144static mp_state_enum smart_cmd_simple(int /*fd*/, enum SmartCommand /*command*/, uint8_t /*val0*/, bool /*show_error*/);
142static int smart_read_thresholds(int, thresholds_t *); 145static int smart_read_thresholds(int /*fd*/, smart_thresholds * /*thresholds*/);
143static bool verbose = false; 146static int verbose = 0;
144 147
145int main(int argc, char *argv[]) { 148typedef struct {
146 char *device = NULL; 149 int errorcode;
147 int o; 150 check_ide_smart_config config;
148 int longindex; 151} check_ide_smart_config_wrapper;
149 int retval = 0; 152static check_ide_smart_config_wrapper process_arguments(int argc, char **argv) {
150
151 thresholds_t thresholds;
152 values_t values;
153 int fd;
154
155 static struct option longopts[] = {{"device", required_argument, 0, 'd'}, 153 static struct option longopts[] = {{"device", required_argument, 0, 'd'},
156 {"immediate", no_argument, 0, 'i'}, 154 {"immediate", no_argument, 0, 'i'},
157 {"quiet-check", no_argument, 0, 'q'}, 155 {"quiet-check", no_argument, 0, 'q'},
@@ -162,24 +160,22 @@ int main(int argc, char *argv[]) {
162 {"version", no_argument, 0, 'V'}, 160 {"version", no_argument, 0, 'V'},
163 {0, 0, 0, 0}}; 161 {0, 0, 0, 0}};
164 162
165 /* Parse extra opts if any */ 163 check_ide_smart_config_wrapper result = {
166 argv = np_extra_opts(&argc, argv, progname); 164 .errorcode = OK,
167 165 .config = check_ide_smart_init(),
168 setlocale(LC_ALL, ""); 166 };
169 bindtextdomain(PACKAGE, LOCALEDIR);
170 textdomain(PACKAGE);
171 167
172 while (true) { 168 while (true) {
169 int longindex = 0;
170 int option_index = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex);
173 171
174 o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); 172 if (option_index == -1 || option_index == EOF || option_index == 1) {
175
176 if (o == -1 || o == EOF || o == 1) {
177 break; 173 break;
178 } 174 }
179 175
180 switch (o) { 176 switch (option_index) {
181 case 'd': 177 case 'd':
182 device = optarg; 178 result.config.device = optarg;
183 break; 179 break;
184 case 'q': 180 case 'q':
185 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\".")); 181 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\"."));
@@ -189,84 +185,103 @@ int main(int argc, char *argv[]) {
189 case '1': 185 case '1':
190 case '0': 186 case '0':
191 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help).")); 187 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help)."));
192 return STATE_CRITICAL; 188 result.errorcode = ERROR;
189 return result;
193 break; 190 break;
194 case 'n': 191 case 'n':
195 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the")); 192 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the"));
196 fprintf(stderr, "%s\n", _("default and will be removed from future releases.")); 193 fprintf(stderr, "%s\n", _("default and will be removed from future releases."));
197 break; 194 break;
198 case 'v': /* verbose */ 195 case 'v': /* verbose */
199 verbose = true; 196 verbose++;
200 break; 197 break;
201 case 'h': 198 case 'h':
202 print_help(); 199 print_help();
203 return STATE_UNKNOWN; 200 exit(STATE_UNKNOWN);
204 case 'V': 201 case 'V':
205 print_revision(progname, NP_VERSION); 202 print_revision(progname, NP_VERSION);
206 return STATE_UNKNOWN; 203 exit(STATE_UNKNOWN);
207 default: 204 default:
208 usage5(); 205 usage5();
209 } 206 }
210 } 207 }
211 208
212 if (optind < argc) { 209 if (optind < argc) {
213 device = argv[optind]; 210 result.config.device = argv[optind];
214 } 211 }
215 212
216 if (!device) { 213 if (result.config.device == NULL) {
217 print_help(); 214 print_help();
218 return STATE_UNKNOWN; 215 exit(STATE_UNKNOWN);
216 }
217
218 return result;
219}
220
221int main(int argc, char *argv[]) {
222 setlocale(LC_ALL, "");
223 bindtextdomain(PACKAGE, LOCALEDIR);
224 textdomain(PACKAGE);
225
226 /* Parse extra opts if any */
227 argv = np_extra_opts(&argc, argv, progname);
228
229 check_ide_smart_config_wrapper tmp_config = process_arguments(argc, argv);
230
231 if (tmp_config.errorcode != OK) {
232 die(STATE_UNKNOWN, _("Failed to parse commandline"));
219 } 233 }
220 234
221 fd = open(device, OPEN_MODE); 235 check_ide_smart_config config = tmp_config.config;
222 236
223 if (fd < 0) { 237 int device_file_descriptor = open(config.device, OPEN_MODE);
224 printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno)); 238
239 if (device_file_descriptor < 0) {
240 printf(_("CRITICAL - Couldn't open device %s: %s\n"), config.device, strerror(errno));
225 return STATE_CRITICAL; 241 return STATE_CRITICAL;
226 } 242 }
227 243
228 if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) { 244 if (smart_cmd_simple(device_file_descriptor, SMART_CMD_ENABLE, 0, false)) {
229 printf(_("CRITICAL - SMART_CMD_ENABLE\n")); 245 printf(_("CRITICAL - SMART_CMD_ENABLE\n"));
230 return STATE_CRITICAL; 246 return STATE_CRITICAL;
231 } 247 }
232 248
233 smart_read_values(fd, &values); 249 smart_values values;
234 smart_read_thresholds(fd, &thresholds); 250 smart_read_values(device_file_descriptor, &values);
235 retval = nagios(&values, &thresholds); 251 smart_thresholds thresholds;
252 smart_read_thresholds(device_file_descriptor, &thresholds);
253 mp_state_enum retval = compare_values_and_thresholds(&values, &thresholds);
236 if (verbose) { 254 if (verbose) {
237 print_values(&values, &thresholds); 255 print_values(&values, &thresholds);
238 } 256 }
239 257
240 close(fd); 258 close(device_file_descriptor);
241 return retval; 259 return retval;
242} 260}
243 261
244char *get_offline_text(int status) { 262char *get_offline_text(int status) {
245 int i; 263 for (int index = 0; offline_status_text[index].text; index++) {
246 for (i = 0; offline_status_text[i].text; i++) { 264 if (offline_status_text[index].value == status) {
247 if (offline_status_text[i].value == status) { 265 return offline_status_text[index].text;
248 return offline_status_text[i].text;
249 } 266 }
250 } 267 }
251 return "UNKNOWN"; 268 return "UNKNOWN";
252} 269}
253 270
254int smart_read_values(int fd, values_t *values) { 271int smart_read_values(int file_descriptor, smart_values *values) {
255#ifdef __linux__ 272#ifdef __linux__
256 int e;
257 uint8_t args[4 + 512]; 273 uint8_t args[4 + 512];
258 args[0] = WIN_SMART; 274 args[0] = WIN_SMART;
259 args[1] = 0; 275 args[1] = 0;
260 args[2] = SMART_READ_VALUES; 276 args[2] = SMART_READ_VALUES;
261 args[3] = 1; 277 args[3] = 1;
262 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 278 if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) {
263 e = errno; 279 int errno_storage = errno;
264 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); 280 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
265 return e; 281 return errno_storage;
266 } 282 }
267 memcpy(values, args + 4, 512); 283 memcpy(values, args + 4, 512);
268#endif /* __linux__ */ 284#elif defined __NetBSD__
269#ifdef __NetBSD__
270 struct atareq req; 285 struct atareq req;
271 unsigned char inbuf[DEV_BSIZE]; 286 unsigned char inbuf[DEV_BSIZE];
272 287
@@ -281,34 +296,37 @@ int smart_read_values(int fd, values_t *values) {
281 req.datalen = sizeof(inbuf); 296 req.datalen = sizeof(inbuf);
282 req.cylinder = WDSMART_CYL; 297 req.cylinder = WDSMART_CYL;
283 298
284 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 299 if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) {
285 if (req.retsts != ATACMD_OK) { 300 if (req.retsts != ATACMD_OK) {
286 errno = ENODEV; 301 errno = ENODEV;
287 } 302 }
288 } 303 }
289 304
290 if (errno != 0) { 305 if (errno != 0) {
291 int e = errno; 306 int errno_storage = errno;
292 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); 307 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
293 return e; 308 return errno_storage;
294 } 309 }
295 310
296 (void)memcpy(values, inbuf, 512); 311 (void)memcpy(values, inbuf, 512);
297#endif /* __NetBSD__ */ 312#else // __linux__ || __NetBSD__
313# error Not implemented for this OS
314#endif
315
298 return 0; 316 return 0;
299} 317}
300 318
301int nagios(values_t *p, thresholds_t *t) { 319mp_state_enum compare_values_and_thresholds(smart_values *values, smart_thresholds *thresholds) {
302 value_t *value = p->values; 320 smart_value *value = values->values;
303 threshold_t *threshold = t->thresholds; 321 smart_threshold *threshold = thresholds->thresholds;
322
304 int status = OPERATIONAL; 323 int status = OPERATIONAL;
305 int prefailure = 0; 324 int prefailure = 0;
306 int advisory = 0; 325 int advisory = 0;
307 int failed = 0; 326 int failed = 0;
308 int passed = 0; 327 int passed = 0;
309 int total = 0; 328 int total = 0;
310 int i; 329 for (int i = 0; i < NR_ATTRIBUTES; i++) {
311 for (i = 0; i < NR_ATTRIBUTES; i++) {
312 if (value->id && threshold->id && value->id == threshold->id) { 330 if (value->id && threshold->id && value->id == threshold->id) {
313 if (value->value < threshold->threshold) { 331 if (value->value < threshold->threshold) {
314 ++failed; 332 ++failed;
@@ -327,6 +345,7 @@ int nagios(values_t *p, thresholds_t *t) {
327 ++value; 345 ++value;
328 ++threshold; 346 ++threshold;
329 } 347 }
348
330 switch (status) { 349 switch (status) {
331 case PREFAILURE: 350 case PREFAILURE:
332 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed, 351 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed,
@@ -349,50 +368,51 @@ int nagios(values_t *p, thresholds_t *t) {
349 return status; 368 return status;
350} 369}
351 370
352void print_value(value_t *p, threshold_t *t) { 371void print_value(smart_value *value_pointer, smart_threshold *threshold_pointer) {
353 printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", 372 printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", value_pointer->id, value_pointer->status,
354 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, p->value >= t->threshold ? "Passed" : "Failed"); 373 value_pointer->status & 1 ? "PreFailure" : "Advisory ", value_pointer->status & 2 ? "OnLine " : "OffLine",
374 value_pointer->value, threshold_pointer->threshold, value_pointer->value >= threshold_pointer->threshold ? "Passed" : "Failed");
355} 375}
356 376
357void print_values(values_t *p, thresholds_t *t) { 377void print_values(smart_values *values, smart_thresholds *thresholds) {
358 value_t *value = p->values; 378 smart_value *value = values->values;
359 threshold_t *threshold = t->thresholds; 379 smart_threshold *threshold = thresholds->thresholds;
360 int i; 380 for (int i = 0; i < NR_ATTRIBUTES; i++) {
361 for (i = 0; i < NR_ATTRIBUTES; i++) {
362 if (value->id && threshold->id && value->id == threshold->id) { 381 if (value->id && threshold->id && value->id == threshold->id) {
363 print_value(value++, threshold++); 382 print_value(value++, threshold++);
364 } 383 }
365 } 384 }
366 printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), p->offline_status, 385 printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), values->offline_status,
367 get_offline_text(p->offline_status & 0x7f), (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); 386 get_offline_text(values->offline_status & 0x7f), (values->offline_status & 0x80 ? "Yes" : "No"), values->offline_timeout / 60);
368 printf(_("OffLineCapability=%d {%s %s %s}\n"), p->offline_capability, p->offline_capability & 1 ? "Immediate" : "", 387 printf(_("OffLineCapability=%d {%s %s %s}\n"), values->offline_capability, values->offline_capability & 1 ? "Immediate" : "",
369 p->offline_capability & 2 ? "Auto" : "", p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); 388 values->offline_capability & 2 ? "Auto" : "", values->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
370 printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), p->revision, p->checksum, p->smart_capability, 389 printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), values->revision, values->checksum, values->smart_capability,
371 p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); 390 values->smart_capability & 1 ? "SaveOnStandBy" : "", values->smart_capability & 2 ? "AutoSave" : "");
372} 391}
373 392
374int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { 393mp_state_enum smart_cmd_simple(int file_descriptor, enum SmartCommand command, uint8_t val0, bool show_error) {
375 int e = STATE_UNKNOWN; 394 mp_state_enum result = STATE_UNKNOWN;
376#ifdef __linux__ 395#ifdef __linux__
377 uint8_t args[4]; 396 uint8_t args[4] = {
378 args[0] = WIN_SMART; 397 WIN_SMART,
379 args[1] = val0; 398 val0,
380 args[2] = smart_command[command].value; 399 smart_command[command].value,
381 args[3] = 0; 400 0,
382 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 401 };
383 e = STATE_CRITICAL; 402
403 if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) {
404 result = STATE_CRITICAL;
384 if (show_error) { 405 if (show_error) {
385 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); 406 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
386 } 407 }
387 } else { 408 } else {
388 e = STATE_OK; 409 result = STATE_OK;
389 if (show_error) { 410 if (show_error) {
390 printf(_("OK - Command sent (%s)\n"), smart_command[command].text); 411 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
391 } 412 }
392 } 413 }
393 414
394#endif /* __linux__ */ 415#elif defined __NetBSD__
395#ifdef __NetBSD__
396 struct atareq req; 416 struct atareq req;
397 417
398 memset(&req, 0, sizeof(req)); 418 memset(&req, 0, sizeof(req));
@@ -403,7 +423,7 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_
403 req.cylinder = WDSMART_CYL; 423 req.cylinder = WDSMART_CYL;
404 req.sec_count = val0; 424 req.sec_count = val0;
405 425
406 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 426 if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) {
407 if (req.retsts != ATACMD_OK) { 427 if (req.retsts != ATACMD_OK) {
408 errno = ENODEV; 428 errno = ENODEV;
409 } 429 }
@@ -413,42 +433,42 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_
413 } 433 }
414 434
415 if (errno != 0) { 435 if (errno != 0) {
416 e = STATE_CRITICAL; 436 result = STATE_CRITICAL;
417 if (show_error) { 437 if (show_error) {
418 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); 438 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
419 } 439 }
420 } else { 440 } else {
421 e = STATE_OK; 441 result = STATE_OK;
422 if (show_error) { 442 if (show_error) {
423 printf(_("OK - Command sent (%s)\n"), smart_command[command].text); 443 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
424 } 444 }
425 } 445 }
426 446#else
447# error Not implemented for this OS
427#endif /* __NetBSD__ */ 448#endif /* __NetBSD__ */
428 return e; 449
450 return result;
429} 451}
430 452
431int smart_read_thresholds(int fd, thresholds_t *thresholds) { 453int smart_read_thresholds(int file_descriptor, smart_thresholds *thresholds) {
432#ifdef __linux__ 454#ifdef __linux__
433 int e;
434 uint8_t args[4 + 512]; 455 uint8_t args[4 + 512];
435 args[0] = WIN_SMART; 456 args[0] = WIN_SMART;
436 args[1] = 0; 457 args[1] = 0;
437 args[2] = SMART_READ_THRESHOLDS; 458 args[2] = SMART_READ_THRESHOLDS;
438 args[3] = 1; 459 args[3] = 1;
439 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 460 if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) {
440 e = errno; 461 int errno_storage = errno;
441 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); 462 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
442 return e; 463 return errno_storage;
443 } 464 }
444 memcpy(thresholds, args + 4, 512); 465 memcpy(thresholds, args + 4, 512);
445#endif /* __linux__ */ 466#elif defined __NetBSD__
446#ifdef __NetBSD__
447 struct atareq req; 467 struct atareq req;
448 unsigned char inbuf[DEV_BSIZE];
449
450 memset(&req, 0, sizeof(req)); 468 memset(&req, 0, sizeof(req));
451 req.timeout = 1000; 469 req.timeout = 1000;
470
471 unsigned char inbuf[DEV_BSIZE];
452 memset(&inbuf, 0, sizeof(inbuf)); 472 memset(&inbuf, 0, sizeof(inbuf));
453 473
454 req.flags = ATACMD_READ; 474 req.flags = ATACMD_READ;
@@ -458,20 +478,23 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) {
458 req.datalen = sizeof(inbuf); 478 req.datalen = sizeof(inbuf);
459 req.cylinder = WDSMART_CYL; 479 req.cylinder = WDSMART_CYL;
460 480
461 if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { 481 if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) {
462 if (req.retsts != ATACMD_OK) { 482 if (req.retsts != ATACMD_OK) {
463 errno = ENODEV; 483 errno = ENODEV;
464 } 484 }
465 } 485 }
466 486
467 if (errno != 0) { 487 if (errno != 0) {
468 int e = errno; 488 int errno_storage = errno;
469 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); 489 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
470 return e; 490 return errno_storage;
471 } 491 }
472 492
473 (void)memcpy(thresholds, inbuf, 512); 493 (void)memcpy(thresholds, inbuf, 512);
494#else
495# error Not implemented for this OS
474#endif /* __NetBSD__ */ 496#endif /* __NetBSD__ */
497
475 return 0; 498 return 0;
476} 499}
477 500
diff --git a/plugins/check_ide_smart.d/config.h b/plugins/check_ide_smart.d/config.h
new file mode 100644
index 00000000..36899abe
--- /dev/null
+++ b/plugins/check_ide_smart.d/config.h
@@ -0,0 +1,15 @@
1#pragma once
2
3#include "../../config.h"
4#include <stddef.h>
5
6typedef struct {
7 char *device;
8} check_ide_smart_config;
9
10check_ide_smart_config check_ide_smart_init() {
11 check_ide_smart_config tmp = {
12 .device = NULL,
13 };
14 return tmp;
15}
diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c
index 1b2e2826..7f8282b4 100644
--- a/plugins/check_ldap.c
+++ b/plugins/check_ldap.c
@@ -400,7 +400,7 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) {
400 break; 400 break;
401 case 'w': { 401 case 'w': {
402 mp_range_parsed tmp = mp_parse_range_string(optarg); 402 mp_range_parsed tmp = mp_parse_range_string(optarg);
403 if (tmp.error != MP_PARSING_SUCCES) { 403 if (tmp.error != MP_PARSING_SUCCESS) {
404 die(STATE_UNKNOWN, "failed to parse warning connection time threshold"); 404 die(STATE_UNKNOWN, "failed to parse warning connection time threshold");
405 } 405 }
406 result.config.connection_time_threshold = 406 result.config.connection_time_threshold =
@@ -408,7 +408,7 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) {
408 } break; 408 } break;
409 case 'c': { 409 case 'c': {
410 mp_range_parsed tmp = mp_parse_range_string(optarg); 410 mp_range_parsed tmp = mp_parse_range_string(optarg);
411 if (tmp.error != MP_PARSING_SUCCES) { 411 if (tmp.error != MP_PARSING_SUCCESS) {
412 die(STATE_UNKNOWN, "failed to parse critical connection time threshold"); 412 die(STATE_UNKNOWN, "failed to parse critical connection time threshold");
413 } 413 }
414 result.config.connection_time_threshold = 414 result.config.connection_time_threshold =
@@ -416,7 +416,7 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) {
416 } break; 416 } break;
417 case 'W': { 417 case 'W': {
418 mp_range_parsed tmp = mp_parse_range_string(optarg); 418 mp_range_parsed tmp = mp_parse_range_string(optarg);
419 if (tmp.error != MP_PARSING_SUCCES) { 419 if (tmp.error != MP_PARSING_SUCCESS) {
420 die(STATE_UNKNOWN, "failed to parse number of entries warning threshold"); 420 die(STATE_UNKNOWN, "failed to parse number of entries warning threshold");
421 } 421 }
422 result.config.entries_thresholds = 422 result.config.entries_thresholds =
@@ -424,7 +424,7 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) {
424 } break; 424 } break;
425 case 'C': { 425 case 'C': {
426 mp_range_parsed tmp = mp_parse_range_string(optarg); 426 mp_range_parsed tmp = mp_parse_range_string(optarg);
427 if (tmp.error != MP_PARSING_SUCCES) { 427 if (tmp.error != MP_PARSING_SUCCESS) {
428 die(STATE_UNKNOWN, "failed to parse number of entries critical threshold"); 428 die(STATE_UNKNOWN, "failed to parse number of entries critical threshold");
429 } 429 }
430 result.config.entries_thresholds = 430 result.config.entries_thresholds =
@@ -462,11 +462,7 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) {
462 } 462 }
463 break; 463 break;
464 case '6': 464 case '6':
465#ifdef USE_IPV6
466 address_family = AF_INET6; 465 address_family = AF_INET6;
467#else
468 usage(_("IPv6 support not available\n"));
469#endif
470 break; 466 break;
471 case output_format_index: { 467 case output_format_index: {
472 parsed_output_format parser = mp_parse_output_format(optarg); 468 parsed_output_format parser = mp_parse_output_format(optarg);
diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c
index cdc2a035..bb38fcc5 100644
--- a/plugins/check_mrtg.c
+++ b/plugins/check_mrtg.c
@@ -255,7 +255,7 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
255 break; 255 break;
256 case 'w': /* critical time threshold */ { 256 case 'w': /* critical time threshold */ {
257 mp_range_parsed tmp = mp_parse_range_string(optarg); 257 mp_range_parsed tmp = mp_parse_range_string(optarg);
258 if (tmp.error != MP_PARSING_SUCCES) { 258 if (tmp.error != MP_PARSING_SUCCESS) {
259 die(STATE_UNKNOWN, "failed to parse warning threshold"); 259 die(STATE_UNKNOWN, "failed to parse warning threshold");
260 } 260 }
261 result.config.values_threshold = 261 result.config.values_threshold =
@@ -263,7 +263,7 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
263 } break; 263 } break;
264 case 'c': /* warning time threshold */ { 264 case 'c': /* warning time threshold */ {
265 mp_range_parsed tmp = mp_parse_range_string(optarg); 265 mp_range_parsed tmp = mp_parse_range_string(optarg);
266 if (tmp.error != MP_PARSING_SUCCES) { 266 if (tmp.error != MP_PARSING_SUCCESS) {
267 die(STATE_UNKNOWN, "failed to parse critical threshold"); 267 die(STATE_UNKNOWN, "failed to parse critical threshold");
268 } 268 }
269 result.config.values_threshold = 269 result.config.values_threshold =
@@ -330,7 +330,7 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
330 330
331 if (argc > option_char && !result.config.values_threshold.warning_is_set) { 331 if (argc > option_char && !result.config.values_threshold.warning_is_set) {
332 mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]); 332 mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]);
333 if (tmp.error != MP_PARSING_SUCCES) { 333 if (tmp.error != MP_PARSING_SUCCESS) {
334 die(STATE_UNKNOWN, "failed to parse warning threshold"); 334 die(STATE_UNKNOWN, "failed to parse warning threshold");
335 } 335 }
336 result.config.values_threshold = 336 result.config.values_threshold =
@@ -339,7 +339,7 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) {
339 339
340 if (argc > option_char && !result.config.values_threshold.critical_is_set) { 340 if (argc > option_char && !result.config.values_threshold.critical_is_set) {
341 mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]); 341 mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]);
342 if (tmp.error != MP_PARSING_SUCCES) { 342 if (tmp.error != MP_PARSING_SUCCESS) {
343 die(STATE_UNKNOWN, "failed to parse critical threshold"); 343 die(STATE_UNKNOWN, "failed to parse critical threshold");
344 } 344 }
345 result.config.values_threshold = 345 result.config.values_threshold =
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 26730d4c..15005bf5 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -572,7 +572,7 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) {
572 break; 572 break;
573 case 'w': { 573 case 'w': {
574 mp_range_parsed tmp = mp_parse_range_string(optarg); 574 mp_range_parsed tmp = mp_parse_range_string(optarg);
575 if (tmp.error != MP_PARSING_SUCCES) { 575 if (tmp.error != MP_PARSING_SUCCESS) {
576 die(STATE_UNKNOWN, "failed to parse warning time threshold"); 576 die(STATE_UNKNOWN, "failed to parse warning time threshold");
577 } 577 }
578 result.config.replica_thresholds = 578 result.config.replica_thresholds =
@@ -580,7 +580,7 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) {
580 } break; 580 } break;
581 case 'c': { 581 case 'c': {
582 mp_range_parsed tmp = mp_parse_range_string(optarg); 582 mp_range_parsed tmp = mp_parse_range_string(optarg);
583 if (tmp.error != MP_PARSING_SUCCES) { 583 if (tmp.error != MP_PARSING_SUCCESS) {
584 die(STATE_UNKNOWN, "failed to parse critical time threshold"); 584 die(STATE_UNKNOWN, "failed to parse critical time threshold");
585 } 585 }
586 result.config.replica_thresholds = 586 result.config.replica_thresholds =
diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c
index ae6cc15d..fc0966d3 100644
--- a/plugins/check_mysql_query.c
+++ b/plugins/check_mysql_query.c
@@ -277,14 +277,14 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) {
277 break; 277 break;
278 case 'w': { 278 case 'w': {
279 mp_range_parsed tmp = mp_parse_range_string(optarg); 279 mp_range_parsed tmp = mp_parse_range_string(optarg);
280 if (tmp.error != MP_PARSING_SUCCES) { 280 if (tmp.error != MP_PARSING_SUCCESS) {
281 die(STATE_UNKNOWN, "failed to parse warning threshold"); 281 die(STATE_UNKNOWN, "failed to parse warning threshold");
282 } 282 }
283 result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range); 283 result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range);
284 } break; 284 } break;
285 case 'c': { 285 case 'c': {
286 mp_range_parsed tmp = mp_parse_range_string(optarg); 286 mp_range_parsed tmp = mp_parse_range_string(optarg);
287 if (tmp.error != MP_PARSING_SUCCES) { 287 if (tmp.error != MP_PARSING_SUCCESS) {
288 die(STATE_UNKNOWN, "failed to parse critical threshold"); 288 die(STATE_UNKNOWN, "failed to parse critical threshold");
289 } 289 }
290 result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range); 290 result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range);
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index 26f74286..b5cfb460 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -548,7 +548,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
548 break; 548 break;
549 case 'w': { 549 case 'w': {
550 mp_range_parsed tmp = mp_parse_range_string(optarg); 550 mp_range_parsed tmp = mp_parse_range_string(optarg);
551 if (tmp.error != MP_PARSING_SUCCES) { 551 if (tmp.error != MP_PARSING_SUCCESS) {
552 die(STATE_UNKNOWN, "failed to parse warning offset threshold"); 552 die(STATE_UNKNOWN, "failed to parse warning offset threshold");
553 } 553 }
554 554
@@ -557,7 +557,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
557 } break; 557 } break;
558 case 'c': { 558 case 'c': {
559 mp_range_parsed tmp = mp_parse_range_string(optarg); 559 mp_range_parsed tmp = mp_parse_range_string(optarg);
560 if (tmp.error != MP_PARSING_SUCCES) { 560 if (tmp.error != MP_PARSING_SUCCESS) {
561 die(STATE_UNKNOWN, "failed to parse critical offset threshold"); 561 die(STATE_UNKNOWN, "failed to parse critical offset threshold");
562 } 562 }
563 563
@@ -567,7 +567,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
567 case 'W': { 567 case 'W': {
568 result.config.do_stratum = true; 568 result.config.do_stratum = true;
569 mp_range_parsed tmp = mp_parse_range_string(optarg); 569 mp_range_parsed tmp = mp_parse_range_string(optarg);
570 if (tmp.error != MP_PARSING_SUCCES) { 570 if (tmp.error != MP_PARSING_SUCCESS) {
571 die(STATE_UNKNOWN, "failed to parse warning stratum threshold"); 571 die(STATE_UNKNOWN, "failed to parse warning stratum threshold");
572 } 572 }
573 573
@@ -577,7 +577,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
577 case 'C': { 577 case 'C': {
578 result.config.do_stratum = true; 578 result.config.do_stratum = true;
579 mp_range_parsed tmp = mp_parse_range_string(optarg); 579 mp_range_parsed tmp = mp_parse_range_string(optarg);
580 if (tmp.error != MP_PARSING_SUCCES) { 580 if (tmp.error != MP_PARSING_SUCCESS) {
581 die(STATE_UNKNOWN, "failed to parse critical stratum threshold"); 581 die(STATE_UNKNOWN, "failed to parse critical stratum threshold");
582 } 582 }
583 583
@@ -587,7 +587,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
587 case 'j': { 587 case 'j': {
588 result.config.do_jitter = true; 588 result.config.do_jitter = true;
589 mp_range_parsed tmp = mp_parse_range_string(optarg); 589 mp_range_parsed tmp = mp_parse_range_string(optarg);
590 if (tmp.error != MP_PARSING_SUCCES) { 590 if (tmp.error != MP_PARSING_SUCCESS) {
591 die(STATE_UNKNOWN, "failed to parse warning jitter threshold"); 591 die(STATE_UNKNOWN, "failed to parse warning jitter threshold");
592 } 592 }
593 593
@@ -597,7 +597,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
597 case 'k': { 597 case 'k': {
598 result.config.do_jitter = true; 598 result.config.do_jitter = true;
599 mp_range_parsed tmp = mp_parse_range_string(optarg); 599 mp_range_parsed tmp = mp_parse_range_string(optarg);
600 if (tmp.error != MP_PARSING_SUCCES) { 600 if (tmp.error != MP_PARSING_SUCCESS) {
601 die(STATE_UNKNOWN, "failed to parse critical jitter threshold"); 601 die(STATE_UNKNOWN, "failed to parse critical jitter threshold");
602 } 602 }
603 603
@@ -607,7 +607,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
607 case 'm': { 607 case 'm': {
608 result.config.do_truechimers = true; 608 result.config.do_truechimers = true;
609 mp_range_parsed tmp = mp_parse_range_string(optarg); 609 mp_range_parsed tmp = mp_parse_range_string(optarg);
610 if (tmp.error != MP_PARSING_SUCCES) { 610 if (tmp.error != MP_PARSING_SUCCESS) {
611 die(STATE_UNKNOWN, "failed to parse warning truechimer threshold"); 611 die(STATE_UNKNOWN, "failed to parse warning truechimer threshold");
612 } 612 }
613 613
@@ -617,7 +617,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
617 case 'n': { 617 case 'n': {
618 result.config.do_truechimers = true; 618 result.config.do_truechimers = true;
619 mp_range_parsed tmp = mp_parse_range_string(optarg); 619 mp_range_parsed tmp = mp_parse_range_string(optarg);
620 if (tmp.error != MP_PARSING_SUCCES) { 620 if (tmp.error != MP_PARSING_SUCCESS) {
621 die(STATE_UNKNOWN, "failed to parse critical truechimer threshold"); 621 die(STATE_UNKNOWN, "failed to parse critical truechimer threshold");
622 } 622 }
623 623
@@ -640,11 +640,7 @@ check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) {
640 address_family = AF_INET; 640 address_family = AF_INET;
641 break; 641 break;
642 case '6': 642 case '6':
643#ifdef USE_IPV6
644 address_family = AF_INET6; 643 address_family = AF_INET6;
645#else
646 usage4(_("IPv6 support not available"));
647#endif
648 break; 644 break;
649 case '?': 645 case '?':
650 /* print short usage statement if args not parsable */ 646 /* print short usage statement if args not parsable */
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 9e0beb9c..4e3a55db 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -605,7 +605,7 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
605 break; 605 break;
606 case 'w': { 606 case 'w': {
607 mp_range_parsed tmp = mp_parse_range_string(optarg); 607 mp_range_parsed tmp = mp_parse_range_string(optarg);
608 if (tmp.error != MP_PARSING_SUCCES) { 608 if (tmp.error != MP_PARSING_SUCCESS) {
609 die(STATE_UNKNOWN, "failed to parse warning threshold"); 609 die(STATE_UNKNOWN, "failed to parse warning threshold");
610 } 610 }
611 611
@@ -614,7 +614,7 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
614 } break; 614 } break;
615 case 'c': { 615 case 'c': {
616 mp_range_parsed tmp = mp_parse_range_string(optarg); 616 mp_range_parsed tmp = mp_parse_range_string(optarg);
617 if (tmp.error != MP_PARSING_SUCCES) { 617 if (tmp.error != MP_PARSING_SUCCESS) {
618 die(STATE_UNKNOWN, "failed to parse crit threshold"); 618 die(STATE_UNKNOWN, "failed to parse crit threshold");
619 } 619 }
620 620
@@ -640,11 +640,7 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
640 address_family = AF_INET; 640 address_family = AF_INET;
641 break; 641 break;
642 case '6': 642 case '6':
643#ifdef USE_IPV6
644 address_family = AF_INET6; 643 address_family = AF_INET6;
645#else
646 usage4(_("IPv6 support not available"));
647#endif
648 break; 644 break;
649 case '?': 645 case '?':
650 /* print short usage statement if args not parsable */ 646 /* print short usage statement if args not parsable */
@@ -661,6 +657,14 @@ static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
661} 657}
662 658
663int main(int argc, char *argv[]) { 659int main(int argc, char *argv[]) {
660#ifdef __OpenBSD__
661 /* - rpath is required to read --extra-opts (given up later)
662 * - inet is required for sockets
663 * - unix is required for Unix domain sockets
664 * - dns is required for name lookups */
665 pledge("stdio rpath inet unix dns", NULL);
666#endif // __OpenBSD__
667
664 setlocale(LC_ALL, ""); 668 setlocale(LC_ALL, "");
665 bindtextdomain(PACKAGE, LOCALEDIR); 669 bindtextdomain(PACKAGE, LOCALEDIR);
666 textdomain(PACKAGE); 670 textdomain(PACKAGE);
@@ -674,6 +678,10 @@ int main(int argc, char *argv[]) {
674 usage4(_("Could not parse arguments")); 678 usage4(_("Could not parse arguments"));
675 } 679 }
676 680
681#ifdef __OpenBSD__
682 pledge("stdio inet unix dns", NULL);
683#endif // __OpenBSD__
684
677 const check_ntp_time_config config = tmp_config.config; 685 const check_ntp_time_config config = tmp_config.config;
678 686
679 if (config.output_format_is_set) { 687 if (config.output_format_is_set) {
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 0ce75e0a..8cbaaeeb 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -401,7 +401,7 @@ static check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
401 break; 401 break;
402 case 'c': /* critical time threshold */ { 402 case 'c': /* critical time threshold */ {
403 mp_range_parsed tmp = mp_parse_range_string(optarg); 403 mp_range_parsed tmp = mp_parse_range_string(optarg);
404 if (tmp.error != MP_PARSING_SUCCES) { 404 if (tmp.error != MP_PARSING_SUCCESS) {
405 die(STATE_UNKNOWN, "failed to parse critical time threshold"); 405 die(STATE_UNKNOWN, "failed to parse critical time threshold");
406 } 406 }
407 result.config.time_thresholds = 407 result.config.time_thresholds =
@@ -409,7 +409,7 @@ static check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
409 } break; 409 } break;
410 case 'w': /* warning time threshold */ { 410 case 'w': /* warning time threshold */ {
411 mp_range_parsed tmp = mp_parse_range_string(optarg); 411 mp_range_parsed tmp = mp_parse_range_string(optarg);
412 if (tmp.error != MP_PARSING_SUCCES) { 412 if (tmp.error != MP_PARSING_SUCCESS) {
413 die(STATE_UNKNOWN, "failed to parse warning time threshold"); 413 die(STATE_UNKNOWN, "failed to parse warning time threshold");
414 } 414 }
415 result.config.time_thresholds = 415 result.config.time_thresholds =
@@ -417,7 +417,7 @@ static check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
417 } break; 417 } break;
418 case 'C': /* critical query threshold */ { 418 case 'C': /* critical query threshold */ {
419 mp_range_parsed tmp = mp_parse_range_string(optarg); 419 mp_range_parsed tmp = mp_parse_range_string(optarg);
420 if (tmp.error != MP_PARSING_SUCCES) { 420 if (tmp.error != MP_PARSING_SUCCESS) {
421 die(STATE_UNKNOWN, "failed to parse critical query threshold"); 421 die(STATE_UNKNOWN, "failed to parse critical query threshold");
422 } 422 }
423 423
@@ -427,7 +427,7 @@ static check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
427 } break; 427 } break;
428 case 'W': /* warning query threshold */ { 428 case 'W': /* warning query threshold */ {
429 mp_range_parsed tmp = mp_parse_range_string(optarg); 429 mp_range_parsed tmp = mp_parse_range_string(optarg);
430 if (tmp.error != MP_PARSING_SUCCES) { 430 if (tmp.error != MP_PARSING_SUCCESS) {
431 die(STATE_UNKNOWN, "failed to parse warning query threshold"); 431 die(STATE_UNKNOWN, "failed to parse warning query threshold");
432 } 432 }
433 result.config.qthresholds = 433 result.config.qthresholds =
diff --git a/plugins/check_ping.c b/plugins/check_ping.c
index 61feb958..e1ee0f5c 100644
--- a/plugins/check_ping.c
+++ b/plugins/check_ping.c
@@ -246,11 +246,7 @@ check_ping_config_wrapper process_arguments(int argc, char **argv) {
246 address_family = AF_INET; 246 address_family = AF_INET;
247 break; 247 break;
248 case '6': /* IPv6 only */ 248 case '6': /* IPv6 only */
249#ifdef USE_IPV6
250 address_family = AF_INET6; 249 address_family = AF_INET6;
251#else
252 usage(_("IPv6 support not available\n"));
253#endif
254 break; 250 break;
255 case 'H': /* hostname */ { 251 case 'H': /* hostname */ {
256 char *ptr = optarg; 252 char *ptr = optarg;
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index ae6e9c23..50837cb4 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -430,7 +430,7 @@ check_procs_config_wrapper process_arguments(int argc, char **argv) {
430 while (true) { 430 while (true) {
431 int option = 0; 431 int option = 0;
432 int option_index = 432 int option_index =
433 getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); 433 getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:TX:", longopts, &option);
434 434
435 if (option_index == -1 || option_index == EOF) { 435 if (option_index == -1 || option_index == EOF) {
436 break; 436 break;
diff --git a/plugins/check_real.c b/plugins/check_real.c
index 66d07f8f..b415578f 100644
--- a/plugins/check_real.c
+++ b/plugins/check_real.c
@@ -28,19 +28,21 @@
28 * 28 *
29 *****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "output.h"
32#include "perfdata.h"
31#include "states.h" 33#include "states.h"
32#include <stdio.h> 34#include <stdio.h>
33const char *progname = "check_real";
34const char *copyright = "2000-2024";
35const char *email = "devel@monitoring-plugins.org";
36
37#include "common.h" 35#include "common.h"
38#include "netutils.h" 36#include "netutils.h"
37#include "thresholds.h"
39#include "utils.h" 38#include "utils.h"
40#include "check_real.d/config.h" 39#include "check_real.d/config.h"
41 40
42#define EXPECT "RTSP/1." 41const char *progname = "check_real";
43#define URL "" 42const char *copyright = "2000-2024";
43const char *email = "devel@monitoring-plugins.org";
44
45#define URL ""
44 46
45typedef struct { 47typedef struct {
46 int errorcode; 48 int errorcode;
@@ -68,42 +70,68 @@ int main(int argc, char **argv) {
68 70
69 const check_real_config config = tmp_config.config; 71 const check_real_config config = tmp_config.config;
70 72
73 if (config.output_format_is_set) {
74 mp_set_format(config.output_format);
75 }
76
71 /* initialize alarm signal handling */ 77 /* initialize alarm signal handling */
72 signal(SIGALRM, socket_timeout_alarm_handler); 78 signal(SIGALRM, socket_timeout_alarm_handler);
73 79
74 /* set socket timeout */ 80 /* set socket timeout */
75 alarm(socket_timeout); 81 alarm(socket_timeout);
82 time_t start_time;
76 time(&start_time); 83 time(&start_time);
77 84
85 mp_check overall = mp_check_init();
86 mp_subcheck sc_connect = mp_subcheck_init();
87
78 /* try to connect to the host at the given port number */ 88 /* try to connect to the host at the given port number */
79 int socket; 89 int socket;
80 if (my_tcp_connect(config.server_address, config.server_port, &socket) != STATE_OK) { 90 if (my_tcp_connect(config.server_address, config.server_port, &socket) != STATE_OK) {
81 die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), config.server_address, 91 xasprintf(&sc_connect.output, _("unable to connect to %s on port %d"),
82 config.server_port); 92 config.server_address, config.server_port);
93 sc_connect = mp_set_subcheck_state(sc_connect, STATE_CRITICAL);
94 mp_add_subcheck_to_check(&overall, sc_connect);
95 mp_exit(overall);
83 } 96 }
84 97
98 xasprintf(&sc_connect.output, _("connected to %s on port %d"), config.server_address,
99 config.server_port);
100 sc_connect = mp_set_subcheck_state(sc_connect, STATE_OK);
101 mp_add_subcheck_to_check(&overall, sc_connect);
102
85 /* Part I - Server Check */ 103 /* Part I - Server Check */
104 mp_subcheck sc_send = mp_subcheck_init();
86 105
87 /* send the OPTIONS request */ 106 /* send the OPTIONS request */
88 char buffer[MAX_INPUT_BUFFER]; 107 char buffer[MAX_INPUT_BUFFER];
89 sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", config.host_name, config.server_port); 108 sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", config.host_name, config.server_port);
90 ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0); 109 ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0);
91 if (sent_bytes == -1) { 110 if (sent_bytes == -1) {
92 die(STATE_CRITICAL, _("Sending options to %s failed\n"), config.host_name); 111 xasprintf(&sc_send.output, _("Sending options to %s failed"), config.host_name);
112 sc_send = mp_set_subcheck_state(sc_send, STATE_CRITICAL);
113 mp_add_subcheck_to_check(&overall, sc_send);
114 mp_exit(overall);
93 } 115 }
94 116
95 /* send the header sync */ 117 /* send the header sync */
96 sprintf(buffer, "CSeq: 1\r\n"); 118 sprintf(buffer, "CSeq: 1\r\n");
97 sent_bytes = send(socket, buffer, strlen(buffer), 0); 119 sent_bytes = send(socket, buffer, strlen(buffer), 0);
98 if (sent_bytes == -1) { 120 if (sent_bytes == -1) {
99 die(STATE_CRITICAL, _("Sending header sync to %s failed\n"), config.host_name); 121 xasprintf(&sc_send.output, _("Sending header sync to %s failed"), config.host_name);
122 sc_send = mp_set_subcheck_state(sc_send, STATE_CRITICAL);
123 mp_add_subcheck_to_check(&overall, sc_send);
124 mp_exit(overall);
100 } 125 }
101 126
102 /* send a newline so the server knows we're done with the request */ 127 /* send a newline so the server knows we're done with the request */
103 sprintf(buffer, "\r\n"); 128 sprintf(buffer, "\r\n");
104 sent_bytes = send(socket, buffer, strlen(buffer), 0); 129 sent_bytes = send(socket, buffer, strlen(buffer), 0);
105 if (sent_bytes == -1) { 130 if (sent_bytes == -1) {
106 die(STATE_CRITICAL, _("Sending newline to %s failed\n"), config.host_name); 131 xasprintf(&sc_send.output, _("Sending newline to %s failed"), config.host_name);
132 sc_send = mp_set_subcheck_state(sc_send, STATE_CRITICAL);
133 mp_add_subcheck_to_check(&overall, sc_send);
134 mp_exit(overall);
107 } 135 }
108 136
109 /* watch for the REAL connection string */ 137 /* watch for the REAL connection string */
@@ -111,60 +139,75 @@ int main(int argc, char **argv) {
111 139
112 /* return a CRITICAL status if we couldn't read any data */ 140 /* return a CRITICAL status if we couldn't read any data */
113 if (received_bytes == -1) { 141 if (received_bytes == -1) {
114 die(STATE_CRITICAL, _("No data received from %s\n"), config.host_name); 142 xasprintf(&sc_send.output, _("No data received from %s"), config.host_name);
143 sc_send = mp_set_subcheck_state(sc_send, STATE_CRITICAL);
144 mp_add_subcheck_to_check(&overall, sc_send);
145 mp_exit(overall);
115 } 146 }
116 147
117 mp_state_enum result = STATE_OK; 148 time_t end_time;
118 char *status_line = NULL; 149 {
119 /* make sure we find the response we are looking for */ 150 mp_subcheck sc_options_request = mp_subcheck_init();
120 if (!strstr(buffer, config.server_expect)) { 151 mp_state_enum options_result = STATE_OK;
121 if (config.server_port == PORT) { 152 /* make sure we find the response we are looking for */
122 printf("%s\n", _("Invalid REAL response received from host")); 153 if (!strstr(buffer, config.server_expect)) {
154 if (config.server_port == PORT) {
155 xasprintf(&sc_options_request.output, "invalid REAL response received from host");
156 } else {
157 xasprintf(&sc_options_request.output,
158 "invalid REAL response received from host on port %d",
159 config.server_port);
160 }
123 } else { 161 } else {
124 printf(_("Invalid REAL response received from host on port %d\n"), config.server_port); 162 /* else we got the REAL string, so check the return code */
125 } 163 time(&end_time);
126 } else {
127 /* else we got the REAL string, so check the return code */
128 164
129 time(&end_time); 165 options_result = STATE_OK;
130 166
131 result = STATE_OK; 167 char *status_line = strtok(buffer, "\n");
168 xasprintf(&sc_options_request.output, "status line: %s", status_line);
132 169
133 status_line = strtok(buffer, "\n"); 170 if (strstr(status_line, "200")) {
134 171 options_result = STATE_OK;
135 if (strstr(status_line, "200")) { 172 }
136 result = STATE_OK; 173 /* client errors options_result in a warning state */
174 else if (strstr(status_line, "400")) {
175 options_result = STATE_WARNING;
176 } else if (strstr(status_line, "401")) {
177 options_result = STATE_WARNING;
178 } else if (strstr(status_line, "402")) {
179 options_result = STATE_WARNING;
180 } else if (strstr(status_line, "403")) {
181 options_result = STATE_WARNING;
182 } else if (strstr(status_line, "404")) {
183 options_result = STATE_WARNING;
184 } else if (strstr(status_line, "500")) {
185 /* server errors options_result in a critical state */
186 options_result = STATE_CRITICAL;
187 } else if (strstr(status_line, "501")) {
188 options_result = STATE_CRITICAL;
189 } else if (strstr(status_line, "502")) {
190 options_result = STATE_CRITICAL;
191 } else if (strstr(status_line, "503")) {
192 options_result = STATE_CRITICAL;
193 } else {
194 options_result = STATE_UNKNOWN;
195 }
137 } 196 }
138 197
139 /* client errors result in a warning state */ 198 sc_options_request = mp_set_subcheck_state(sc_options_request, options_result);
140 else if (strstr(status_line, "400")) { 199 mp_add_subcheck_to_check(&overall, sc_options_request);
141 result = STATE_WARNING; 200
142 } else if (strstr(status_line, "401")) { 201 if (options_result != STATE_OK) {
143 result = STATE_WARNING; 202 // exit here if Setting options already failed
144 } else if (strstr(status_line, "402")) { 203 mp_exit(overall);
145 result = STATE_WARNING;
146 } else if (strstr(status_line, "403")) {
147 result = STATE_WARNING;
148 } else if (strstr(status_line, "404")) {
149 result = STATE_WARNING;
150 } else if (strstr(status_line, "500")) {
151 /* server errors result in a critical state */
152 result = STATE_CRITICAL;
153 } else if (strstr(status_line, "501")) {
154 result = STATE_CRITICAL;
155 } else if (strstr(status_line, "502")) {
156 result = STATE_CRITICAL;
157 } else if (strstr(status_line, "503")) {
158 result = STATE_CRITICAL;
159 } else {
160 result = STATE_UNKNOWN;
161 } 204 }
162 } 205 }
163 206
164 /* Part II - Check stream exists and is ok */ 207 /* Part II - Check stream exists and is ok */
165 if ((result == STATE_OK) && (config.server_url != NULL)) { 208 if (config.server_url != NULL) {
166
167 /* Part I - Server Check */ 209 /* Part I - Server Check */
210 mp_subcheck sc_describe = mp_subcheck_init();
168 211
169 /* send the DESCRIBE request */ 212 /* send the DESCRIBE request */
170 sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", config.host_name, 213 sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", config.host_name,
@@ -172,98 +215,115 @@ int main(int argc, char **argv) {
172 215
173 ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0); 216 ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0);
174 if (sent_bytes == -1) { 217 if (sent_bytes == -1) {
175 die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); 218 sc_describe = mp_set_subcheck_state(sc_describe, STATE_CRITICAL);
219 xasprintf(&sc_describe.output, "sending DESCRIBE request to %s failed",
220 config.host_name);
221 mp_add_subcheck_to_check(&overall, sc_describe);
222 mp_exit(overall);
176 } 223 }
177 224
178 /* send the header sync */ 225 /* send the header sync */
179 sprintf(buffer, "CSeq: 2\r\n"); 226 sprintf(buffer, "CSeq: 2\r\n");
180 sent_bytes = send(socket, buffer, strlen(buffer), 0); 227 sent_bytes = send(socket, buffer, strlen(buffer), 0);
181 if (sent_bytes == -1) { 228 if (sent_bytes == -1) {
182 die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); 229 sc_describe = mp_set_subcheck_state(sc_describe, STATE_CRITICAL);
230 xasprintf(&sc_describe.output, "sending DESCRIBE request to %s failed",
231 config.host_name);
232 mp_add_subcheck_to_check(&overall, sc_describe);
233 mp_exit(overall);
183 } 234 }
184 235
185 /* send a newline so the server knows we're done with the request */ 236 /* send a newline so the server knows we're done with the request */
186 sprintf(buffer, "\r\n"); 237 sprintf(buffer, "\r\n");
187 sent_bytes = send(socket, buffer, strlen(buffer), 0); 238 sent_bytes = send(socket, buffer, strlen(buffer), 0);
188 if (sent_bytes == -1) { 239 if (sent_bytes == -1) {
189 die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); 240 sc_describe = mp_set_subcheck_state(sc_describe, STATE_CRITICAL);
241 xasprintf(&sc_describe.output, "sending DESCRIBE request to %s failed",
242 config.host_name);
243 mp_add_subcheck_to_check(&overall, sc_describe);
244 mp_exit(overall);
190 } 245 }
191 246
192 /* watch for the REAL connection string */ 247 /* watch for the REAL connection string */
193 ssize_t recv_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); 248 ssize_t recv_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0);
194 if (recv_bytes == -1) { 249 if (recv_bytes == -1) {
195 /* return a CRITICAL status if we couldn't read any data */ 250 /* return a CRITICAL status if we couldn't read any data */
196 printf(_("No data received from host\n")); 251 sc_describe = mp_set_subcheck_state(sc_describe, STATE_CRITICAL);
197 result = STATE_CRITICAL; 252 xasprintf(&sc_describe.output, "No data received from host on DESCRIBE request");
253 mp_add_subcheck_to_check(&overall, sc_describe);
254 mp_exit(overall);
198 } else { 255 } else {
199 buffer[result] = '\0'; /* null terminate received buffer */ 256 buffer[recv_bytes] = '\0'; /* null terminate received buffer */
200 /* make sure we find the response we are looking for */ 257 /* make sure we find the response we are looking for */
201 if (!strstr(buffer, config.server_expect)) { 258 if (!strstr(buffer, config.server_expect)) {
202 if (config.server_port == PORT) { 259 if (config.server_port == PORT) {
203 printf("%s\n", _("Invalid REAL response received from host")); 260 xasprintf(&sc_describe.output, "invalid REAL response received from host");
204 } else { 261 } else {
205 printf(_("Invalid REAL response received from host on port %d\n"), 262 xasprintf(&sc_describe.output,
206 config.server_port); 263 "invalid REAL response received from host on port %d",
264 config.server_port);
207 } 265 }
208 } else {
209 266
267 sc_describe = mp_set_subcheck_state(sc_describe, STATE_UNKNOWN);
268 mp_add_subcheck_to_check(&overall, sc_describe);
269 mp_exit(overall);
270 } else {
210 /* else we got the REAL string, so check the return code */ 271 /* else we got the REAL string, so check the return code */
211 272
212 time(&end_time); 273 time(&end_time);
213 274
214 result = STATE_OK; 275 char *status_line = strtok(buffer, "\n");
215 276 xasprintf(&sc_describe.output, "status line: %s", status_line);
216 status_line = strtok(buffer, "\n");
217 277
278 mp_state_enum describe_result;
218 if (strstr(status_line, "200")) { 279 if (strstr(status_line, "200")) {
219 result = STATE_OK; 280 describe_result = STATE_OK;
220 } 281 }
221 282 /* client errors describe_result in a warning state */
222 /* client errors result in a warning state */
223 else if (strstr(status_line, "400")) { 283 else if (strstr(status_line, "400")) {
224 result = STATE_WARNING; 284 describe_result = STATE_WARNING;
225 } else if (strstr(status_line, "401")) { 285 } else if (strstr(status_line, "401")) {
226 result = STATE_WARNING; 286 describe_result = STATE_WARNING;
227 } else if (strstr(status_line, "402")) { 287 } else if (strstr(status_line, "402")) {
228 result = STATE_WARNING; 288 describe_result = STATE_WARNING;
229 } else if (strstr(status_line, "403")) { 289 } else if (strstr(status_line, "403")) {
230 result = STATE_WARNING; 290 describe_result = STATE_WARNING;
231 } else if (strstr(status_line, "404")) { 291 } else if (strstr(status_line, "404")) {
232 result = STATE_WARNING; 292 describe_result = STATE_WARNING;
233 } 293 }
234 294 /* server errors describe_result in a critical state */
235 /* server errors result in a critical state */
236 else if (strstr(status_line, "500")) { 295 else if (strstr(status_line, "500")) {
237 result = STATE_CRITICAL; 296 describe_result = STATE_CRITICAL;
238 } else if (strstr(status_line, "501")) { 297 } else if (strstr(status_line, "501")) {
239 result = STATE_CRITICAL; 298 describe_result = STATE_CRITICAL;
240 } else if (strstr(status_line, "502")) { 299 } else if (strstr(status_line, "502")) {
241 result = STATE_CRITICAL; 300 describe_result = STATE_CRITICAL;
242 } else if (strstr(status_line, "503")) { 301 } else if (strstr(status_line, "503")) {
243 result = STATE_CRITICAL; 302 describe_result = STATE_CRITICAL;
303 } else {
304 describe_result = STATE_UNKNOWN;
244 } 305 }
245 306
246 else { 307 sc_describe = mp_set_subcheck_state(sc_describe, describe_result);
247 result = STATE_UNKNOWN; 308 mp_add_subcheck_to_check(&overall, sc_describe);
248 }
249 } 309 }
250 } 310 }
251 } 311 }
252 312
253 /* Return results */ 313 /* Return results */
254 if (result == STATE_OK) { 314 mp_subcheck sc_timing = mp_subcheck_init();
255 if (config.check_critical_time && (end_time - start_time) > config.critical_time) { 315 xasprintf(&sc_timing.output, "response time: %lds", end_time - start_time);
256 result = STATE_CRITICAL; 316 sc_timing = mp_set_subcheck_default_state(sc_timing, STATE_OK);
257 } else if (config.check_warning_time && (end_time - start_time) > config.warning_time) {
258 result = STATE_WARNING;
259 }
260 317
261 /* Put some HTML in here to create a dynamic link */ 318 mp_perfdata pd_response_time = perfdata_init();
262 printf(_("REAL %s - %d second response time\n"), state_text(result), 319 pd_response_time = mp_set_pd_value(pd_response_time, (end_time - start_time));
263 (int)(end_time - start_time)); 320 pd_response_time.label = "response_time";
264 } else { 321 pd_response_time.uom = "s";
265 printf("%s\n", status_line); 322 pd_response_time = mp_pd_set_thresholds(pd_response_time, config.time_thresholds);
266 } 323 mp_add_perfdata_to_subcheck(&sc_connect, pd_response_time);
324 sc_timing = mp_set_subcheck_state(sc_timing, mp_get_pd_status(pd_response_time));
325
326 mp_add_subcheck_to_check(&overall, sc_timing);
267 327
268 /* close the connection */ 328 /* close the connection */
269 close(socket); 329 close(socket);
@@ -271,18 +331,28 @@ int main(int argc, char **argv) {
271 /* reset the alarm */ 331 /* reset the alarm */
272 alarm(0); 332 alarm(0);
273 333
274 exit(result); 334 mp_exit(overall);
275} 335}
276 336
277/* process command-line arguments */ 337/* process command-line arguments */
278check_real_config_wrapper process_arguments(int argc, char **argv) { 338check_real_config_wrapper process_arguments(int argc, char **argv) {
279 static struct option longopts[] = { 339 enum {
280 {"hostname", required_argument, 0, 'H'}, {"IPaddress", required_argument, 0, 'I'}, 340 output_format_index = CHAR_MAX + 1,
281 {"expect", required_argument, 0, 'e'}, {"url", required_argument, 0, 'u'}, 341 };
282 {"port", required_argument, 0, 'p'}, {"critical", required_argument, 0, 'c'}, 342
283 {"warning", required_argument, 0, 'w'}, {"timeout", required_argument, 0, 't'}, 343 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
284 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 344 {"IPaddress", required_argument, 0, 'I'},
285 {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; 345 {"expect", required_argument, 0, 'e'},
346 {"url", required_argument, 0, 'u'},
347 {"port", required_argument, 0, 'p'},
348 {"critical", required_argument, 0, 'c'},
349 {"warning", required_argument, 0, 'w'},
350 {"timeout", required_argument, 0, 't'},
351 {"verbose", no_argument, 0, 'v'},
352 {"version", no_argument, 0, 'V'},
353 {"help", no_argument, 0, 'h'},
354 {"output-format", required_argument, 0, output_format_index},
355 {0, 0, 0, 0}};
286 356
287 check_real_config_wrapper result = { 357 check_real_config_wrapper result = {
288 .errorcode = OK, 358 .errorcode = OK,
@@ -337,21 +407,23 @@ check_real_config_wrapper process_arguments(int argc, char **argv) {
337 } 407 }
338 break; 408 break;
339 case 'w': /* warning time threshold */ 409 case 'w': /* warning time threshold */
340 if (is_intnonneg(optarg)) { 410 {
341 result.config.warning_time = atoi(optarg); 411 mp_range_parsed critical_range = mp_parse_range_string(optarg);
342 result.config.check_warning_time = true; 412 if (critical_range.error != MP_PARSING_SUCCESS) {
343 } else { 413 die(STATE_UNKNOWN, "failed to parse warning threshold: %s", optarg);
344 usage4(_("Warning time must be a positive integer"));
345 } 414 }
346 break; 415 result.config.time_thresholds =
416 mp_thresholds_set_warn(result.config.time_thresholds, critical_range.range);
417 } break;
347 case 'c': /* critical time threshold */ 418 case 'c': /* critical time threshold */
348 if (is_intnonneg(optarg)) { 419 {
349 result.config.critical_time = atoi(optarg); 420 mp_range_parsed critical_range = mp_parse_range_string(optarg);
350 result.config.check_critical_time = true; 421 if (critical_range.error != MP_PARSING_SUCCESS) {
351 } else { 422 die(STATE_UNKNOWN, "failed to parse critical threshold: %s", optarg);
352 usage4(_("Critical time must be a positive integer"));
353 } 423 }
354 break; 424 result.config.time_thresholds =
425 mp_thresholds_set_crit(result.config.time_thresholds, critical_range.range);
426 } break;
355 case 'v': /* verbose */ 427 case 'v': /* verbose */
356 verbose = true; 428 verbose = true;
357 break; 429 break;
@@ -368,6 +440,18 @@ check_real_config_wrapper process_arguments(int argc, char **argv) {
368 case 'h': /* help */ 440 case 'h': /* help */
369 print_help(); 441 print_help();
370 exit(STATE_UNKNOWN); 442 exit(STATE_UNKNOWN);
443 case output_format_index: {
444 parsed_output_format parser = mp_parse_output_format(optarg);
445 if (!parser.parsing_success) {
446 // TODO List all available formats here, maybe add anothoer usage function
447 printf("Invalid output format: %s\n", optarg);
448 exit(STATE_UNKNOWN);
449 }
450
451 result.config.output_format_is_set = true;
452 result.config.output_format = parser.output_format;
453 break;
454 }
371 case '?': /* usage */ 455 case '?': /* usage */
372 usage5(); 456 usage5();
373 } 457 }
@@ -390,10 +474,6 @@ check_real_config_wrapper process_arguments(int argc, char **argv) {
390 result.config.host_name = strdup(result.config.server_address); 474 result.config.host_name = strdup(result.config.server_address);
391 } 475 }
392 476
393 if (result.config.server_expect == NULL) {
394 result.config.server_expect = strdup(EXPECT);
395 }
396
397 return result; 477 return result;
398} 478}
399 479
@@ -420,7 +500,7 @@ void print_help(void) {
420 printf(" %s\n", "-u, --url=STRING"); 500 printf(" %s\n", "-u, --url=STRING");
421 printf(" %s\n", _("Connect to this url")); 501 printf(" %s\n", _("Connect to this url"));
422 printf(" %s\n", "-e, --expect=STRING"); 502 printf(" %s\n", "-e, --expect=STRING");
423 printf(_("String to expect in first line of server response (default: %s)\n"), EXPECT); 503 printf(_("String to expect in first line of server response (default: %s)\n"), default_expect);
424 504
425 printf(UT_WARN_CRIT); 505 printf(UT_WARN_CRIT);
426 506
diff --git a/plugins/check_real.d/config.h b/plugins/check_real.d/config.h
index c4663cf9..2d99ad49 100644
--- a/plugins/check_real.d/config.h
+++ b/plugins/check_real.d/config.h
@@ -1,12 +1,16 @@
1#pragma once 1#pragma once
2 2
3#include "../../config.h" 3#include "../../config.h"
4#include "output.h"
5#include "thresholds.h"
4#include <stddef.h> 6#include <stddef.h>
5 7
6enum { 8enum {
7 PORT = 554 9 PORT = 554
8}; 10};
9 11
12const char *default_expect = "RTSP/1.";
13
10typedef struct { 14typedef struct {
11 char *server_address; 15 char *server_address;
12 char *host_name; 16 char *host_name;
@@ -14,10 +18,11 @@ typedef struct {
14 char *server_url; 18 char *server_url;
15 19
16 char *server_expect; 20 char *server_expect;
17 int warning_time; 21
18 bool check_warning_time; 22 mp_thresholds time_thresholds;
19 int critical_time; 23
20 bool check_critical_time; 24 bool output_format_is_set;
25 mp_output_format output_format;
21} check_real_config; 26} check_real_config;
22 27
23check_real_config check_real_config_init() { 28check_real_config check_real_config_init() {
@@ -27,11 +32,11 @@ check_real_config check_real_config_init() {
27 .server_port = PORT, 32 .server_port = PORT,
28 .server_url = NULL, 33 .server_url = NULL,
29 34
30 .server_expect = NULL, 35 .server_expect = default_expect,
31 .warning_time = 0, 36
32 .check_warning_time = false, 37 .time_thresholds = mp_thresholds_init(),
33 .critical_time = 0, 38
34 .check_critical_time = false, 39 .output_format_is_set = false,
35 }; 40 };
36 return tmp; 41 return tmp;
37} 42}
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index e806ad29..24883fd8 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -37,7 +37,6 @@
37#include "base64.h" 37#include "base64.h"
38#include "regex.h" 38#include "regex.h"
39 39
40#include <bits/getopt_ext.h>
41#include <ctype.h> 40#include <ctype.h>
42#include <string.h> 41#include <string.h>
43#include "check_smtp.d/config.h" 42#include "check_smtp.d/config.h"
@@ -101,6 +100,14 @@ static int my_close(int /*socket_descriptor*/);
101static int verbose = 0; 100static int verbose = 0;
102 101
103int main(int argc, char **argv) { 102int main(int argc, char **argv) {
103#ifdef __OpenBSD__
104 /* - rpath is required to read --extra-opts (given up later)
105 * - inet is required for sockets
106 * - unix is required for Unix domain sockets
107 * - dns is required for name lookups */
108 pledge("stdio rpath inet unix dns", NULL);
109#endif // __OpenBSD__
110
104 setlocale(LC_ALL, ""); 111 setlocale(LC_ALL, "");
105 bindtextdomain(PACKAGE, LOCALEDIR); 112 bindtextdomain(PACKAGE, LOCALEDIR);
106 textdomain(PACKAGE); 113 textdomain(PACKAGE);
@@ -114,6 +121,10 @@ int main(int argc, char **argv) {
114 usage4(_("Could not parse arguments")); 121 usage4(_("Could not parse arguments"));
115 } 122 }
116 123
124#ifdef __OpenBSD__
125 pledge("stdio inet unix dns", NULL);
126#endif // __OpenBSD__
127
117 const check_smtp_config config = tmp_config.config; 128 const check_smtp_config config = tmp_config.config;
118 129
119 if (config.output_format_is_set) { 130 if (config.output_format_is_set) {
@@ -724,7 +735,7 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) {
724 break; 735 break;
725 case 'c': /* critical time threshold */ { 736 case 'c': /* critical time threshold */ {
726 mp_range_parsed tmp = mp_parse_range_string(optarg); 737 mp_range_parsed tmp = mp_parse_range_string(optarg);
727 if (tmp.error != MP_PARSING_SUCCES) { 738 if (tmp.error != MP_PARSING_SUCCESS) {
728 die(STATE_UNKNOWN, "failed to parse critical time threshold"); 739 die(STATE_UNKNOWN, "failed to parse critical time threshold");
729 } 740 }
730 result.config.connection_time = 741 result.config.connection_time =
@@ -732,7 +743,7 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) {
732 } break; 743 } break;
733 case 'w': /* warning time threshold */ { 744 case 'w': /* warning time threshold */ {
734 mp_range_parsed tmp = mp_parse_range_string(optarg); 745 mp_range_parsed tmp = mp_parse_range_string(optarg);
735 if (tmp.error != MP_PARSING_SUCCES) { 746 if (tmp.error != MP_PARSING_SUCCESS) {
736 die(STATE_UNKNOWN, "failed to parse warning time threshold"); 747 die(STATE_UNKNOWN, "failed to parse warning time threshold");
737 } 748 }
738 result.config.connection_time = 749 result.config.connection_time =
@@ -808,11 +819,7 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) {
808 address_family = AF_INET; 819 address_family = AF_INET;
809 break; 820 break;
810 case '6': 821 case '6':
811#ifdef USE_IPV6
812 address_family = AF_INET6; 822 address_family = AF_INET6;
813#else
814 usage4(_("IPv6 support not available"));
815#endif
816 break; 823 break;
817 case 'V': /* version */ 824 case 'V': /* version */
818 print_revision(progname, NP_VERSION); 825 print_revision(progname, NP_VERSION);
diff --git a/plugins/check_snmp.d/check_snmp_helpers.c b/plugins/check_snmp.d/check_snmp_helpers.c
index f506537a..83e94a34 100644
--- a/plugins/check_snmp.d/check_snmp_helpers.c
+++ b/plugins/check_snmp.d/check_snmp_helpers.c
@@ -36,7 +36,8 @@ int check_snmp_set_thresholds(const char *threshold_string, check_snmp_test_unit
36 threshold_string++; 36 threshold_string++;
37 } 37 }
38 38
39 for (char *ptr = strtok(threshold_string, ", "); ptr != NULL; 39 char *thr_string_copy = strdup(threshold_string);
40 for (char *ptr = strtok(thr_string_copy, ", "); ptr != NULL;
40 ptr = strtok(NULL, ", "), tu_index++) { 41 ptr = strtok(NULL, ", "), tu_index++) {
41 42
42 if (tu_index > max_test_units) { 43 if (tu_index > max_test_units) {
@@ -51,7 +52,7 @@ int check_snmp_set_thresholds(const char *threshold_string, check_snmp_test_unit
51 } 52 }
52 53
53 mp_range_parsed tmp = mp_parse_range_string(ptr); 54 mp_range_parsed tmp = mp_parse_range_string(ptr);
54 if (tmp.error != MP_PARSING_SUCCES) { 55 if (tmp.error != MP_PARSING_SUCCESS) {
55 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", ptr); 56 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", ptr);
56 } 57 }
57 58
@@ -64,11 +65,12 @@ int check_snmp_set_thresholds(const char *threshold_string, check_snmp_test_unit
64 } 65 }
65 } 66 }
66 67
68 free(thr_string_copy);
67 } else { 69 } else {
68 // Single value 70 // Single value
69 // only valid for the first test unit 71 // only valid for the first test unit
70 mp_range_parsed tmp = mp_parse_range_string(threshold_string); 72 mp_range_parsed tmp = mp_parse_range_string(threshold_string);
71 if (tmp.error != MP_PARSING_SUCCES) { 73 if (tmp.error != MP_PARSING_SUCCESS) {
72 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", threshold_string); 74 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", threshold_string);
73 } 75 }
74 76
@@ -843,8 +845,8 @@ char *_np_state_calculate_location_prefix(void) {
843 * Sets variables. Generates filename. Returns np_state_key. die with 845 * Sets variables. Generates filename. Returns np_state_key. die with
844 * UNKNOWN if exception 846 * UNKNOWN if exception
845 */ 847 */
846state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, 848state_key np_enable_state(char *keyname, int expected_data_version, const char *plugin_name,
847 char **argv) { 849 int argc, char **argv) {
848 state_key *this_state = (state_key *)calloc(1, sizeof(state_key)); 850 state_key *this_state = (state_key *)calloc(1, sizeof(state_key));
849 if (this_state == NULL) { 851 if (this_state == NULL) {
850 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); 852 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno));
@@ -869,7 +871,7 @@ state_key np_enable_state(char *keyname, int expected_data_version, char *plugin
869 tmp_char++; 871 tmp_char++;
870 } 872 }
871 this_state->name = temp_keyname; 873 this_state->name = temp_keyname;
872 this_state->plugin_name = plugin_name; 874 this_state->plugin_name = (char *)plugin_name;
873 this_state->data_version = expected_data_version; 875 this_state->data_version = expected_data_version;
874 this_state->state_data = NULL; 876 this_state->state_data = NULL;
875 877
diff --git a/plugins/check_snmp.d/check_snmp_helpers.h b/plugins/check_snmp.d/check_snmp_helpers.h
index 0f7780b1..95b361ac 100644
--- a/plugins/check_snmp.d/check_snmp_helpers.h
+++ b/plugins/check_snmp.d/check_snmp_helpers.h
@@ -66,6 +66,6 @@ typedef struct state_key_struct {
66} state_key; 66} state_key;
67 67
68state_data *np_state_read(state_key stateKey); 68state_data *np_state_read(state_key stateKey);
69state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, 69state_key np_enable_state(char *keyname, int expected_data_version, const char *plugin_name,
70 char **argv); 70 int argc, char **argv);
71void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore); 71void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore);
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c
index f6c8d551..911f6787 100644
--- a/plugins/check_ssh.c
+++ b/plugins/check_ssh.c
@@ -61,6 +61,14 @@ static int ssh_connect(mp_check *overall, char *haddr, int hport, char *remote_v
61 char *remote_protocol); 61 char *remote_protocol);
62 62
63int main(int argc, char **argv) { 63int main(int argc, char **argv) {
64#ifdef __OpenBSD__
65 /* - rpath is required to read --extra-opts (given up later)
66 * - inet is required for sockets
67 * - unix is required for Unix domain sockets
68 * - dns is required for name lookups */
69 pledge("stdio rpath inet unix dns", NULL);
70#endif // __OpenBSD__
71
64 setlocale(LC_ALL, ""); 72 setlocale(LC_ALL, "");
65 bindtextdomain(PACKAGE, LOCALEDIR); 73 bindtextdomain(PACKAGE, LOCALEDIR);
66 textdomain(PACKAGE); 74 textdomain(PACKAGE);
@@ -74,6 +82,10 @@ int main(int argc, char **argv) {
74 usage4(_("Could not parse arguments")); 82 usage4(_("Could not parse arguments"));
75 } 83 }
76 84
85#ifdef __OpenBSD__
86 pledge("stdio inet unix dns", NULL);
87#endif // __OpenBSD__
88
77 check_ssh_config config = tmp_config.config; 89 check_ssh_config config = tmp_config.config;
78 90
79 mp_check overall = mp_check_init(); 91 mp_check overall = mp_check_init();
@@ -161,11 +173,7 @@ process_arguments_wrapper process_arguments(int argc, char **argv) {
161 address_family = AF_INET; 173 address_family = AF_INET;
162 break; 174 break;
163 case '6': 175 case '6':
164#ifdef USE_IPV6
165 address_family = AF_INET6; 176 address_family = AF_INET6;
166#else
167 usage4(_("IPv6 support not available"));
168#endif
169 break; 177 break;
170 case 'r': /* remote version */ 178 case 'r': /* remote version */
171 result.config.remote_version = optarg; 179 result.config.remote_version = optarg;
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c
index 09806373..49a8c4c1 100644
--- a/plugins/check_tcp.c
+++ b/plugins/check_tcp.c
@@ -89,6 +89,14 @@ const int DEFAULT_NNTPS_PORT = 563;
89const int DEFAULT_CLAMD_PORT = 3310; 89const int DEFAULT_CLAMD_PORT = 3310;
90 90
91int main(int argc, char **argv) { 91int main(int argc, char **argv) {
92#ifdef __OpenBSD__
93 /* - rpath is required to read --extra-opts (given up later)
94 * - inet is required for sockets
95 * - unix is required for Unix domain sockets
96 * - dns is required for name lookups */
97 pledge("stdio rpath inet unix dns", NULL);
98#endif // __OpenBSD__
99
92 setlocale(LC_ALL, ""); 100 setlocale(LC_ALL, "");
93 bindtextdomain(PACKAGE, LOCALEDIR); 101 bindtextdomain(PACKAGE, LOCALEDIR);
94 textdomain(PACKAGE); 102 textdomain(PACKAGE);
@@ -216,6 +224,10 @@ int main(int argc, char **argv) {
216 usage4(_("Could not parse arguments")); 224 usage4(_("Could not parse arguments"));
217 } 225 }
218 226
227#ifdef __OpenBSD__
228 pledge("stdio inet unix dns", NULL);
229#endif // __OpenBSD__
230
219 config = paw.config; 231 config = paw.config;
220 232
221 if (verbosity > 0) { 233 if (verbosity > 0) {
@@ -571,11 +583,7 @@ static check_tcp_config_wrapper process_arguments(int argc, char **argv, check_t
571 address_family = AF_INET; 583 address_family = AF_INET;
572 break; 584 break;
573 case '6': // Apparently unused TODO 585 case '6': // Apparently unused TODO
574#ifdef USE_IPV6
575 address_family = AF_INET6; 586 address_family = AF_INET6;
576#else
577 usage4(_("IPv6 support not available"));
578#endif
579 break; 587 break;
580 case 'H': /* hostname */ 588 case 'H': /* hostname */
581 config.host_specified = true; 589 config.host_specified = true;
diff --git a/plugins/check_time.c b/plugins/check_time.c
index fc9ba3f9..99708ad3 100644
--- a/plugins/check_time.c
+++ b/plugins/check_time.c
@@ -68,6 +68,7 @@ int main(int argc, char **argv) {
68 68
69 /* set socket timeout */ 69 /* set socket timeout */
70 alarm(socket_timeout); 70 alarm(socket_timeout);
71 time_t start_time;
71 time(&start_time); 72 time(&start_time);
72 73
73 int socket; 74 int socket;
@@ -113,6 +114,7 @@ int main(int argc, char **argv) {
113 close(socket); 114 close(socket);
114 115
115 /* reset the alarm */ 116 /* reset the alarm */
117 time_t end_time;
116 time(&end_time); 118 time(&end_time);
117 alarm(0); 119 alarm(0);
118 120
diff --git a/plugins/check_users.c b/plugins/check_users.c
index 3b2e265e..4027d21a 100644
--- a/plugins/check_users.c
+++ b/plugins/check_users.c
@@ -222,7 +222,7 @@ check_users_config_wrapper process_arguments(int argc, char **argv) {
222 exit(STATE_UNKNOWN); 222 exit(STATE_UNKNOWN);
223 } 223 }
224 224
225 if (tmp.error == MP_PARSING_SUCCES) { 225 if (tmp.error == MP_PARSING_SUCCESS) {
226 result.config.thresholds.warning = tmp.range; 226 result.config.thresholds.warning = tmp.range;
227 result.config.thresholds.warning_is_set = true; 227 result.config.thresholds.warning_is_set = true;
228 } else { 228 } else {
@@ -238,7 +238,7 @@ check_users_config_wrapper process_arguments(int argc, char **argv) {
238 exit(STATE_UNKNOWN); 238 exit(STATE_UNKNOWN);
239 } 239 }
240 240
241 if (tmp.error == MP_PARSING_SUCCES) { 241 if (tmp.error == MP_PARSING_SUCCESS) {
242 result.config.thresholds.critical = tmp.range; 242 result.config.thresholds.critical = tmp.range;
243 result.config.thresholds.critical_is_set = true; 243 result.config.thresholds.critical_is_set = true;
244 } else { 244 } else {
diff --git a/plugins/netutils.c b/plugins/netutils.c
index b4c6ff0a..f9933ebd 100644
--- a/plugins/netutils.c
+++ b/plugins/netutils.c
@@ -38,11 +38,7 @@ mp_state_enum socket_timeout_state = STATE_CRITICAL;
38mp_state_enum econn_refuse_state = STATE_CRITICAL; 38mp_state_enum econn_refuse_state = STATE_CRITICAL;
39bool was_refused = false; 39bool was_refused = false;
40 40
41#if USE_IPV6
42int address_family = AF_UNSPEC; 41int address_family = AF_UNSPEC;
43#else
44int address_family = AF_INET;
45#endif
46 42
47/* handles socket timeouts */ 43/* handles socket timeouts */
48void socket_timeout_alarm_handler(int sig) { 44void socket_timeout_alarm_handler(int sig) {
@@ -348,7 +344,6 @@ void host_or_die(const char *str) {
348} 344}
349 345
350bool is_addr(const char *address) { 346bool is_addr(const char *address) {
351#ifdef USE_IPV6
352 if (address_family == AF_INET && is_inet_addr(address)) { 347 if (address_family == AF_INET && is_inet_addr(address)) {
353 return true; 348 return true;
354 } 349 }
@@ -356,11 +351,6 @@ bool is_addr(const char *address) {
356 if (address_family == AF_INET6 && is_inet6_addr(address)) { 351 if (address_family == AF_INET6 && is_inet6_addr(address)) {
357 return true; 352 return true;
358 } 353 }
359#else
360 if (is_inet_addr(address)) {
361 return true;
362 }
363#endif
364 354
365 return false; 355 return false;
366} 356}
diff --git a/plugins/netutils.h b/plugins/netutils.h
index dbd22398..f3d046c3 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -78,12 +78,8 @@ bool dns_lookup(const char *, struct sockaddr_storage *, int);
78void host_or_die(const char *str); 78void host_or_die(const char *str);
79#define resolve_host_or_addr(addr, family) dns_lookup(addr, NULL, family) 79#define resolve_host_or_addr(addr, family) dns_lookup(addr, NULL, family)
80#define is_inet_addr(addr) resolve_host_or_addr(addr, AF_INET) 80#define is_inet_addr(addr) resolve_host_or_addr(addr, AF_INET)
81#ifdef USE_IPV6
82# define is_inet6_addr(addr) resolve_host_or_addr(addr, AF_INET6) 81# define is_inet6_addr(addr) resolve_host_or_addr(addr, AF_INET6)
83# define is_hostname(addr) resolve_host_or_addr(addr, address_family) 82# define is_hostname(addr) resolve_host_or_addr(addr, address_family)
84#else
85# define is_hostname(addr) resolve_host_or_addr(addr, AF_INET)
86#endif
87 83
88extern unsigned int socket_timeout; 84extern unsigned int socket_timeout;
89extern mp_state_enum socket_timeout_state; 85extern mp_state_enum socket_timeout_state;
diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t
index 0f62fb2b..72a83ea4 100644
--- a/plugins/t/check_disk.t
+++ b/plugins/t/check_disk.t
@@ -80,14 +80,25 @@ if($free_percent_on_mp1 == $avg_free_percent || $free_percent_on_mp2 == $avg_fre
80 die "One mountpoints has average space free - cannot do rest of test"; 80 die "One mountpoints has average space free - cannot do rest of test";
81} 81}
82 82
83my $free_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'}; 83my $used_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'};
84my $total_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'}; 84my $total_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'};
85
86my $free_inodes_on_mp1 = $total_inodes_on_mp1 - $used_inodes_on_mp1;
85my $free_inode_percentage_on_mp1 = $free_inodes_on_mp1 / ($total_inodes_on_mp1 / 100); 87my $free_inode_percentage_on_mp1 = $free_inodes_on_mp1 / ($total_inodes_on_mp1 / 100);
86 88
87my $free_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'}; 89# print("free inodes on mp1: " . $free_inodes_on_mp1 . "\n");
90# print("total inodes on mp1: " . $total_inodes_on_mp1 . "\n");
91# print("free inode percentage on mp1: " . $free_inode_percentage_on_mp1 . "\n");
92
93my $used_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'};
88my $total_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'}; 94my $total_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'};
95my $free_inodes_on_mp2 = $total_inodes_on_mp2 - $used_inodes_on_mp2;
89my $free_inode_percentage_on_mp2 = $free_inodes_on_mp2 / ($total_inodes_on_mp2 / 100); 96my $free_inode_percentage_on_mp2 = $free_inodes_on_mp2 / ($total_inodes_on_mp2 / 100);
90 97
98# print("free inodes on mp2: " . $free_inodes_on_mp2 . "\n");
99# print("total inodes on mp2: " . $total_inodes_on_mp2 . "\n");
100# print("free inode percentage on mp2: " . $free_inode_percentage_on_mp2 . "\n");
101
91my $avg_inode_free_percentage = ceil(($free_inode_percentage_on_mp1 + $free_inode_percentage_on_mp2)/2); 102my $avg_inode_free_percentage = ceil(($free_inode_percentage_on_mp1 + $free_inode_percentage_on_mp2)/2);
92my ($more_inode_free, $less_inode_free); 103my ($more_inode_free, $less_inode_free);
93if ($free_inode_percentage_on_mp1 > $free_inode_percentage_on_mp2) { 104if ($free_inode_percentage_on_mp1 > $free_inode_percentage_on_mp2) {
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t
index 52c5ad1c..248eb4c5 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -20,9 +20,14 @@ use Test::More;
20use NPTest; 20use NPTest;
21use FindBin qw($Bin); 21use FindBin qw($Bin);
22 22
23use URI;
24use URI::QueryParam;
25use HTTP::Daemon;
26use HTTP::Daemon::SSL;
27
23$ENV{'LC_TIME'} = "C"; 28$ENV{'LC_TIME'} = "C";
24 29
25my $common_tests = 75; 30my $common_tests = 95;
26my $ssl_only_tests = 8; 31my $ssl_only_tests = 8;
27# Check that all dependent modules are available 32# Check that all dependent modules are available
28eval "use HTTP::Daemon 6.01;"; 33eval "use HTTP::Daemon 6.01;";
@@ -186,6 +191,123 @@ sub run_server {
186 $c->send_response('moved to /redirect2'); 191 $c->send_response('moved to /redirect2');
187 } elsif ($r->url->path eq "/redir_timeout") { 192 } elsif ($r->url->path eq "/redir_timeout") {
188 $c->send_redirect( "/timeout" ); 193 $c->send_redirect( "/timeout" );
194 } elsif ($r->url->path =~ m{^/redirect_with_increment}) {
195 # <scheme>://<username>:<password>@<host>:<port>/<path>;<parameters>?<query>#<fragment>
196 # Find every parameter, query , and fragment keys and increment them
197
198 my $content = "";
199
200 # Use URI to help with query/fragment; parse path params manually.
201 my $original_url = $r->url->as_string;
202 $content .= " original_url: ${original_url}\n";
203 my $uri = URI->new($original_url);
204 $content .= " uri: ${uri}\n";
205
206 my $path = $uri->path // '';
207 my $query = $uri->query // '';
208 my $fragment = $uri->fragment // '';
209
210 $content .= " path: ${path}\n";
211 $content .= " query: ${query}\n";
212 $content .= " fragment: ${fragment}\n";
213
214 # split the URI part and parameters. URI package cannot do this
215 # group 1 is captured: anything without a semicolon: ([^;]*)
216 # group 2 is uncaptured: (?:;(.*))?
217 # (?: ... )? prevents capturing the parameter section
218 # inside group 2, ';' matches the first ever semicolon
219 # group3 is captured: any character string : (.*)
220 # \? matches an actual ? mark, which starts the query parameters
221 my ($before_params, $params) = $uri =~ m{^([^;]*)(?:;(.*))?\?};
222 $before_params //= '';
223 $params //= '';
224 $content .= " before_params: ${before_params}\n";
225 $content .= " params: ${params}\n";
226 my @parameter_pairs;
227 if (defined $params && length $params) {
228 for my $p (split /;/, $params) {
229 my ($key,$value) = split /=/, $p, 2;
230 $value //= '';
231 push @parameter_pairs, [ $key, $value ];
232 $content .= " parameter: ${key} -> ${value}\n";
233 }
234 }
235
236 # query parameters are offered directly from the library
237 my @query_form = $uri->query_form;
238 my @query_parameter_pairs;
239 while (@query_form) {
240 my $key = shift @query_form;
241 my $value = shift @query_form;
242 $value //= ''; # there can be valueless keys
243 push @query_parameter_pairs, [ $key, $value ];
244 $content .= " query: ${key} -> ${value}\n";
245 }
246
247 # helper to increment value
248 my $increment = sub {
249 my ($v) = @_;
250 return $v if !defined $v || $v eq '';
251 # numeric integer
252 if ($v =~ /^-?\d+$/) {
253 return $v + 1;
254 }
255 # otherwise -> increment as if its an ascii character
256 # sed replacement syntax, but the $& holds the matched character
257 if (length($v)) {
258 (my $new_v = $v) =~ s/./chr(ord($&) + 1)/ge;
259 return $new_v;
260 }
261 };
262
263 # increment values in pairs
264 for my $pair (@parameter_pairs) {
265 $pair->[1] = $increment->($pair->[1]);
266 $content .= " parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n";
267 }
268 for my $pair (@query_parameter_pairs) {
269 $pair->[1] = $increment->($pair->[1]);
270 $content .= " query parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n";
271 }
272
273 # rebuild strings
274 my $new_parameter_str = join(';', map { $_->[0] . '=' . $_->[1] } @parameter_pairs);
275 $content .= " new_parameter_str: ${new_parameter_str}\n";
276
277 # library can rebuild from an array
278 my @new_query_form;
279 for my $p (@query_parameter_pairs) { push @new_query_form, $p->[0], $p->[1] }
280
281 my $new_fragment_str = '';
282 for my $pair (@parameter_pairs) {
283 my $key = $pair->[0];
284 my $value = $pair->[1];
285 if ($key eq "fragment") {
286 $new_fragment_str = $value
287 }
288 }
289 $content .= " new_fragment_str: ${new_fragment_str}\n";
290
291 # construct new URI using the library
292 my $new_uri = URI->new('');
293 $new_uri->path( $before_params . ($new_parameter_str ? ';' . $new_parameter_str : '') );
294 $new_uri->query_form( \@new_query_form ) if @new_query_form;
295 $new_uri->fragment( $new_fragment_str ) if $new_fragment_str ne '';
296 $content .= " new_uri: ${new_uri}\n";
297
298 # Redirect until fail_count or redirect_count reaches 3
299 if ($new_uri =~ /fail_count=3/){
300 $c->send_error(HTTP::Status->RC_FORBIDDEN, "fail count reached 3, url path:" . $r->url->path );
301 } elsif ($new_uri =~ /redirect_count=3/){
302 $c->send_response(HTTP::Response->new( 200, 'OK', undef , $content ));
303 } elsif ($new_uri =~ /location_redirect_count=3/){
304 $c->send_basic_header(302);
305 $c->send_header("Location", "$new_uri" );
306 $c->send_crlf;
307 $c->send_response("$content \n moved to $new_uri");
308 } else {
309 $c->send_redirect( $new_uri->as_string, 301, $content );
310 }
189 } elsif ($r->url->path eq "/timeout") { 311 } elsif ($r->url->path eq "/timeout") {
190 # Keep $c from being destroyed, but prevent severe leaks 312 # Keep $c from being destroyed, but prevent severe leaks
191 unshift @persist, $c; 313 unshift @persist, $c;
@@ -215,7 +337,7 @@ sub run_server {
215 return($chunk); 337 return($chunk);
216 })); 338 }));
217 } else { 339 } else {
218 $c->send_error(HTTP::Status->RC_FORBIDDEN); 340 $c->send_error(HTTP::Status->RC_FORBIDDEN, "unknown url path:" . $r->url->path );
219 } 341 }
220 $c->close; 342 $c->close;
221 } 343 }
@@ -482,6 +604,64 @@ sub run_common_tests {
482 is( $result->return_code, 0, $cmd); 604 is( $result->return_code, 0, $cmd);
483 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); 605 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output );
484 606
607 # Redirect with increment tests. These are for checking if the url parameters, query parameters and fragment are parsed.
608 # The server at this point has dynamic redirection. It tries to increment values that it sees in these fields, then redirects.
609 # It also appends some debug log and writes it into HTTP content, pass the -vvv parameter to see them.
610
611 $cmd = "$command -u '/redirect_with_increment/path1/path2/path3/path4' --onredirect=follow -vvv";
612 $result = NPTest->testCmd( "$cmd" );
613 is( $result->return_code, 1, $cmd);
614 like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count was not present, got redirected to / : ".$result->output );
615
616 # redirect_count=0 is parsed as a parameter and incremented. When it goes up to 3, the redirection returns HTTP OK
617 $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv";
618 $result = NPTest->testCmd( "$cmd" );
619 is( $result->return_code, 0, $cmd);
620 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count went up to 3, and returned OK: ".$result->output );
621
622 # location_redirect_count=0 goes up to 3, which uses the HTTP 302 style of redirection with 'Location' header
623 $cmd = "$command -u '/redirect_with_increment/path1/path2;location_redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv";
624 $result = NPTest->testCmd( "$cmd" );
625 is( $result->return_code, 0, $cmd);
626 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output );
627
628 # fail_count parameter may also go up to 3, which returns a HTTP 403
629 $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;fail_count=2' --onredirect=follow -vvv";
630 $result = NPTest->testCmd( "$cmd" );
631 is( $result->return_code, 1, $cmd);
632 like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, early due to fail_count reaching 3: ".$result->output );
633
634 # redirect_count=0, p1=1 , p2=ab => redirect_count=1, p1=2 , p2=bc => redirect_count=2, p1=3 , p2=cd => redirect_count=3 , p1=4 , p2=de
635 # Last visited URI returns HTTP OK instead of redirect, and the one before that contains the new_uri in its content
636 $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv";
637 $result = NPTest->testCmd( "$cmd" );
638 is( $result->return_code, 0, $cmd);
639 like( $result->output, '/.*redirect_count=3;p1=4;p2=de\?*/', "Output correct, parsed and incremented both parameters p1 and p2 : ".$result->output );
640 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output );
641
642 # Same incrementation as before, uses the query parameters that come after the first '?' : qp1 and qp2
643 $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv";
644 $result = NPTest->testCmd( "$cmd" );
645 is( $result->return_code, 0, $cmd);
646 like( $result->output, '/.*\?qp1=13&qp2=no*/', "Output correct, parsed and incremented both query parameters qp1 and qp2 : ".$result->output );
647 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output );
648
649 # Check if the query parameter order is kept intact
650 $cmd = "$command -u '/redirect_with_increment;redirect_count=0;?qp0=0&qp1=1&qp2=2&qp3=3&qp4=4&qp5=5' --onredirect=follow -vvv";
651 $result = NPTest->testCmd( "$cmd" );
652 is( $result->return_code, 0, $cmd);
653 like( $result->output, '/.*\?qp0=3&qp1=4&qp2=5&qp3=6&qp4=7&qp5=8*/', "Output correct, parsed and incremented query parameters qp1,qp2,qp3,qp4,qp5 in order : ".$result->output );
654 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output );
655
656 # The fragment is passed as another parameter.
657 # During the server redirects the fragment will be set to its value, if such a key is present.
658 # 'ebiil' => 'fcjjm' => 'gdkkn' => 'hello'
659 $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;fragment=ebiil?qp1=0' --onredirect=follow -vvv";
660 $result = NPTest->testCmd( "$cmd" );
661 is( $result->return_code, 0, $cmd);
662 like( $result->output, '/.*redirect_count=3;fragment=hello\?qp1=3#hello*/', "Output correct, fragments are specified by server and followed by check_curl: ".$result->output );
663 like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output );
664
485 # These tests may block 665 # These tests may block
486 # stickyport - on full urlS port is set back to 80 otherwise 666 # stickyport - on full urlS port is set back to 80 otherwise
487 $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; 667 $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected";
diff --git a/plugins/utils.c b/plugins/utils.c
index 41fe5fcf..dc6f5a85 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -40,7 +40,6 @@ extern const char *progname;
40#define STRLEN 64 40#define STRLEN 64
41#define TXTBLK 128 41#define TXTBLK 128
42 42
43time_t start_time, end_time;
44 43
45void usage(const char *msg) { 44void usage(const char *msg) {
46 printf("%s\n", msg); 45 printf("%s\n", msg);
diff --git a/plugins/utils.h b/plugins/utils.h
index 1f0e021b..68ff1630 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -32,8 +32,6 @@ suite of plugins. */
32void support(void); 32void support(void);
33void print_revision(const char *, const char *); 33void print_revision(const char *, const char *);
34 34
35extern time_t start_time, end_time;
36
37/* Test input types */ 35/* Test input types */
38 36
39bool is_integer(char *); 37bool is_integer(char *);