summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/monitoring-plugins.spec14
-rw-r--r--.gitignore1
-rw-r--r--plugins/Makefile.am8
-rw-r--r--plugins/check_mrtgtraf.c18
-rw-r--r--plugins/check_mrtgtraf.d/config.h (renamed from plugins/check_mrtgraf.d/config.h)6
-rw-r--r--plugins/check_nt.c527
-rw-r--r--plugins/check_nt.d/config.h53
-rw-r--r--plugins/check_ntp_time.c210
-rw-r--r--plugins/check_ntp_time.d/config.h28
-rw-r--r--plugins/check_overcr.c417
-rw-r--r--plugins/check_pgsql.c216
-rw-r--r--plugins/check_pgsql.d/config.h61
12 files changed, 649 insertions, 910 deletions
diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec
index 5cae3e59..64ee34f2 100644
--- a/.github/monitoring-plugins.spec
+++ b/.github/monitoring-plugins.spec
@@ -193,7 +193,6 @@ Requires: %{name}-ntp_peer
193Requires: %{name}-ntp_time 193Requires: %{name}-ntp_time
194Requires: %{name}-nwstat 194Requires: %{name}-nwstat
195Requires: %{name}-oracle 195Requires: %{name}-oracle
196Requires: %{name}-overcr
197Requires: %{name}-pgsql 196Requires: %{name}-pgsql
198Requires: %{name}-ping 197Requires: %{name}-ping
199Requires: %{name}-procs 198Requires: %{name}-procs
@@ -729,19 +728,6 @@ Provides check_oracle of the Monitoring Plugins.
729 728
730 729
731 730
732# check_overcr
733%package overcr
734Summary: Monitoring Plugins - check_overcr
735Requires: %{name} = %{version}-%{release}
736
737%description overcr
738Provides check_overcr of the Monitoring Plugins.
739
740%files overcr
741%{plugindir}/check_overcr
742
743
744
745# check_pgsql 731# check_pgsql
746%package pgsql 732%package pgsql
747Summary: Monitoring Plugins - check_pgsql 733Summary: Monitoring Plugins - check_pgsql
diff --git a/.gitignore b/.gitignore
index 0efc2b66..f9cb37e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -178,7 +178,6 @@ NP-VERSION-FILE
178/plugins/check_ntp_peer 178/plugins/check_ntp_peer
179/plugins/check_ntp_time 179/plugins/check_ntp_time
180/plugins/check_nwstat 180/plugins/check_nwstat
181/plugins/check_overcr
182/plugins/check_pgsql 181/plugins/check_pgsql
183/plugins/check_ping 182/plugins/check_ping
184/plugins/check_pop 183/plugins/check_pop
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index d27c9efd..6c582a15 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -27,7 +27,7 @@ MATHLIBS = @MATHLIBS@
27#AM_CFLAGS = -Wall 27#AM_CFLAGS = -Wall
28 28
29libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \ 29libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \
30 check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_overcr check_ping \ 30 check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_ping \
31 check_real check_smtp check_ssh check_tcp check_time check_ntp_time \ 31 check_real check_smtp check_ssh check_tcp check_time check_ntp_time \
32 check_ups check_users negate \ 32 check_ups check_users negate \
33 urlize @EXTRAS@ 33 urlize @EXTRAS@
@@ -56,14 +56,17 @@ EXTRA_DIST = t \
56 check_nagios.d \ 56 check_nagios.d \
57 check_dbi.d \ 57 check_dbi.d \
58 check_ssh.d \ 58 check_ssh.d \
59 check_nt.d \
59 check_dns.d \ 60 check_dns.d \
60 check_mrtgraf.d \ 61 check_mrtgtraf.d \
61 check_mysql_query.d \ 62 check_mysql_query.d \
62 check_mrtg.d \ 63 check_mrtg.d \
63 check_apt.d \ 64 check_apt.d \
65 check_pgsql.d \
64 check_by_ssh.d \ 66 check_by_ssh.d \
65 check_smtp.d \ 67 check_smtp.d \
66 check_mysql.d \ 68 check_mysql.d \
69 check_ntp_time.d \
67 check_dig.d \ 70 check_dig.d \
68 check_cluster.d \ 71 check_cluster.d \
69 check_fping.d 72 check_fping.d
@@ -129,7 +132,6 @@ check_nt_LDADD = $(NETLIBS)
129check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) 132check_ntp_LDADD = $(NETLIBS) $(MATHLIBS)
130check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) 133check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS)
131check_nwstat_LDADD = $(NETLIBS) 134check_nwstat_LDADD = $(NETLIBS)
132check_overcr_LDADD = $(NETLIBS)
133check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) 135check_pgsql_LDADD = $(NETLIBS) $(PGLIBS)
134check_ping_LDADD = $(NETLIBS) 136check_ping_LDADD = $(NETLIBS)
135check_procs_LDADD = $(BASEOBJS) 137check_procs_LDADD = $(BASEOBJS)
diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c
index c9e26099..8c7cf8aa 100644
--- a/plugins/check_mrtgtraf.c
+++ b/plugins/check_mrtgtraf.c
@@ -33,16 +33,16 @@ const char *progname = "check_mrtgtraf";
33const char *copyright = "1999-2024"; 33const char *copyright = "1999-2024";
34const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
35 35
36#include "check_mrtgraf.d/config.h" 36#include "check_mrtgtraf.d/config.h"
37#include "common.h" 37#include "common.h"
38#include "utils.h" 38#include "utils.h"
39 39
40typedef struct { 40typedef struct {
41 int errorcode; 41 int errorcode;
42 check_mrtgraf_config config; 42 check_mrtgtraf_config config;
43} check_mrtgraf_config_wrapper; 43} check_mrtgtraf_config_wrapper;
44 44
45static check_mrtgraf_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); 45static check_mrtgtraf_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
46static void print_help(void); 46static void print_help(void);
47void print_usage(void); 47void print_usage(void);
48 48
@@ -54,12 +54,12 @@ int main(int argc, char **argv) {
54 /* Parse extra opts if any */ 54 /* Parse extra opts if any */
55 argv = np_extra_opts(&argc, argv, progname); 55 argv = np_extra_opts(&argc, argv, progname);
56 56
57 check_mrtgraf_config_wrapper tmp_config = process_arguments(argc, argv); 57 check_mrtgtraf_config_wrapper tmp_config = process_arguments(argc, argv);
58 if (tmp_config.errorcode == ERROR) { 58 if (tmp_config.errorcode == ERROR) {
59 usage4(_("Could not parse arguments")); 59 usage4(_("Could not parse arguments"));
60 } 60 }
61 61
62 const check_mrtgraf_config config = tmp_config.config; 62 const check_mrtgtraf_config config = tmp_config.config;
63 63
64 /* open the MRTG log file for reading */ 64 /* open the MRTG log file for reading */
65 FILE *mrtg_log_file_ptr = fopen(config.log_file, "r"); 65 FILE *mrtg_log_file_ptr = fopen(config.log_file, "r");
@@ -200,7 +200,7 @@ int main(int argc, char **argv) {
200} 200}
201 201
202/* process command-line arguments */ 202/* process command-line arguments */
203check_mrtgraf_config_wrapper process_arguments(int argc, char **argv) { 203check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) {
204 static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, 204 static struct option longopts[] = {{"filename", required_argument, 0, 'F'},
205 {"expires", required_argument, 0, 'e'}, 205 {"expires", required_argument, 0, 'e'},
206 {"aggregation", required_argument, 0, 'a'}, 206 {"aggregation", required_argument, 0, 'a'},
@@ -210,9 +210,9 @@ check_mrtgraf_config_wrapper process_arguments(int argc, char **argv) {
210 {"help", no_argument, 0, 'h'}, 210 {"help", no_argument, 0, 'h'},
211 {0, 0, 0, 0}}; 211 {0, 0, 0, 0}};
212 212
213 check_mrtgraf_config_wrapper result = { 213 check_mrtgtraf_config_wrapper result = {
214 .errorcode = OK, 214 .errorcode = OK,
215 .config = check_mrtgraf_config_init(), 215 .config = check_mrtgtraf_config_init(),
216 }; 216 };
217 if (argc < 2) { 217 if (argc < 2) {
218 result.errorcode = ERROR; 218 result.errorcode = ERROR;
diff --git a/plugins/check_mrtgraf.d/config.h b/plugins/check_mrtgtraf.d/config.h
index 6d949b50..94929ff7 100644
--- a/plugins/check_mrtgraf.d/config.h
+++ b/plugins/check_mrtgtraf.d/config.h
@@ -13,10 +13,10 @@ typedef struct {
13 unsigned long outgoing_warning_threshold; 13 unsigned long outgoing_warning_threshold;
14 unsigned long outgoing_critical_threshold; 14 unsigned long outgoing_critical_threshold;
15 15
16} check_mrtgraf_config; 16} check_mrtgtraf_config;
17 17
18check_mrtgraf_config check_mrtgraf_config_init() { 18check_mrtgtraf_config check_mrtgtraf_config_init() {
19 check_mrtgraf_config tmp = { 19 check_mrtgtraf_config tmp = {
20 .log_file = NULL, 20 .log_file = NULL,
21 .expire_minutes = -1, 21 .expire_minutes = -1,
22 .use_average = true, 22 .use_average = true,
diff --git a/plugins/check_nt.c b/plugins/check_nt.c
index dec0b668..7dd23e5c 100644
--- a/plugins/check_nt.c
+++ b/plugins/check_nt.c
@@ -13,7 +13,7 @@
13 * This plugin collects data from the NSClient service running on a 13 * This plugin collects data from the NSClient service running on a
14 * Windows NT/2000/XP/2003 server. 14 * Windows NT/2000/XP/2003 server.
15 * This plugin requires NSClient software to run on NT 15 * This plugin requires NSClient software to run on NT
16 * (http://nsclient.ready2run.nl/) 16 * (https://nsclient.org/)
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
@@ -39,82 +39,28 @@ const char *email = "devel@monitoring-plugins.org";
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#include "check_nt.d/config.h"
43enum checkvars {
44 CHECK_NONE,
45 CHECK_CLIENTVERSION,
46 CHECK_CPULOAD,
47 CHECK_UPTIME,
48 CHECK_USEDDISKSPACE,
49 CHECK_SERVICESTATE,
50 CHECK_PROCSTATE,
51 CHECK_MEMUSE,
52 CHECK_COUNTER,
53 CHECK_FILEAGE,
54 CHECK_INSTANCES
55};
56 43
57enum { 44enum {
58 MAX_VALUE_LIST = 30, 45 MAX_VALUE_LIST = 30,
59 PORT = 1248
60}; 46};
61 47
62static char *server_address = NULL;
63static int server_port = PORT;
64static char *value_list = NULL;
65static char *req_password = NULL;
66static unsigned long lvalue_list[MAX_VALUE_LIST];
67static unsigned long warning_value = 0L;
68static unsigned long critical_value = 0L;
69static bool check_warning_value = false;
70static bool check_critical_value = false;
71static enum checkvars vars_to_check = CHECK_NONE;
72static bool show_all = false;
73
74static char recv_buffer[MAX_INPUT_BUFFER]; 48static char recv_buffer[MAX_INPUT_BUFFER];
75 49
76static void fetch_data(const char *address, int port, const char *sendb); 50static void fetch_data(const char *address, int port, const char *sendb);
77static int process_arguments(int /*argc*/, char ** /*argv*/); 51
52typedef struct {
53 int errorcode;
54 check_nt_config config;
55} check_nt_config_wrapper;
56static check_nt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
57
78static void preparelist(char *string); 58static void preparelist(char *string);
79static bool strtoularray(unsigned long *array, char *string, const char *delim); 59static bool strtoularray(unsigned long *array, char *string, const char *delim);
80static void print_help(void); 60static void print_help(void);
81void print_usage(void); 61void print_usage(void);
82 62
83int main(int argc, char **argv) { 63int main(int argc, char **argv) {
84
85 /* should be int result = STATE_UNKNOWN; */
86
87 int return_code = STATE_UNKNOWN;
88 char *send_buffer = NULL;
89 char *output_message = NULL;
90 char *perfdata = NULL;
91 char *temp_string = NULL;
92 char *temp_string_perf = NULL;
93 char *description = NULL, *counter_unit = NULL;
94 char *minval = NULL, *maxval = NULL, *errcvt = NULL;
95 char *fds = NULL, *tds = NULL;
96 char *numstr;
97
98 double total_disk_space = 0;
99 double free_disk_space = 0;
100 double percent_used_space = 0;
101 double warning_used_space = 0;
102 double critical_used_space = 0;
103 double mem_commitLimit = 0;
104 double mem_commitByte = 0;
105 double fminval = 0, fmaxval = 0;
106 unsigned long utilization;
107 unsigned long uptime;
108 unsigned long age_in_minutes;
109 double counter_value = 0.0;
110 int offset = 0;
111 int updays = 0;
112 int uphours = 0;
113 int upminutes = 0;
114
115 bool isPercent = false;
116 bool allRight = false;
117
118 setlocale(LC_ALL, ""); 64 setlocale(LC_ALL, "");
119 bindtextdomain(PACKAGE, LOCALEDIR); 65 bindtextdomain(PACKAGE, LOCALEDIR);
120 textdomain(PACKAGE); 66 textdomain(PACKAGE);
@@ -122,8 +68,12 @@ int main(int argc, char **argv) {
122 /* Parse extra opts if any */ 68 /* Parse extra opts if any */
123 argv = np_extra_opts(&argc, argv, progname); 69 argv = np_extra_opts(&argc, argv, progname);
124 70
125 if (process_arguments(argc, argv) == ERROR) 71 check_nt_config_wrapper tmp_config = process_arguments(argc, argv);
72 if (tmp_config.errorcode == ERROR) {
126 usage4(_("Could not parse arguments")); 73 usage4(_("Could not parse arguments"));
74 }
75
76 const check_nt_config config = tmp_config.config;
127 77
128 /* initialize alarm signal handling */ 78 /* initialize alarm signal handling */
129 signal(SIGALRM, socket_timeout_alarm_handler); 79 signal(SIGALRM, socket_timeout_alarm_handler);
@@ -131,49 +81,57 @@ int main(int argc, char **argv) {
131 /* set socket timeout */ 81 /* set socket timeout */
132 alarm(socket_timeout); 82 alarm(socket_timeout);
133 83
134 switch (vars_to_check) { 84 int return_code = STATE_UNKNOWN;
135 85 char *send_buffer = NULL;
86 char *output_message = NULL;
87 char *perfdata = NULL;
88 char *temp_string = NULL;
89 char *temp_string_perf = NULL;
90 char *description = NULL;
91 char *counter_unit = NULL;
92 char *errcvt = NULL;
93 unsigned long lvalue_list[MAX_VALUE_LIST];
94 switch (config.vars_to_check) {
136 case CHECK_CLIENTVERSION: 95 case CHECK_CLIENTVERSION:
137 96 xasprintf(&send_buffer, "%s&1", config.req_password);
138 xasprintf(&send_buffer, "%s&1", req_password); 97 fetch_data(config.server_address, config.server_port, send_buffer);
139 fetch_data(server_address, server_port, send_buffer); 98 if (config.value_list != NULL && strcmp(recv_buffer, config.value_list) != 0) {
140 if (value_list != NULL && strcmp(recv_buffer, value_list) != 0) { 99 xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, config.value_list);
141 xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, value_list);
142 return_code = STATE_WARNING; 100 return_code = STATE_WARNING;
143 } else { 101 } else {
144 xasprintf(&output_message, "%s", recv_buffer); 102 xasprintf(&output_message, "%s", recv_buffer);
145 return_code = STATE_OK; 103 return_code = STATE_OK;
146 } 104 }
147 break; 105 break;
148
149 case CHECK_CPULOAD: 106 case CHECK_CPULOAD:
150 107 if (config.value_list == NULL) {
151 if (value_list == NULL)
152 output_message = strdup(_("missing -l parameters")); 108 output_message = strdup(_("missing -l parameters"));
153 else if (!strtoularray(lvalue_list, value_list, ",")) 109 } else if (!strtoularray(lvalue_list, config.value_list, ",")) {
154 output_message = strdup(_("wrong -l parameter.")); 110 output_message = strdup(_("wrong -l parameter."));
155 else { 111 } else {
156 /* -l parameters is present with only integers */ 112 /* -l parameters is present with only integers */
157 return_code = STATE_OK; 113 return_code = STATE_OK;
158 temp_string = strdup(_("CPU Load")); 114 temp_string = strdup(_("CPU Load"));
159 temp_string_perf = strdup(" "); 115 temp_string_perf = strdup(" ");
160 116
161 /* loop until one of the parameters is wrong or not present */ 117 /* loop until one of the parameters is wrong or not present */
118 int offset = 0;
162 while (lvalue_list[0 + offset] > (unsigned long)0 && lvalue_list[0 + offset] <= (unsigned long)17280 && 119 while (lvalue_list[0 + offset] > (unsigned long)0 && lvalue_list[0 + offset] <= (unsigned long)17280 &&
163 lvalue_list[1 + offset] > (unsigned long)0 && lvalue_list[1 + offset] <= (unsigned long)100 && 120 lvalue_list[1 + offset] > (unsigned long)0 && lvalue_list[1 + offset] <= (unsigned long)100 &&
164 lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) { 121 lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) {
165 122
166 /* Send request and retrieve data */ 123 /* Send request and retrieve data */
167 xasprintf(&send_buffer, "%s&2&%lu", req_password, lvalue_list[0 + offset]); 124 xasprintf(&send_buffer, "%s&2&%lu", config.req_password, lvalue_list[0 + offset]);
168 fetch_data(server_address, server_port, send_buffer); 125 fetch_data(config.server_address, config.server_port, send_buffer);
169 126
170 utilization = strtoul(recv_buffer, NULL, 10); 127 unsigned long utilization = strtoul(recv_buffer, NULL, 10);
171 128
172 /* Check if any of the request is in a warning or critical state */ 129 /* Check if any of the request is in a warning or critical state */
173 if (utilization >= lvalue_list[2 + offset]) 130 if (utilization >= lvalue_list[2 + offset]) {
174 return_code = STATE_CRITICAL; 131 return_code = STATE_CRITICAL;
175 else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) 132 } else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) {
176 return_code = STATE_WARNING; 133 return_code = STATE_WARNING;
134 }
177 135
178 xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]); 136 xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]);
179 xasprintf(&temp_string, "%s%s", temp_string, output_message); 137 xasprintf(&temp_string, "%s%s", temp_string, output_message);
@@ -186,82 +144,87 @@ int main(int argc, char **argv) {
186 if (strlen(temp_string) > 10) { /* we had at least one loop */ 144 if (strlen(temp_string) > 10) { /* we had at least one loop */
187 output_message = strdup(temp_string); 145 output_message = strdup(temp_string);
188 perfdata = temp_string_perf; 146 perfdata = temp_string_perf;
189 } else 147 } else {
190 output_message = strdup(_("not enough values for -l parameters")); 148 output_message = strdup(_("not enough values for -l parameters"));
149 }
191 } 150 }
192 break; 151 break;
193 152 case CHECK_UPTIME: {
194 case CHECK_UPTIME: 153 char *tmp_value_list = config.value_list;
195 154 if (config.value_list == NULL) {
196 if (value_list == NULL) { 155 tmp_value_list = "minutes";
197 value_list = "minutes";
198 } 156 }
199 if (strncmp(value_list, "seconds", strlen("seconds") + 1) && strncmp(value_list, "minutes", strlen("minutes") + 1) && 157 if (strncmp(tmp_value_list, "seconds", strlen("seconds") + 1) && strncmp(tmp_value_list, "minutes", strlen("minutes") + 1) &&
200 strncmp(value_list, "hours", strlen("hours") + 1) && strncmp(value_list, "days", strlen("days") + 1)) { 158 strncmp(config.value_list, "hours", strlen("hours") + 1) && strncmp(tmp_value_list, "days", strlen("days") + 1)) {
201 159
202 output_message = strdup(_("wrong -l argument")); 160 output_message = strdup(_("wrong -l argument"));
203 } else { 161 } else {
204 xasprintf(&send_buffer, "%s&3", req_password); 162 xasprintf(&send_buffer, "%s&3", config.req_password);
205 fetch_data(server_address, server_port, send_buffer); 163 fetch_data(config.server_address, config.server_port, send_buffer);
206 uptime = strtoul(recv_buffer, NULL, 10); 164 unsigned long uptime = strtoul(recv_buffer, NULL, 10);
207 updays = uptime / 86400; 165 int updays = uptime / 86400;
208 uphours = (uptime % 86400) / 3600; 166 int uphours = (uptime % 86400) / 3600;
209 upminutes = ((uptime % 86400) % 3600) / 60; 167 int upminutes = ((uptime % 86400) % 3600) / 60;
210 168
211 if (!strncmp(value_list, "minutes", strlen("minutes"))) 169 if (!strncmp(tmp_value_list, "minutes", strlen("minutes"))) {
212 uptime = uptime / 60; 170 uptime = uptime / 60;
213 else if (!strncmp(value_list, "hours", strlen("hours"))) 171 } else if (!strncmp(tmp_value_list, "hours", strlen("hours"))) {
214 uptime = uptime / 3600; 172 uptime = uptime / 3600;
215 else if (!strncmp(value_list, "days", strlen("days"))) 173 } else if (!strncmp(tmp_value_list, "days", strlen("days"))) {
216 uptime = uptime / 86400; 174 uptime = uptime / 86400;
175 }
217 /* else uptime in seconds, nothing to do */ 176 /* else uptime in seconds, nothing to do */
218 177
219 xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes, 178 xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes,
220 uptime); 179 uptime);
221 180
222 if (check_critical_value && uptime <= critical_value) 181 if (config.check_critical_value && uptime <= config.critical_value) {
223 return_code = STATE_CRITICAL; 182 return_code = STATE_CRITICAL;
224 else if (check_warning_value && uptime <= warning_value) 183 } else if (config.check_warning_value && uptime <= config.warning_value) {
225 return_code = STATE_WARNING; 184 return_code = STATE_WARNING;
226 else 185 } else {
227 return_code = STATE_OK; 186 return_code = STATE_OK;
187 }
228 } 188 }
229 break; 189 } break;
230
231 case CHECK_USEDDISKSPACE: 190 case CHECK_USEDDISKSPACE:
232 191 if (config.value_list == NULL) {
233 if (value_list == NULL)
234 output_message = strdup(_("missing -l parameters")); 192 output_message = strdup(_("missing -l parameters"));
235 else if (strlen(value_list) != 1) 193 } else if (strlen(config.value_list) != 1) {
236 output_message = strdup(_("wrong -l argument")); 194 output_message = strdup(_("wrong -l argument"));
237 else { 195 } else {
238 xasprintf(&send_buffer, "%s&4&%s", req_password, value_list); 196 xasprintf(&send_buffer, "%s&4&%s", config.req_password, config.value_list);
239 fetch_data(server_address, server_port, send_buffer); 197 fetch_data(config.server_address, config.server_port, send_buffer);
240 fds = strtok(recv_buffer, "&"); 198 char *fds = strtok(recv_buffer, "&");
241 tds = strtok(NULL, "&"); 199 char *tds = strtok(NULL, "&");
242 if (fds != NULL) 200 double total_disk_space = 0;
201 double free_disk_space = 0;
202 if (fds != NULL) {
243 free_disk_space = atof(fds); 203 free_disk_space = atof(fds);
244 if (tds != NULL) 204 }
205 if (tds != NULL) {
245 total_disk_space = atof(tds); 206 total_disk_space = atof(tds);
207 }
246 208
247 if (total_disk_space > 0 && free_disk_space >= 0) { 209 if (total_disk_space > 0 && free_disk_space >= 0) {
248 percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; 210 double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100;
249 warning_used_space = ((float)warning_value / 100) * total_disk_space; 211 double warning_used_space = ((float)config.warning_value / 100) * total_disk_space;
250 critical_used_space = ((float)critical_value / 100) * total_disk_space; 212 double critical_used_space = ((float)config.critical_value / 100) * total_disk_space;
251 213
252 xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), value_list, 214 xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), config.value_list,
253 total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space, 215 total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space,
254 free_disk_space / 1073741824, (free_disk_space / total_disk_space) * 100); 216 free_disk_space / 1073741824, (free_disk_space / total_disk_space) * 100);
255 xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), value_list, 217 xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), config.value_list,
256 (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824, 218 (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824,
257 critical_used_space / 1073741824, total_disk_space / 1073741824); 219 critical_used_space / 1073741824, total_disk_space / 1073741824);
258 220
259 if (check_critical_value && percent_used_space >= critical_value) 221 if (config.check_critical_value && percent_used_space >= config.critical_value) {
260 return_code = STATE_CRITICAL; 222 return_code = STATE_CRITICAL;
261 else if (check_warning_value && percent_used_space >= warning_value) 223 } else if (config.check_warning_value && percent_used_space >= config.warning_value) {
262 return_code = STATE_WARNING; 224 return_code = STATE_WARNING;
263 else 225 } else {
264 return_code = STATE_OK; 226 return_code = STATE_OK;
227 }
265 228
266 output_message = strdup(temp_string); 229 output_message = strdup(temp_string);
267 perfdata = temp_string_perf; 230 perfdata = temp_string_perf;
@@ -271,41 +234,40 @@ int main(int argc, char **argv) {
271 } 234 }
272 } 235 }
273 break; 236 break;
274
275 case CHECK_SERVICESTATE: 237 case CHECK_SERVICESTATE:
276 case CHECK_PROCSTATE: 238 case CHECK_PROCSTATE:
277 239 if (config.value_list == NULL) {
278 if (value_list == NULL)
279 output_message = strdup(_("No service/process specified")); 240 output_message = strdup(_("No service/process specified"));
280 else { 241 } else {
281 preparelist(value_list); /* replace , between services with & to send the request */ 242 preparelist(config.value_list); /* replace , between services with & to send the request */
282 xasprintf(&send_buffer, "%s&%u&%s&%s", req_password, (vars_to_check == CHECK_SERVICESTATE) ? 5 : 6, 243 xasprintf(&send_buffer, "%s&%u&%s&%s", config.req_password, (config.vars_to_check == CHECK_SERVICESTATE) ? 5 : 6,
283 (show_all) ? "ShowAll" : "ShowFail", value_list); 244 (config.show_all) ? "ShowAll" : "ShowFail", config.value_list);
284 fetch_data(server_address, server_port, send_buffer); 245 fetch_data(config.server_address, config.server_port, send_buffer);
285 numstr = strtok(recv_buffer, "&"); 246 char *numstr = strtok(recv_buffer, "&");
286 if (numstr == NULL) 247 if (numstr == NULL) {
287 die(STATE_UNKNOWN, _("could not fetch information from server\n")); 248 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
249 }
288 return_code = atoi(numstr); 250 return_code = atoi(numstr);
289 temp_string = strtok(NULL, "&"); 251 temp_string = strtok(NULL, "&");
290 output_message = strdup(temp_string); 252 output_message = strdup(temp_string);
291 } 253 }
292 break; 254 break;
293
294 case CHECK_MEMUSE: 255 case CHECK_MEMUSE:
295 256 xasprintf(&send_buffer, "%s&7", config.req_password);
296 xasprintf(&send_buffer, "%s&7", req_password); 257 fetch_data(config.server_address, config.server_port, send_buffer);
297 fetch_data(server_address, server_port, send_buffer); 258 char *numstr = strtok(recv_buffer, "&");
298 numstr = strtok(recv_buffer, "&"); 259 if (numstr == NULL) {
299 if (numstr == NULL)
300 die(STATE_UNKNOWN, _("could not fetch information from server\n")); 260 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
301 mem_commitLimit = atof(numstr); 261 }
262 double mem_commitLimit = atof(numstr);
302 numstr = strtok(NULL, "&"); 263 numstr = strtok(NULL, "&");
303 if (numstr == NULL) 264 if (numstr == NULL) {
304 die(STATE_UNKNOWN, _("could not fetch information from server\n")); 265 die(STATE_UNKNOWN, _("could not fetch information from server\n"));
305 mem_commitByte = atof(numstr); 266 }
306 percent_used_space = (mem_commitByte / mem_commitLimit) * 100; 267 double mem_commitByte = atof(numstr);
307 warning_used_space = ((float)warning_value / 100) * mem_commitLimit; 268 double percent_used_space = (mem_commitByte / mem_commitLimit) * 100;
308 critical_used_space = ((float)critical_value / 100) * mem_commitLimit; 269 double warning_used_space = ((float)config.warning_value / 100) * mem_commitLimit;
270 double critical_used_space = ((float)config.critical_value / 100) * mem_commitLimit;
309 271
310 /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, 272 /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here,
311 which equals RAM + Pagefiles. */ 273 which equals RAM + Pagefiles. */
@@ -316,15 +278,14 @@ int main(int argc, char **argv) {
316 critical_used_space / 1048567, mem_commitLimit / 1048567); 278 critical_used_space / 1048567, mem_commitLimit / 1048567);
317 279
318 return_code = STATE_OK; 280 return_code = STATE_OK;
319 if (check_critical_value && percent_used_space >= critical_value) 281 if (config.check_critical_value && percent_used_space >= config.critical_value) {
320 return_code = STATE_CRITICAL; 282 return_code = STATE_CRITICAL;
321 else if (check_warning_value && percent_used_space >= warning_value) 283 } else if (config.check_warning_value && percent_used_space >= config.warning_value) {
322 return_code = STATE_WARNING; 284 return_code = STATE_WARNING;
285 }
323 286
324 break; 287 break;
325 288 case CHECK_COUNTER: {
326 case CHECK_COUNTER:
327
328 /* 289 /*
329 CHECK_COUNTER has been modified to provide extensive perfdata information. 290 CHECK_COUNTER has been modified to provide extensive perfdata information.
330 In order to do this, some modifications have been done to the code 291 In order to do this, some modifications have been done to the code
@@ -346,26 +307,32 @@ int main(int argc, char **argv) {
346 strange things will happen when you make graphs of your data. 307 strange things will happen when you make graphs of your data.
347 */ 308 */
348 309
349 if (value_list == NULL) 310 double counter_value = 0.0;
311 if (config.value_list == NULL) {
350 output_message = strdup(_("No counter specified")); 312 output_message = strdup(_("No counter specified"));
351 else { 313 } else {
352 preparelist(value_list); /* replace , between services with & to send the request */ 314 preparelist(config.value_list); /* replace , between services with & to send the request */
353 isPercent = (strchr(value_list, '%') != NULL); 315 bool isPercent = (strchr(config.value_list, '%') != NULL);
354 316
355 strtok(value_list, "&"); /* burn the first parameters */ 317 strtok(config.value_list, "&"); /* burn the first parameters */
356 description = strtok(NULL, "&"); 318 description = strtok(NULL, "&");
357 counter_unit = strtok(NULL, "&"); 319 counter_unit = strtok(NULL, "&");
358 xasprintf(&send_buffer, "%s&8&%s", req_password, value_list); 320 xasprintf(&send_buffer, "%s&8&%s", config.req_password, config.value_list);
359 fetch_data(server_address, server_port, send_buffer); 321 fetch_data(config.server_address, config.server_port, send_buffer);
360 counter_value = atof(recv_buffer); 322 counter_value = atof(recv_buffer);
361 323
362 if (description == NULL) 324 bool allRight = false;
325 if (description == NULL) {
363 xasprintf(&output_message, "%.f", counter_value); 326 xasprintf(&output_message, "%.f", counter_value);
364 else if (isPercent) { 327 } else if (isPercent) {
365 counter_unit = strdup("%"); 328 counter_unit = strdup("%");
366 allRight = true; 329 allRight = true;
367 } 330 }
368 331
332 char *minval = NULL;
333 char *maxval = NULL;
334 double fminval = 0;
335 double fmaxval = 0;
369 if ((counter_unit != NULL) && (!allRight)) { 336 if ((counter_unit != NULL) && (!allRight)) {
370 minval = strtok(NULL, "&"); 337 minval = strtok(NULL, "&");
371 maxval = strtok(NULL, "&"); 338 maxval = strtok(NULL, "&");
@@ -375,16 +342,18 @@ int main(int argc, char **argv) {
375 fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1; 342 fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1;
376 fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1; 343 fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1;
377 344
378 if ((fminval == 0) && (minval == errcvt)) 345 if ((fminval == 0) && (minval == errcvt)) {
379 output_message = strdup(_("Minimum value contains non-numbers")); 346 output_message = strdup(_("Minimum value contains non-numbers"));
380 else { 347 } else {
381 if ((fmaxval == 0) && (maxval == errcvt)) 348 if ((fmaxval == 0) && (maxval == errcvt)) {
382 output_message = strdup(_("Maximum value contains non-numbers")); 349 output_message = strdup(_("Maximum value contains non-numbers"));
383 else 350 } else {
384 allRight = true; /* Everything is OK. */ 351 allRight = true; /* Everything is OK. */
352 }
385 } 353 }
386 } else if ((counter_unit == NULL) && (description != NULL)) 354 } else if ((counter_unit == NULL) && (description != NULL)) {
387 output_message = strdup(_("No unit counter specified")); 355 output_message = strdup(_("No unit counter specified"));
356 }
388 357
389 if (allRight) { 358 if (allRight) {
390 /* Let's format the output string, finally... */ 359 /* Let's format the output string, finally... */
@@ -396,63 +365,65 @@ int main(int argc, char **argv) {
396 } 365 }
397 xasprintf(&output_message, "%s |", output_message); 366 xasprintf(&output_message, "%s |", output_message);
398 xasprintf(&output_message, "%s %s", output_message, 367 xasprintf(&output_message, "%s %s", output_message,
399 fperfdata(description, counter_value, counter_unit, 1, warning_value, 1, critical_value, 368 fperfdata(description, counter_value, counter_unit, 1, config.warning_value, 1, config.critical_value,
400 (!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval)); 369 (!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval));
401 } 370 }
402 } 371 }
403 372
404 if (critical_value > warning_value) { /* Normal thresholds */ 373 if (config.critical_value > config.warning_value) { /* Normal thresholds */
405 if (check_critical_value && counter_value >= critical_value) 374 if (config.check_critical_value && counter_value >= config.critical_value) {
406 return_code = STATE_CRITICAL; 375 return_code = STATE_CRITICAL;
407 else if (check_warning_value && counter_value >= warning_value) 376 } else if (config.check_warning_value && counter_value >= config.warning_value) {
408 return_code = STATE_WARNING; 377 return_code = STATE_WARNING;
409 else 378 } else {
410 return_code = STATE_OK; 379 return_code = STATE_OK;
380 }
411 } else { /* inverse thresholds */ 381 } else { /* inverse thresholds */
412 return_code = STATE_OK; 382 return_code = STATE_OK;
413 if (check_critical_value && counter_value <= critical_value) 383 if (config.check_critical_value && counter_value <= config.critical_value) {
414 return_code = STATE_CRITICAL; 384 return_code = STATE_CRITICAL;
415 else if (check_warning_value && counter_value <= warning_value) 385 } else if (config.check_warning_value && counter_value <= config.warning_value) {
416 return_code = STATE_WARNING; 386 return_code = STATE_WARNING;
387 }
417 } 388 }
418 break; 389 } break;
419
420 case CHECK_FILEAGE: 390 case CHECK_FILEAGE:
421 391 if (config.value_list == NULL) {
422 if (value_list == NULL)
423 output_message = strdup(_("No counter specified")); 392 output_message = strdup(_("No counter specified"));
424 else { 393 } else {
425 preparelist(value_list); /* replace , between services with & to send the request */ 394 preparelist(config.value_list); /* replace , between services with & to send the request */
426 xasprintf(&send_buffer, "%s&9&%s", req_password, value_list); 395 xasprintf(&send_buffer, "%s&9&%s", config.req_password, config.value_list);
427 fetch_data(server_address, server_port, send_buffer); 396 fetch_data(config.server_address, config.server_port, send_buffer);
428 age_in_minutes = atoi(strtok(recv_buffer, "&")); 397 unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&"));
429 description = strtok(NULL, "&"); 398 description = strtok(NULL, "&");
430 output_message = strdup(description); 399 output_message = strdup(description);
431 400
432 if (critical_value > warning_value) { /* Normal thresholds */ 401 if (config.critical_value > config.warning_value) { /* Normal thresholds */
433 if (check_critical_value && age_in_minutes >= critical_value) 402 if (config.check_critical_value && age_in_minutes >= config.critical_value) {
434 return_code = STATE_CRITICAL; 403 return_code = STATE_CRITICAL;
435 else if (check_warning_value && age_in_minutes >= warning_value) 404 } else if (config.check_warning_value && age_in_minutes >= config.warning_value) {
436 return_code = STATE_WARNING; 405 return_code = STATE_WARNING;
437 else 406 } else {
438 return_code = STATE_OK; 407 return_code = STATE_OK;
408 }
439 } else { /* inverse thresholds */ 409 } else { /* inverse thresholds */
440 if (check_critical_value && age_in_minutes <= critical_value) 410 if (config.check_critical_value && age_in_minutes <= config.critical_value) {
441 return_code = STATE_CRITICAL; 411 return_code = STATE_CRITICAL;
442 else if (check_warning_value && age_in_minutes <= warning_value) 412 } else if (config.check_warning_value && age_in_minutes <= config.warning_value) {
443 return_code = STATE_WARNING; 413 return_code = STATE_WARNING;
444 else 414 } else {
445 return_code = STATE_OK; 415 return_code = STATE_OK;
416 }
446 } 417 }
447 } 418 }
448 break; 419 break;
449 420
450 case CHECK_INSTANCES: 421 case CHECK_INSTANCES:
451 if (value_list == NULL) 422 if (config.value_list == NULL) {
452 output_message = strdup(_("No counter specified")); 423 output_message = strdup(_("No counter specified"));
453 else { 424 } else {
454 xasprintf(&send_buffer, "%s&10&%s", req_password, value_list); 425 xasprintf(&send_buffer, "%s&10&%s", config.req_password, config.value_list);
455 fetch_data(server_address, server_port, send_buffer); 426 fetch_data(config.server_address, config.server_port, send_buffer);
456 if (!strncmp(recv_buffer, "ERROR", 5)) { 427 if (!strncmp(recv_buffer, "ERROR", 5)) {
457 printf("NSClient - %s\n", recv_buffer); 428 printf("NSClient - %s\n", recv_buffer);
458 exit(STATE_UNKNOWN); 429 exit(STATE_UNKNOWN);
@@ -471,18 +442,16 @@ int main(int argc, char **argv) {
471 /* reset timeout */ 442 /* reset timeout */
472 alarm(0); 443 alarm(0);
473 444
474 if (perfdata == NULL) 445 if (perfdata == NULL) {
475 printf("%s\n", output_message); 446 printf("%s\n", output_message);
476 else 447 } else {
477 printf("%s | %s\n", output_message, perfdata); 448 printf("%s | %s\n", output_message, perfdata);
449 }
478 return return_code; 450 return return_code;
479} 451}
480 452
481/* process command-line arguments */ 453/* process command-line arguments */
482int process_arguments(int argc, char **argv) { 454check_nt_config_wrapper process_arguments(int argc, char **argv) {
483 int c;
484
485 int option = 0;
486 static struct option longopts[] = {{"port", required_argument, 0, 'p'}, 455 static struct option longopts[] = {{"port", required_argument, 0, 'p'},
487 {"timeout", required_argument, 0, 't'}, 456 {"timeout", required_argument, 0, 't'},
488 {"critical", required_argument, 0, 'c'}, 457 {"critical", required_argument, 0, 'c'},
@@ -497,34 +466,44 @@ int process_arguments(int argc, char **argv) {
497 {"help", no_argument, 0, 'h'}, 466 {"help", no_argument, 0, 'h'},
498 {0, 0, 0, 0}}; 467 {0, 0, 0, 0}};
499 468
469 check_nt_config_wrapper result = {
470 .errorcode = OK,
471 .config = check_nt_config_init(),
472 };
473
500 /* no options were supplied */ 474 /* no options were supplied */
501 if (argc < 2) 475 if (argc < 2) {
502 return ERROR; 476 result.errorcode = ERROR;
477 return result;
478 }
503 479
504 /* backwards compatibility */ 480 /* backwards compatibility */
505 if (!is_option(argv[1])) { 481 if (!is_option(argv[1])) {
506 server_address = strdup(argv[1]); 482 result.config.server_address = strdup(argv[1]);
507 argv[1] = argv[0]; 483 argv[1] = argv[0];
508 argv = &argv[1]; 484 argv = &argv[1];
509 argc--; 485 argc--;
510 } 486 }
511 487
512 for (c = 1; c < argc; c++) { 488 for (int index = 1; index < argc; index++) {
513 if (strcmp("-to", argv[c]) == 0) 489 if (strcmp("-to", argv[index]) == 0) {
514 strcpy(argv[c], "-t"); 490 strcpy(argv[index], "-t");
515 else if (strcmp("-wv", argv[c]) == 0) 491 } else if (strcmp("-wv", argv[index]) == 0) {
516 strcpy(argv[c], "-w"); 492 strcpy(argv[index], "-w");
517 else if (strcmp("-cv", argv[c]) == 0) 493 } else if (strcmp("-cv", argv[index]) == 0) {
518 strcpy(argv[c], "-c"); 494 strcpy(argv[index], "-c");
495 }
519 } 496 }
520 497
521 while (1) { 498 int option = 0;
522 c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option); 499 while (true) {
500 int option_index = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option);
523 501
524 if (c == -1 || c == EOF || c == 1) 502 if (option_index == -1 || option_index == EOF || option_index == 1) {
525 break; 503 break;
504 }
526 505
527 switch (c) { 506 switch (option_index) {
528 case '?': /* print short usage statement if args not parsable */ 507 case '?': /* print short usage statement if args not parsable */
529 usage5(); 508 usage5();
530 case 'h': /* help */ 509 case 'h': /* help */
@@ -534,118 +513,128 @@ int process_arguments(int argc, char **argv) {
534 print_revision(progname, NP_VERSION); 513 print_revision(progname, NP_VERSION);
535 exit(STATE_UNKNOWN); 514 exit(STATE_UNKNOWN);
536 case 'H': /* hostname */ 515 case 'H': /* hostname */
537 server_address = optarg; 516 result.config.server_address = optarg;
538 break; 517 break;
539 case 's': /* password */ 518 case 's': /* password */
540 req_password = optarg; 519 result.config.req_password = optarg;
541 break; 520 break;
542 case 'p': /* port */ 521 case 'p': /* port */
543 if (is_intnonneg(optarg)) 522 if (is_intnonneg(optarg)) {
544 server_port = atoi(optarg); 523 result.config.server_port = atoi(optarg);
545 else 524 } else {
546 die(STATE_UNKNOWN, _("Server port must be an integer\n")); 525 die(STATE_UNKNOWN, _("Server port must be an integer\n"));
526 }
547 break; 527 break;
548 case 'v': 528 case 'v':
549 if (strlen(optarg) < 4) 529 if (strlen(optarg) < 4) {
550 return ERROR; 530 result.errorcode = ERROR;
551 if (!strcmp(optarg, "CLIENTVERSION")) 531 return result;
552 vars_to_check = CHECK_CLIENTVERSION; 532 }
553 else if (!strcmp(optarg, "CPULOAD")) 533 if (!strcmp(optarg, "CLIENTVERSION")) {
554 vars_to_check = CHECK_CPULOAD; 534 result.config.vars_to_check = CHECK_CLIENTVERSION;
555 else if (!strcmp(optarg, "UPTIME")) 535 } else if (!strcmp(optarg, "CPULOAD")) {
556 vars_to_check = CHECK_UPTIME; 536 result.config.vars_to_check = CHECK_CPULOAD;
557 else if (!strcmp(optarg, "USEDDISKSPACE")) 537 } else if (!strcmp(optarg, "UPTIME")) {
558 vars_to_check = CHECK_USEDDISKSPACE; 538 result.config.vars_to_check = CHECK_UPTIME;
559 else if (!strcmp(optarg, "SERVICESTATE")) 539 } else if (!strcmp(optarg, "USEDDISKSPACE")) {
560 vars_to_check = CHECK_SERVICESTATE; 540 result.config.vars_to_check = CHECK_USEDDISKSPACE;
561 else if (!strcmp(optarg, "PROCSTATE")) 541 } else if (!strcmp(optarg, "SERVICESTATE")) {
562 vars_to_check = CHECK_PROCSTATE; 542 result.config.vars_to_check = CHECK_SERVICESTATE;
563 else if (!strcmp(optarg, "MEMUSE")) 543 } else if (!strcmp(optarg, "PROCSTATE")) {
564 vars_to_check = CHECK_MEMUSE; 544 result.config.vars_to_check = CHECK_PROCSTATE;
565 else if (!strcmp(optarg, "COUNTER")) 545 } else if (!strcmp(optarg, "MEMUSE")) {
566 vars_to_check = CHECK_COUNTER; 546 result.config.vars_to_check = CHECK_MEMUSE;
567 else if (!strcmp(optarg, "FILEAGE")) 547 } else if (!strcmp(optarg, "COUNTER")) {
568 vars_to_check = CHECK_FILEAGE; 548 result.config.vars_to_check = CHECK_COUNTER;
569 else if (!strcmp(optarg, "INSTANCES")) 549 } else if (!strcmp(optarg, "FILEAGE")) {
570 vars_to_check = CHECK_INSTANCES; 550 result.config.vars_to_check = CHECK_FILEAGE;
571 else 551 } else if (!strcmp(optarg, "INSTANCES")) {
572 return ERROR; 552 result.config.vars_to_check = CHECK_INSTANCES;
553 } else {
554 result.errorcode = ERROR;
555 return result;
556 }
573 break; 557 break;
574 case 'l': /* value list */ 558 case 'l': /* value list */
575 value_list = optarg; 559 result.config.value_list = optarg;
576 break; 560 break;
577 case 'w': /* warning threshold */ 561 case 'w': /* warning threshold */
578 warning_value = strtoul(optarg, NULL, 10); 562 result.config.warning_value = strtoul(optarg, NULL, 10);
579 check_warning_value = true; 563 result.config.check_warning_value = true;
580 break; 564 break;
581 case 'c': /* critical threshold */ 565 case 'c': /* critical threshold */
582 critical_value = strtoul(optarg, NULL, 10); 566 result.config.critical_value = strtoul(optarg, NULL, 10);
583 check_critical_value = true; 567 result.config.check_critical_value = true;
584 break; 568 break;
585 case 'd': /* Display select for services */ 569 case 'd': /* Display select for services */
586 if (!strcmp(optarg, "SHOWALL")) 570 if (!strcmp(optarg, "SHOWALL")) {
587 show_all = true; 571 result.config.show_all = true;
572 }
588 break; 573 break;
589 case 'u': 574 case 'u':
590 socket_timeout_state = STATE_UNKNOWN; 575 socket_timeout_state = STATE_UNKNOWN;
591 break; 576 break;
592 case 't': /* timeout */ 577 case 't': /* timeout */
593 socket_timeout = atoi(optarg); 578 socket_timeout = atoi(optarg);
594 if (socket_timeout <= 0) 579 if (socket_timeout <= 0) {
595 return ERROR; 580 result.errorcode = ERROR;
581 return result;
582 }
596 } 583 }
597 } 584 }
598 if (server_address == NULL) 585 if (result.config.server_address == NULL) {
599 usage4(_("You must provide a server address or host name")); 586 usage4(_("You must provide a server address or host name"));
587 }
600 588
601 if (vars_to_check == CHECK_NONE) 589 if (result.config.vars_to_check == CHECK_NONE) {
602 return ERROR; 590 result.errorcode = ERROR;
591 return result;
592 }
603 593
604 if (req_password == NULL) 594 if (result.config.req_password == NULL) {
605 req_password = strdup(_("None")); 595 result.config.req_password = strdup(_("None"));
596 }
606 597
607 return OK; 598 return result;
608} 599}
609 600
610void fetch_data(const char *address, int port, const char *sendb) { 601void fetch_data(const char *address, int port, const char *sendb) {
611 int result; 602 int result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer));
612
613 result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer));
614 603
615 if (result != STATE_OK) 604 if (result != STATE_OK) {
616 die(result, _("could not fetch information from server\n")); 605 die(result, _("could not fetch information from server\n"));
606 }
617 607
618 if (!strncmp(recv_buffer, "ERROR", 5)) 608 if (!strncmp(recv_buffer, "ERROR", 5)) {
619 die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer); 609 die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer);
610 }
620} 611}
621 612
622bool strtoularray(unsigned long *array, char *string, const char *delim) { 613bool strtoularray(unsigned long *array, char *string, const char *delim) {
623 /* split a <delim> delimited string into a long array */ 614 /* split a <delim> delimited string into a long array */
624 int idx = 0; 615 for (int idx = 0; idx < MAX_VALUE_LIST; idx++) {
625 char *t1;
626
627 for (idx = 0; idx < MAX_VALUE_LIST; idx++)
628 array[idx] = 0; 616 array[idx] = 0;
617 }
629 618
630 idx = 0; 619 int idx = 0;
631 for (t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) { 620 for (char *t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) {
632 if (is_numeric(t1) && idx < MAX_VALUE_LIST) { 621 if (is_numeric(t1) && idx < MAX_VALUE_LIST) {
633 array[idx] = strtoul(t1, NULL, 10); 622 array[idx] = strtoul(t1, NULL, 10);
634 idx++; 623 idx++;
635 } else 624 } else {
636 return false; 625 return false;
626 }
637 } 627 }
638 return true; 628 return true;
639} 629}
640 630
641void preparelist(char *string) { 631void preparelist(char *string) {
642 /* Replace all , with & which is the delimiter for the request */ 632 /* Replace all , with & which is the delimiter for the request */
643 int i; 633 for (int i = 0; (size_t)i < strlen(string); i++) {
644
645 for (i = 0; (size_t)i < strlen(string); i++)
646 if (string[i] == ',') { 634 if (string[i] == ',') {
647 string[i] = '&'; 635 string[i] = '&';
648 } 636 }
637 }
649} 638}
650 639
651void print_help(void) { 640void print_help(void) {
diff --git a/plugins/check_nt.d/config.h b/plugins/check_nt.d/config.h
new file mode 100644
index 00000000..431889cb
--- /dev/null
+++ b/plugins/check_nt.d/config.h
@@ -0,0 +1,53 @@
1#pragma once
2
3#include "../../config.h"
4#include <stddef.h>
5
6enum {
7 PORT = 1248,
8};
9
10enum checkvars {
11 CHECK_NONE,
12 CHECK_CLIENTVERSION,
13 CHECK_CPULOAD,
14 CHECK_UPTIME,
15 CHECK_USEDDISKSPACE,
16 CHECK_SERVICESTATE,
17 CHECK_PROCSTATE,
18 CHECK_MEMUSE,
19 CHECK_COUNTER,
20 CHECK_FILEAGE,
21 CHECK_INSTANCES
22};
23
24typedef struct {
25 char *server_address;
26 int server_port;
27 char *req_password;
28 enum checkvars vars_to_check;
29 bool show_all;
30 char *value_list;
31 bool check_warning_value;
32 unsigned long warning_value;
33 bool check_critical_value;
34 unsigned long critical_value;
35} check_nt_config;
36
37check_nt_config check_nt_config_init() {
38 check_nt_config tmp = {
39 .server_address = NULL,
40 .server_port = PORT,
41 .req_password = NULL,
42
43 .vars_to_check = CHECK_NONE,
44 .show_all = false,
45 .value_list = NULL,
46
47 .check_warning_value = false,
48 .warning_value = 0,
49 .check_critical_value = false,
50 .critical_value = 0,
51 };
52 return tmp;
53}
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 703b69df..31162883 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -41,17 +41,18 @@ const char *email = "devel@monitoring-plugins.org";
41#include "common.h" 41#include "common.h"
42#include "netutils.h" 42#include "netutils.h"
43#include "utils.h" 43#include "utils.h"
44#include "states.h"
45#include "thresholds.h"
46#include "check_ntp_time.d/config.h"
44 47
45static char *server_address = NULL;
46static char *port = "123";
47static int verbose = 0; 48static int verbose = 0;
48static bool quiet = false;
49static char *owarn = "60";
50static char *ocrit = "120";
51static int time_offset = 0;
52 49
53static int process_arguments(int, char **); 50typedef struct {
54static thresholds *offset_thresholds = NULL; 51 int errorcode;
52 check_ntp_time_config config;
53} check_ntp_time_config_wrapper;
54static check_ntp_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
55
55static void print_help(void); 56static void print_help(void);
56void print_usage(void); 57void print_usage(void);
57 58
@@ -159,7 +160,7 @@ typedef struct {
159#define EPOCHDIFF 0x83aa7e80UL 160#define EPOCHDIFF 0x83aa7e80UL
160 161
161/* extract a 32-bit ntp fixed point number into a double */ 162/* extract a 32-bit ntp fixed point number into a double */
162#define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x)) / 65536.0) 163#define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0))
163 164
164/* likewise for a 64-bit ntp fp number */ 165/* likewise for a 64-bit ntp fp number */
165#define NTP64asDOUBLE(n) \ 166#define NTP64asDOUBLE(n) \
@@ -208,56 +209,52 @@ typedef struct {
208 } while (0); 209 } while (0);
209 210
210/* calculate the offset of the local clock */ 211/* calculate the offset of the local clock */
211static inline double calc_offset(const ntp_message *m, const struct timeval *t) { 212static inline double calc_offset(const ntp_message *message, const struct timeval *time_value) {
212 double client_tx = NTP64asDOUBLE(m->origts); 213 double client_tx = NTP64asDOUBLE(message->origts);
213 double peer_rx = NTP64asDOUBLE(m->rxts); 214 double peer_rx = NTP64asDOUBLE(message->rxts);
214 double peer_tx = NTP64asDOUBLE(m->txts); 215 double peer_tx = NTP64asDOUBLE(message->txts);
215 double client_rx = TVasDOUBLE((*t)); 216 double client_rx = TVasDOUBLE((*time_value));
216 return (.5 * ((peer_tx - client_rx) + (peer_rx - client_tx))); 217 return (((peer_tx - client_rx) + (peer_rx - client_tx)) / 2);
217} 218}
218 219
219/* print out a ntp packet in human readable/debuggable format */ 220/* print out a ntp packet in human readable/debuggable format */
220void print_ntp_message(const ntp_message *p) { 221void print_ntp_message(const ntp_message *message) {
221 struct timeval ref; 222 struct timeval ref;
222 struct timeval orig; 223 struct timeval orig;
223 struct timeval rx;
224 struct timeval tx;
225 224
226 NTP64toTV(p->refts, ref); 225 NTP64toTV(message->refts, ref);
227 NTP64toTV(p->origts, orig); 226 NTP64toTV(message->origts, orig);
228 NTP64toTV(p->rxts, rx);
229 NTP64toTV(p->txts, tx);
230 227
231 printf("packet contents:\n"); 228 printf("packet contents:\n");
232 printf("\tflags: 0x%.2x\n", p->flags); 229 printf("\tflags: 0x%.2x\n", message->flags);
233 printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); 230 printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK);
234 printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); 231 printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK);
235 printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); 232 printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK);
236 printf("\tstratum = %d\n", p->stratum); 233 printf("\tstratum = %d\n", message->stratum);
237 printf("\tpoll = %g\n", pow(2, p->poll)); 234 printf("\tpoll = %g\n", pow(2, message->poll));
238 printf("\tprecision = %g\n", pow(2, p->precision)); 235 printf("\tprecision = %g\n", pow(2, message->precision));
239 printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay)); 236 printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(message->rtdelay));
240 printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp)); 237 printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(message->rtdisp));
241 printf("\trefid = %x\n", p->refid); 238 printf("\trefid = %x\n", message->refid);
242 printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts)); 239 printf("\trefts = %-.16g\n", NTP64asDOUBLE(message->refts));
243 printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts)); 240 printf("\torigts = %-.16g\n", NTP64asDOUBLE(message->origts));
244 printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts)); 241 printf("\trxts = %-.16g\n", NTP64asDOUBLE(message->rxts));
245 printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); 242 printf("\ttxts = %-.16g\n", NTP64asDOUBLE(message->txts));
246} 243}
247 244
248void setup_request(ntp_message *p) { 245void setup_request(ntp_message *message) {
249 memset(p, 0, sizeof(ntp_message)); 246 memset(message, 0, sizeof(ntp_message));
250 LI_SET(p->flags, LI_ALARM); 247 LI_SET(message->flags, LI_ALARM);
251 VN_SET(p->flags, 4); 248 VN_SET(message->flags, 4);
252 MODE_SET(p->flags, MODE_CLIENT); 249 MODE_SET(message->flags, MODE_CLIENT);
253 p->poll = 4; 250 message->poll = 4;
254 p->precision = (int8_t)0xfa; 251 message->precision = (int8_t)0xfa;
255 L16(p->rtdelay) = htons(1); 252 L16(message->rtdelay) = htons(1);
256 L16(p->rtdisp) = htons(1); 253 L16(message->rtdisp) = htons(1);
257 254
258 struct timeval t; 255 struct timeval t;
259 gettimeofday(&t, NULL); 256 gettimeofday(&t, NULL);
260 TVtoNTP64(t, p->txts); 257 TVtoNTP64(t, message->txts);
261} 258}
262 259
263/* select the "best" server from a list of servers, and return its index. 260/* select the "best" server from a list of servers, and return its index.
@@ -273,14 +270,16 @@ int best_offset_server(const ntp_server_results *slist, int nservers) {
273 * stratum 0 is for reference clocks so no NTP server should ever report 270 * stratum 0 is for reference clocks so no NTP server should ever report
274 * a stratum 0 */ 271 * a stratum 0 */
275 if (slist[cserver].stratum == 0) { 272 if (slist[cserver].stratum == 0) {
276 if (verbose) 273 if (verbose) {
277 printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum); 274 printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum);
275 }
278 continue; 276 continue;
279 } 277 }
280 /* Sort out servers with error flags */ 278 /* Sort out servers with error flags */
281 if (LI(slist[cserver].flags) == LI_ALARM) { 279 if (LI(slist[cserver].flags) == LI_ALARM) {
282 if (verbose) 280 if (verbose) {
283 printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags)); 281 printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags));
282 }
284 continue; 283 continue;
285 } 284 }
286 285
@@ -322,7 +321,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers) {
322 * we don't waste time sitting around waiting for single packets. 321 * we don't waste time sitting around waiting for single packets.
323 * - we also "manually" handle resolving host names and connecting, because 322 * - we also "manually" handle resolving host names and connecting, because
324 * we have to do it in a way that our lazy macros don't handle currently :( */ 323 * we have to do it in a way that our lazy macros don't handle currently :( */
325double offset_request(const char *host, int *status) { 324double offset_request(const char *host, const char *port, mp_state_enum *status, int time_offset) {
326 /* setup hints to only return results from getaddrinfo that we'd like */ 325 /* setup hints to only return results from getaddrinfo that we'd like */
327 struct addrinfo hints; 326 struct addrinfo hints;
328 memset(&hints, 0, sizeof(struct addrinfo)); 327 memset(&hints, 0, sizeof(struct addrinfo));
@@ -331,39 +330,43 @@ double offset_request(const char *host, int *status) {
331 hints.ai_socktype = SOCK_DGRAM; 330 hints.ai_socktype = SOCK_DGRAM;
332 331
333 /* fill in ai with the list of hosts resolved by the host name */ 332 /* fill in ai with the list of hosts resolved by the host name */
334 struct addrinfo *ai = NULL; 333 struct addrinfo *addresses = NULL;
335 int ga_result = getaddrinfo(host, port, &hints, &ai); 334 int ga_result = getaddrinfo(host, port, &hints, &addresses);
336 if (ga_result != 0) { 335 if (ga_result != 0) {
337 die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); 336 die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result));
338 } 337 }
339 338
340 /* count the number of returned hosts, and allocate stuff accordingly */ 339 /* count the number of returned hosts, and allocate stuff accordingly */
341 int num_hosts = 0; 340 size_t num_hosts = 0;
342 for (struct addrinfo *ai_tmp = ai; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { 341 for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) {
343 num_hosts++; 342 num_hosts++;
344 } 343 }
345 344
346 ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); 345 ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts);
347 346
348 if (req == NULL) 347 if (req == NULL) {
349 die(STATE_UNKNOWN, "can not allocate ntp message array"); 348 die(STATE_UNKNOWN, "can not allocate ntp message array");
349 }
350 int *socklist = (int *)malloc(sizeof(int) * num_hosts); 350 int *socklist = (int *)malloc(sizeof(int) * num_hosts);
351 351
352 if (socklist == NULL) 352 if (socklist == NULL) {
353 die(STATE_UNKNOWN, "can not allocate socket array"); 353 die(STATE_UNKNOWN, "can not allocate socket array");
354 }
354 355
355 struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts); 356 struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd) * num_hosts);
356 if (ufds == NULL) 357 if (ufds == NULL) {
357 die(STATE_UNKNOWN, "can not allocate socket array"); 358 die(STATE_UNKNOWN, "can not allocate socket array");
359 }
358 360
359 ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); 361 ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts);
360 if (servers == NULL) 362 if (servers == NULL) {
361 die(STATE_UNKNOWN, "can not allocate server array"); 363 die(STATE_UNKNOWN, "can not allocate server array");
364 }
362 memset(servers, 0, sizeof(ntp_server_results) * num_hosts); 365 memset(servers, 0, sizeof(ntp_server_results) * num_hosts);
363 DBG(printf("Found %d peers to check\n", num_hosts)); 366 DBG(printf("Found %zu peers to check\n", num_hosts));
364 367
365 /* setup each socket for writing, and the corresponding struct pollfd */ 368 /* setup each socket for writing, and the corresponding struct pollfd */
366 struct addrinfo *ai_tmp = ai; 369 struct addrinfo *ai_tmp = addresses;
367 for (int i = 0; ai_tmp; i++) { 370 for (int i = 0; ai_tmp; i++) {
368 socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); 371 socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
369 if (socklist[i] == -1) { 372 if (socklist[i] == -1) {
@@ -389,7 +392,7 @@ double offset_request(const char *host, int *status) {
389 time_t start_ts = 0; 392 time_t start_ts = 0;
390 time_t now_time = 0; 393 time_t now_time = 0;
391 now_time = start_ts = time(NULL); 394 now_time = start_ts = time(NULL);
392 int servers_completed = 0; 395 size_t servers_completed = 0;
393 bool one_read = false; 396 bool one_read = false;
394 while (servers_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) { 397 while (servers_completed < num_hosts && now_time - start_ts <= socket_timeout / 2) {
395 /* loop through each server and find each one which hasn't 398 /* loop through each server and find each one which hasn't
@@ -398,12 +401,14 @@ double offset_request(const char *host, int *status) {
398 * and update the "waiting" timestamp with the current time. */ 401 * and update the "waiting" timestamp with the current time. */
399 now_time = time(NULL); 402 now_time = time(NULL);
400 403
401 for (int i = 0; i < num_hosts; i++) { 404 for (size_t i = 0; i < num_hosts; i++) {
402 if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) { 405 if (servers[i].waiting < now_time && servers[i].num_responses < AVG_NUM) {
403 if (verbose && servers[i].waiting != 0) 406 if (verbose && servers[i].waiting != 0) {
404 printf("re-"); 407 printf("re-");
405 if (verbose) 408 }
406 printf("sending request to peer %d\n", i); 409 if (verbose) {
410 printf("sending request to peer %zu\n", i);
411 }
407 setup_request(&req[i]); 412 setup_request(&req[i]);
408 write(socklist[i], &req[i], sizeof(ntp_message)); 413 write(socklist[i], &req[i], sizeof(ntp_message));
409 servers[i].waiting = now_time; 414 servers[i].waiting = now_time;
@@ -419,10 +424,10 @@ double offset_request(const char *host, int *status) {
419 } 424 }
420 425
421 /* read from any sockets with pending data */ 426 /* read from any sockets with pending data */
422 for (int i = 0; servers_readable && i < num_hosts; i++) { 427 for (size_t i = 0; servers_readable && i < num_hosts; i++) {
423 if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) { 428 if (ufds[i].revents & POLLIN && servers[i].num_responses < AVG_NUM) {
424 if (verbose) { 429 if (verbose) {
425 printf("response from peer %d: ", i); 430 printf("response from peer %zu: ", i);
426 } 431 }
427 432
428 read(ufds[i].fd, &req[i], sizeof(ntp_message)); 433 read(ufds[i].fd, &req[i], sizeof(ntp_message));
@@ -442,14 +447,15 @@ double offset_request(const char *host, int *status) {
442 servers[i].flags = req[i].flags; 447 servers[i].flags = req[i].flags;
443 servers_readable--; 448 servers_readable--;
444 one_read = true; 449 one_read = true;
445 if (servers[i].num_responses == AVG_NUM) 450 if (servers[i].num_responses == AVG_NUM) {
446 servers_completed++; 451 servers_completed++;
452 }
447 } 453 }
448 } 454 }
449 /* lather, rinse, repeat. */ 455 /* lather, rinse, repeat. */
450 } 456 }
451 457
452 if (one_read == false) { 458 if (!one_read) {
453 die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); 459 die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");
454 } 460 }
455 461
@@ -467,21 +473,22 @@ double offset_request(const char *host, int *status) {
467 } 473 }
468 474
469 /* cleanup */ 475 /* cleanup */
470 for (int j = 0; j < num_hosts; j++) { 476 for (size_t j = 0; j < num_hosts; j++) {
471 close(socklist[j]); 477 close(socklist[j]);
472 } 478 }
473 free(socklist); 479 free(socklist);
474 free(ufds); 480 free(ufds);
475 free(servers); 481 free(servers);
476 free(req); 482 free(req);
477 freeaddrinfo(ai); 483 freeaddrinfo(addresses);
478 484
479 if (verbose) 485 if (verbose) {
480 printf("overall average offset: %.10g\n", avg_offset); 486 printf("overall average offset: %.10g\n", avg_offset);
487 }
481 return avg_offset; 488 return avg_offset;
482} 489}
483 490
484int process_arguments(int argc, char **argv) { 491check_ntp_time_config_wrapper process_arguments(int argc, char **argv) {
485 static struct option longopts[] = {{"version", no_argument, 0, 'V'}, 492 static struct option longopts[] = {{"version", no_argument, 0, 'V'},
486 {"help", no_argument, 0, 'h'}, 493 {"help", no_argument, 0, 'h'},
487 {"verbose", no_argument, 0, 'v'}, 494 {"verbose", no_argument, 0, 'v'},
@@ -496,14 +503,24 @@ int process_arguments(int argc, char **argv) {
496 {"port", required_argument, 0, 'p'}, 503 {"port", required_argument, 0, 'p'},
497 {0, 0, 0, 0}}; 504 {0, 0, 0, 0}};
498 505
499 if (argc < 2) 506 if (argc < 2) {
500 usage("\n"); 507 usage("\n");
508 }
509
510 check_ntp_time_config_wrapper result = {
511 .errorcode = OK,
512 .config = check_ntp_time_config_init(),
513 };
514
515 char *owarn = "60";
516 char *ocrit = "120";
501 517
502 while (true) { 518 while (true) {
503 int option = 0; 519 int option = 0;
504 int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option); 520 int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option);
505 if (option_char == -1 || option_char == EOF || option_char == 1) 521 if (option_char == -1 || option_char == EOF || option_char == 1) {
506 break; 522 break;
523 }
507 524
508 switch (option_char) { 525 switch (option_char) {
509 case 'h': 526 case 'h':
@@ -518,7 +535,7 @@ int process_arguments(int argc, char **argv) {
518 verbose++; 535 verbose++;
519 break; 536 break;
520 case 'q': 537 case 'q':
521 quiet = true; 538 result.config.quiet = true;
522 break; 539 break;
523 case 'w': 540 case 'w':
524 owarn = optarg; 541 owarn = optarg;
@@ -527,18 +544,19 @@ int process_arguments(int argc, char **argv) {
527 ocrit = optarg; 544 ocrit = optarg;
528 break; 545 break;
529 case 'H': 546 case 'H':
530 if (!is_host(optarg)) 547 if (!is_host(optarg)) {
531 usage2(_("Invalid hostname/address"), optarg); 548 usage2(_("Invalid hostname/address"), optarg);
532 server_address = strdup(optarg); 549 }
550 result.config.server_address = strdup(optarg);
533 break; 551 break;
534 case 'p': 552 case 'p':
535 port = strdup(optarg); 553 result.config.port = strdup(optarg);
536 break; 554 break;
537 case 't': 555 case 't':
538 socket_timeout = atoi(optarg); 556 socket_timeout = atoi(optarg);
539 break; 557 break;
540 case 'o': 558 case 'o':
541 time_offset = atoi(optarg); 559 result.config.time_offset = atoi(optarg);
542 break; 560 break;
543 case '4': 561 case '4':
544 address_family = AF_INET; 562 address_family = AF_INET;
@@ -557,14 +575,16 @@ int process_arguments(int argc, char **argv) {
557 } 575 }
558 } 576 }
559 577
560 if (server_address == NULL) { 578 if (result.config.server_address == NULL) {
561 usage4(_("Hostname was not supplied")); 579 usage4(_("Hostname was not supplied"));
562 } 580 }
563 581
564 return 0; 582 set_thresholds(&result.config.offset_thresholds, owarn, ocrit);
583
584 return result;
565} 585}
566 586
567char *perfd_offset(double offset) { 587char *perfd_offset(double offset, thresholds *offset_thresholds) {
568 return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false, 588 return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false,
569 0); 589 0);
570} 590}
@@ -577,10 +597,13 @@ int main(int argc, char *argv[]) {
577 /* Parse extra opts if any */ 597 /* Parse extra opts if any */
578 argv = np_extra_opts(&argc, argv, progname); 598 argv = np_extra_opts(&argc, argv, progname);
579 599
580 if (process_arguments(argc, argv) == ERROR) 600 check_ntp_time_config_wrapper tmp_config = process_arguments(argc, argv);
601
602 if (tmp_config.errorcode == ERROR) {
581 usage4(_("Could not parse arguments")); 603 usage4(_("Could not parse arguments"));
604 }
582 605
583 set_thresholds(&offset_thresholds, owarn, ocrit); 606 const check_ntp_time_config config = tmp_config.config;
584 607
585 /* initialize alarm signal handling */ 608 /* initialize alarm signal handling */
586 signal(SIGALRM, socket_timeout_alarm_handler); 609 signal(SIGALRM, socket_timeout_alarm_handler);
@@ -588,13 +611,13 @@ int main(int argc, char *argv[]) {
588 /* set socket timeout */ 611 /* set socket timeout */
589 alarm(socket_timeout); 612 alarm(socket_timeout);
590 613
591 int offset_result = STATE_OK; 614 mp_state_enum offset_result = STATE_OK;
592 int result = STATE_OK; 615 mp_state_enum result = STATE_OK;
593 double offset = offset_request(server_address, &offset_result); 616 double offset = offset_request(config.server_address, config.port, &offset_result, config.time_offset);
594 if (offset_result == STATE_UNKNOWN) { 617 if (offset_result == STATE_UNKNOWN) {
595 result = ((!quiet) ? STATE_UNKNOWN : STATE_CRITICAL); 618 result = ((!config.quiet) ? STATE_UNKNOWN : STATE_CRITICAL);
596 } else { 619 } else {
597 result = get_status(fabs(offset), offset_thresholds); 620 result = get_status(fabs(offset), config.offset_thresholds);
598 } 621 }
599 622
600 char *result_line; 623 char *result_line;
@@ -619,13 +642,14 @@ int main(int argc, char *argv[]) {
619 xasprintf(&perfdata_line, ""); 642 xasprintf(&perfdata_line, "");
620 } else { 643 } else {
621 xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); 644 xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset);
622 xasprintf(&perfdata_line, "%s", perfd_offset(offset)); 645 xasprintf(&perfdata_line, "%s", perfd_offset(offset, config.offset_thresholds));
623 } 646 }
624 printf("%s|%s\n", result_line, perfdata_line); 647 printf("%s|%s\n", result_line, perfdata_line);
625 648
626 if (server_address != NULL) 649 if (config.server_address != NULL) {
627 free(server_address); 650 free(config.server_address);
628 return result; 651 }
652 exit(result);
629} 653}
630 654
631void print_help(void) { 655void print_help(void) {
diff --git a/plugins/check_ntp_time.d/config.h b/plugins/check_ntp_time.d/config.h
new file mode 100644
index 00000000..99dabbbd
--- /dev/null
+++ b/plugins/check_ntp_time.d/config.h
@@ -0,0 +1,28 @@
1#pragma once
2
3#include "../../config.h"
4#include "thresholds.h"
5#include <stddef.h>
6
7typedef struct {
8 char *server_address;
9 char *port;
10
11 bool quiet;
12 int time_offset;
13
14 thresholds *offset_thresholds;
15} check_ntp_time_config;
16
17check_ntp_time_config check_ntp_time_config_init() {
18 check_ntp_time_config tmp = {
19 .server_address = NULL,
20 .port = "123",
21
22 .quiet = false,
23 .time_offset = 0,
24
25 .offset_thresholds = NULL,
26 };
27 return tmp;
28}
diff --git a/plugins/check_overcr.c b/plugins/check_overcr.c
deleted file mode 100644
index 599540b7..00000000
--- a/plugins/check_overcr.c
+++ /dev/null
@@ -1,417 +0,0 @@
1/*****************************************************************************
2 *
3 * Monitoring check_overcr plugin
4 *
5 * License: GPL
6 * Copyright (c) 2000-2024 Monitoring Plugins Development Team
7 *
8 * Description:
9 *
10 * This file contains the check_overcr plugin
11 *
12 * This plugin attempts to contact the Over-CR collector daemon running on the
13 * remote UNIX server in order to gather the requested system information.
14 *
15 *
16 * This program is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 *
29 *
30 *****************************************************************************/
31
32const char *progname = "check_overcr";
33const char *copyright = "2000-2024";
34const char *email = "devel@monitoring-plugins.org";
35
36#include "common.h"
37#include "netutils.h"
38#include "utils.h"
39
40enum checkvar {
41 NONE,
42 LOAD1,
43 LOAD5,
44 LOAD15,
45 DPU,
46 PROCS,
47 NETSTAT,
48 UPTIME
49};
50
51enum {
52 PORT = 2000
53};
54
55static char *server_address = NULL;
56static int server_port = PORT;
57static double warning_value = 0L;
58static double critical_value = 0L;
59static bool check_warning_value = false;
60static bool check_critical_value = false;
61static enum checkvar vars_to_check = NONE;
62
63static int netstat_port = 0;
64static char *disk_name = NULL;
65static char *process_name = NULL;
66static char send_buffer[MAX_INPUT_BUFFER];
67
68static int process_arguments(int, char **);
69void print_usage(void);
70static void print_help(void);
71
72int main(int argc, char **argv) {
73 int result = STATE_UNKNOWN;
74 char recv_buffer[MAX_INPUT_BUFFER];
75 char temp_buffer[MAX_INPUT_BUFFER];
76 char *temp_ptr = NULL;
77 bool found_disk = false;
78 unsigned long percent_used_disk_space = 100;
79 double load;
80 double load_1min;
81 double load_5min;
82 double load_15min;
83 int port_connections = 0;
84 int processes = 0;
85 double uptime_raw_hours;
86 int uptime_raw_minutes = 0;
87 int uptime_days = 0;
88 int uptime_hours = 0;
89 int uptime_minutes = 0;
90
91 setlocale(LC_ALL, "");
92 bindtextdomain(PACKAGE, LOCALEDIR);
93 textdomain(PACKAGE);
94
95 /* Parse extra opts if any */
96 argv = np_extra_opts(&argc, argv, progname);
97
98 if (process_arguments(argc, argv) == ERROR)
99 usage4(_("Could not parse arguments"));
100
101 /* initialize alarm signal handling */
102 signal(SIGALRM, socket_timeout_alarm_handler);
103
104 /* set socket timeout */
105 alarm(socket_timeout);
106
107 result = process_tcp_request2(server_address, server_port, send_buffer, recv_buffer, sizeof(recv_buffer));
108
109 switch (vars_to_check) {
110
111 case LOAD1:
112 case LOAD5:
113 case LOAD15:
114
115 if (result != STATE_OK)
116 die(result, _("Unknown error fetching load data\n"));
117
118 temp_ptr = (char *)strtok(recv_buffer, "\r\n");
119 if (temp_ptr == NULL)
120 die(STATE_CRITICAL, _("Invalid response from server - no load information\n"));
121 else
122 load_1min = strtod(temp_ptr, NULL);
123
124 temp_ptr = (char *)strtok(NULL, "\r\n");
125 if (temp_ptr == NULL)
126 die(STATE_CRITICAL, _("Invalid response from server after load 1\n"));
127 else
128 load_5min = strtod(temp_ptr, NULL);
129
130 temp_ptr = (char *)strtok(NULL, "\r\n");
131 if (temp_ptr == NULL)
132 die(STATE_CRITICAL, _("Invalid response from server after load 5\n"));
133 else
134 load_15min = strtod(temp_ptr, NULL);
135
136 switch (vars_to_check) {
137 case LOAD1:
138 strcpy(temp_buffer, "1");
139 load = load_1min;
140 break;
141 case LOAD5:
142 strcpy(temp_buffer, "5");
143 load = load_5min;
144 break;
145 default:
146 strcpy(temp_buffer, "15");
147 load = load_15min;
148 break;
149 }
150
151 if (check_critical_value && (load >= critical_value))
152 result = STATE_CRITICAL;
153 else if (check_warning_value && (load >= warning_value))
154 result = STATE_WARNING;
155
156 die(result, _("Load %s - %s-min load average = %0.2f"), state_text(result), temp_buffer, load);
157
158 break;
159
160 case DPU:
161
162 if (result != STATE_OK)
163 die(result, _("Unknown error fetching disk data\n"));
164
165 for (temp_ptr = (char *)strtok(recv_buffer, " "); temp_ptr != NULL; temp_ptr = (char *)strtok(NULL, " ")) {
166
167 if (!strcmp(temp_ptr, disk_name)) {
168 found_disk = true;
169 temp_ptr = (char *)strtok(NULL, "%");
170 if (temp_ptr == NULL)
171 die(STATE_CRITICAL, _("Invalid response from server\n"));
172 else
173 percent_used_disk_space = strtoul(temp_ptr, NULL, 10);
174 break;
175 }
176
177 temp_ptr = (char *)strtok(NULL, "\r\n");
178 }
179
180 /* error if we couldn't find the info for the disk */
181 if (!found_disk)
182 die(STATE_CRITICAL, "CRITICAL - Disk '%s' non-existent or not mounted", disk_name);
183
184 if (check_critical_value && (percent_used_disk_space >= critical_value))
185 result = STATE_CRITICAL;
186 else if (check_warning_value && (percent_used_disk_space >= warning_value))
187 result = STATE_WARNING;
188
189 die(result, "Disk %s - %lu%% used on %s", state_text(result), percent_used_disk_space, disk_name);
190
191 break;
192
193 case NETSTAT:
194
195 if (result != STATE_OK)
196 die(result, _("Unknown error fetching network status\n"));
197 else
198 port_connections = strtod(recv_buffer, NULL);
199
200 if (check_critical_value && (port_connections >= critical_value))
201 result = STATE_CRITICAL;
202 else if (check_warning_value && (port_connections >= warning_value))
203 result = STATE_WARNING;
204
205 die(result, _("Net %s - %d connection%s on port %d"), state_text(result), port_connections, (port_connections == 1) ? "" : "s",
206 netstat_port);
207
208 break;
209
210 case PROCS:
211
212 if (result != STATE_OK)
213 die(result, _("Unknown error fetching process status\n"));
214
215 temp_ptr = (char *)strtok(recv_buffer, "(");
216 if (temp_ptr == NULL)
217 die(STATE_CRITICAL, _("Invalid response from server\n"));
218
219 temp_ptr = (char *)strtok(NULL, ")");
220 if (temp_ptr == NULL)
221 die(STATE_CRITICAL, _("Invalid response from server\n"));
222 else
223 processes = strtod(temp_ptr, NULL);
224
225 if (check_critical_value && (processes >= critical_value))
226 result = STATE_CRITICAL;
227 else if (check_warning_value && (processes >= warning_value))
228 result = STATE_WARNING;
229
230 die(result, _("Process %s - %d instance%s of %s running"), state_text(result), processes, (processes == 1) ? "" : "s",
231 process_name);
232 break;
233
234 case UPTIME:
235
236 if (result != STATE_OK)
237 return result;
238
239 uptime_raw_hours = strtod(recv_buffer, NULL);
240 uptime_raw_minutes = (unsigned long)(uptime_raw_hours * 60.0);
241
242 if (check_critical_value && (uptime_raw_minutes <= critical_value))
243 result = STATE_CRITICAL;
244 else if (check_warning_value && (uptime_raw_minutes <= warning_value))
245 result = STATE_WARNING;
246
247 uptime_days = uptime_raw_minutes / 1440;
248 uptime_raw_minutes %= 1440;
249 uptime_hours = uptime_raw_minutes / 60;
250 uptime_raw_minutes %= 60;
251 uptime_minutes = uptime_raw_minutes;
252
253 die(result, _("Uptime %s - Up %d days %d hours %d minutes"), state_text(result), uptime_days, uptime_hours, uptime_minutes);
254 break;
255
256 default:
257 die(STATE_UNKNOWN, _("Nothing to check!\n"));
258 break;
259 }
260}
261
262/* process command-line arguments */
263int process_arguments(int argc, char **argv) {
264 int c;
265
266 int option = 0;
267 static struct option longopts[] = {
268 {"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'},
269 {"warning", required_argument, 0, 'w'}, {"variable", required_argument, 0, 'v'}, {"hostname", required_argument, 0, 'H'},
270 {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
271
272 /* no options were supplied */
273 if (argc < 2)
274 return ERROR;
275
276 /* backwards compatibility */
277 if (!is_option(argv[1])) {
278 server_address = argv[1];
279 argv[1] = argv[0];
280 argv = &argv[1];
281 argc--;
282 }
283
284 for (c = 1; c < argc; c++) {
285 if (strcmp("-to", argv[c]) == 0)
286 strcpy(argv[c], "-t");
287 else if (strcmp("-wv", argv[c]) == 0)
288 strcpy(argv[c], "-w");
289 else if (strcmp("-cv", argv[c]) == 0)
290 strcpy(argv[c], "-c");
291 }
292
293 while (1) {
294 c = getopt_long(argc, argv, "+hVH:t:c:w:p:v:", longopts, &option);
295
296 if (c == -1 || c == EOF || c == 1)
297 break;
298
299 switch (c) {
300 case '?': /* print short usage statement if args not parsable */
301 usage5();
302 case 'h': /* help */
303 print_help();
304 exit(STATE_UNKNOWN);
305 case 'V': /* version */
306 print_revision(progname, NP_VERSION);
307 exit(STATE_UNKNOWN);
308 case 'H': /* hostname */
309 server_address = optarg;
310 break;
311 case 'p': /* port */
312 if (is_intnonneg(optarg))
313 server_port = atoi(optarg);
314 else
315 die(STATE_UNKNOWN, _("Server port an integer\n"));
316 break;
317 case 'v': /* variable */
318 if (strcmp(optarg, "LOAD") == 0) {
319 strcpy(send_buffer, "LOAD\r\nQUIT\r\n");
320 if (strcmp(optarg, "LOAD1") == 0)
321 vars_to_check = LOAD1;
322 else if (strcmp(optarg, "LOAD5") == 0)
323 vars_to_check = LOAD5;
324 else if (strcmp(optarg, "LOAD15") == 0)
325 vars_to_check = LOAD15;
326 } else if (strcmp(optarg, "UPTIME") == 0) {
327 vars_to_check = UPTIME;
328 strcpy(send_buffer, "UPTIME\r\n");
329 } else if (strstr(optarg, "PROC") == optarg) {
330 vars_to_check = PROCS;
331 process_name = strscpy(process_name, optarg + 4);
332 sprintf(send_buffer, "PROCESS %s\r\n", process_name);
333 } else if (strstr(optarg, "NET") == optarg) {
334 vars_to_check = NETSTAT;
335 netstat_port = atoi(optarg + 3);
336 sprintf(send_buffer, "NETSTAT %d\r\n", netstat_port);
337 } else if (strstr(optarg, "DPU") == optarg) {
338 vars_to_check = DPU;
339 strcpy(send_buffer, "DISKSPACE\r\n");
340 disk_name = strscpy(disk_name, optarg + 3);
341 } else
342 return ERROR;
343 break;
344 case 'w': /* warning threshold */
345 warning_value = strtoul(optarg, NULL, 10);
346 check_warning_value = true;
347 break;
348 case 'c': /* critical threshold */
349 critical_value = strtoul(optarg, NULL, 10);
350 check_critical_value = true;
351 break;
352 case 't': /* timeout */
353 socket_timeout = atoi(optarg);
354 if (socket_timeout <= 0)
355 return ERROR;
356 }
357 }
358 return OK;
359}
360
361void print_help(void) {
362 char *myport;
363 xasprintf(&myport, "%d", PORT);
364
365 print_revision(progname, NP_VERSION);
366
367 printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
368 printf(COPYRIGHT, copyright, email);
369
370 printf("%s\n", _("This plugin attempts to contact the Over-CR collector daemon running on the"));
371 printf("%s\n", _("remote UNIX server in order to gather the requested system information."));
372
373 printf("\n\n");
374
375 print_usage();
376
377 printf(UT_HELP_VRSN);
378 printf(UT_EXTRA_OPTS);
379
380 printf(UT_HOST_PORT, 'p', myport);
381
382 printf(" %s\n", "-w, --warning=INTEGER");
383 printf(" %s\n", _("Threshold which will result in a warning status"));
384 printf(" %s\n", "-c, --critical=INTEGER");
385 printf(" %s\n", _("Threshold which will result in a critical status"));
386 printf(" %s\n", "-v, --variable=STRING");
387 printf(" %s\n", _("Variable to check. Valid variables include:"));
388 printf(" %s\n", _("LOAD1 = 1 minute average CPU load"));
389 printf(" %s\n", _("LOAD5 = 5 minute average CPU load"));
390 printf(" %s\n", _("LOAD15 = 15 minute average CPU load"));
391 printf(" %s\n", _("DPU<filesys> = percent used disk space on filesystem <filesys>"));
392 printf(" %s\n", _("PROC<process> = number of running processes with name <process>"));
393 printf(" %s\n", _("NET<port> = number of active connections on TCP port <port>"));
394 printf(" %s\n", _("UPTIME = system uptime in seconds"));
395
396 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
397
398 printf(UT_VERBOSE);
399
400 printf("\n");
401 printf("%s\n", _("This plugin requires that Eric Molitors' Over-CR collector daemon be"));
402 printf("%s\n", _("running on the remote server."));
403 printf("%s\n", _("Over-CR can be downloaded from http://www.molitor.org/overcr"));
404 printf("%s\n", _("This plugin was tested with version 0.99.53 of the Over-CR collector"));
405
406 printf("\n");
407 printf("%s\n", _("Notes:"));
408 printf(" %s\n", _("For the available options, the critical threshold value should always be"));
409 printf(" %s\n", _("higher than the warning threshold value, EXCEPT with the uptime variable"));
410
411 printf(UT_SUPPORT);
412}
413
414void print_usage(void) {
415 printf("%s\n", _("Usage:"));
416 printf("%s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", progname);
417}
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 6613634d..84305adb 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -28,6 +28,7 @@
28 * 28 *
29 *****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "states.h"
31const char *progname = "check_pgsql"; 32const char *progname = "check_pgsql";
32const char *copyright = "1999-2024"; 33const char *copyright = "1999-2024";
33const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
@@ -35,12 +36,13 @@ const char *email = "devel@monitoring-plugins.org";
35#include "common.h" 36#include "common.h"
36#include "utils.h" 37#include "utils.h"
37#include "utils_cmd.h" 38#include "utils_cmd.h"
39#include "check_pgsql.d/config.h"
40#include "thresholds.h"
38 41
39#include "netutils.h" 42#include "netutils.h"
40#include <libpq-fe.h> 43#include <libpq-fe.h>
41#include <pg_config_manual.h> 44#include <pg_config_manual.h>
42 45
43#define DEFAULT_DB "template1"
44#define DEFAULT_HOST "127.0.0.1" 46#define DEFAULT_HOST "127.0.0.1"
45 47
46/* return the PSQL server version as a 3-tuple */ 48/* return the PSQL server version as a 3-tuple */
@@ -53,33 +55,18 @@ const char *email = "devel@monitoring-plugins.org";
53#define PSQL_SOCKET3(host, port) \ 55#define PSQL_SOCKET3(host, port) \
54 ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port 56 ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port
55 57
56enum { 58typedef struct {
57 DEFAULT_PORT = 5432, 59 int errorcode;
58 DEFAULT_WARN = 2, 60 check_pgsql_config config;
59 DEFAULT_CRIT = 8 61} check_pgsql_config_wrapper;
60}; 62static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
61 63
62static int process_arguments(int /*argc*/, char ** /*argv*/);
63static void print_help(void); 64static void print_help(void);
64static bool is_pg_logname(char * /*username*/); 65static bool is_pg_logname(char * /*username*/);
65static int do_query(PGconn * /*conn*/, char * /*query*/); 66static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char /*pgqueryname*/[], thresholds * /*qthresholds*/,
67 char * /*query_warning*/, char * /*query_critical*/);
66void print_usage(void); 68void print_usage(void);
67 69
68static char *pghost = NULL; /* host name of the backend server */
69static char *pgport = NULL; /* port of the backend server */
70static char *pgoptions = NULL;
71static char *pgtty = NULL;
72static char dbName[NAMEDATALEN] = DEFAULT_DB;
73static char *pguser = NULL;
74static char *pgpasswd = NULL;
75static char *pgparams = NULL;
76static double twarn = (double)DEFAULT_WARN;
77static double tcrit = (double)DEFAULT_CRIT;
78static char *pgquery = NULL;
79static char *pgqueryname = NULL;
80static char *query_warning = NULL;
81static char *query_critical = NULL;
82static thresholds *qthresholds = NULL;
83static int verbose = 0; 70static int verbose = 0;
84 71
85#define OPTID_QUERYNAME -1000 72#define OPTID_QUERYNAME -1000
@@ -139,21 +126,19 @@ int main(int argc, char **argv) {
139 bindtextdomain(PACKAGE, LOCALEDIR); 126 bindtextdomain(PACKAGE, LOCALEDIR);
140 textdomain(PACKAGE); 127 textdomain(PACKAGE);
141 128
142 /* begin, by setting the parameters for a backend connection if the
143 * parameters are null, then the system will try to use reasonable
144 * defaults by looking up environment variables or, failing that,
145 * using hardwired constants */
146
147 pgoptions = NULL; /* special options to start up the backend server */
148 pgtty = NULL; /* debugging tty for the backend server */
149
150 /* Parse extra opts if any */ 129 /* Parse extra opts if any */
151 argv = np_extra_opts(&argc, argv, progname); 130 argv = np_extra_opts(&argc, argv, progname);
152 131
153 if (process_arguments(argc, argv) == ERROR) 132 check_pgsql_config_wrapper tmp_config = process_arguments(argc, argv);
133 if (tmp_config.errorcode == ERROR) {
154 usage4(_("Could not parse arguments")); 134 usage4(_("Could not parse arguments"));
155 if (verbose > 2) 135 }
136
137 const check_pgsql_config config = tmp_config.config;
138
139 if (verbose > 2) {
156 printf("Arguments initialized\n"); 140 printf("Arguments initialized\n");
141 }
157 142
158 /* Set signal handling and alarm */ 143 /* Set signal handling and alarm */
159 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { 144 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
@@ -162,25 +147,32 @@ int main(int argc, char **argv) {
162 alarm(timeout_interval); 147 alarm(timeout_interval);
163 148
164 char *conninfo = NULL; 149 char *conninfo = NULL;
165 if (pgparams) 150 if (config.pgparams) {
166 asprintf(&conninfo, "%s ", pgparams); 151 asprintf(&conninfo, "%s ", config.pgparams);
167 152 }
168 asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", dbName); 153
169 if (pghost) 154 asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", config.dbName);
170 asprintf(&conninfo, "%s host = '%s'", conninfo, pghost); 155 if (config.pghost) {
171 if (pgport) 156 asprintf(&conninfo, "%s host = '%s'", conninfo, config.pghost);
172 asprintf(&conninfo, "%s port = '%s'", conninfo, pgport); 157 }
173 if (pgoptions) 158 if (config.pgport) {
174 asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions); 159 asprintf(&conninfo, "%s port = '%s'", conninfo, config.pgport);
160 }
161 if (config.pgoptions) {
162 asprintf(&conninfo, "%s options = '%s'", conninfo, config.pgoptions);
163 }
175 /* if (pgtty) -- ignored by PQconnectdb */ 164 /* if (pgtty) -- ignored by PQconnectdb */
176 if (pguser) 165 if (config.pguser) {
177 asprintf(&conninfo, "%s user = '%s'", conninfo, pguser); 166 asprintf(&conninfo, "%s user = '%s'", conninfo, config.pguser);
167 }
178 168
179 if (verbose) /* do not include password (see right below) in output */ 169 if (verbose) { /* do not include password (see right below) in output */
180 printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, pgpasswd ? " password = <hidden>" : ""); 170 printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, config.pgpasswd ? " password = <hidden>" : "");
171 }
181 172
182 if (pgpasswd) 173 if (config.pgpasswd) {
183 asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd); 174 asprintf(&conninfo, "%s password = '%s'", conninfo, config.pgpasswd);
175 }
184 176
185 /* make a connection to the database */ 177 /* make a connection to the database */
186 struct timeval start_timeval; 178 struct timeval start_timeval;
@@ -194,24 +186,26 @@ int main(int argc, char **argv) {
194 end_timeval.tv_usec += 1000000; 186 end_timeval.tv_usec += 1000000;
195 } 187 }
196 double elapsed_time = 188 double elapsed_time =
197 (double)(end_timeval.tv_sec - start_timeval.tv_sec) + (double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0; 189 (double)(end_timeval.tv_sec - start_timeval.tv_sec) + ((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0);
198 190
199 if (verbose) 191 if (verbose) {
200 printf("Time elapsed: %f\n", elapsed_time); 192 printf("Time elapsed: %f\n", elapsed_time);
193 }
201 194
202 /* check to see that the backend connection was successfully made */ 195 /* check to see that the backend connection was successfully made */
203 if (verbose) 196 if (verbose) {
204 printf("Verifying connection\n"); 197 printf("Verifying connection\n");
198 }
205 if (PQstatus(conn) == CONNECTION_BAD) { 199 if (PQstatus(conn) == CONNECTION_BAD) {
206 printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, PQerrorMessage(conn)); 200 printf(_("CRITICAL - no connection to '%s' (%s).\n"), config.dbName, PQerrorMessage(conn));
207 PQfinish(conn); 201 PQfinish(conn);
208 return STATE_CRITICAL; 202 return STATE_CRITICAL;
209 } 203 }
210 204
211 int status = STATE_UNKNOWN; 205 mp_state_enum status = STATE_UNKNOWN;
212 if (elapsed_time > tcrit) { 206 if (elapsed_time > config.tcrit) {
213 status = STATE_CRITICAL; 207 status = STATE_CRITICAL;
214 } else if (elapsed_time > twarn) { 208 } else if (elapsed_time > config.twarn) {
215 status = STATE_WARNING; 209 status = STATE_WARNING;
216 } else { 210 } else {
217 status = STATE_OK; 211 status = STATE_OK;
@@ -228,21 +222,23 @@ int main(int argc, char **argv) {
228 PQprotocolVersion(conn), PQbackendPID(conn)); 222 PQprotocolVersion(conn), PQbackendPID(conn));
229 } 223 }
230 224
231 printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), dbName, elapsed_time, 225 printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), config.dbName, elapsed_time,
232 fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, !!(tcrit > 0.0), tcrit, true, 0, false, 0)); 226 fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), config.twarn, (config.tcrit > 0.0), config.tcrit, true, 0, false, 0));
233 227
234 int query_status = STATE_UNKNOWN; 228 mp_state_enum query_status = STATE_UNKNOWN;
235 if (pgquery) 229 if (config.pgquery) {
236 query_status = do_query(conn, pgquery); 230 query_status = do_query(conn, config.pgquery, config.pgqueryname, config.qthresholds, config.query_warning, config.query_critical);
231 }
237 232
238 if (verbose) 233 if (verbose) {
239 printf("Closing connection\n"); 234 printf("Closing connection\n");
235 }
240 PQfinish(conn); 236 PQfinish(conn);
241 return (pgquery && query_status > status) ? query_status : status; 237 return (config.pgquery && query_status > status) ? query_status : status;
242} 238}
243 239
244/* process command-line arguments */ 240/* process command-line arguments */
245int process_arguments(int argc, char **argv) { 241check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
246 static struct option longopts[] = {{"help", no_argument, 0, 'h'}, 242 static struct option longopts[] = {{"help", no_argument, 0, 'h'},
247 {"version", no_argument, 0, 'V'}, 243 {"version", no_argument, 0, 'V'},
248 {"timeout", required_argument, 0, 't'}, 244 {"timeout", required_argument, 0, 't'},
@@ -262,12 +258,18 @@ int process_arguments(int argc, char **argv) {
262 {"verbose", no_argument, 0, 'v'}, 258 {"verbose", no_argument, 0, 'v'},
263 {0, 0, 0, 0}}; 259 {0, 0, 0, 0}};
264 260
261 check_pgsql_config_wrapper result = {
262 .errorcode = OK,
263 .config = check_pgsql_config_init(),
264 };
265
265 while (true) { 266 while (true) {
266 int option = 0; 267 int option = 0;
267 int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option); 268 int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option);
268 269
269 if (option_char == EOF) 270 if (option_char == EOF) {
270 break; 271 break;
272 }
271 273
272 switch (option_char) { 274 switch (option_char) {
273 case '?': /* usage */ 275 case '?': /* usage */
@@ -279,68 +281,75 @@ int process_arguments(int argc, char **argv) {
279 print_revision(progname, NP_VERSION); 281 print_revision(progname, NP_VERSION);
280 exit(STATE_UNKNOWN); 282 exit(STATE_UNKNOWN);
281 case 't': /* timeout period */ 283 case 't': /* timeout period */
282 if (!is_integer(optarg)) 284 if (!is_integer(optarg)) {
283 usage2(_("Timeout interval must be a positive integer"), optarg); 285 usage2(_("Timeout interval must be a positive integer"), optarg);
284 else 286 } else {
285 timeout_interval = atoi(optarg); 287 timeout_interval = atoi(optarg);
288 }
286 break; 289 break;
287 case 'c': /* critical time threshold */ 290 case 'c': /* critical time threshold */
288 if (!is_nonnegative(optarg)) 291 if (!is_nonnegative(optarg)) {
289 usage2(_("Critical threshold must be a positive integer"), optarg); 292 usage2(_("Critical threshold must be a positive integer"), optarg);
290 else 293 } else {
291 tcrit = strtod(optarg, NULL); 294 result.config.tcrit = strtod(optarg, NULL);
295 }
292 break; 296 break;
293 case 'w': /* warning time threshold */ 297 case 'w': /* warning time threshold */
294 if (!is_nonnegative(optarg)) 298 if (!is_nonnegative(optarg)) {
295 usage2(_("Warning threshold must be a positive integer"), optarg); 299 usage2(_("Warning threshold must be a positive integer"), optarg);
296 else 300 } else {
297 twarn = strtod(optarg, NULL); 301 result.config.twarn = strtod(optarg, NULL);
302 }
298 break; 303 break;
299 case 'C': /* critical query threshold */ 304 case 'C': /* critical query threshold */
300 query_critical = optarg; 305 result.config.query_critical = optarg;
301 break; 306 break;
302 case 'W': /* warning query threshold */ 307 case 'W': /* warning query threshold */
303 query_warning = optarg; 308 result.config.query_warning = optarg;
304 break; 309 break;
305 case 'H': /* host */ 310 case 'H': /* host */
306 if ((*optarg != '/') && (!is_host(optarg))) 311 if ((*optarg != '/') && (!is_host(optarg))) {
307 usage2(_("Invalid hostname/address"), optarg); 312 usage2(_("Invalid hostname/address"), optarg);
308 else 313 } else {
309 pghost = optarg; 314 result.config.pghost = optarg;
315 }
310 break; 316 break;
311 case 'P': /* port */ 317 case 'P': /* port */
312 if (!is_integer(optarg)) 318 if (!is_integer(optarg)) {
313 usage2(_("Port must be a positive integer"), optarg); 319 usage2(_("Port must be a positive integer"), optarg);
314 else 320 } else {
315 pgport = optarg; 321 result.config.pgport = optarg;
322 }
316 break; 323 break;
317 case 'd': /* database name */ 324 case 'd': /* database name */
318 if (strlen(optarg) >= NAMEDATALEN) { 325 if (strlen(optarg) >= NAMEDATALEN) {
319 usage2(_("Database name exceeds the maximum length"), optarg); 326 usage2(_("Database name exceeds the maximum length"), optarg);
320 } 327 }
321 snprintf(dbName, NAMEDATALEN, "%s", optarg); 328 snprintf(result.config.dbName, NAMEDATALEN, "%s", optarg);
322 break; 329 break;
323 case 'l': /* login name */ 330 case 'l': /* login name */
324 if (!is_pg_logname(optarg)) 331 if (!is_pg_logname(optarg)) {
325 usage2(_("User name is not valid"), optarg); 332 usage2(_("User name is not valid"), optarg);
326 else 333 } else {
327 pguser = optarg; 334 result.config.pguser = optarg;
335 }
328 break; 336 break;
329 case 'p': /* authentication password */ 337 case 'p': /* authentication password */
330 case 'a': 338 case 'a':
331 pgpasswd = optarg; 339 result.config.pgpasswd = optarg;
332 break; 340 break;
333 case 'o': 341 case 'o':
334 if (pgparams) 342 if (result.config.pgparams) {
335 asprintf(&pgparams, "%s %s", pgparams, optarg); 343 asprintf(&result.config.pgparams, "%s %s", result.config.pgparams, optarg);
336 else 344 } else {
337 asprintf(&pgparams, "%s", optarg); 345 asprintf(&result.config.pgparams, "%s", optarg);
346 }
338 break; 347 break;
339 case 'q': 348 case 'q':
340 pgquery = optarg; 349 result.config.pgquery = optarg;
341 break; 350 break;
342 case OPTID_QUERYNAME: 351 case OPTID_QUERYNAME:
343 pgqueryname = optarg; 352 result.config.pgqueryname = optarg;
344 break; 353 break;
345 case 'v': 354 case 'v':
346 verbose++; 355 verbose++;
@@ -348,9 +357,9 @@ int process_arguments(int argc, char **argv) {
348 } 357 }
349 } 358 }
350 359
351 set_thresholds(&qthresholds, query_warning, query_critical); 360 set_thresholds(&result.config.qthresholds, result.config.query_warning, result.config.query_critical);
352 361
353 return OK; 362 return result;
354} 363}
355 364
356/** 365/**
@@ -378,8 +387,9 @@ should be added.</para>
378******************************************************************************/ 387******************************************************************************/
379 388
380bool is_pg_logname(char *username) { 389bool is_pg_logname(char *username) {
381 if (strlen(username) > NAMEDATALEN - 1) 390 if (strlen(username) > NAMEDATALEN - 1) {
382 return (false); 391 return (false);
392 }
383 return (true); 393 return (true);
384} 394}
385 395
@@ -394,7 +404,7 @@ bool is_pg_logname(char *username) {
394void print_help(void) { 404void print_help(void) {
395 char *myport; 405 char *myport;
396 406
397 xasprintf(&myport, "%d", DEFAULT_PORT); 407 xasprintf(&myport, "%d", 5432);
398 408
399 print_revision(progname, NP_VERSION); 409 print_revision(progname, NP_VERSION);
400 410
@@ -482,9 +492,11 @@ void print_usage(void) {
482 "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n"); 492 "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n");
483} 493}
484 494
485int do_query(PGconn *conn, char *query) { 495mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thresholds *qthresholds, char *query_warning,
486 if (verbose) 496 char *query_critical) {
497 if (verbose) {
487 printf("Executing SQL query \"%s\".\n", query); 498 printf("Executing SQL query \"%s\".\n", query);
499 }
488 PGresult *res = PQexec(conn, query); 500 PGresult *res = PQexec(conn, query);
489 501
490 if (PGRES_TUPLES_OK != PQresultStatus(res)) { 502 if (PGRES_TUPLES_OK != PQresultStatus(res)) {
@@ -510,8 +522,9 @@ int do_query(PGconn *conn, char *query) {
510 522
511 char *endptr = NULL; 523 char *endptr = NULL;
512 double value = strtod(val_str, &endptr); 524 double value = strtod(val_str, &endptr);
513 if (verbose) 525 if (verbose) {
514 printf("Query result: %f\n", value); 526 printf("Query result: %f\n", value);
527 }
515 528
516 if (endptr == val_str) { 529 if (endptr == val_str) {
517 printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); 530 printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str);
@@ -519,11 +532,12 @@ int do_query(PGconn *conn, char *query) {
519 } 532 }
520 533
521 if ((endptr != NULL) && (*endptr != '\0')) { 534 if ((endptr != NULL) && (*endptr != '\0')) {
522 if (verbose) 535 if (verbose) {
523 printf("Garbage after value: %s.\n", endptr); 536 printf("Garbage after value: %s.\n", endptr);
537 }
524 } 538 }
525 539
526 int my_status = get_status(value, qthresholds); 540 mp_state_enum my_status = get_status(value, qthresholds);
527 printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK") 541 printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK")
528 : (my_status == STATE_WARNING) ? _("WARNING") 542 : (my_status == STATE_WARNING) ? _("WARNING")
529 : (my_status == STATE_CRITICAL) ? _("CRITICAL") 543 : (my_status == STATE_CRITICAL) ? _("CRITICAL")
diff --git a/plugins/check_pgsql.d/config.h b/plugins/check_pgsql.d/config.h
new file mode 100644
index 00000000..2d4b8b89
--- /dev/null
+++ b/plugins/check_pgsql.d/config.h
@@ -0,0 +1,61 @@
1#pragma once
2
3#include "../../config.h"
4#include "thresholds.h"
5#include <stddef.h>
6#include <pg_config_manual.h>
7
8#define DEFAULT_DB "template1"
9
10enum {
11 DEFAULT_WARN = 2,
12 DEFAULT_CRIT = 8,
13};
14
15typedef struct {
16 char *pghost; /* host name of the backend server */
17 char *pgport; /* port of the backend server */
18 char *pgoptions; /* special options to start up the backend server */
19 char *pgtty; /* debugging tty for the backend server */
20 char dbName[NAMEDATALEN];
21 char *pguser;
22 char *pgpasswd;
23 char *pgparams;
24 char *pgquery;
25 char *pgqueryname;
26
27 double twarn;
28 double tcrit;
29 thresholds *qthresholds;
30 char *query_warning;
31 char *query_critical;
32} check_pgsql_config;
33
34/* begin, by setting the parameters for a backend connection if the
35 * parameters are null, then the system will try to use reasonable
36 * defaults by looking up environment variables or, failing that,
37 * using hardwired constants
38 * this targets .pgoptions and .pgtty
39 */
40
41check_pgsql_config check_pgsql_config_init() {
42 check_pgsql_config tmp = {
43 .pghost = NULL,
44 .pgport = NULL,
45 .pgoptions = NULL,
46 .pgtty = NULL,
47 .dbName = DEFAULT_DB,
48 .pguser = NULL,
49 .pgpasswd = NULL,
50 .pgparams = NULL,
51 .pgquery = NULL,
52 .pgqueryname = NULL,
53
54 .twarn = (double)DEFAULT_WARN,
55 .tcrit = (double)DEFAULT_CRIT,
56 .qthresholds = NULL,
57 .query_warning = NULL,
58 .query_critical = NULL,
59 };
60 return tmp;
61}