summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.github/prepare_debian.sh8
-rw-r--r--NEWS55
-rwxr-xr-xNP-VERSION-GEN2
-rw-r--r--THANKS.in6
-rw-r--r--configure.ac2
-rw-r--r--doc/RELEASING.md30
-rw-r--r--plugins/check_curl.c62
-rw-r--r--plugins/check_http.c21
-rw-r--r--plugins/check_ups.c1043
-rw-r--r--plugins/t/check_curl.t4
-rw-r--r--plugins/t/check_http.t4
-rwxr-xr-xplugins/tests/check_curl.t14
-rwxr-xr-xplugins/tests/check_http.t12
13 files changed, 710 insertions, 553 deletions
diff --git a/.github/prepare_debian.sh b/.github/prepare_debian.sh
index dcf778bc..3f4674a2 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
67if [ $(ip addr show | grep "inet6 ::1" | wc -l) -eq "0" ]; then 67sed '/^::1/d' /etc/hosts > /tmp/hosts
68 sed '/^::1/d' /etc/hosts > /tmp/hosts 68cp -f /tmp/hosts /etc/hosts
69 cp -f /tmp/hosts /etc/hosts
70fi
71
72ip addr show 69ip addr show
73
74cat /etc/hosts 70cat /etc/hosts
75 71
76# apache 72# apache
diff --git a/NEWS b/NEWS
index 5ddadf4d..fd43fd3a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,60 @@
1This file documents the major additions and syntax changes between releases. 1This file documents the major additions and syntax changes between releases.
2 2
32.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
32.3.5 18th Oct 2023 582.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 c353b1d1..e16f37da 100755
--- a/NP-VERSION-GEN
+++ b/NP-VERSION-GEN
@@ -6,7 +6,7 @@
6SRC_ROOT=`dirname $0` 6SRC_ROOT=`dirname $0`
7 7
8NPVF=NP-VERSION-FILE 8NPVF=NP-VERSION-FILE
9DEF_VER=2.3git 9DEF_VER=2.4git
10 10
11LF=' 11LF='
12' 12'
diff --git a/THANKS.in b/THANKS.in
index 69b32244..66397ad1 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -420,3 +420,9 @@ Stuart Henderson
420Thoralf Rickert-Wendt 420Thoralf Rickert-Wendt
421Thorsten Kukuk 421Thorsten Kukuk
422Matthias Döhler 422Matthias Döhler
423Emmanuel Riviere
424Eric Knibbe
425Eunice Remoquillo
426Louis Sautier
427Sven Hartge
428Alvar Penning
diff --git a/configure.ac b/configure.ac
index 17272e45..8594238f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
1dnl Process this file with autoconf to produce a configure script. 1dnl Process this file with autoconf to produce a configure script.
2AC_PREREQ(2.64) 2AC_PREREQ(2.64)
3AC_INIT(monitoring-plugins,2.3git) 3AC_INIT(monitoring-plugins,2.4git)
4AC_CONFIG_SRCDIR(NPTest.pm) 4AC_CONFIG_SRCDIR(NPTest.pm)
5AC_CONFIG_FILES([gl/Makefile]) 5AC_CONFIG_FILES([gl/Makefile])
6AC_CONFIG_AUX_DIR(build-aux) 6AC_CONFIG_AUX_DIR(build-aux)
diff --git a/doc/RELEASING.md b/doc/RELEASING.md
index f0932bd4..e1f3bf74 100644
--- a/doc/RELEASING.md
+++ b/doc/RELEASING.md
@@ -2,7 +2,7 @@ Releasing a New Monitoring Plugins Version
2========================================== 2==========================================
3 3
4Throughout this document, it is assumed that the current Monitoring 4Throughout this document, it is assumed that the current Monitoring
5Plugins version is 2.3.4, and that we're about to publish version 2.4. 5Plugins version is 2.4.0, and that we're about to publish version 2.5.
6It is also assumed that the official repository on GitHub is tracked 6It is also assumed that the official repository on GitHub is tracked
7using the remote name `monitoring-plugins` (rather than `origin`). 7using 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
17Prepare and commit files 17Prepare 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
29Create annotated tag 29Create 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
34Push the code and tag to GitHub 34Push 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
40Create new maintenance branch 40Create 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
48Checkout new version 48Checkout 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
54Build the tarball 54Build the tarball
55----------------- 55-----------------
@@ -62,26 +62,26 @@ Build the tarball
62Upload tarball to web site 62Upload 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
68Generate SHA1 checksum file on web site 68Generate 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
74Announce new release 74Announce 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
94If you want to mention the number of contributors in the announcement: 94If 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 fbb197f7..e9c15e64 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -134,6 +134,7 @@ char regexp[MAX_RE_SIZE];
134int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; 134int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE;
135int errcode; 135int errcode;
136bool invert_regex = false; 136bool invert_regex = false;
137int state_regex = STATE_CRITICAL;
137 138
138char *server_address = NULL; 139char *server_address = NULL;
139char *host_name = NULL; 140char *host_name = NULL;
@@ -467,6 +468,7 @@ int
467check_http (void) 468check_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
1191int 1193int
@@ -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
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 425ce86b..cdf768c9 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -85,6 +85,7 @@ char errbuf[MAX_INPUT_BUFFER];
85int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; 85int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE;
86int errcode; 86int errcode;
87int invert_regex = 0; 87int invert_regex = 0;
88int state_regex = STATE_CRITICAL;
88 89
89struct timeval tv; 90struct timeval tv;
90struct timeval tv_temp; 91struct 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_ups.c b/plugins/check_ups.c
index 2fb04eef..380ff3bc 100644
--- a/plugins/check_ups.c
+++ b/plugins/check_ups.c
@@ -1,699 +1,746 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_ups plugin 3 * Monitoring check_ups plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2000 Tom Shields 6 * Copyright (c) 2000 Tom Shields
7* 2004 Alain Richard <alain.richard@equation.fr> 7 * 2004 Alain Richard <alain.richard@equation.fr>
8* 2004 Arnaud Quette <arnaud.quette@mgeups.com> 8 * 2004 Arnaud Quette <arnaud.quette@mgeups.com>
9* Copyright (c) 2002-2007 Monitoring Plugins Development Team 9 * Copyright (c) 2002-2023 Monitoring Plugins Development Team
10* 10 *
11* Description: 11 * Description:
12* 12 *
13* This file contains Network UPS Tools plugin for Monitoring 13 * This file contains Network UPS Tools plugin for Monitoring
14* 14 *
15* This plugin tests the UPS service on the specified host. Network UPS Tools 15 * This plugin tests the UPS service on the specified host. Network UPS Tools
16* from www.networkupstools.org must be running for this plugin to work. 16 * from www.networkupstools.org must be running for this plugin to work.
17* 17 *
18* 18 *
19* This program is free software: you can redistribute it and/or modify 19 * This program is free software: you can redistribute it and/or modify
20* it under the terms of the GNU General Public License as published by 20 * it under the terms of the GNU General Public License as published by
21* the Free Software Foundation, either version 3 of the License, or 21 * the Free Software Foundation, either version 3 of the License, or
22* (at your option) any later version. 22 * (at your option) any later version.
23* 23 *
24* This program is distributed in the hope that it will be useful, 24 * This program is distributed in the hope that it will be useful,
25* but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27* GNU General Public License for more details. 27 * GNU General Public License for more details.
28* 28 *
29* You should have received a copy of the GNU General Public License 29 * You should have received a copy of the GNU General Public License
30* along with this program. If not, see <http://www.gnu.org/licenses/>. 30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31* 31 *
32* 32 *
33*****************************************************************************/ 33 *****************************************************************************/
34 34
35const char *progname = "check_ups"; 35const char *progname = "check_ups";
36const char *copyright = "2000-2007"; 36const char *copyright = "2000-2023";
37const char *email = "devel@monitoring-plugins.org"; 37const char *email = "devel@monitoring-plugins.org";
38 38
39#include "common.h" 39#include "common.h"
40#include "netutils.h" 40#include "netutils.h"
41#include "utils.h" 41#include "utils.h"
42 42
43enum { 43enum { PORT = 3493 };
44 PORT = 3493
45};
46 44
47#define CHECK_NONE 0 45#define UPS_NONE 0 /* no supported options */
48 46#define UPS_UTILITY 1 /* supports utility line */
49#define UPS_NONE 0 /* no supported options */ 47#define UPS_BATTPCT 2 /* supports percent battery remaining */
50#define UPS_UTILITY 1 /* supports utility line */ 48#define UPS_STATUS 4 /* supports UPS status */
51#define UPS_BATTPCT 2 /* supports percent battery remaining */ 49#define UPS_TEMP 8 /* supports UPS temperature */
52#define UPS_STATUS 4 /* supports UPS status */ 50#define UPS_LOADPCT 16 /* supports load percent */
53#define UPS_TEMP 8 /* supports UPS temperature */
54#define UPS_LOADPCT 16 /* supports load percent */
55#define UPS_REALPOWER 32 /* supports real power */ 51#define UPS_REALPOWER 32 /* supports real power */
56 52
57#define UPSSTATUS_NONE 0 53#define UPSSTATUS_NONE 0
58#define UPSSTATUS_OFF 1 54#define UPSSTATUS_OFF 1
59#define UPSSTATUS_OL 2 55#define UPSSTATUS_OL 2
60#define UPSSTATUS_OB 4 56#define UPSSTATUS_OB 4
61#define UPSSTATUS_LB 8 57#define UPSSTATUS_LB 8
62#define UPSSTATUS_CAL 16 58#define UPSSTATUS_CAL 16
63#define UPSSTATUS_RB 32 /*Replace Battery */ 59#define UPSSTATUS_RB 32 /*Replace Battery */
64#define UPSSTATUS_BYPASS 64 60#define UPSSTATUS_BYPASS 64
65#define UPSSTATUS_OVER 128 61#define UPSSTATUS_OVER 128
66#define UPSSTATUS_TRIM 256 62#define UPSSTATUS_TRIM 256
67#define UPSSTATUS_BOOST 512 63#define UPSSTATUS_BOOST 512
68#define UPSSTATUS_CHRG 1024 64#define UPSSTATUS_CHRG 1024
69#define UPSSTATUS_DISCHRG 2048 65#define UPSSTATUS_DISCHRG 2048
70#define UPSSTATUS_UNKNOWN 4096 66#define UPSSTATUS_UNKNOWN 4096
71 67#define UPSSTATUS_ALARM 8192
72enum { NOSUCHVAR = ERROR-1 }; 68
73 69enum { NOSUCHVAR = ERROR - 1 };
74int server_port = PORT; 70
75char *server_address; 71typedef struct ups_config {
76char *ups_name = NULL; 72 unsigned int server_port;
77double warning_value = 0.0; 73 char *server_address;
78double critical_value = 0.0; 74 char *ups_name;
79bool check_warn = false; 75 double warning_value;
80bool check_crit = false; 76 double critical_value;
81int check_variable = UPS_NONE; 77 bool check_warn;
82int supported_options = UPS_NONE; 78 bool check_crit;
83int status = UPSSTATUS_NONE; 79 int check_variable;
84 80 int status;
85double ups_utility_voltage = 0.0; 81 bool temp_output_c;
86double ups_battery_percent = 0.0; 82} ups_config;
87double ups_load_percent = 0.0; 83
88double ups_temperature = 0.0; 84ups_config ups_config_init(void) {
89double ups_realpower = 0.0; 85 ups_config tmp = {0};
90char *ups_status; 86 tmp.server_port = PORT;
91bool temp_output_c = false; 87 tmp.server_address = NULL;
92 88 tmp.ups_name = NULL;
93int determine_status (void); 89 tmp.check_variable = UPS_NONE;
94int get_ups_variable (const char *, char *); 90 tmp.status = UPSSTATUS_NONE;
95 91
96int process_arguments (int, char **); 92 return tmp;
97int validate_arguments (void); 93}
98void print_help (void); 94
99void print_usage (void); 95// Forward declarations
100 96int determine_status(ups_config *, int *supported_options);
101int 97int get_ups_variable(const char *, char *, const ups_config config);
102main (int argc, char **argv) 98
103{ 99int process_arguments(int, char **, ups_config *);
104 int result = STATE_UNKNOWN; 100int validate_arguments(ups_config);
105 char *message; 101void print_help(void);
102void print_usage(void);
103
104int main(int argc, char **argv) {
105 setlocale(LC_ALL, "");
106 bindtextdomain(PACKAGE, LOCALEDIR);
107 textdomain(PACKAGE);
108
109 char *ups_status;
110 ups_status = strdup("N/A");
111
106 char *data; 112 char *data;
107 char *tunits; 113 data = strdup("");
108 char temp_buffer[MAX_INPUT_BUFFER];
109 double ups_utility_deviation = 0.0;
110 int res;
111 114
112 setlocale (LC_ALL, ""); 115 char *message;
113 bindtextdomain (PACKAGE, LOCALEDIR); 116 message = strdup("");
114 textdomain (PACKAGE);
115 117
116 ups_status = strdup ("N/A"); 118 // Exit result
117 data = strdup (""); 119 int result = STATE_UNKNOWN;
118 message = strdup ("");
119 120
120 /* Parse extra opts if any */ 121 /* Parse extra opts if any */
121 argv=np_extra_opts (&argc, argv, progname); 122 argv = np_extra_opts(&argc, argv, progname);
122 123
123 if (process_arguments (argc, argv) == ERROR) 124 // Config from commandline
124 usage4 (_("Could not parse arguments")); 125 ups_config config = ups_config_init();
126
127 if (process_arguments(argc, argv, &config) == ERROR) {
128 usage4(_("Could not parse arguments"));
129 }
125 130
126 /* initialize alarm signal handling */ 131 /* initialize alarm signal handling */
127 signal (SIGALRM, socket_timeout_alarm_handler); 132 signal(SIGALRM, socket_timeout_alarm_handler);
128 133
129 /* set socket timeout */ 134 /* set socket timeout */
130 alarm (socket_timeout); 135 alarm(socket_timeout);
136
137 int supported_options = UPS_NONE;
131 138
132 /* get the ups status if possible */ 139 /* get the ups status if possible */
133 if (determine_status () != OK) 140 if (determine_status(&config, &supported_options) != OK) {
134 return STATE_CRITICAL; 141 return STATE_CRITICAL;
142 }
143
144
135 if (supported_options & UPS_STATUS) { 145 if (supported_options & UPS_STATUS) {
136 146
137 ups_status = strdup (""); 147 ups_status = strdup("");
148
138 result = STATE_OK; 149 result = STATE_OK;
139 150
140 if (status & UPSSTATUS_OFF) { 151 if (config.status & UPSSTATUS_OFF) {
141 xasprintf (&ups_status, "Off"); 152 xasprintf(&ups_status, "Off");
142 result = STATE_CRITICAL; 153 result = STATE_CRITICAL;
143 } 154 } else if ((config.status & (UPSSTATUS_OB | UPSSTATUS_LB)) ==
144 else if ((status & (UPSSTATUS_OB | UPSSTATUS_LB)) == 155 (UPSSTATUS_OB | UPSSTATUS_LB)) {
145 (UPSSTATUS_OB | UPSSTATUS_LB)) { 156 xasprintf(&ups_status, _("On Battery, Low Battery"));
146 xasprintf (&ups_status, _("On Battery, Low Battery"));
147 result = STATE_CRITICAL; 157 result = STATE_CRITICAL;
148 } 158 } else {
149 else { 159 if (config.status & UPSSTATUS_OL) {
150 if (status & UPSSTATUS_OL) { 160 xasprintf(&ups_status, "%s%s", ups_status, _("Online"));
151 xasprintf (&ups_status, "%s%s", ups_status, _("Online"));
152 } 161 }
153 if (status & UPSSTATUS_OB) { 162 if (config.status & UPSSTATUS_OB) {
154 xasprintf (&ups_status, "%s%s", ups_status, _("On Battery")); 163 xasprintf(&ups_status, "%s%s", ups_status, _("On Battery"));
155 result = STATE_WARNING; 164 result = max_state(result, STATE_WARNING);
156 } 165 }
157 if (status & UPSSTATUS_LB) { 166 if (config.status & UPSSTATUS_LB) {
158 xasprintf (&ups_status, "%s%s", ups_status, _(", Low Battery")); 167 xasprintf(&ups_status, "%s%s", ups_status, _(", Low Battery"));
159 result = STATE_WARNING; 168 result = max_state(result, STATE_WARNING);
160 } 169 }
161 if (status & UPSSTATUS_CAL) { 170 if (config.status & UPSSTATUS_CAL) {
162 xasprintf (&ups_status, "%s%s", ups_status, _(", Calibrating")); 171 xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating"));
163 } 172 }
164 if (status & UPSSTATUS_RB) { 173 if (config.status & UPSSTATUS_RB) {
165 xasprintf (&ups_status, "%s%s", ups_status, _(", Replace Battery")); 174 xasprintf(&ups_status, "%s%s", ups_status,
166 result = STATE_WARNING; 175 _(", Replace Battery"));
176 result = max_state(result, STATE_WARNING);
167 } 177 }
168 if (status & UPSSTATUS_BYPASS) { 178 if (config.status & UPSSTATUS_BYPASS) {
169 xasprintf (&ups_status, "%s%s", ups_status, _(", On Bypass")); 179 xasprintf(&ups_status, "%s%s", ups_status, _(", On Bypass"));
180 // Bypassing the battery is likely a bad thing
181 result = STATE_CRITICAL;
182 }
183 if (config.status & UPSSTATUS_OVER) {
184 xasprintf(&ups_status, "%s%s", ups_status, _(", Overload"));
185 result = max_state(result, STATE_WARNING);
170 } 186 }
171 if (status & UPSSTATUS_OVER) { 187 if (config.status & UPSSTATUS_TRIM) {
172 xasprintf (&ups_status, "%s%s", ups_status, _(", Overload")); 188 xasprintf(&ups_status, "%s%s", ups_status, _(", Trimming"));
173 } 189 }
174 if (status & UPSSTATUS_TRIM) { 190 if (config.status & UPSSTATUS_BOOST) {
175 xasprintf (&ups_status, "%s%s", ups_status, _(", Trimming")); 191 xasprintf(&ups_status, "%s%s", ups_status, _(", Boosting"));
176 } 192 }
177 if (status & UPSSTATUS_BOOST) { 193 if (config.status & UPSSTATUS_CHRG) {
178 xasprintf (&ups_status, "%s%s", ups_status, _(", Boosting")); 194 xasprintf(&ups_status, "%s%s", ups_status, _(", Charging"));
179 } 195 }
180 if (status & UPSSTATUS_CHRG) { 196 if (config.status & UPSSTATUS_DISCHRG) {
181 xasprintf (&ups_status, "%s%s", ups_status, _(", Charging")); 197 xasprintf(&ups_status, "%s%s", ups_status, _(", Discharging"));
198 result = max_state(result, STATE_WARNING);
182 } 199 }
183 if (status & UPSSTATUS_DISCHRG) { 200 if (config.status & UPSSTATUS_ALARM) {
184 xasprintf (&ups_status, "%s%s", ups_status, _(", Discharging")); 201 xasprintf(&ups_status, "%s%s", ups_status, _(", ALARM"));
202 result = STATE_CRITICAL;
185 } 203 }
186 if (status & UPSSTATUS_UNKNOWN) { 204 if (config.status & UPSSTATUS_UNKNOWN) {
187 xasprintf (&ups_status, "%s%s", ups_status, _(", Unknown")); 205 xasprintf(&ups_status, "%s%s", ups_status, _(", Unknown"));
188 } 206 }
189 } 207 }
190 xasprintf (&message, "%sStatus=%s ", message, ups_status); 208 xasprintf(&message, "%sStatus=%s ", message, ups_status);
191 } 209 }
192 210
211 int res;
212 char temp_buffer[MAX_INPUT_BUFFER];
213
193 /* get the ups utility voltage if possible */ 214 /* get the ups utility voltage if possible */
194 res=get_ups_variable ("input.voltage", temp_buffer); 215 res = get_ups_variable("input.voltage", temp_buffer, config);
195 if (res == NOSUCHVAR) supported_options &= ~UPS_UTILITY; 216 if (res == NOSUCHVAR) {
196 else if (res != OK) 217 supported_options &= ~UPS_UTILITY;
218 } else if (res != OK) {
197 return STATE_CRITICAL; 219 return STATE_CRITICAL;
198 else { 220 } else {
199 supported_options |= UPS_UTILITY; 221 supported_options |= UPS_UTILITY;
200 222
201 ups_utility_voltage = atof (temp_buffer); 223 double ups_utility_voltage = 0.0;
202 xasprintf (&message, "%sUtility=%3.1fV ", message, ups_utility_voltage); 224 ups_utility_voltage = atof(temp_buffer);
225 xasprintf(&message, "%sUtility=%3.1fV ", message, ups_utility_voltage);
226
227 double ups_utility_deviation = 0.0;
203 228
204 if (ups_utility_voltage > 120.0) 229 if (ups_utility_voltage > 120.0) {
205 ups_utility_deviation = 120.0 - ups_utility_voltage; 230 ups_utility_deviation = 120.0 - ups_utility_voltage;
206 else 231 } else {
207 ups_utility_deviation = ups_utility_voltage - 120.0; 232 ups_utility_deviation = ups_utility_voltage - 120.0;
233 }
208 234
209 if (check_variable == UPS_UTILITY) { 235 if (config.check_variable == UPS_UTILITY) {
210 if (check_crit && ups_utility_deviation>=critical_value) { 236 if (config.check_crit &&
237 ups_utility_deviation >= config.critical_value) {
211 result = STATE_CRITICAL; 238 result = STATE_CRITICAL;
212 } 239 } else if (config.check_warn &&
213 else if (check_warn && ups_utility_deviation>=warning_value) { 240 ups_utility_deviation >= config.warning_value) {
214 result = max_state (result, STATE_WARNING); 241 result = max_state(result, STATE_WARNING);
215 } 242 }
216 xasprintf (&data, "%s", 243 xasprintf(&data, "%s",
217 perfdata ("voltage", (long)(1000*ups_utility_voltage), "mV", 244 perfdata("voltage", (long)(1000 * ups_utility_voltage),
218 check_warn, (long)(1000*warning_value), 245 "mV", config.check_warn,
219 check_crit, (long)(1000*critical_value), 246 (long)(1000 * config.warning_value),
220 true, 0, false, 0)); 247 config.check_crit,
248 (long)(1000 * config.critical_value), true, 0,
249 false, 0));
221 } else { 250 } else {
222 xasprintf (&data, "%s", 251 xasprintf(&data, "%s",
223 perfdata ("voltage", (long)(1000*ups_utility_voltage), "mV", 252 perfdata("voltage", (long)(1000 * ups_utility_voltage),
224 false, 0, false, 0, true, 0, false, 0)); 253 "mV", false, 0, false, 0, true, 0, false, 0));
225 } 254 }
226 } 255 }
227 256
228 /* get the ups battery percent if possible */ 257 /* get the ups battery percent if possible */
229 res=get_ups_variable ("battery.charge", temp_buffer); 258 res = get_ups_variable("battery.charge", temp_buffer, config);
230 if (res == NOSUCHVAR) supported_options &= ~UPS_BATTPCT; 259 if (res == NOSUCHVAR) {
231 else if ( res != OK) 260 supported_options &= ~UPS_BATTPCT;
261 } else if (res != OK) {
232 return STATE_CRITICAL; 262 return STATE_CRITICAL;
233 else { 263 } else {
234 supported_options |= UPS_BATTPCT; 264 supported_options |= UPS_BATTPCT;
235 ups_battery_percent = atof (temp_buffer);
236 xasprintf (&message, "%sBatt=%3.1f%% ", message, ups_battery_percent);
237 265
238 if (check_variable == UPS_BATTPCT) { 266 double ups_battery_percent = 0.0;
239 if (check_crit && ups_battery_percent <= critical_value) { 267 ups_battery_percent = atof(temp_buffer);
268 xasprintf(&message, "%sBatt=%3.1f%% ", message, ups_battery_percent);
269
270 if (config.check_variable == UPS_BATTPCT) {
271 if (config.check_crit &&
272 ups_battery_percent <= config.critical_value) {
240 result = STATE_CRITICAL; 273 result = STATE_CRITICAL;
241 } 274 } else if (config.check_warn &&
242 else if (check_warn && ups_battery_percent<=warning_value) { 275 ups_battery_percent <= config.warning_value) {
243 result = max_state (result, STATE_WARNING); 276 result = max_state(result, STATE_WARNING);
244 } 277 }
245 xasprintf (&data, "%s %s", data, 278 xasprintf(&data, "%s %s", data,
246 perfdata ("battery", (long)ups_battery_percent, "%", 279 perfdata("battery", (long)ups_battery_percent, "%",
247 check_warn, (long)(warning_value), 280 config.check_warn, (long)(config.warning_value),
248 check_crit, (long)(critical_value), 281 config.check_crit, (long)(config.critical_value),
249 true, 0, true, 100)); 282 true, 0, true, 100));
250 } else { 283 } else {
251 xasprintf (&data, "%s %s", data, 284 xasprintf(&data, "%s %s", data,
252 perfdata ("battery", (long)ups_battery_percent, "%", 285 perfdata("battery", (long)ups_battery_percent, "%", false,
253 false, 0, false, 0, true, 0, true, 100)); 286 0, false, 0, true, 0, true, 100));
254 } 287 }
255 } 288 }
256 289
257 /* get the ups load percent if possible */ 290 /* get the ups load percent if possible */
258 res=get_ups_variable ("ups.load", temp_buffer); 291 res = get_ups_variable("ups.load", temp_buffer, config);
259 if ( res == NOSUCHVAR ) supported_options &= ~UPS_LOADPCT; 292 if (res == NOSUCHVAR) {
260 else if ( res != OK) 293 supported_options &= ~UPS_LOADPCT;
294 } else if (res != OK) {
261 return STATE_CRITICAL; 295 return STATE_CRITICAL;
262 else { 296 } else {
263 supported_options |= UPS_LOADPCT; 297 supported_options |= UPS_LOADPCT;
264 ups_load_percent = atof (temp_buffer);
265 xasprintf (&message, "%sLoad=%3.1f%% ", message, ups_load_percent);
266 298
267 if (check_variable == UPS_LOADPCT) { 299 double ups_load_percent = 0.0;
268 if (check_crit && ups_load_percent>=critical_value) { 300 ups_load_percent = atof(temp_buffer);
301 xasprintf(&message, "%sLoad=%3.1f%% ", message, ups_load_percent);
302
303 if (config.check_variable == UPS_LOADPCT) {
304 if (config.check_crit &&
305 ups_load_percent >= config.critical_value) {
269 result = STATE_CRITICAL; 306 result = STATE_CRITICAL;
270 } 307 } else if (config.check_warn &&
271 else if (check_warn && ups_load_percent>=warning_value) { 308 ups_load_percent >= config.warning_value) {
272 result = max_state (result, STATE_WARNING); 309 result = max_state(result, STATE_WARNING);
273 } 310 }
274 xasprintf (&data, "%s %s", data, 311 xasprintf(&data, "%s %s", data,
275 perfdata ("load", (long)ups_load_percent, "%", 312 perfdata("load", (long)ups_load_percent, "%",
276 check_warn, (long)(warning_value), 313 config.check_warn, (long)(config.warning_value),
277 check_crit, (long)(critical_value), 314 config.check_crit, (long)(config.critical_value),
278 true, 0, true, 100)); 315 true, 0, true, 100));
279 } else { 316 } else {
280 xasprintf (&data, "%s %s", data, 317 xasprintf(&data, "%s %s", data,
281 perfdata ("load", (long)ups_load_percent, "%", 318 perfdata("load", (long)ups_load_percent, "%", false, 0,
282 false, 0, false, 0, true, 0, true, 100)); 319 false, 0, true, 0, true, 100));
283 } 320 }
284 } 321 }
285 322
286 /* get the ups temperature if possible */ 323 /* get the ups temperature if possible */
287 res=get_ups_variable ("ups.temperature", temp_buffer); 324 res = get_ups_variable("ups.temperature", temp_buffer, config);
288 if ( res == NOSUCHVAR ) supported_options &= ~UPS_TEMP; 325 if (res == NOSUCHVAR) {
289 else if ( res != OK) 326 supported_options &= ~UPS_TEMP;
327 } else if (res != OK) {
290 return STATE_CRITICAL; 328 return STATE_CRITICAL;
291 else { 329 } else {
292 supported_options |= UPS_TEMP; 330 supported_options |= UPS_TEMP;
293 if (temp_output_c) { 331
294 tunits="degC"; 332 double ups_temperature = 0.0;
295 ups_temperature = atof (temp_buffer); 333 char *tunits;
296 xasprintf (&message, "%sTemp=%3.1fC", message, ups_temperature); 334
297 } 335 if (config.temp_output_c) {
298 else { 336 tunits = "degC";
299 tunits="degF"; 337 ups_temperature = atof(temp_buffer);
300 ups_temperature = (atof (temp_buffer) * 1.8) + 32; 338 xasprintf(&message, "%sTemp=%3.1fC", message, ups_temperature);
301 xasprintf (&message, "%sTemp=%3.1fF", message, ups_temperature); 339 } else {
340 tunits = "degF";
341 ups_temperature = (atof(temp_buffer) * 1.8) + 32;
342 xasprintf(&message, "%sTemp=%3.1fF", message, ups_temperature);
302 } 343 }
303 344
304 if (check_variable == UPS_TEMP) { 345 if (config.check_variable == UPS_TEMP) {
305 if (check_crit && ups_temperature>=critical_value) { 346 if (config.check_crit && ups_temperature >= config.critical_value) {
306 result = STATE_CRITICAL; 347 result = STATE_CRITICAL;
307 } 348 } else if (config.check_warn &&
308 else if (check_warn && ups_temperature>=warning_value) { 349 ups_temperature >= config.warning_value) {
309 result = max_state (result, STATE_WARNING); 350 result = max_state(result, STATE_WARNING);
310 } 351 }
311 xasprintf (&data, "%s %s", data, 352 xasprintf(&data, "%s %s", data,
312 perfdata ("temp", (long)ups_temperature, tunits, 353 perfdata("temp", (long)ups_temperature, tunits,
313 check_warn, (long)(warning_value), 354 config.check_warn, (long)(config.warning_value),
314 check_crit, (long)(critical_value), 355 config.check_crit, (long)(config.critical_value),
315 true, 0, false, 0)); 356 true, 0, false, 0));
316 } else { 357 } else {
317 xasprintf (&data, "%s %s", data, 358 xasprintf(&data, "%s %s", data,
318 perfdata ("temp", (long)ups_temperature, tunits, 359 perfdata("temp", (long)ups_temperature, tunits, false, 0,
319 false, 0, false, 0, true, 0, false, 0)); 360 false, 0, true, 0, false, 0));
320 } 361 }
321 } 362 }
322 363
323 /* get the ups real power if possible */ 364 /* get the ups real power if possible */
324 res=get_ups_variable ("ups.realpower", temp_buffer); 365 res = get_ups_variable("ups.realpower", temp_buffer, config);
325 if ( res == NOSUCHVAR ) supported_options &= ~UPS_REALPOWER; 366 if (res == NOSUCHVAR) {
326 else if ( res != OK) 367 supported_options &= ~UPS_REALPOWER;
368 } else if (res != OK) {
327 return STATE_CRITICAL; 369 return STATE_CRITICAL;
328 else { 370 } else {
329 supported_options |= UPS_REALPOWER; 371 supported_options |= UPS_REALPOWER;
330 ups_realpower = atof (temp_buffer); 372 double ups_realpower = 0.0;
331 xasprintf (&message, "%sReal power=%3.1fW ", message, ups_realpower); 373 ups_realpower = atof(temp_buffer);
374 xasprintf(&message, "%sReal power=%3.1fW ", message, ups_realpower);
332 375
333 if (check_variable == UPS_REALPOWER) { 376 if (config.check_variable == UPS_REALPOWER) {
334 if (check_crit && ups_realpower>=critical_value) { 377 if (config.check_crit && ups_realpower >= config.critical_value) {
335 result = STATE_CRITICAL; 378 result = STATE_CRITICAL;
336 } 379 } else if (config.check_warn &&
337 else if (check_warn && ups_realpower>=warning_value) { 380 ups_realpower >= config.warning_value) {
338 result = max_state (result, STATE_WARNING); 381 result = max_state(result, STATE_WARNING);
339 } 382 }
340 xasprintf (&data, "%s %s", data, 383 xasprintf(&data, "%s %s", data,
341 perfdata ("realpower", (long)ups_realpower, "W", 384 perfdata("realpower", (long)ups_realpower, "W",
342 check_warn, (long)(warning_value), 385 config.check_warn, (long)(config.warning_value),
343 check_crit, (long)(critical_value), 386 config.check_crit, (long)(config.critical_value),
344 true, 0, false, 0)); 387 true, 0, false, 0));
345 } else { 388 } else {
346 xasprintf (&data, "%s %s", data, 389 xasprintf(&data, "%s %s", data,
347 perfdata ("realpower", (long)ups_realpower, "W", 390 perfdata("realpower", (long)ups_realpower, "W", false, 0,
348 false, 0, false, 0, true, 0, false, 0)); 391 false, 0, true, 0, false, 0));
349 } 392 }
350 } 393 }
351 394
352 /* if the UPS does not support any options we are looking for, report an error */ 395 /* if the UPS does not support any options we are looking for, report an
396 * error */
353 if (supported_options == UPS_NONE) { 397 if (supported_options == UPS_NONE) {
354 result = STATE_CRITICAL; 398 result = STATE_CRITICAL;
355 xasprintf (&message, _("UPS does not support any available options\n")); 399 xasprintf(&message, _("UPS does not support any available options\n"));
356 } 400 }
357 401
358 /* reset timeout */ 402 /* reset timeout */
359 alarm (0); 403 alarm(0);
360 404
361 printf ("UPS %s - %s|%s\n", state_text(result), message, data); 405 printf("UPS %s - %s|%s\n", state_text(result), message, data);
362 return result; 406 return result;
363} 407}
364 408
365
366
367/* determines what options are supported by the UPS */ 409/* determines what options are supported by the UPS */
368int 410int determine_status(ups_config *config, int *supported_options) {
369determine_status (void)
370{
371 char recv_buffer[MAX_INPUT_BUFFER]; 411 char recv_buffer[MAX_INPUT_BUFFER];
372 char temp_buffer[MAX_INPUT_BUFFER];
373 char *ptr;
374 int res;
375 412
376 res=get_ups_variable ("ups.status", recv_buffer); 413 int res = get_ups_variable("ups.status", recv_buffer, *config);
377 if (res == NOSUCHVAR) return OK; 414 if (res == NOSUCHVAR) {
415 return OK;
416 }
417
378 if (res != STATE_OK) { 418 if (res != STATE_OK) {
379 printf ("%s\n", _("Invalid response received from host")); 419 printf("%s\n", _("Invalid response received from host"));
380 return ERROR; 420 return ERROR;
381 } 421 }
382 422
383 supported_options |= UPS_STATUS; 423 *supported_options |= UPS_STATUS;
384 424
385 strcpy (temp_buffer, recv_buffer); 425 char temp_buffer[MAX_INPUT_BUFFER];
386 for (ptr = (char *) strtok (temp_buffer, " "); ptr != NULL; 426
387 ptr = (char *) strtok (NULL, " ")) { 427 strcpy(temp_buffer, recv_buffer);
388 if (!strcmp (ptr, "OFF")) 428 for (char *ptr = (char *)strtok(temp_buffer, " "); ptr != NULL;
389 status |= UPSSTATUS_OFF; 429 ptr = (char *)strtok(NULL, " ")) {
390 else if (!strcmp (ptr, "OL")) 430 if (!strcmp(ptr, "OFF")) {
391 status |= UPSSTATUS_OL; 431 config->status |= UPSSTATUS_OFF;
392 else if (!strcmp (ptr, "OB")) 432 } else if (!strcmp(ptr, "OL")) {
393 status |= UPSSTATUS_OB; 433 config->status |= UPSSTATUS_OL;
394 else if (!strcmp (ptr, "LB")) 434 } else if (!strcmp(ptr, "OB")) {
395 status |= UPSSTATUS_LB; 435 config->status |= UPSSTATUS_OB;
396 else if (!strcmp (ptr, "CAL")) 436 } else if (!strcmp(ptr, "LB")) {
397 status |= UPSSTATUS_CAL; 437 config->status |= UPSSTATUS_LB;
398 else if (!strcmp (ptr, "RB")) 438 } else if (!strcmp(ptr, "CAL")) {
399 status |= UPSSTATUS_RB; 439 config->status |= UPSSTATUS_CAL;
400 else if (!strcmp (ptr, "BYPASS")) 440 } else if (!strcmp(ptr, "RB")) {
401 status |= UPSSTATUS_BYPASS; 441 config->status |= UPSSTATUS_RB;
402 else if (!strcmp (ptr, "OVER")) 442 } else if (!strcmp(ptr, "BYPASS")) {
403 status |= UPSSTATUS_OVER; 443 config->status |= UPSSTATUS_BYPASS;
404 else if (!strcmp (ptr, "TRIM")) 444 } else if (!strcmp(ptr, "OVER")) {
405 status |= UPSSTATUS_TRIM; 445 config->status |= UPSSTATUS_OVER;
406 else if (!strcmp (ptr, "BOOST")) 446 } else if (!strcmp(ptr, "TRIM")) {
407 status |= UPSSTATUS_BOOST; 447 config->status |= UPSSTATUS_TRIM;
408 else if (!strcmp (ptr, "CHRG")) 448 } else if (!strcmp(ptr, "BOOST")) {
409 status |= UPSSTATUS_CHRG; 449 config->status |= UPSSTATUS_BOOST;
410 else if (!strcmp (ptr, "DISCHRG")) 450 } else if (!strcmp(ptr, "CHRG")) {
411 status |= UPSSTATUS_DISCHRG; 451 config->status |= UPSSTATUS_CHRG;
412 else 452 } else if (!strcmp(ptr, "DISCHRG")) {
413 status |= UPSSTATUS_UNKNOWN; 453 config->status |= UPSSTATUS_DISCHRG;
454 } else if (!strcmp(ptr, "ALARM")) {
455 config->status |= UPSSTATUS_ALARM;
456 } else {
457 config->status |= UPSSTATUS_UNKNOWN;
458 }
414 } 459 }
415 460
416 return OK; 461 return OK;
417} 462}
418 463
419
420/* gets a variable value for a specific UPS */ 464/* gets a variable value for a specific UPS */
421int 465int get_ups_variable(const char *varname, char *buf, const ups_config config) {
422get_ups_variable (const char *varname, char *buf)
423{
424 /* char command[MAX_INPUT_BUFFER]; */
425 char temp_buffer[MAX_INPUT_BUFFER];
426 char send_buffer[MAX_INPUT_BUFFER]; 466 char send_buffer[MAX_INPUT_BUFFER];
427 char *ptr;
428 char *logout = "OK Goodbye\n";
429 int logout_len = strlen(logout);
430 int len;
431
432 *buf=0;
433 467
434 /* create the command string to send to the UPS daemon */ 468 /* create the command string to send to the UPS daemon */
435 /* Add LOGOUT to avoid read failure logs */ 469 /* Add LOGOUT to avoid read failure logs */
436 int res = snprintf (send_buffer, sizeof(send_buffer), "GET VAR %s %s\nLOGOUT\n", ups_name, varname); 470 int res = snprintf(send_buffer, sizeof(send_buffer),
437 if ( (res > 0) && ((size_t)res >= sizeof(send_buffer))) { 471 "GET VAR %s %s\nLOGOUT\n", config.ups_name, varname);
472 if ((res > 0) && ((size_t)res >= sizeof(send_buffer))) {
438 printf("%s\n", _("UPS name to long for buffer")); 473 printf("%s\n", _("UPS name to long for buffer"));
439 return ERROR; 474 return ERROR;
440 } 475 }
441 476
477 char temp_buffer[MAX_INPUT_BUFFER];
478
442 /* send the command to the daemon and get a response back */ 479 /* send the command to the daemon and get a response back */
443 if (process_tcp_request 480 if (process_tcp_request(config.server_address, config.server_port,
444 (server_address, server_port, send_buffer, temp_buffer, 481 send_buffer, temp_buffer,
445 sizeof (temp_buffer)) != STATE_OK) { 482 sizeof(temp_buffer)) != STATE_OK) {
446 printf ("%s\n", _("Invalid response received from host")); 483 printf("%s\n", _("Invalid response received from host"));
447 return ERROR; 484 return ERROR;
448 } 485 }
449 486
450 ptr = temp_buffer; 487 char *ptr = temp_buffer;
451 len = strlen(ptr); 488 int len = strlen(ptr);
452 if (len > logout_len && strcmp (ptr + len - logout_len, logout) == 0) len -= logout_len; 489 const char *logout = "OK Goodbye\n";
453 if (len > 0 && ptr[len-1] == '\n') ptr[len-1]=0; 490 const int logout_len = strlen(logout);
454 if (strcmp (ptr, "ERR UNKNOWN-UPS") == 0) { 491
455 printf (_("CRITICAL - no such UPS '%s' on that host\n"), ups_name); 492 if (len > logout_len && strcmp(ptr + len - logout_len, logout) == 0) {
493 len -= logout_len;
494 }
495 if (len > 0 && ptr[len - 1] == '\n') {
496 ptr[len - 1] = 0;
497 }
498 if (strcmp(ptr, "ERR UNKNOWN-UPS") == 0) {
499 printf(_("CRITICAL - no such UPS '%s' on that host\n"),
500 config.ups_name);
456 return ERROR; 501 return ERROR;
457 } 502 }
458 503
459 if (strcmp (ptr, "ERR VAR-NOT-SUPPORTED") == 0) { 504 if (strcmp(ptr, "ERR VAR-NOT-SUPPORTED") == 0) {
460 /*printf ("Error: Variable '%s' is not supported\n", varname);*/ 505 /*printf ("Error: Variable '%s' is not supported\n", varname);*/
461 return NOSUCHVAR; 506 return NOSUCHVAR;
462 } 507 }
463 508
464 if (strcmp (ptr, "ERR DATA-STALE") == 0) { 509 if (strcmp(ptr, "ERR DATA-STALE") == 0) {
465 printf ("%s\n", _("CRITICAL - UPS data is stale")); 510 printf("%s\n", _("CRITICAL - UPS data is stale"));
466 return ERROR; 511 return ERROR;
467 } 512 }
468 513
469 if (strncmp (ptr, "ERR", 3) == 0) { 514 if (strncmp(ptr, "ERR", 3) == 0) {
470 printf (_("Unknown error: %s\n"), ptr); 515 printf(_("Unknown error: %s\n"), ptr);
471 return ERROR; 516 return ERROR;
472 } 517 }
473 518
474 ptr = temp_buffer + strlen (varname) + strlen (ups_name) + 6; 519 ptr = temp_buffer + strlen(varname) + strlen(config.ups_name) + 6;
475 len = strlen(ptr); 520 len = strlen(ptr);
476 if (len < 2 || ptr[0] != '"' || ptr[len-1] != '"') { 521 if (len < 2 || ptr[0] != '"' || ptr[len - 1] != '"') {
477 printf ("%s\n", _("Error: unable to parse variable")); 522 printf("%s\n", _("Error: unable to parse variable"));
478 return ERROR; 523 return ERROR;
479 } 524 }
480 strncpy (buf, ptr+1, len - 2); 525
526 *buf = 0;
527 strncpy(buf, ptr + 1, len - 2);
481 buf[len - 2] = 0; 528 buf[len - 2] = 0;
482 529
483 return OK; 530 return OK;
484} 531}
485 532
486
487/* Command line: CHECK_UPS -H <host_address> -u ups [-p port] [-v variable] 533/* Command line: CHECK_UPS -H <host_address> -u ups [-p port] [-v variable]
488 [-wv warn_value] [-cv crit_value] [-to to_sec] */ 534 [-wv warn_value] [-cv crit_value] [-to to_sec] */
489 535
490
491/* process command-line arguments */ 536/* process command-line arguments */
492int 537int process_arguments(int argc, char **argv, ups_config *config) {
493process_arguments (int argc, char **argv) 538
494{ 539 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
495 int c; 540 {"ups", required_argument, 0, 'u'},
496 541 {"port", required_argument, 0, 'p'},
497 int option = 0; 542 {"critical", required_argument, 0, 'c'},
498 static struct option longopts[] = { 543 {"warning", required_argument, 0, 'w'},
499 {"hostname", required_argument, 0, 'H'}, 544 {"timeout", required_argument, 0, 't'},
500 {"ups", required_argument, 0, 'u'}, 545 {"temperature", no_argument, 0, 'T'},
501 {"port", required_argument, 0, 'p'}, 546 {"variable", required_argument, 0, 'v'},
502 {"critical", required_argument, 0, 'c'}, 547 {"version", no_argument, 0, 'V'},
503 {"warning", required_argument, 0, 'w'}, 548 {"help", no_argument, 0, 'h'},
504 {"timeout", required_argument, 0, 't'}, 549 {0, 0, 0, 0}};
505 {"temperature", no_argument, 0, 'T'}, 550
506 {"variable", required_argument, 0, 'v'}, 551 if (argc < 2) {
507 {"version", no_argument, 0, 'V'},
508 {"help", no_argument, 0, 'h'},
509 {0, 0, 0, 0}
510 };
511
512 if (argc < 2)
513 return ERROR; 552 return ERROR;
553 }
514 554
555 int c;
515 for (c = 1; c < argc; c++) { 556 for (c = 1; c < argc; c++) {
516 if (strcmp ("-to", argv[c]) == 0) 557 if (strcmp("-to", argv[c]) == 0) {
517 strcpy (argv[c], "-t"); 558 strcpy(argv[c], "-t");
518 else if (strcmp ("-wt", argv[c]) == 0) 559 } else if (strcmp("-wt", argv[c]) == 0) {
519 strcpy (argv[c], "-w"); 560 strcpy(argv[c], "-w");
520 else if (strcmp ("-ct", argv[c]) == 0) 561 } else if (strcmp("-ct", argv[c]) == 0) {
521 strcpy (argv[c], "-c"); 562 strcpy(argv[c], "-c");
563 }
522 } 564 }
523 565
566 int option = 0;
524 while (1) { 567 while (1) {
525 c = getopt_long (argc, argv, "hVTH:u:p:v:c:w:t:", longopts, 568 c = getopt_long(argc, argv, "hVTH:u:p:v:c:w:t:", longopts, &option);
526 &option);
527 569
528 if (c == -1 || c == EOF) 570 if (c == -1 || c == EOF) {
529 break; 571 break;
572 }
530 573
531 switch (c) { 574 switch (c) {
532 case '?': /* help */ 575 case '?': /* help */
533 usage5 (); 576 usage5();
534 case 'H': /* hostname */ 577 case 'H': /* hostname */
535 if (is_host (optarg)) { 578 if (is_host(optarg)) {
536 server_address = optarg; 579 config->server_address = optarg;
537 } 580 } else {
538 else { 581 usage2(_("Invalid hostname/address"), optarg);
539 usage2 (_("Invalid hostname/address"), optarg);
540 } 582 }
541 break; 583 break;
542 case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for Fahrenheit) */ 584 case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for
543 temp_output_c = true; 585 Fahrenheit) */
586 config->temp_output_c = true;
544 break; 587 break;
545 case 'u': /* ups name */ 588 case 'u': /* ups name */
546 ups_name = optarg; 589 config->ups_name = optarg;
547 break; 590 break;
548 case 'p': /* port */ 591 case 'p': /* port */
549 if (is_intpos (optarg)) { 592 if (is_intpos(optarg)) {
550 server_port = atoi (optarg); 593 config->server_port = atoi(optarg);
551 } 594 } else {
552 else { 595 usage2(_("Port must be a positive integer"), optarg);
553 usage2 (_("Port must be a positive integer"), optarg);
554 } 596 }
555 break; 597 break;
556 case 'c': /* critical time threshold */ 598 case 'c': /* critical time threshold */
557 if (is_intnonneg (optarg)) { 599 if (is_intnonneg(optarg)) {
558 critical_value = atoi (optarg); 600 config->critical_value = atoi(optarg);
559 check_crit = true; 601 config->check_crit = true;
560 } 602 } else {
561 else { 603 usage2(_("Critical time must be a positive integer"), optarg);
562 usage2 (_("Critical time must be a positive integer"), optarg);
563 } 604 }
564 break; 605 break;
565 case 'w': /* warning time threshold */ 606 case 'w': /* warning time threshold */
566 if (is_intnonneg (optarg)) { 607 if (is_intnonneg(optarg)) {
567 warning_value = atoi (optarg); 608 config->warning_value = atoi(optarg);
568 check_warn = true; 609 config->check_warn = true;
569 } 610 } else {
570 else { 611 usage2(_("Warning time must be a positive integer"), optarg);
571 usage2 (_("Warning time must be a positive integer"), optarg);
572 } 612 }
573 break; 613 break;
574 case 'v': /* variable */ 614 case 'v': /* variable */
575 if (!strcmp (optarg, "LINE")) 615 if (!strcmp(optarg, "LINE")) {
576 check_variable = UPS_UTILITY; 616 config->check_variable = UPS_UTILITY;
577 else if (!strcmp (optarg, "TEMP")) 617 } else if (!strcmp(optarg, "TEMP")) {
578 check_variable = UPS_TEMP; 618 config->check_variable = UPS_TEMP;
579 else if (!strcmp (optarg, "BATTPCT")) 619 } else if (!strcmp(optarg, "BATTPCT")) {
580 check_variable = UPS_BATTPCT; 620 config->check_variable = UPS_BATTPCT;
581 else if (!strcmp (optarg, "LOADPCT")) 621 } else if (!strcmp(optarg, "LOADPCT")) {
582 check_variable = UPS_LOADPCT; 622 config->check_variable = UPS_LOADPCT;
583 else if (!strcmp (optarg, "REALPOWER")) 623 } else if (!strcmp(optarg, "REALPOWER")) {
584 check_variable = UPS_REALPOWER; 624 config->check_variable = UPS_REALPOWER;
585 else 625 } else {
586 usage2 (_("Unrecognized UPS variable"), optarg); 626 usage2(_("Unrecognized UPS variable"), optarg);
587 break;
588 case 't': /* timeout */
589 if (is_intnonneg (optarg)) {
590 socket_timeout = atoi (optarg);
591 } 627 }
592 else { 628 break;
593 usage4 (_("Timeout interval must be a positive integer")); 629 case 't': /* timeout */
630 if (is_intnonneg(optarg)) {
631 socket_timeout = atoi(optarg);
632 } else {
633 usage4(_("Timeout interval must be a positive integer"));
594 } 634 }
595 break; 635 break;
596 case 'V': /* version */ 636 case 'V': /* version */
597 print_revision (progname, NP_VERSION); 637 print_revision(progname, NP_VERSION);
598 exit (STATE_UNKNOWN); 638 exit(STATE_UNKNOWN);
599 case 'h': /* help */ 639 case 'h': /* help */
600 print_help (); 640 print_help();
601 exit (STATE_UNKNOWN); 641 exit(STATE_UNKNOWN);
602 } 642 }
603 } 643 }
604 644
605 645 if (config->server_address == NULL && argc > optind) {
606 if (server_address == NULL && argc > optind) { 646 if (is_host(argv[optind])) {
607 if (is_host (argv[optind])) 647 config->server_address = argv[optind++];
608 server_address = argv[optind++]; 648 } else {
609 else 649 usage2(_("Invalid hostname/address"), optarg);
610 usage2 (_("Invalid hostname/address"), optarg); 650 }
611 } 651 }
612 652
613 if (server_address == NULL) 653 if (config->server_address == NULL) {
614 server_address = strdup("127.0.0.1"); 654 config->server_address = strdup("127.0.0.1");
655 }
615 656
616 return validate_arguments(); 657 return validate_arguments(*config);
617} 658}
618 659
619 660int validate_arguments(ups_config config) {
620int 661 if (!config.ups_name) {
621validate_arguments (void) 662 printf("%s\n", _("Error : no UPS indicated"));
622{
623 if (! ups_name) {
624 printf ("%s\n", _("Error : no UPS indicated"));
625 return ERROR; 663 return ERROR;
626 } 664 }
627 return OK; 665 return OK;
628} 666}
629 667
668void print_help(void) {
669 print_revision(progname, NP_VERSION);
630 670
631void 671 printf("Copyright (c) 2000 Tom Shields\n");
632print_help (void) 672 printf("Copyright (c) 2004 Alain Richard <alain.richard@equation.fr>\n");
633{ 673 printf("Copyright (c) 2004 Arnaud Quette <arnaud.quette@mgeups.com>\n");
634 char *myport; 674 printf(COPYRIGHT, copyright, email);
635 xasprintf (&myport, "%d", PORT);
636
637 print_revision (progname, NP_VERSION);
638
639 printf ("Copyright (c) 2000 Tom Shields\n");
640 printf ("Copyright (c) 2004 Alain Richard <alain.richard@equation.fr>\n");
641 printf ("Copyright (c) 2004 Arnaud Quette <arnaud.quette@mgeups.com>\n");
642 printf (COPYRIGHT, copyright, email);
643
644 printf ("%s\n", _("This plugin tests the UPS service on the specified host. Network UPS Tools"));
645 printf ("%s\n", _("from www.networkupstools.org must be running for this plugin to work."));
646
647 printf ("\n\n");
648
649 print_usage ();
650 675
651 printf (UT_HELP_VRSN); 676 printf("%s\n", _("This plugin tests the UPS service on the specified host. "
652 printf (UT_EXTRA_OPTS); 677 "Network UPS Tools"));
678 printf("%s\n", _("from www.networkupstools.org must be running for this "
679 "plugin to work."));
653 680
654 printf (UT_HOST_PORT, 'p', myport); 681 printf("\n\n");
655 682
656 printf (" %s\n", "-u, --ups=STRING"); 683 print_usage();
657 printf (" %s\n", _("Name of UPS"));
658 printf (" %s\n", "-T, --temperature");
659 printf (" %s\n", _("Output of temperatures in Celsius"));
660 printf (" %s\n", "-v, --variable=STRING");
661 printf (" %s %s\n", _("Valid values for STRING are"), "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER");
662 684
663 printf (UT_WARN_CRIT); 685 printf(UT_HELP_VRSN);
686 printf(UT_EXTRA_OPTS);
664 687
665 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 688 char *myport;
666 689 xasprintf(&myport, "%d", PORT);
667/* TODO: -v clashing with -v/-variable. Commenting out help text since verbose 690 printf(UT_HOST_PORT, 'p', myport);
668 is unused up to now */ 691
669/* printf (UT_VERBOSE); */ 692 printf(" %s\n", "-u, --ups=STRING");
670 693 printf(" %s\n", _("Name of UPS"));
671 printf ("\n"); 694 printf(" %s\n", "-T, --temperature");
672 printf ("%s\n", _("This plugin attempts to determine the status of a UPS (Uninterruptible Power")); 695 printf(" %s\n", _("Output of temperatures in Celsius"));
673 printf ("%s\n", _("Supply) on a local or remote host. If the UPS is online or calibrating, the")); 696 printf(" %s\n", "-v, --variable=STRING");
674 printf ("%s\n", _("plugin will return an OK state. If the battery is on it will return a WARNING")); 697 printf(" %s %s\n", _("Valid values for STRING are"),
675 printf ("%s\n", _("state. If the UPS is off or has a low battery the plugin will return a CRITICAL")); 698 "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER");
676 printf ("%s\n", _("state.")); 699
677 700 printf(UT_WARN_CRIT);
678 printf ("\n"); 701
679 printf ("%s\n", _("Notes:")); 702 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
680 printf (" %s\n", _("You may also specify a variable to check (such as temperature, utility voltage,")); 703
681 printf (" %s\n", _("battery load, etc.) as well as warning and critical thresholds for the value")); 704 /* TODO: -v clashing with -v/-variable. Commenting out help text since
682 printf (" %s\n", _("of that variable. If the remote host has multiple UPS that are being monitored")); 705 verbose is unused up to now */
683 printf (" %s\n", _("you will have to use the --ups option to specify which UPS to check.")); 706 /* printf (UT_VERBOSE); */
684 printf ("\n"); 707
685 printf (" %s\n", _("This plugin requires that the UPSD daemon distributed with Russell Kroll's")); 708 printf("\n");
686 printf (" %s\n", _("Network UPS Tools be installed on the remote host. If you do not have the")); 709 printf("%s\n", _("This plugin attempts to determine the status of a UPS "
687 printf (" %s\n", _("package installed on your system, you can download it from")); 710 "(Uninterruptible Power"));
688 printf (" %s\n", _("http://www.networkupstools.org")); 711 printf("%s\n", _("Supply) on a local or remote host. If the UPS is online "
689 712 "or calibrating, the"));
690 printf (UT_SUPPORT); 713 printf("%s\n", _("plugin will return an OK state. If the battery is on it "
714 "will return a WARNING"));
715 printf("%s\n", _("state. If the UPS is off or has a low battery the plugin "
716 "will return a CRITICAL"));
717 printf("%s\n", _("state."));
718
719 printf("\n");
720 printf("%s\n", _("Notes:"));
721 printf(" %s\n", _("You may also specify a variable to check (such as "
722 "temperature, utility voltage,"));
723 printf(" %s\n", _("battery load, etc.) as well as warning and critical "
724 "thresholds for the value"));
725 printf(" %s\n", _("of that variable. If the remote host has multiple UPS "
726 "that are being monitored"));
727 printf(" %s\n", _("you will have to use the --ups option to specify which "
728 "UPS to check."));
729 printf("\n");
730 printf(" %s\n", _("This plugin requires that the UPSD daemon distributed "
731 "with Russell Kroll's"));
732 printf(" %s\n", _("Network UPS Tools be installed on the remote host. If "
733 "you do not have the"));
734 printf(" %s\n",
735 _("package installed on your system, you can download it from"));
736 printf(" %s\n", _("http://www.networkupstools.org"));
737
738 printf(UT_SUPPORT);
691} 739}
692 740
693 741void print_usage(void) {
694void 742 printf("%s\n", _("Usage:"));
695print_usage (void) 743 printf("%s -H host -u ups [-p port] [-v variable] [-w warn_value] [-c "
696{ 744 "crit_value] [-to to_sec] [-T]\n",
697 printf ("%s\n", _("Usage:")); 745 progname);
698 printf ("%s -H host -u ups [-p port] [-v variable] [-w warn_value] [-c crit_value] [-to to_sec] [-T]\n", progname);
699} 746}
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t
index eae98cc1..7a930a4e 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 1f2fbdfd..6ab4a5b6 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 3c914830..eaa9f518 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -21,7 +21,7 @@ use FindBin qw($Bin);
21 21
22$ENV{'LC_TIME'} = "C"; 22$ENV{'LC_TIME'} = "C";
23 23
24my $common_tests = 73; 24my $common_tests = 75;
25my $ssl_only_tests = 8; 25my $ssl_only_tests = 8;
26# Check that all dependent modules are available 26# Check that all dependent modules are available
27eval "use HTTP::Daemon 6.01;"; 27eval "use HTTP::Daemon 6.01;";
@@ -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 6078b274..6eaf85b2 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
16my $common_tests = 71; 16my $common_tests = 73;
17my $virtual_port_tests = 8; 17my $virtual_port_tests = 8;
18my $ssl_only_tests = 12; 18my $ssl_only_tests = 12;
19my $chunked_encoding_special_tests = 1; 19my $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