diff options
-rwxr-xr-x | .github/prepare_debian.sh | 8 | ||||
-rw-r--r-- | NEWS | 55 | ||||
-rwxr-xr-x | NP-VERSION-GEN | 2 | ||||
-rw-r--r-- | THANKS.in | 6 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | doc/RELEASING.md | 30 | ||||
-rw-r--r-- | plugins/check_curl.c | 64 | ||||
-rw-r--r-- | plugins/check_http.c | 21 | ||||
-rw-r--r-- | plugins/check_snmp.c | 10 | ||||
-rw-r--r-- | plugins/t/check_curl.t | 4 | ||||
-rw-r--r-- | plugins/t/check_http.t | 4 | ||||
-rwxr-xr-x | plugins/tests/check_curl.t | 14 | ||||
-rwxr-xr-x | plugins/tests/check_http.t | 12 |
13 files changed, 171 insertions, 61 deletions
diff --git a/.github/prepare_debian.sh b/.github/prepare_debian.sh index dcf778b..3f4674a 100755 --- a/.github/prepare_debian.sh +++ b/.github/prepare_debian.sh | |||
@@ -64,13 +64,9 @@ apt-get -y install perl \ | |||
64 | iproute2 | 64 | iproute2 |
65 | 65 | ||
66 | # remove ipv6 interface from hosts | 66 | # remove ipv6 interface from hosts |
67 | if [ $(ip addr show | grep "inet6 ::1" | wc -l) -eq "0" ]; then | 67 | sed '/^::1/d' /etc/hosts > /tmp/hosts |
68 | sed '/^::1/d' /etc/hosts > /tmp/hosts | 68 | cp -f /tmp/hosts /etc/hosts |
69 | cp -f /tmp/hosts /etc/hosts | ||
70 | fi | ||
71 | |||
72 | ip addr show | 69 | ip addr show |
73 | |||
74 | cat /etc/hosts | 70 | cat /etc/hosts |
75 | 71 | ||
76 | # apache | 72 | # apache |
@@ -1,5 +1,60 @@ | |||
1 | This file documents the major additions and syntax changes between releases. | 1 | This file documents the major additions and syntax changes between releases. |
2 | 2 | ||
3 | 2.4.0 25th Jul 2024 | ||
4 | FIXES | ||
5 | * check_dbi: Compiler warning for uninitialized variable | ||
6 | * check_curl: Initialize pointer before usage | ||
7 | * check_ntp: Initialize intermediate results in any case | ||
8 | * Fixes for -Wsign-compare | ||
9 | * check_tcp: Fixes an error with using the wrong type for a variable | ||
10 | * check_mailq: exit on empty strings and exit early | ||
11 | * check_users: Change option for sanity checking arguments to avoid segfault | ||
12 | * check_users: Update help to properly show that thresholds are ranges | ||
13 | * check_users: fix segfault | ||
14 | * check_dbi: Fix compiler warning for uninitialized variable | ||
15 | * check_curl: Initialize pointer before usage | ||
16 | * check_ntp: Initialize intermediate results in any case | ||
17 | * Fix logic in is_uint64_t to fix type-limit warning | ||
18 | * check_ntp_peer: Fixes for Wmaybe-unitialized and some restructuring | ||
19 | * check_dns: Remove unused variable | ||
20 | * check_disk: fix ignore-missing in combination with includes | ||
21 | * check_procs: ignore our own children | ||
22 | * Prevent -lcrypto from showing up in Makefile dependencies | ||
23 | * Change irritating NULL assignment | ||
24 | * check_http: Remove self assignment of a variable and add some comments | ||
25 | * check_snmp: Remove unused variable | ||
26 | * check_dhcp: Make implicit conversion explicit to dismiss warning | ||
27 | * Ini Parser: Avoid freeing symbols from text section | ||
28 | * check_icmp: keep performance data order in case of none-reachable hosts | ||
29 | * check_swap: Change another fake boolean to a real one | ||
30 | * check_swap: Rename type since *_t is reserved for C standard types | ||
31 | * check_ssh: Fix a typo in "remote-protocol parameter | ||
32 | * check_ssh: Handle non-alpha software versions | ||
33 | * check_ssh: properly parse a delayed version control string | ||
34 | * check_disk: Fail on missing arguments for --warning and --critical and fix a test case | ||
35 | * check_disk: Use new test function for percentage expressions | ||
36 | * check_load: remove unused code | ||
37 | * check_curl/check_http: clarified format of POST data | ||
38 | |||
39 | ENHANCEMENTS | ||
40 | * Use C99 booleans | ||
41 | * check_mailq: remove trailing whitespaces | ||
42 | * check_mailq: unify tabs/spaces | ||
43 | * check_oracle: Shellcheck fixes | ||
44 | * check_ups: output ups.realpower if supported | ||
45 | * check_disk: add -n short option for --ignore-missing | ||
46 | * check_procs: Improve help text, mentioning excluded processes | ||
47 | * check_procs: Generalise wording, remove mentioning of nrpe | ||
48 | * check_curl: add haproxy protocol option | ||
49 | * Improve negate plugin helptext | ||
50 | * check_disk: increase alert precision | ||
51 | * check_ircd: IPv6 support | ||
52 | * check_nwstat: adds percentage used space | ||
53 | * Add new test function for percentage expressions | ||
54 | * check_swap: Possibility to run check_swap without thresholds | ||
55 | * check_ups: additional alarm conditions | ||
56 | * check_http/check_curl: added a --regex-state option to change the state of a regex check | ||
57 | |||
3 | 2.3.5 18th Oct 2023 | 58 | 2.3.5 18th Oct 2023 |
4 | FIXES | 59 | FIXES |
5 | * Include maxfd.h in lib Makefile | 60 | * Include maxfd.h in lib Makefile |
diff --git a/NP-VERSION-GEN b/NP-VERSION-GEN index c353b1d..e16f37d 100755 --- a/NP-VERSION-GEN +++ b/NP-VERSION-GEN | |||
@@ -6,7 +6,7 @@ | |||
6 | SRC_ROOT=`dirname $0` | 6 | SRC_ROOT=`dirname $0` |
7 | 7 | ||
8 | NPVF=NP-VERSION-FILE | 8 | NPVF=NP-VERSION-FILE |
9 | DEF_VER=2.3git | 9 | DEF_VER=2.4git |
10 | 10 | ||
11 | LF=' | 11 | LF=' |
12 | ' | 12 | ' |
@@ -420,3 +420,9 @@ Stuart Henderson | |||
420 | Thoralf Rickert-Wendt | 420 | Thoralf Rickert-Wendt |
421 | Thorsten Kukuk | 421 | Thorsten Kukuk |
422 | Matthias Döhler | 422 | Matthias Döhler |
423 | Emmanuel Riviere | ||
424 | Eric Knibbe | ||
425 | Eunice Remoquillo | ||
426 | Louis Sautier | ||
427 | Sven Hartge | ||
428 | Alvar Penning | ||
diff --git a/configure.ac b/configure.ac index 17272e4..8594238 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,6 +1,6 @@ | |||
1 | dnl Process this file with autoconf to produce a configure script. | 1 | dnl Process this file with autoconf to produce a configure script. |
2 | AC_PREREQ(2.64) | 2 | AC_PREREQ(2.64) |
3 | AC_INIT(monitoring-plugins,2.3git) | 3 | AC_INIT(monitoring-plugins,2.4git) |
4 | AC_CONFIG_SRCDIR(NPTest.pm) | 4 | AC_CONFIG_SRCDIR(NPTest.pm) |
5 | AC_CONFIG_FILES([gl/Makefile]) | 5 | AC_CONFIG_FILES([gl/Makefile]) |
6 | AC_CONFIG_AUX_DIR(build-aux) | 6 | AC_CONFIG_AUX_DIR(build-aux) |
diff --git a/doc/RELEASING.md b/doc/RELEASING.md index f0932bd..e1f3bf7 100644 --- a/doc/RELEASING.md +++ b/doc/RELEASING.md | |||
@@ -2,7 +2,7 @@ Releasing a New Monitoring Plugins Version | |||
2 | ========================================== | 2 | ========================================== |
3 | 3 | ||
4 | Throughout this document, it is assumed that the current Monitoring | 4 | Throughout this document, it is assumed that the current Monitoring |
5 | Plugins version is 2.3.4, and that we're about to publish version 2.4. | 5 | Plugins version is 2.4.0, and that we're about to publish version 2.5. |
6 | It is also assumed that the official repository on GitHub is tracked | 6 | It is also assumed that the official repository on GitHub is tracked |
7 | using the remote name `monitoring-plugins` (rather than `origin`). | 7 | using the remote name `monitoring-plugins` (rather than `origin`). |
8 | 8 | ||
@@ -11,14 +11,14 @@ Before you start | |||
11 | 11 | ||
12 | - Check Github Actions status. | 12 | - Check Github Actions status. |
13 | - Update local Git repository to the current `master` tip. For a | 13 | - Update local Git repository to the current `master` tip. For a |
14 | maintenance release (e.g., version 2.3.4), update to the current | 14 | maintenance release (e.g., version 2.4.1), update to the current |
15 | `maint-2.3` tip, instead. | 15 | `maint-2.4` tip, instead. |
16 | 16 | ||
17 | Prepare and commit files | 17 | Prepare and commit files |
18 | ------------------------ | 18 | ------------------------ |
19 | 19 | ||
20 | - Update `configure.ac` and `NP-VERSION-GEN` with new version. | 20 | - Update `configure.ac` and `NP-VERSION-GEN` with new version. |
21 | - Update `NEWS` from `git log --reverse v2.3.4..` output, and specify | 21 | - Update `NEWS` from `git log --reverse v2.4.0..` output, and specify |
22 | the release version/date. | 22 | the release version/date. |
23 | - Update `AUTHORS` if there are new team members. | 23 | - Update `AUTHORS` if there are new team members. |
24 | - Update `THANKS.in` using `tools/update-thanks`. | 24 | - Update `THANKS.in` using `tools/update-thanks`. |
@@ -29,27 +29,27 @@ Prepare and commit files | |||
29 | Create annotated tag | 29 | Create annotated tag |
30 | -------------------- | 30 | -------------------- |
31 | 31 | ||
32 | git tag -a -m 'Monitoring Plugins 2.4' v2.4 | 32 | git tag -a -m 'Monitoring Plugins 2.5' v2.5 |
33 | 33 | ||
34 | Push the code and tag to GitHub | 34 | Push the code and tag to GitHub |
35 | ------------------------------- | 35 | ------------------------------- |
36 | 36 | ||
37 | git push monitoring-plugins master | 37 | git push monitoring-plugins master |
38 | git push monitoring-plugins v2.4 | 38 | git push monitoring-plugins v2.5 |
39 | 39 | ||
40 | Create new maintenance branch | 40 | Create new maintenance branch |
41 | ----------------------------- | 41 | ----------------------------- |
42 | 42 | ||
43 | _Only necessary when creating a feature release._ | 43 | _Only necessary when creating a feature release._ |
44 | 44 | ||
45 | git checkout -b maint-2.4 v2.4 | 45 | git checkout -b maint-2.5 v2.5 |
46 | git push -u monitoring-plugins maint-2.4 | 46 | git push -u monitoring-plugins maint-2.5 |
47 | 47 | ||
48 | Checkout new version | 48 | Checkout new version |
49 | -------------------- | 49 | -------------------- |
50 | 50 | ||
51 | rm -rf /tmp/plugins | 51 | rm -rf /tmp/plugins |
52 | git archive --prefix=tmp/plugins/ v2.4 | (cd /; tar -xf -) | 52 | git archive --prefix=tmp/plugins/ v2.5 | (cd /; tar -xf -) |
53 | 53 | ||
54 | Build the tarball | 54 | Build the tarball |
55 | ----------------- | 55 | ----------------- |
@@ -62,26 +62,26 @@ Build the tarball | |||
62 | Upload tarball to web site | 62 | Upload tarball to web site |
63 | -------------------------- | 63 | -------------------------- |
64 | 64 | ||
65 | scp monitoring-plugins-2.4.tar.gz \ | 65 | scp monitoring-plugins-2.5.tar.gz \ |
66 | plugins@orwell.monitoring-plugins.org:web/download/ | 66 | plugins@orwell.monitoring-plugins.org:web/download/ |
67 | 67 | ||
68 | Generate SHA1 checksum file on web site | 68 | Generate SHA1 checksum file on web site |
69 | --------------------------------------- | 69 | --------------------------------------- |
70 | 70 | ||
71 | ssh plugins@orwell.monitoring-plugins.org \ | 71 | ssh plugins@orwell.monitoring-plugins.org \ |
72 | '(cd web/download; $HOME/bin/create-checksum monitoring-plugins-2.4.tar.gz)' | 72 | '(cd web/download; $HOME/bin/create-checksum monitoring-plugins-2.5.tar.gz)' |
73 | 73 | ||
74 | Announce new release | 74 | Announce new release |
75 | -------------------- | 75 | -------------------- |
76 | 76 | ||
77 | - In the site.git repository: | 77 | - In the site.git repository: |
78 | 78 | ||
79 | - Create `web/input/news/release-2-4.md`. | 79 | - Create `web/input/news/release-2.5.md`. |
80 | - Update the `plugins_release` version in `web/macros.py`. | 80 | - Update the `plugins_release` version in `web/macros.py`. |
81 | - Commit and push the result: | 81 | - Commit and push the result: |
82 | 82 | ||
83 | git add web/input/news/release-2-4.md | 83 | git add web/input/news/release-2.5.md |
84 | git commit web/input/news/release-2-4.md web/macros.py | 84 | git commit web/input/news/release-2.5.md web/macros.py |
85 | git push origin master | 85 | git push origin master |
86 | 86 | ||
87 | - Post an announcement on (at least) the following mailing lists: | 87 | - Post an announcement on (at least) the following mailing lists: |
@@ -93,6 +93,6 @@ Announce new release | |||
93 | 93 | ||
94 | If you want to mention the number of contributors in the announcement: | 94 | If you want to mention the number of contributors in the announcement: |
95 | 95 | ||
96 | git shortlog -s v2.3.4..v2.4 | wc -l | 96 | git shortlog -s v2.4.0..v2.5 | wc -l |
97 | 97 | ||
98 | <!-- vim:set filetype=markdown textwidth=72: --> | 98 | <!-- vim:set filetype=markdown textwidth=72: --> |
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index fbb197f..e25d7a7 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -134,6 +134,7 @@ char regexp[MAX_RE_SIZE]; | |||
134 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; | 134 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; |
135 | int errcode; | 135 | int errcode; |
136 | bool invert_regex = false; | 136 | bool invert_regex = false; |
137 | int state_regex = STATE_CRITICAL; | ||
137 | 138 | ||
138 | char *server_address = NULL; | 139 | char *server_address = NULL; |
139 | char *host_name = NULL; | 140 | char *host_name = NULL; |
@@ -467,6 +468,7 @@ int | |||
467 | check_http (void) | 468 | check_http (void) |
468 | { | 469 | { |
469 | int result = STATE_OK; | 470 | int result = STATE_OK; |
471 | int result_ssl = STATE_OK; | ||
470 | int page_len = 0; | 472 | int page_len = 0; |
471 | int i; | 473 | int i; |
472 | char *force_host_header = NULL; | 474 | char *force_host_header = NULL; |
@@ -851,9 +853,9 @@ check_http (void) | |||
851 | /* check certificate with OpenSSL functions, curl has been built against OpenSSL | 853 | /* check certificate with OpenSSL functions, curl has been built against OpenSSL |
852 | * and we actually have OpenSSL in the monitoring tools | 854 | * and we actually have OpenSSL in the monitoring tools |
853 | */ | 855 | */ |
854 | result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | 856 | result_ssl = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); |
855 | if (!continue_after_check_cert) { | 857 | if (!continue_after_check_cert) { |
856 | return result; | 858 | return result_ssl; |
857 | } | 859 | } |
858 | #else /* USE_OPENSSL */ | 860 | #else /* USE_OPENSSL */ |
859 | die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); | 861 | die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); |
@@ -897,17 +899,17 @@ GOT_FIRST_CERT: | |||
897 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 899 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
898 | } | 900 | } |
899 | BIO_free (cert_BIO); | 901 | BIO_free (cert_BIO); |
900 | result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | 902 | result_ssl = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); |
901 | if (!continue_after_check_cert) { | 903 | if (!continue_after_check_cert) { |
902 | return result; | 904 | return result_ssl; |
903 | } | 905 | } |
904 | #else /* USE_OPENSSL */ | 906 | #else /* USE_OPENSSL */ |
905 | /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, | 907 | /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, |
906 | * so we use the libcurl CURLINFO data | 908 | * so we use the libcurl CURLINFO data |
907 | */ | 909 | */ |
908 | result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); | 910 | result_ssl = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); |
909 | if (!continue_after_check_cert) { | 911 | if (!continue_after_check_cert) { |
910 | return result; | 912 | return result_ssl; |
911 | } | 913 | } |
912 | #endif /* USE_OPENSSL */ | 914 | #endif /* USE_OPENSSL */ |
913 | } else { | 915 | } else { |
@@ -1133,7 +1135,7 @@ GOT_FIRST_CERT: | |||
1133 | strcpy(msg, tmp); | 1135 | strcpy(msg, tmp); |
1134 | 1136 | ||
1135 | } | 1137 | } |
1136 | result = STATE_CRITICAL; | 1138 | result = state_regex; |
1137 | } else { | 1139 | } else { |
1138 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 1140 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); |
1139 | 1141 | ||
@@ -1175,7 +1177,7 @@ GOT_FIRST_CERT: | |||
1175 | } | 1177 | } |
1176 | 1178 | ||
1177 | /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ | 1179 | /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ |
1178 | die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", | 1180 | die (max_state_alt(result, result_ssl), "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", |
1179 | state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), | 1181 | state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), |
1180 | status_line.http_code, status_line.msg, | 1182 | status_line.http_code, status_line.msg, |
1181 | strlen(msg) > 0 ? " - " : "", | 1183 | strlen(msg) > 0 ? " - " : "", |
@@ -1185,7 +1187,7 @@ GOT_FIRST_CERT: | |||
1185 | (show_body ? body_buf.buf : ""), | 1187 | (show_body ? body_buf.buf : ""), |
1186 | (show_body ? "\n" : "") ); | 1188 | (show_body ? "\n" : "") ); |
1187 | 1189 | ||
1188 | return result; | 1190 | return max_state_alt(result, result_ssl); |
1189 | } | 1191 | } |
1190 | 1192 | ||
1191 | int | 1193 | int |
@@ -1284,10 +1286,12 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1284 | } | 1286 | } |
1285 | } | 1287 | } |
1286 | 1288 | ||
1287 | if (!uri_strcmp (uri.scheme, "https")) | 1289 | if (uri.scheme.first) { |
1288 | use_ssl = true; | 1290 | if (!uri_strcmp (uri.scheme, "https")) |
1289 | else | 1291 | use_ssl = true; |
1290 | use_ssl = false; | 1292 | else |
1293 | use_ssl = false; | ||
1294 | } | ||
1291 | 1295 | ||
1292 | /* we do a sloppy test here only, because uriparser would have failed | 1296 | /* we do a sloppy test here only, because uriparser would have failed |
1293 | * above, if the port would be invalid, we just check for MAX_PORT | 1297 | * above, if the port would be invalid, we just check for MAX_PORT |
@@ -1305,10 +1309,13 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1305 | MAX_PORT, location, display_html ? "</A>" : ""); | 1309 | MAX_PORT, location, display_html ? "</A>" : ""); |
1306 | 1310 | ||
1307 | /* by RFC 7231 relative URLs in Location should be taken relative to | 1311 | /* by RFC 7231 relative URLs in Location should be taken relative to |
1308 | * the original URL, so wy try to form a new absolute URL here | 1312 | * the original URL, so we try to form a new absolute URL here |
1309 | */ | 1313 | */ |
1310 | if (!uri.scheme.first && !uri.hostText.first) { | 1314 | if (!uri.scheme.first && !uri.hostText.first) { |
1311 | new_host = strdup (host_name ? host_name : server_address); | 1315 | new_host = strdup (host_name ? host_name : server_address); |
1316 | new_port = server_port; | ||
1317 | if(use_ssl) | ||
1318 | uri_string (uri.scheme, "https", DEFAULT_BUFFER_SIZE); | ||
1312 | } else { | 1319 | } else { |
1313 | new_host = strdup (uri_string (uri.hostText, buf, DEFAULT_BUFFER_SIZE)); | 1320 | new_host = strdup (uri_string (uri.hostText, buf, DEFAULT_BUFFER_SIZE)); |
1314 | } | 1321 | } |
@@ -1391,7 +1398,8 @@ process_arguments (int argc, char **argv) | |||
1391 | HTTP_VERSION_OPTION, | 1398 | HTTP_VERSION_OPTION, |
1392 | AUTOMATIC_DECOMPRESSION, | 1399 | AUTOMATIC_DECOMPRESSION, |
1393 | COOKIE_JAR, | 1400 | COOKIE_JAR, |
1394 | HAPROXY_PROTOCOL | 1401 | HAPROXY_PROTOCOL, |
1402 | STATE_REGEX | ||
1395 | }; | 1403 | }; |
1396 | 1404 | ||
1397 | int option = 0; | 1405 | int option = 0; |
@@ -1430,6 +1438,7 @@ process_arguments (int argc, char **argv) | |||
1430 | {"content-type", required_argument, 0, 'T'}, | 1438 | {"content-type", required_argument, 0, 'T'}, |
1431 | {"pagesize", required_argument, 0, 'm'}, | 1439 | {"pagesize", required_argument, 0, 'm'}, |
1432 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, | 1440 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, |
1441 | {"state-regex", required_argument, 0, STATE_REGEX}, | ||
1433 | {"use-ipv4", no_argument, 0, '4'}, | 1442 | {"use-ipv4", no_argument, 0, '4'}, |
1434 | {"use-ipv6", no_argument, 0, '6'}, | 1443 | {"use-ipv6", no_argument, 0, '6'}, |
1435 | {"extended-perfdata", no_argument, 0, 'E'}, | 1444 | {"extended-perfdata", no_argument, 0, 'E'}, |
@@ -1765,6 +1774,13 @@ process_arguments (int argc, char **argv) | |||
1765 | case INVERT_REGEX: | 1774 | case INVERT_REGEX: |
1766 | invert_regex = true; | 1775 | invert_regex = true; |
1767 | break; | 1776 | break; |
1777 | case STATE_REGEX: | ||
1778 | if (!strcmp (optarg, "critical")) | ||
1779 | state_regex = STATE_CRITICAL; | ||
1780 | else if (!strcmp (optarg, "warning")) | ||
1781 | state_regex = STATE_WARNING; | ||
1782 | else usage2 (_("Invalid state-regex option"), optarg); | ||
1783 | break; | ||
1768 | case '4': | 1784 | case '4': |
1769 | address_family = AF_INET; | 1785 | address_family = AF_INET; |
1770 | break; | 1786 | break; |
@@ -1992,8 +2008,11 @@ print_help (void) | |||
1992 | printf (" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); | 2008 | printf (" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); |
1993 | #endif | 2009 | #endif |
1994 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); | 2010 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); |
1995 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); | 2011 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443.")); |
1996 | printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use")); | 2012 | printf (" %s\n", _("A STATE_WARNING is returned if the certificate has a validity less than the")); |
2013 | printf (" %s\n", _("first agument's value. If there is a second argument and the certificate's")); | ||
2014 | printf (" %s\n", _("validity is less than its value, a STATE_CRITICAL is returned.")); | ||
2015 | printf (" %s\n", _("(When this option is used the URL is not checked by default. You can use")); | ||
1997 | printf (" %s\n", _(" --continue-after-certificate to override this behavior)")); | 2016 | printf (" %s\n", _(" --continue-after-certificate to override this behavior)")); |
1998 | printf (" %s\n", "--continue-after-certificate"); | 2017 | printf (" %s\n", "--continue-after-certificate"); |
1999 | printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); | 2018 | printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); |
@@ -2022,7 +2041,7 @@ print_help (void) | |||
2022 | printf (" %s\n", "-u, --url=PATH"); | 2041 | printf (" %s\n", "-u, --url=PATH"); |
2023 | printf (" %s\n", _("URL to GET or POST (default: /)")); | 2042 | printf (" %s\n", _("URL to GET or POST (default: /)")); |
2024 | printf (" %s\n", "-P, --post=STRING"); | 2043 | printf (" %s\n", "-P, --post=STRING"); |
2025 | printf (" %s\n", _("URL encoded http POST data")); | 2044 | printf (" %s\n", _("URL decoded http POST data")); |
2026 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); | 2045 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); |
2027 | printf (" %s\n", _("Set HTTP method.")); | 2046 | printf (" %s\n", _("Set HTTP method.")); |
2028 | printf (" %s\n", "-N, --no-body"); | 2047 | printf (" %s\n", "-N, --no-body"); |
@@ -2040,7 +2059,10 @@ print_help (void) | |||
2040 | printf (" %s\n", "-R, --eregi=STRING"); | 2059 | printf (" %s\n", "-R, --eregi=STRING"); |
2041 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); | 2060 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); |
2042 | printf (" %s\n", "--invert-regex"); | 2061 | printf (" %s\n", "--invert-regex"); |
2043 | printf (" %s\n", _("Return CRITICAL if found, OK if not\n")); | 2062 | printf (" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); |
2063 | printf (" %s\n", _("can be changed with --state--regex)")); | ||
2064 | printf (" %s\n", "--regex-state=STATE"); | ||
2065 | printf (" %s\n", _("Return STATE if regex is found, OK if not\n")); | ||
2044 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); | 2066 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); |
2045 | printf (" %s\n", _("Username:password on sites with basic authentication")); | 2067 | printf (" %s\n", _("Username:password on sites with basic authentication")); |
2046 | printf (" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); | 2068 | printf (" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); |
@@ -2073,7 +2095,7 @@ print_help (void) | |||
2073 | printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); | 2095 | printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); |
2074 | printf(" %s\n", "--haproxy-protocol"); | 2096 | printf(" %s\n", "--haproxy-protocol"); |
2075 | printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL).")); | 2097 | printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL).")); |
2076 | printf (" %s\n", "---cookie-jar=FILE"); | 2098 | printf (" %s\n", "--cookie-jar=FILE"); |
2077 | printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); | 2099 | printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); |
2078 | printf ("\n"); | 2100 | printf ("\n"); |
2079 | 2101 | ||
@@ -2168,8 +2190,6 @@ print_usage (void) | |||
2168 | printf ("%s\n", _("In the first form, make an HTTP request.")); | 2190 | printf ("%s\n", _("In the first form, make an HTTP request.")); |
2169 | printf ("%s\n\n", _("In the second form, connect to the server and check the TLS certificate.")); | 2191 | printf ("%s\n\n", _("In the second form, connect to the server and check the TLS certificate.")); |
2170 | #endif | 2192 | #endif |
2171 | printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); | ||
2172 | printf ("%s\n\n", _("check_http if you need a stable version.")); | ||
2173 | } | 2193 | } |
2174 | 2194 | ||
2175 | void | 2195 | void |
diff --git a/plugins/check_http.c b/plugins/check_http.c index 425ce86..cdf768c 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
@@ -85,6 +85,7 @@ char errbuf[MAX_INPUT_BUFFER]; | |||
85 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; | 85 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; |
86 | int errcode; | 86 | int errcode; |
87 | int invert_regex = 0; | 87 | int invert_regex = 0; |
88 | int state_regex = STATE_CRITICAL; | ||
88 | 89 | ||
89 | struct timeval tv; | 90 | struct timeval tv; |
90 | struct timeval tv_temp; | 91 | struct timeval tv_temp; |
@@ -210,7 +211,8 @@ bool process_arguments (int argc, char **argv) | |||
210 | INVERT_REGEX = CHAR_MAX + 1, | 211 | INVERT_REGEX = CHAR_MAX + 1, |
211 | SNI_OPTION, | 212 | SNI_OPTION, |
212 | MAX_REDIRS_OPTION, | 213 | MAX_REDIRS_OPTION, |
213 | CONTINUE_AFTER_CHECK_CERT | 214 | CONTINUE_AFTER_CHECK_CERT, |
215 | STATE_REGEX | ||
214 | }; | 216 | }; |
215 | 217 | ||
216 | int option = 0; | 218 | int option = 0; |
@@ -246,6 +248,7 @@ bool process_arguments (int argc, char **argv) | |||
246 | {"content-type", required_argument, 0, 'T'}, | 248 | {"content-type", required_argument, 0, 'T'}, |
247 | {"pagesize", required_argument, 0, 'm'}, | 249 | {"pagesize", required_argument, 0, 'm'}, |
248 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, | 250 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, |
251 | {"state-regex", required_argument, 0, STATE_REGEX}, | ||
249 | {"use-ipv4", no_argument, 0, '4'}, | 252 | {"use-ipv4", no_argument, 0, '4'}, |
250 | {"use-ipv6", no_argument, 0, '6'}, | 253 | {"use-ipv6", no_argument, 0, '6'}, |
251 | {"extended-perfdata", no_argument, 0, 'E'}, | 254 | {"extended-perfdata", no_argument, 0, 'E'}, |
@@ -511,6 +514,13 @@ bool process_arguments (int argc, char **argv) | |||
511 | case INVERT_REGEX: | 514 | case INVERT_REGEX: |
512 | invert_regex = 1; | 515 | invert_regex = 1; |
513 | break; | 516 | break; |
517 | case STATE_REGEX: | ||
518 | if (!strcmp (optarg, "critical")) | ||
519 | state_regex = STATE_CRITICAL; | ||
520 | else if (!strcmp (optarg, "warning")) | ||
521 | state_regex = STATE_WARNING; | ||
522 | else usage2 (_("Invalid state-regex option"), optarg); | ||
523 | break; | ||
514 | case '4': | 524 | case '4': |
515 | address_family = AF_INET; | 525 | address_family = AF_INET; |
516 | break; | 526 | break; |
@@ -1317,7 +1327,7 @@ check_http (void) | |||
1317 | xasprintf (&msg, _("%spattern not found, "), msg); | 1327 | xasprintf (&msg, _("%spattern not found, "), msg); |
1318 | else | 1328 | else |
1319 | xasprintf (&msg, _("%spattern found, "), msg); | 1329 | xasprintf (&msg, _("%spattern found, "), msg); |
1320 | result = STATE_CRITICAL; | 1330 | result = state_regex; |
1321 | } | 1331 | } |
1322 | else { | 1332 | else { |
1323 | /* FIXME: Shouldn't that be UNKNOWN? */ | 1333 | /* FIXME: Shouldn't that be UNKNOWN? */ |
@@ -1774,7 +1784,7 @@ print_help (void) | |||
1774 | printf (" %s\n", "-u, --url=PATH"); | 1784 | printf (" %s\n", "-u, --url=PATH"); |
1775 | printf (" %s\n", _("URL to GET or POST (default: /)")); | 1785 | printf (" %s\n", _("URL to GET or POST (default: /)")); |
1776 | printf (" %s\n", "-P, --post=STRING"); | 1786 | printf (" %s\n", "-P, --post=STRING"); |
1777 | printf (" %s\n", _("URL encoded http POST data")); | 1787 | printf (" %s\n", _("URL decoded http POST data")); |
1778 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT, CONNECT:POST)"); | 1788 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT, CONNECT:POST)"); |
1779 | printf (" %s\n", _("Set HTTP method.")); | 1789 | printf (" %s\n", _("Set HTTP method.")); |
1780 | printf (" %s\n", "-N, --no-body"); | 1790 | printf (" %s\n", "-N, --no-body"); |
@@ -1793,7 +1803,10 @@ print_help (void) | |||
1793 | printf (" %s\n", "-R, --eregi=STRING"); | 1803 | printf (" %s\n", "-R, --eregi=STRING"); |
1794 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); | 1804 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); |
1795 | printf (" %s\n", "--invert-regex"); | 1805 | printf (" %s\n", "--invert-regex"); |
1796 | printf (" %s\n", _("Return CRITICAL if found, OK if not\n")); | 1806 | printf (" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); |
1807 | printf (" %s\n", _("can be changed with --state--regex)")); | ||
1808 | printf (" %s\n", "--regex-state=STATE"); | ||
1809 | printf (" %s\n", _("Return STATE if regex is found, OK if not\n")); | ||
1797 | 1810 | ||
1798 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); | 1811 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); |
1799 | printf (" %s\n", _("Username:password on sites with basic authentication")); | 1812 | printf (" %s\n", _("Username:password on sites with basic authentication")); |
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 295aa9b..937b3a5 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c | |||
@@ -1253,10 +1253,12 @@ print_help (void) | |||
1253 | printf (" %s\n", _("SNMPv3 context")); | 1253 | printf (" %s\n", _("SNMPv3 context")); |
1254 | printf (" %s\n", "-L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]"); | 1254 | printf (" %s\n", "-L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]"); |
1255 | printf (" %s\n", _("SNMPv3 securityLevel")); | 1255 | printf (" %s\n", _("SNMPv3 securityLevel")); |
1256 | printf (" %s\n", "-a, --authproto=[MD5|SHA]"); | 1256 | printf (" %s\n", "-a, --authproto=AUTHENTICATION_PROTOCOL"); |
1257 | printf (" %s\n", _("SNMPv3 auth proto")); | 1257 | printf (" %s\n", _("SNMPv3 authentication protocol (default MD5), available options depend on the specific version of the net-snmp tools")); |
1258 | printf (" %s\n", "-x, --privproto=[DES|AES]"); | 1258 | printf (" %s\n", _("if < 5.8 SHA (1) and MD5 should be available, if >= 5.8 additionally SHA-224, SHA-256, SHA-384 and SHA-512")); |
1259 | printf (" %s\n", _("SNMPv3 priv proto (default DES)")); | 1259 | printf (" %s\n", "-x, --privproto=PRIVACY_PROTOCOL"); |
1260 | printf (" %s\n", _("SNMPv3 privacy protocol (default DES), available options depend on the specific version of the net-snmp tools")); | ||
1261 | printf (" %s\n", _("if < 5.8 DES and AES should be available, if >= 5.8 additionally AES-192 and AES-256")); | ||
1260 | 1262 | ||
1261 | /* Authentication Tokens*/ | 1263 | /* Authentication Tokens*/ |
1262 | printf (" %s\n", "-C, --community=STRING"); | 1264 | printf (" %s\n", "-C, --community=STRING"); |
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index eae98cc..7a930a4 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t | |||
@@ -205,9 +205,9 @@ SKIP: { | |||
205 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); | 205 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); |
206 | like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); | 206 | like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); |
207 | 207 | ||
208 | $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f curl" ); | 208 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org -u /download.html -f follow" ); |
209 | is( $res->return_code, 0, "Redirection based on location is okay"); | 209 | is( $res->return_code, 0, "Redirection based on location is okay"); |
210 | 210 | ||
211 | $res = NPTest->testCmd( "./$plugin -H www.mozilla.com --extended-perfdata" ); | 211 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org --extended-perfdata" ); |
212 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); | 212 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); |
213 | } | 213 | } |
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t index 1f2fbdf..6ab4a5b 100644 --- a/plugins/t/check_http.t +++ b/plugins/t/check_http.t | |||
@@ -166,10 +166,10 @@ SKIP: { | |||
166 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); | 166 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); |
167 | like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); | 167 | like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); |
168 | 168 | ||
169 | $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f follow" ); | 169 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org -u /download.html -f follow" ); |
170 | is( $res->return_code, 0, "Redirection based on location is okay"); | 170 | is( $res->return_code, 0, "Redirection based on location is okay"); |
171 | 171 | ||
172 | $res = NPTest->testCmd( "./$plugin -H www.mozilla.com --extended-perfdata" ); | 172 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org --extended-perfdata" ); |
173 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); | 173 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); |
174 | } | 174 | } |
175 | 175 | ||
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index 3c91483..eaa9f51 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t | |||
@@ -21,7 +21,7 @@ use FindBin qw($Bin); | |||
21 | 21 | ||
22 | $ENV{'LC_TIME'} = "C"; | 22 | $ENV{'LC_TIME'} = "C"; |
23 | 23 | ||
24 | my $common_tests = 73; | 24 | my $common_tests = 75; |
25 | my $ssl_only_tests = 8; | 25 | my $ssl_only_tests = 8; |
26 | # Check that all dependent modules are available | 26 | # Check that all dependent modules are available |
27 | eval "use HTTP::Daemon 6.01;"; | 27 | eval "use HTTP::Daemon 6.01;"; |
@@ -178,6 +178,11 @@ sub run_server { | |||
178 | $c->send_basic_header; | 178 | $c->send_basic_header; |
179 | $c->send_crlf; | 179 | $c->send_crlf; |
180 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); | 180 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); |
181 | } elsif ($r->url->path eq "/redirect_rel") { | ||
182 | $c->send_basic_header(302); | ||
183 | $c->send_header("Location", "/redirect2" ); | ||
184 | $c->send_crlf; | ||
185 | $c->send_response('moved to /redirect2'); | ||
181 | } elsif ($r->url->path eq "/redir_timeout") { | 186 | } elsif ($r->url->path eq "/redir_timeout") { |
182 | $c->send_redirect( "/timeout" ); | 187 | $c->send_redirect( "/timeout" ); |
183 | } elsif ($r->url->path eq "/timeout") { | 188 | } elsif ($r->url->path eq "/timeout") { |
@@ -471,9 +476,12 @@ sub run_common_tests { | |||
471 | is( $result->return_code, 0, $cmd); | 476 | is( $result->return_code, 0, $cmd); |
472 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 477 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); |
473 | 478 | ||
474 | # These tests may block | 479 | $cmd = "$command -f follow -u /redirect_rel -s redirected"; |
475 | print "ALRM\n"; | 480 | $result = NPTest->testCmd( $cmd ); |
481 | is( $result->return_code, 0, $cmd); | ||
482 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | ||
476 | 483 | ||
484 | # These tests may block | ||
477 | # stickyport - on full urlS port is set back to 80 otherwise | 485 | # stickyport - on full urlS port is set back to 80 otherwise |
478 | $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; | 486 | $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; |
479 | eval { | 487 | eval { |
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t index 6078b27..6eaf85b 100755 --- a/plugins/tests/check_http.t +++ b/plugins/tests/check_http.t | |||
@@ -13,7 +13,7 @@ use IO::Socket::INET; | |||
13 | 13 | ||
14 | $ENV{'LC_TIME'} = "C"; | 14 | $ENV{'LC_TIME'} = "C"; |
15 | 15 | ||
16 | my $common_tests = 71; | 16 | my $common_tests = 73; |
17 | my $virtual_port_tests = 8; | 17 | my $virtual_port_tests = 8; |
18 | my $ssl_only_tests = 12; | 18 | my $ssl_only_tests = 12; |
19 | my $chunked_encoding_special_tests = 1; | 19 | my $chunked_encoding_special_tests = 1; |
@@ -199,6 +199,11 @@ sub run_server { | |||
199 | $c->send_basic_header; | 199 | $c->send_basic_header; |
200 | $c->send_crlf; | 200 | $c->send_crlf; |
201 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); | 201 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); |
202 | } elsif ($r->url->path eq "/redirect_rel") { | ||
203 | $c->send_basic_header(302); | ||
204 | $c->send_header("Location", "/redirect2" ); | ||
205 | $c->send_crlf; | ||
206 | $c->send_response('moved to /redirect2'); | ||
202 | } elsif ($r->url->path eq "/redir_timeout") { | 207 | } elsif ($r->url->path eq "/redir_timeout") { |
203 | $c->send_redirect( "/timeout" ); | 208 | $c->send_redirect( "/timeout" ); |
204 | } elsif ($r->url->path eq "/timeout") { | 209 | } elsif ($r->url->path eq "/timeout") { |
@@ -515,6 +520,11 @@ sub run_common_tests { | |||
515 | is( $result->return_code, 0, $cmd); | 520 | is( $result->return_code, 0, $cmd); |
516 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 521 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); |
517 | 522 | ||
523 | $cmd = "$command -f follow -u /redirect_rel -s redirected"; | ||
524 | $result = NPTest->testCmd( $cmd ); | ||
525 | is( $result->return_code, 0, $cmd); | ||
526 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | ||
527 | |||
518 | # These tests may block | 528 | # These tests may block |
519 | print "ALRM\n"; | 529 | print "ALRM\n"; |
520 | 530 | ||