diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/Makefile.am | 3 | ||||
| -rw-r--r-- | plugins/check_by_ssh.c | 34 | ||||
| -rw-r--r-- | plugins/check_curl.c | 65 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.c | 32 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.h | 2 | ||||
| -rw-r--r-- | plugins/check_curl.d/config.h | 6 | ||||
| -rw-r--r-- | plugins/check_http.c | 2 | ||||
| -rw-r--r-- | plugins/check_ide_smart.c | 259 | ||||
| -rw-r--r-- | plugins/check_ide_smart.d/config.h | 15 | ||||
| -rw-r--r-- | plugins/check_real.c | 318 | ||||
| -rw-r--r-- | plugins/check_real.d/config.h | 23 | ||||
| -rw-r--r-- | plugins/check_smtp.c | 1 | ||||
| -rw-r--r-- | plugins/check_snmp.d/check_snmp_helpers.c | 10 | ||||
| -rw-r--r-- | plugins/check_snmp.d/check_snmp_helpers.h | 4 | ||||
| -rw-r--r-- | plugins/check_time.c | 2 | ||||
| -rwxr-xr-x | plugins/tests/check_curl.t | 184 | ||||
| -rw-r--r-- | plugins/utils.c | 1 | ||||
| -rw-r--r-- | plugins/utils.h | 2 |
18 files changed, 649 insertions, 314 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) | |||
| 164 | check_real_LDADD = $(NETLIBS) | 165 | check_real_LDADD = $(NETLIBS) |
| 165 | check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c | 166 | check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c |
| 166 | check_snmp_LDADD = $(BASEOBJS) | 167 | check_snmp_LDADD = $(BASEOBJS) |
| 167 | check_snmp_LDFLAGS = $(AM_LDFLAGS) `net-snmp-config --libs` | 168 | check_snmp_LDFLAGS = $(AM_LDFLAGS) -lm `net-snmp-config --libs` |
| 168 | check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags` | 169 | check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags` |
| 169 | check_smtp_LDADD = $(SSLOBJS) | 170 | check_smtp_LDADD = $(SSLOBJS) |
| 170 | check_ssh_LDADD = $(NETLIBS) | 171 | check_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..1dec8a2a 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
| @@ -92,16 +92,16 @@ typedef struct { | |||
| 92 | static check_curl_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | 92 | static check_curl_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 93 | 93 | ||
| 94 | static mp_subcheck check_http(check_curl_config /*config*/, check_curl_working_state workingState, | 94 | static mp_subcheck check_http(check_curl_config /*config*/, check_curl_working_state workingState, |
| 95 | int redir_depth); | 95 | long redir_depth); |
| 96 | 96 | ||
| 97 | typedef struct { | 97 | typedef 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; |
| 103 | static redir_wrapper redir(curlhelp_write_curlbuf * /*header_buf*/, check_curl_config /*config*/, | 103 | static 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 | ||
| 106 | static void print_help(void); | 106 | static void print_help(void); |
| 107 | void print_usage(void); | 107 | void print_usage(void); |
| @@ -198,7 +198,7 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) { | |||
| 198 | #endif /* HAVE_SSL */ | 198 | #endif /* HAVE_SSL */ |
| 199 | 199 | ||
| 200 | mp_subcheck check_http(const check_curl_config config, check_curl_working_state workingState, | 200 | mp_subcheck check_http(const check_curl_config config, check_curl_working_state workingState, |
| 201 | int redir_depth) { | 201 | long redir_depth) { |
| 202 | 202 | ||
| 203 | // ======================= | 203 | // ======================= |
| 204 | // Initialisation for curl | 204 | // Initialisation for curl |
| @@ -441,19 +441,19 @@ mp_subcheck check_http(const check_curl_config config, check_curl_working_state | |||
| 441 | "CURLINFO_REDIRECT_COUNT"); | 441 | "CURLINFO_REDIRECT_COUNT"); |
| 442 | 442 | ||
| 443 | if (verbose >= 2) { | 443 | if (verbose >= 2) { |
| 444 | printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth); | 444 | printf(_("* curl LIBINFO_REDIRECT_COUNT is %ld\n"), redir_depth); |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | mp_subcheck sc_redir_depth = mp_subcheck_init(); | 447 | mp_subcheck sc_redir_depth = mp_subcheck_init(); |
| 448 | if (redir_depth > config.max_depth) { | 448 | if (redir_depth > config.max_depth) { |
| 449 | xasprintf(&sc_redir_depth.output, | 449 | xasprintf(&sc_redir_depth.output, |
| 450 | "maximum redirection depth %d exceeded in libcurl", | 450 | "maximum redirection depth %ld exceeded in libcurl", |
| 451 | config.max_depth); | 451 | config.max_depth); |
| 452 | sc_redir_depth = mp_set_subcheck_state(sc_redir_depth, STATE_CRITICAL); | 452 | sc_redir_depth = mp_set_subcheck_state(sc_redir_depth, STATE_CRITICAL); |
| 453 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); | 453 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); |
| 454 | return sc_result; | 454 | return sc_result; |
| 455 | } | 455 | } |
| 456 | xasprintf(&sc_redir_depth.output, "redirection depth %d (of a maximum %d)", | 456 | xasprintf(&sc_redir_depth.output, "redirection depth %ld (of a maximum %ld)", |
| 457 | redir_depth, config.max_depth); | 457 | redir_depth, config.max_depth); |
| 458 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); | 458 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); |
| 459 | 459 | ||
| @@ -653,7 +653,7 @@ char *uri_string(const UriTextRangeA range, char *buf, size_t buflen) { | |||
| 653 | } | 653 | } |
| 654 | 654 | ||
| 655 | redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config, | 655 | redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config, |
| 656 | int redir_depth, check_curl_working_state working_state) { | 656 | long redir_depth, check_curl_working_state working_state) { |
| 657 | curlhelp_statusline status_line; | 657 | curlhelp_statusline status_line; |
| 658 | struct phr_header headers[255]; | 658 | struct phr_header headers[255]; |
| 659 | size_t msglen; | 659 | size_t msglen; |
| @@ -678,7 +678,7 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config | |||
| 678 | } | 678 | } |
| 679 | 679 | ||
| 680 | if (++redir_depth > config.max_depth) { | 680 | if (++redir_depth > config.max_depth) { |
| 681 | die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %d exceeded - %s\n"), | 681 | die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %ld exceeded - %s\n"), |
| 682 | config.max_depth, location); | 682 | config.max_depth, location); |
| 683 | } | 683 | } |
| 684 | 684 | ||
| @@ -761,7 +761,7 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config | |||
| 761 | } | 761 | } |
| 762 | 762 | ||
| 763 | /* compose new path */ | 763 | /* compose new path */ |
| 764 | /* TODO: handle fragments and query part of URL */ | 764 | /* TODO: handle fragments of URL */ |
| 765 | char *new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE); | 765 | char *new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE); |
| 766 | if (uri.pathHead) { | 766 | if (uri.pathHead) { |
| 767 | for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment; | 767 | for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment; |
| @@ -772,6 +772,29 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config | |||
| 772 | } | 772 | } |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | /* missing components have null,null in their UriTextRangeA | ||
| 776 | * add query parameters if they exist. | ||
| 777 | */ | ||
| 778 | if (uri.query.first && uri.query.afterLast) { | ||
| 779 | // Ensure we have space for '?' + query_str + '\0' ahead of time, instead of calling strncat | ||
| 780 | // twice | ||
| 781 | size_t current_len = strlen(new_url); | ||
| 782 | size_t remaining_space = DEFAULT_BUFFER_SIZE - current_len - 1; | ||
| 783 | |||
| 784 | const char *query_str = uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE); | ||
| 785 | size_t query_str_len = strlen(query_str); | ||
| 786 | |||
| 787 | if (remaining_space >= query_str_len + 1) { | ||
| 788 | strcat(new_url, "?"); | ||
| 789 | strcat(new_url, query_str); | ||
| 790 | } else { | ||
| 791 | die(STATE_UNKNOWN, | ||
| 792 | _("HTTP UNKNOWN - No space to add query part of size %zu to the buffer, buffer has " | ||
| 793 | "remaining size %zu"), | ||
| 794 | query_str_len, current_len); | ||
| 795 | } | ||
| 796 | } | ||
| 797 | |||
| 775 | if (working_state.serverPort == new_port && | 798 | if (working_state.serverPort == new_port && |
| 776 | !strncmp(working_state.server_address, new_host, MAX_IPV4_HOSTLENGTH) && | 799 | !strncmp(working_state.server_address, new_host, MAX_IPV4_HOSTLENGTH) && |
| 777 | (working_state.host_name && | 800 | (working_state.host_name && |
| @@ -1400,7 +1423,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 1400 | } | 1423 | } |
| 1401 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ | 1424 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ |
| 1402 | if (verbose >= 2) { | 1425 | if (verbose >= 2) { |
| 1403 | printf(_("* Set SSL/TLS version to %d\n"), result.config.curl_config.ssl_version); | 1426 | printf(_("* Set SSL/TLS version to %ld\n"), result.config.curl_config.ssl_version); |
| 1404 | } | 1427 | } |
| 1405 | if (!specify_port) { | 1428 | if (!specify_port) { |
| 1406 | result.config.initial_config.serverPort = HTTPS_PORT; | 1429 | result.config.initial_config.serverPort = HTTPS_PORT; |
| @@ -1482,8 +1505,8 @@ void print_help(void) { | |||
| 1482 | printf(" %s\n", "-I, --IP-address=ADDRESS"); | 1505 | printf(" %s\n", "-I, --IP-address=ADDRESS"); |
| 1483 | printf(" %s\n", | 1506 | printf(" %s\n", |
| 1484 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); | 1507 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); |
| 1485 | printf(" %s\n", | 1508 | 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"); | 1509 | "else (HTTP headers) as they are"); |
| 1487 | printf(" %s\n", "-p, --port=INTEGER"); | 1510 | printf(" %s\n", "-p, --port=INTEGER"); |
| 1488 | printf(" %s", _("Port number (default: ")); | 1511 | printf(" %s", _("Port number (default: ")); |
| 1489 | printf("%d)\n", HTTP_PORT); | 1512 | printf("%d)\n", HTTP_PORT); |
| @@ -1547,7 +1570,8 @@ void print_help(void) { | |||
| 1547 | printf(" %s\n", _("String to expect in the content")); | 1570 | printf(" %s\n", _("String to expect in the content")); |
| 1548 | printf(" %s\n", "-u, --url=PATH"); | 1571 | printf(" %s\n", "-u, --url=PATH"); |
| 1549 | printf(" %s\n", _("URL to GET or POST (default: /)")); | 1572 | 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'")); | 1573 | printf(" %s\n", _("This is the part after the address in a URL, so for " |
| 1574 | "\"https://example.com/index.html\" it would be '-u /index.html'")); | ||
| 1551 | printf(" %s\n", "-P, --post=STRING"); | 1575 | printf(" %s\n", "-P, --post=STRING"); |
| 1552 | printf(" %s\n", _("URL decoded http POST data")); | 1576 | printf(" %s\n", _("URL decoded http POST data")); |
| 1553 | printf(" %s\n", | 1577 | printf(" %s\n", |
| @@ -1648,6 +1672,8 @@ void print_help(void) { | |||
| 1648 | printf(" %s\n", _("certificate matches the hostname of the server, or if the certificate")); | 1672 | 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.")); | 1673 | printf(" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); |
| 1650 | printf("\n"); | 1674 | printf("\n"); |
| 1675 | printf(" %s\n", _("To also verify certificates, please set --verify-cert.")); | ||
| 1676 | printf("\n"); | ||
| 1651 | printf("%s\n", _("Examples:")); | 1677 | printf("%s\n", _("Examples:")); |
| 1652 | printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com"); | 1678 | 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,")); | 1679 | printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); |
| @@ -1657,16 +1683,18 @@ void print_help(void) { | |||
| 1657 | _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | 1683 | _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); |
| 1658 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); | 1684 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); |
| 1659 | printf("\n"); | 1685 | printf("\n"); |
| 1660 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14"); | 1686 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14 -D"); |
| 1661 | printf(" %s\n", | 1687 | printf(" %s\n", |
| 1662 | _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); | 1688 | _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); |
| 1663 | printf(" %s\n", | 1689 | printf(" %s\n", |
| 1664 | _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | 1690 | _("a STATE_OK is returned. When the certificate is still valid, but for less than")); |
| 1665 | printf(" %s\n", | 1691 | printf(" %s\n", |
| 1666 | _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); | 1692 | _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); |
| 1667 | printf(" %s\n\n", _("the certificate is expired.")); | 1693 | printf(" %s\n", _("the certificate is expired.")); |
| 1694 | printf("\n"); | ||
| 1695 | printf(" %s\n", _("The -D flag enforces a certificate validation beyond expiration time.")); | ||
| 1668 | printf("\n"); | 1696 | printf("\n"); |
| 1669 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14"); | 1697 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14 -D"); |
| 1670 | printf(" %s\n", | 1698 | printf(" %s\n", |
| 1671 | _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); | 1699 | _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); |
| 1672 | printf(" %s\n", | 1700 | printf(" %s\n", |
| @@ -1689,7 +1717,8 @@ void print_help(void) { | |||
| 1689 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); | 1717 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); |
| 1690 | printf(" %s\n", | 1718 | printf(" %s\n", |
| 1691 | _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S")); | 1719 | _("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:")); | 1720 | printf(" %s\n", _("legacy proxy requests in check_http style might still work, but are frowned " |
| 1721 | "upon, so DONT:")); | ||
| 1693 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j " | 1722 | 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 ")); | 1723 | "CONNECT -H www.verisign.com ")); |
| 1695 | printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> " | 1724 | 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..5af00973 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; | |||
| 19 | check_curl_configure_curl_wrapper | 19 | check_curl_configure_curl_wrapper |
| 20 | check_curl_configure_curl(const check_curl_static_curl_config config, | 20 | check_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 | ||
| @@ -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 | ||
| 85 | void handle_curl_option_return_code(CURLcode res, const char *option); | 85 | void 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_http.c b/plugins/check_http.c index d264b95d..d2f080c7 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
| @@ -1036,7 +1036,7 @@ int check_http(void) { | |||
| 1036 | printf("SSL initialized\n"); | 1036 | printf("SSL initialized\n"); |
| 1037 | } | 1037 | } |
| 1038 | if (result != STATE_OK) { | 1038 | if (result != STATE_OK) { |
| 1039 | die(STATE_CRITICAL, NULL); | 1039 | die(STATE_CRITICAL, _("HTTP CRITICAL - SSL error\n")); |
| 1040 | } | 1040 | } |
| 1041 | microsec_ssl = deltime(tv_temp); | 1041 | microsec_ssl = deltime(tv_temp); |
| 1042 | elapsed_time_ssl = (double)microsec_ssl / 1.0e6; | 1042 | 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 | ||
| 43 | static void print_help(void); | 45 | static void print_help(void); |
| 44 | void print_usage(void); | 46 | void 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 | ||
| 80 | typedef struct threshold_s { | 83 | typedef 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 | ||
| 86 | typedef struct thresholds_s { | 89 | typedef 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 | ||
| 94 | typedef struct value_s { | 97 | typedef 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 | ||
| 101 | typedef struct values_s { | 104 | typedef 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 | ||
| 115 | static struct { | 118 | static 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 | ||
| 136 | static char *get_offline_text(int); | 139 | static char *get_offline_text(int /*status*/); |
| 137 | static int smart_read_values(int, values_t *); | 140 | static int smart_read_values(int /*fd*/, smart_values * /*values*/); |
| 138 | static int nagios(values_t *, thresholds_t *); | 141 | static mp_state_enum compare_values_and_thresholds(smart_values * /*p*/, smart_thresholds * /*t*/); |
| 139 | static void print_value(value_t *, threshold_t *); | 142 | static void print_value(smart_value * /*p*/, smart_threshold * /*t*/); |
| 140 | static void print_values(values_t *, thresholds_t *); | 143 | static void print_values(smart_values * /*p*/, smart_thresholds * /*t*/); |
| 141 | static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); | 144 | static mp_state_enum smart_cmd_simple(int /*fd*/, enum SmartCommand /*command*/, uint8_t /*val0*/, bool /*show_error*/); |
| 142 | static int smart_read_thresholds(int, thresholds_t *); | 145 | static int smart_read_thresholds(int /*fd*/, smart_thresholds * /*thresholds*/); |
| 143 | static bool verbose = false; | 146 | static int verbose = 0; |
| 144 | 147 | ||
| 145 | int main(int argc, char *argv[]) { | 148 | typedef 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; | 152 | static 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 | |||
| 221 | int 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 | ||
| 244 | char *get_offline_text(int status) { | 262 | char *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 | ||
| 254 | int smart_read_values(int fd, values_t *values) { | 271 | int 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 | ||
| 301 | int nagios(values_t *p, thresholds_t *t) { | 319 | mp_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 | ||
| 352 | void print_value(value_t *p, threshold_t *t) { | 371 | void 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 | ||
| 357 | void print_values(values_t *p, thresholds_t *t) { | 377 | void 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 | ||
| 374 | int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { | 393 | mp_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 | ||
| 431 | int smart_read_thresholds(int fd, thresholds_t *thresholds) { | 453 | int 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 | |||
| 6 | typedef struct { | ||
| 7 | char *device; | ||
| 8 | } check_ide_smart_config; | ||
| 9 | |||
| 10 | check_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_real.c b/plugins/check_real.c index 66d07f8f..15c8a20c 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> |
| 33 | const char *progname = "check_real"; | ||
| 34 | const char *copyright = "2000-2024"; | ||
| 35 | const 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." | 41 | const char *progname = "check_real"; |
| 43 | #define URL "" | 42 | const char *copyright = "2000-2024"; |
| 43 | const char *email = "devel@monitoring-plugins.org"; | ||
| 44 | |||
| 45 | #define URL "" | ||
| 44 | 46 | ||
| 45 | typedef struct { | 47 | typedef 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 */ |
| 278 | check_real_config_wrapper process_arguments(int argc, char **argv) { | 338 | check_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_SUCCES) { |
| 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_SUCCES) { |
| 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 | ||
| 6 | enum { | 8 | enum { |
| 7 | PORT = 554 | 9 | PORT = 554 |
| 8 | }; | 10 | }; |
| 9 | 11 | ||
| 12 | const char *default_expect = "RTSP/1."; | ||
| 13 | |||
| 10 | typedef struct { | 14 | typedef 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 | ||
| 23 | check_real_config check_real_config_init() { | 28 | check_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..e8c35f58 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" |
diff --git a/plugins/check_snmp.d/check_snmp_helpers.c b/plugins/check_snmp.d/check_snmp_helpers.c index f506537a..2dfc88b5 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) { |
| @@ -64,6 +65,7 @@ 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 |
| @@ -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 | */ |
| 846 | state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, | 848 | state_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 | ||
| 68 | state_data *np_state_read(state_key stateKey); | 68 | state_data *np_state_read(state_key stateKey); |
| 69 | state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, | 69 | state_key np_enable_state(char *keyname, int expected_data_version, const char *plugin_name, |
| 70 | char **argv); | 70 | int argc, char **argv); |
| 71 | void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore); | 71 | void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore); |
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/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; | |||
| 20 | use NPTest; | 20 | use NPTest; |
| 21 | use FindBin qw($Bin); | 21 | use FindBin qw($Bin); |
| 22 | 22 | ||
| 23 | use URI; | ||
| 24 | use URI::QueryParam; | ||
| 25 | use HTTP::Daemon; | ||
| 26 | use HTTP::Daemon::SSL; | ||
| 27 | |||
| 23 | $ENV{'LC_TIME'} = "C"; | 28 | $ENV{'LC_TIME'} = "C"; |
| 24 | 29 | ||
| 25 | my $common_tests = 75; | 30 | my $common_tests = 95; |
| 26 | my $ssl_only_tests = 8; | 31 | my $ssl_only_tests = 8; |
| 27 | # Check that all dependent modules are available | 32 | # Check that all dependent modules are available |
| 28 | eval "use HTTP::Daemon 6.01;"; | 33 | eval "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 | ||
| 43 | time_t start_time, end_time; | ||
| 44 | 43 | ||
| 45 | void usage(const char *msg) { | 44 | void 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. */ | |||
| 32 | void support(void); | 32 | void support(void); |
| 33 | void print_revision(const char *, const char *); | 33 | void print_revision(const char *, const char *); |
| 34 | 34 | ||
| 35 | extern time_t start_time, end_time; | ||
| 36 | |||
| 37 | /* Test input types */ | 35 | /* Test input types */ |
| 38 | 36 | ||
| 39 | bool is_integer(char *); | 37 | bool is_integer(char *); |
