summaryrefslogtreecommitdiffstats
path: root/plugins/t
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/t')
0 files changed, 0 insertions, 0 deletions
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index 29c8520..0c0ed6d 100644
--- a/plugins/check_dbi.c
+++ b/plugins/check_dbi.c
@@ -1,33 +1,33 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_dbi plugin 3 * Monitoring check_dbi plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2011 Monitoring Plugins Development Team 6 * Copyright (c) 2011 Monitoring Plugins Development Team
7* Author: Sebastian 'tokkee' Harl <sh@teamix.net> 7 * Author: Sebastian 'tokkee' Harl <sh@teamix.net>
8* 8 *
9* Description: 9 * Description:
10* 10 *
11* This file contains the check_dbi plugin 11 * This file contains the check_dbi plugin
12* 12 *
13* Runs an arbitrary (SQL) command and checks the result. 13 * Runs an arbitrary (SQL) command and checks the result.
14* 14 *
15* 15 *
16* This program is free software: you can redistribute it and/or modify 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 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 18 * the Free Software Foundation, either version 3 of the License, or
19* (at your option) any later version. 19 * (at your option) any later version.
20* 20 *
21* This program is distributed in the hope that it will be useful, 21 * This program is distributed in the hope that it will be useful,
22* but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24* GNU General Public License for more details. 24 * GNU General Public License for more details.
25* 25 *
26* You should have received a copy of the GNU General Public License 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/>. 27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28* 28 *
29* 29 *
30*****************************************************************************/ 30 *****************************************************************************/
31 31
32const char *progname = "check_dbi"; 32const char *progname = "check_dbi";
33const char *copyright = "2011"; 33const char *copyright = "2011";
@@ -43,7 +43,7 @@ const char *email = "devel@monitoring-plugins.org";
43 43
44/* required for NAN */ 44/* required for NAN */
45#ifndef _ISOC99_SOURCE 45#ifndef _ISOC99_SOURCE
46#define _ISOC99_SOURCE 46# define _ISOC99_SOURCE
47#endif 47#endif
48 48
49#include <assert.h> 49#include <assert.h>
@@ -92,20 +92,18 @@ int np_dbi_options_num = 0;
92char *np_dbi_database = NULL; 92char *np_dbi_database = NULL;
93char *np_dbi_query = NULL; 93char *np_dbi_query = NULL;
94 94
95int process_arguments (int, char **); 95int process_arguments(int, char **);
96int validate_arguments (void); 96int validate_arguments(void);
97void print_usage (void); 97void print_usage(void);
98void print_help (void); 98void print_help(void);
99 99
100double timediff (struct timeval, struct timeval); 100double timediff(struct timeval, struct timeval);
101 101
102void np_dbi_print_error (dbi_conn, char *, ...); 102void np_dbi_print_error(dbi_conn, char *, ...);
103 103
104int do_query (dbi_conn, const char **, double *, double *); 104int do_query(dbi_conn, const char **, double *, double *);
105 105
106int 106int main(int argc, char **argv) {
107main (int argc, char **argv)
108{
109 int status = STATE_UNKNOWN; 107 int status = STATE_UNKNOWN;
110 108
111 dbi_driver driver; 109 dbi_driver driver;
@@ -122,59 +120,58 @@ main (int argc, char **argv)
122 120
123 int i; 121 int i;
124 122
125 setlocale (LC_ALL, ""); 123 setlocale(LC_ALL, "");
126 bindtextdomain (PACKAGE, LOCALEDIR); 124 bindtextdomain(PACKAGE, LOCALEDIR);
127 textdomain (PACKAGE); 125 textdomain(PACKAGE);
128 126
129 /* Parse extra opts if any */ 127 /* Parse extra opts if any */
130 argv = np_extra_opts (&argc, argv, progname); 128 argv = np_extra_opts(&argc, argv, progname);
131 129
132 if (process_arguments (argc, argv) == ERROR) 130 if (process_arguments(argc, argv) == ERROR)
133 usage4 (_("Could not parse arguments")); 131 usage4(_("Could not parse arguments"));
134 132
135 /* Set signal handling and alarm */ 133 /* Set signal handling and alarm */
136 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 134 if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
137 usage4 (_("Cannot catch SIGALRM")); 135 usage4(_("Cannot catch SIGALRM"));
138 } 136 }
139 alarm (timeout_interval); 137 alarm(timeout_interval);
140 138
141 if (verbose > 2) 139 if (verbose > 2)
142 printf ("Initializing DBI\n"); 140 printf("Initializing DBI\n");
143 141
144 dbi_inst *instance_p = { 0 }; 142 dbi_inst *instance_p = {0};
145 143
146 if (dbi_initialize_r(NULL, instance_p) < 0) { 144 if (dbi_initialize_r(NULL, instance_p) < 0) {
147 printf ("UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n"); 145 printf("UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n");
148 return STATE_UNKNOWN; 146 return STATE_UNKNOWN;
149 } 147 }
150 148
151 if (instance_p == NULL) { 149 if (instance_p == NULL) {
152 printf ("UNKNOWN - failed to initialize DBI.\n"); 150 printf("UNKNOWN - failed to initialize DBI.\n");
153 return STATE_UNKNOWN; 151 return STATE_UNKNOWN;
154 } 152 }
155 153
156 if (verbose) 154 if (verbose)
157 printf ("Opening DBI driver '%s'\n", np_dbi_driver); 155 printf("Opening DBI driver '%s'\n", np_dbi_driver);
158 156
159 driver = dbi_driver_open_r(np_dbi_driver, instance_p); 157 driver = dbi_driver_open_r(np_dbi_driver, instance_p);
160 if (! driver) { 158 if (!driver) {
161 printf ("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", 159 printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", np_dbi_driver);
162 np_dbi_driver);
163 160
164 printf ("Known drivers:\n"); 161 printf("Known drivers:\n");
165 for (driver = dbi_driver_list_r(NULL, instance_p); driver; driver = dbi_driver_list_r(driver, instance_p)) { 162 for (driver = dbi_driver_list_r(NULL, instance_p); driver; driver = dbi_driver_list_r(driver, instance_p)) {
166 printf (" - %s\n", dbi_driver_get_name (driver)); 163 printf(" - %s\n", dbi_driver_get_name(driver));
167 } 164 }
168 return STATE_UNKNOWN; 165 return STATE_UNKNOWN;
169 } 166 }
170 167
171 /* make a connection to the database */ 168 /* make a connection to the database */
172 gettimeofday (&start_timeval, NULL); 169 gettimeofday(&start_timeval, NULL);
173 170
174 conn = dbi_conn_open (driver); 171 conn = dbi_conn_open(driver);
175 if (! conn) { 172 if (!conn) {
176 printf ("UNKNOWN - failed top open connection object.\n"); 173 printf("UNKNOWN - failed top open connection object.\n");
177 dbi_conn_close (conn); 174 dbi_conn_close(conn);
178 return STATE_UNKNOWN; 175 return STATE_UNKNOWN;
179 } 176 }
180 177
@@ -182,210 +179,189 @@ main (int argc, char **argv)
182 const char *opt; 179 const char *opt;
183 180
184 if (verbose > 1) 181 if (verbose > 1)
185 printf ("Setting DBI driver option '%s' to '%s'\n", 182 printf("Setting DBI driver option '%s' to '%s'\n", np_dbi_options[i].key, np_dbi_options[i].value);
186 np_dbi_options[i].key, np_dbi_options[i].value);
187 183
188 if (! dbi_conn_set_option (conn, np_dbi_options[i].key, np_dbi_options[i].value)) 184 if (!dbi_conn_set_option(conn, np_dbi_options[i].key, np_dbi_options[i].value))
189 continue; 185 continue;
190 /* else: status != 0 */ 186 /* else: status != 0 */
191 187
192 np_dbi_print_error (conn, "UNKNOWN - failed to set option '%s' to '%s'", 188 np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", np_dbi_options[i].key, np_dbi_options[i].value);
193 np_dbi_options[i].key, np_dbi_options[i].value); 189 printf("Known driver options:\n");
194 printf ("Known driver options:\n");
195 190
196 for (opt = dbi_conn_get_option_list (conn, NULL); opt; 191 for (opt = dbi_conn_get_option_list(conn, NULL); opt; opt = dbi_conn_get_option_list(conn, opt)) {
197 opt = dbi_conn_get_option_list (conn, opt)) { 192 printf(" - %s\n", opt);
198 printf (" - %s\n", opt);
199 } 193 }
200 dbi_conn_close (conn); 194 dbi_conn_close(conn);
201 return STATE_UNKNOWN; 195 return STATE_UNKNOWN;
202 } 196 }
203 197
204 if (host) { 198 if (host) {
205 if (verbose > 1) 199 if (verbose > 1)
206 printf ("Setting DBI driver option 'host' to '%s'\n", host); 200 printf("Setting DBI driver option 'host' to '%s'\n", host);
207 dbi_conn_set_option (conn, "host", host); 201 dbi_conn_set_option(conn, "host", host);
208 } 202 }
209 203
210 if (verbose) { 204 if (verbose) {
211 const char *dbname, *host; 205 const char *dbname, *host;
212 206
213 dbname = dbi_conn_get_option (conn, "dbname"); 207 dbname = dbi_conn_get_option(conn, "dbname");
214 host = dbi_conn_get_option (conn, "host"); 208 host = dbi_conn_get_option(conn, "host");
215 209
216 if (! dbname) 210 if (!dbname)
217 dbname = "<unspecified>"; 211 dbname = "<unspecified>";
218 if (! host) 212 if (!host)
219 host = "<unspecified>"; 213 host = "<unspecified>";
220 214
221 printf ("Connecting to database '%s' at host '%s'\n", 215 printf("Connecting to database '%s' at host '%s'\n", dbname, host);
222 dbname, host);
223 } 216 }
224 217
225 if (dbi_conn_connect (conn) < 0) { 218 if (dbi_conn_connect(conn) < 0) {
226 np_dbi_print_error (conn, "UNKNOWN - failed to connect to database"); 219 np_dbi_print_error(conn, "UNKNOWN - failed to connect to database");
227 return STATE_UNKNOWN; 220 return STATE_UNKNOWN;
228 } 221 }
229 222
230 gettimeofday (&end_timeval, NULL); 223 gettimeofday(&end_timeval, NULL);
231 conn_time = timediff (start_timeval, end_timeval); 224 conn_time = timediff(start_timeval, end_timeval);
232 225
233 server_version = dbi_conn_get_engine_version (conn); 226 server_version = dbi_conn_get_engine_version(conn);
234 if (verbose) 227 if (verbose)
235 printf ("Connected to server version %u\n", server_version); 228 printf("Connected to server version %u\n", server_version);
236 229
237 if (metric == METRIC_SERVER_VERSION) 230 if (metric == METRIC_SERVER_VERSION)
238 status = get_status (server_version, dbi_thresholds); 231 status = get_status(server_version, dbi_thresholds);
239 232
240 if (verbose) 233 if (verbose)
241 printf ("Time elapsed: %f\n", conn_time); 234 printf("Time elapsed: %f\n", conn_time);
242 235
243 if (metric == METRIC_CONN_TIME) 236 if (metric == METRIC_CONN_TIME)
244 status = get_status (conn_time, dbi_thresholds); 237 status = get_status(conn_time, dbi_thresholds);
245 238
246 /* select a database */ 239 /* select a database */
247 if (np_dbi_database) { 240 if (np_dbi_database) {
248 if (verbose > 1) 241 if (verbose > 1)
249 printf ("Selecting database '%s'\n", np_dbi_database); 242 printf("Selecting database '%s'\n", np_dbi_database);
250 243
251 if (dbi_conn_select_db (conn, np_dbi_database)) { 244 if (dbi_conn_select_db(conn, np_dbi_database)) {
252 np_dbi_print_error (conn, "UNKNOWN - failed to select database '%s'", 245 np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", np_dbi_database);
253 np_dbi_database);
254 return STATE_UNKNOWN; 246 return STATE_UNKNOWN;
255 } 247 }
256 } 248 }
257 249
258 if (np_dbi_query) { 250 if (np_dbi_query) {
259 /* execute query */ 251 /* execute query */
260 status = do_query (conn, &query_val_str, &query_val, &query_time); 252 status = do_query(conn, &query_val_str, &query_val, &query_time);
261 if (status != STATE_OK) 253 if (status != STATE_OK)
262 /* do_query prints an error message in this case */ 254 /* do_query prints an error message in this case */
263 return status; 255 return status;
264 256
265 if (metric == METRIC_QUERY_RESULT) { 257 if (metric == METRIC_QUERY_RESULT) {
266 if (expect) { 258 if (expect) {
267 if ((! query_val_str) || strcmp (query_val_str, expect)) 259 if ((!query_val_str) || strcmp(query_val_str, expect))
268 status = STATE_CRITICAL; 260 status = STATE_CRITICAL;
269 else 261 else
270 status = STATE_OK; 262 status = STATE_OK;
271 } 263 } else if (expect_re_str) {
272 else if (expect_re_str) {
273 int err; 264 int err;
274 265
275 err = regexec (&expect_re, query_val_str, 0, NULL, /* flags = */ 0); 266 err = regexec(&expect_re, query_val_str, 0, NULL, /* flags = */ 0);
276 if (! err) 267 if (!err)
277 status = STATE_OK; 268 status = STATE_OK;
278 else if (err == REG_NOMATCH) 269 else if (err == REG_NOMATCH)
279 status = STATE_CRITICAL; 270 status = STATE_CRITICAL;
280 else { 271 else {
281 char errmsg[1024]; 272 char errmsg[1024];
282 regerror (err, &expect_re, errmsg, sizeof (errmsg)); 273 regerror(err, &expect_re, errmsg, sizeof(errmsg));
283 printf ("ERROR - failed to execute regular expression: %s\n", 274 printf("ERROR - failed to execute regular expression: %s\n", errmsg);
284 errmsg);
285 status = STATE_CRITICAL; 275 status = STATE_CRITICAL;
286 } 276 }
287 } 277 } else
288 else 278 status = get_status(query_val, dbi_thresholds);
289 status = get_status (query_val, dbi_thresholds); 279 } else if (metric == METRIC_QUERY_TIME)
290 } 280 status = get_status(query_time, dbi_thresholds);
291 else if (metric == METRIC_QUERY_TIME)
292 status = get_status (query_time, dbi_thresholds);
293 } 281 }
294 282
295 if (verbose) 283 if (verbose)
296 printf("Closing connection\n"); 284 printf("Closing connection\n");
297 dbi_conn_close (conn); 285 dbi_conn_close(conn);
298 286
299 /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error 287 /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error
300 * which should have been reported and handled (abort) before 288 * which should have been reported and handled (abort) before
301 * ... unless we expected a string to be returned */ 289 * ... unless we expected a string to be returned */
302 assert ((metric != METRIC_QUERY_RESULT) || (! isnan (query_val)) 290 assert((metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (type == TYPE_STRING));
303 || (type == TYPE_STRING));
304 291
305 assert ((type != TYPE_STRING) || (expect || expect_re_str)); 292 assert((type != TYPE_STRING) || (expect || expect_re_str));
306 293
307 printf ("%s - connection time: %fs", state_text (status), conn_time); 294 printf("%s - connection time: %fs", state_text(status), conn_time);
308 if (np_dbi_query) { 295 if (np_dbi_query) {
309 if (type == TYPE_STRING) { 296 if (type == TYPE_STRING) {
310 assert (expect || expect_re_str); 297 assert(expect || expect_re_str);
311 printf (", '%s' returned '%s' in %fs", np_dbi_query, 298 printf(", '%s' returned '%s' in %fs", np_dbi_query, query_val_str ? query_val_str : "<nothing>", query_time);
312 query_val_str ? query_val_str : "<nothing>", query_time);
313 if (status != STATE_OK) { 299 if (status != STATE_OK) {
314 if (expect) 300 if (expect)
315 printf (" (expected '%s')", expect); 301 printf(" (expected '%s')", expect);
316 else if (expect_re_str) 302 else if (expect_re_str)
317 printf (" (expected regex /%s/%s)", expect_re_str, 303 printf(" (expected regex /%s/%s)", expect_re_str, ((expect_re_cflags & REG_ICASE) ? "i" : ""));
318 ((expect_re_cflags & REG_ICASE) ? "i" : ""));
319 } 304 }
320 } 305 } else if (isnan(query_val))
321 else if (isnan (query_val)) 306 printf(", '%s' query execution time: %fs", np_dbi_query, query_time);
322 printf (", '%s' query execution time: %fs", np_dbi_query, query_time);
323 else 307 else
324 printf (", '%s' returned %f in %fs", np_dbi_query, query_val, query_time); 308 printf(", '%s' returned %f in %fs", np_dbi_query, query_val, query_time);
325 } 309 }
326 310
327 printf (" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time, 311 printf(" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time,
328 ((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "", 312 ((metric == METRIC_CONN_TIME) && warning_range) ? warning_range : "",
329 ((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : "", 313 ((metric == METRIC_CONN_TIME) && critical_range) ? critical_range : "", server_version,
330 server_version, 314 ((metric == METRIC_SERVER_VERSION) && warning_range) ? warning_range : "",
331 ((metric == METRIC_SERVER_VERSION) && warning_range) ? warning_range : "", 315 ((metric == METRIC_SERVER_VERSION) && critical_range) ? critical_range : "");
332 ((metric == METRIC_SERVER_VERSION) && critical_range) ? critical_range : "");
333 if (np_dbi_query) { 316 if (np_dbi_query) {
334 if (! isnan (query_val)) /* this is also true when -e is used */ 317 if (!isnan(query_val)) /* this is also true when -e is used */
335 printf (" query=%f;%s;%s;;", query_val, 318 printf(" query=%f;%s;%s;;", query_val, ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "",
336 ((metric == METRIC_QUERY_RESULT) && warning_range) ? warning_range : "", 319 ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : "");
337 ((metric == METRIC_QUERY_RESULT) && critical_range) ? critical_range : ""); 320 printf(" querytime=%fs;%s;%s;0;", query_time, ((metric == METRIC_QUERY_TIME) && warning_range) ? warning_range : "",
338 printf (" querytime=%fs;%s;%s;0;", query_time, 321 ((metric == METRIC_QUERY_TIME) && critical_range) ? critical_range : "");
339 ((metric == METRIC_QUERY_TIME) && warning_range) ? warning_range : "",
340 ((metric == METRIC_QUERY_TIME) && critical_range) ? critical_range : "");
341 } 322 }
342 printf ("\n"); 323 printf("\n");
343 return status; 324 return status;
344} 325}
345 326
346/* process command-line arguments */ 327/* process command-line arguments */
347int 328int process_arguments(int argc, char **argv) {
348process_arguments (int argc, char **argv)
349{
350 int c; 329 int c;
351 330
352 int option = 0; 331 int option = 0;
353 static struct option longopts[] = { 332 static struct option longopts[] = {STD_LONG_OPTS,
354 STD_LONG_OPTS, 333
355 334 {"expect", required_argument, 0, 'e'},
356 {"expect", required_argument, 0, 'e'}, 335 {"regex", required_argument, 0, 'r'},
357 {"regex", required_argument, 0, 'r'}, 336 {"regexi", required_argument, 0, 'R'},
358 {"regexi", required_argument, 0, 'R'}, 337 {"metric", required_argument, 0, 'm'},
359 {"metric", required_argument, 0, 'm'}, 338 {"driver", required_argument, 0, 'd'},
360 {"driver", required_argument, 0, 'd'}, 339 {"option", required_argument, 0, 'o'},
361 {"option", required_argument, 0, 'o'}, 340 {"query", required_argument, 0, 'q'},
362 {"query", required_argument, 0, 'q'}, 341 {"database", required_argument, 0, 'D'},
363 {"database", required_argument, 0, 'D'}, 342 {0, 0, 0, 0}};
364 {0, 0, 0, 0}
365 };
366 343
367 while (1) { 344 while (1) {
368 c = getopt_long (argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", 345 c = getopt_long(argc, argv, "Vvht:c:w:e:r:R:m:H:d:o:q:D:", longopts, &option);
369 longopts, &option);
370 346
371 if (c == EOF) 347 if (c == EOF)
372 break; 348 break;
373 349
374 switch (c) { 350 switch (c) {
375 case '?': /* usage */ 351 case '?': /* usage */
376 usage5 (); 352 usage5();
377 case 'h': /* help */ 353 case 'h': /* help */
378 print_help (); 354 print_help();
379 exit (STATE_UNKNOWN); 355 exit(STATE_UNKNOWN);
380 case 'V': /* version */ 356 case 'V': /* version */
381 print_revision (progname, NP_VERSION); 357 print_revision(progname, NP_VERSION);
382 exit (STATE_UNKNOWN); 358 exit(STATE_UNKNOWN);
383 359
384 case 'c': /* critical range */ 360 case 'c': /* critical range */
385 critical_range = optarg; 361 critical_range = optarg;
386 type = TYPE_NUMERIC; 362 type = TYPE_NUMERIC;
387 break; 363 break;
388 case 'w': /* warning range */ 364 case 'w': /* warning range */
389 warning_range = optarg; 365 warning_range = optarg;
390 type = TYPE_NUMERIC; 366 type = TYPE_NUMERIC;
391 break; 367 break;
@@ -396,47 +372,45 @@ process_arguments (int argc, char **argv)
396 case 'R': 372 case 'R':
397 expect_re_cflags = REG_ICASE; 373 expect_re_cflags = REG_ICASE;
398 /* fall through */ 374 /* fall through */
399 case 'r': 375 case 'r': {
400 { 376 int err;
401 int err;
402 377
403 expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; 378 expect_re_cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
404 expect_re_str = optarg; 379 expect_re_str = optarg;
405 type = TYPE_STRING; 380 type = TYPE_STRING;
406 381
407 err = regcomp (&expect_re, expect_re_str, expect_re_cflags); 382 err = regcomp(&expect_re, expect_re_str, expect_re_cflags);
408 if (err) { 383 if (err) {
409 char errmsg[1024]; 384 char errmsg[1024];
410 regerror (err, &expect_re, errmsg, sizeof (errmsg)); 385 regerror(err, &expect_re, errmsg, sizeof(errmsg));
411 printf ("ERROR - failed to compile regular expression: %s\n", 386 printf("ERROR - failed to compile regular expression: %s\n", errmsg);
412 errmsg); 387 return ERROR;
413 return ERROR;
414 }
415 break;
416 } 388 }
389 break;
390 }
417 391
418 case 'm': 392 case 'm':
419 if (! strcasecmp (optarg, "CONN_TIME")) 393 if (!strcasecmp(optarg, "CONN_TIME"))
420 metric = METRIC_CONN_TIME; 394 metric = METRIC_CONN_TIME;
421 else if (! strcasecmp (optarg, "SERVER_VERSION")) 395 else if (!strcasecmp(optarg, "SERVER_VERSION"))
422 metric = METRIC_SERVER_VERSION; 396 metric = METRIC_SERVER_VERSION;
423 else if (! strcasecmp (optarg, "QUERY_RESULT")) 397 else if (!strcasecmp(optarg, "QUERY_RESULT"))
424 metric = METRIC_QUERY_RESULT; 398 metric = METRIC_QUERY_RESULT;
425 else if (! strcasecmp (optarg, "QUERY_TIME")) 399 else if (!strcasecmp(optarg, "QUERY_TIME"))
426 metric = METRIC_QUERY_TIME; 400 metric = METRIC_QUERY_TIME;
427 else 401 else
428 usage2 (_("Invalid metric"), optarg); 402 usage2(_("Invalid metric"), optarg);
429 break; 403 break;
430 case 't': /* timeout */ 404 case 't': /* timeout */
431 if (!is_intnonneg (optarg)) 405 if (!is_intnonneg(optarg))
432 usage2 (_("Timeout interval must be a positive integer"), optarg); 406 usage2(_("Timeout interval must be a positive integer"), optarg);
433 else 407 else
434 timeout_interval = atoi (optarg); 408 timeout_interval = atoi(optarg);
435 409
436 break; 410 break;
437 case 'H': /* host */ 411 case 'H': /* host */
438 if (!is_host (optarg)) 412 if (!is_host(optarg))
439 usage2 (_("Invalid hostname/address"), optarg); 413 usage2(_("Invalid hostname/address"), optarg);
440 else 414 else
441 host = optarg; 415 host = optarg;
442 break; 416 break;
@@ -447,36 +421,33 @@ process_arguments (int argc, char **argv)
447 case 'd': 421 case 'd':
448 np_dbi_driver = optarg; 422 np_dbi_driver = optarg;
449 break; 423 break;
450 case 'o': 424 case 'o': {
451 { 425 driver_option_t *new;
452 driver_option_t *new;
453 426
454 char *k, *v; 427 char *k, *v;
455 428
456 k = optarg; 429 k = optarg;
457 v = strchr (k, (int)'='); 430 v = strchr(k, (int)'=');
458 431
459 if (! v) 432 if (!v)
460 usage2 (_("Option must be '<key>=<value>'"), optarg); 433 usage2(_("Option must be '<key>=<value>'"), optarg);
461 434
462 *v = '\0'; 435 *v = '\0';
463 ++v; 436 ++v;
464 437
465 new = realloc (np_dbi_options, 438 new = realloc(np_dbi_options, (np_dbi_options_num + 1) * sizeof(*new));
466 (np_dbi_options_num + 1) * sizeof (*new)); 439 if (!new) {
467 if (! new) { 440 printf("UNKNOWN - failed to reallocate memory\n");
468 printf ("UNKNOWN - failed to reallocate memory\n"); 441 exit(STATE_UNKNOWN);
469 exit (STATE_UNKNOWN); 442 }
470 }
471 443
472 np_dbi_options = new; 444 np_dbi_options = new;
473 new = np_dbi_options + np_dbi_options_num; 445 new = np_dbi_options + np_dbi_options_num;
474 ++np_dbi_options_num; 446 ++np_dbi_options_num;
475 447
476 new->key = k; 448 new->key = k;
477 new->value = v; 449 new->value = v;
478 } 450 } break;
479 break;
480 case 'q': 451 case 'q':
481 np_dbi_query = optarg; 452 np_dbi_query = optarg;
482 break; 453 break;
@@ -486,341 +457,312 @@ process_arguments (int argc, char **argv)
486 } 457 }
487 } 458 }
488 459
489 set_thresholds (&dbi_thresholds, warning_range, critical_range); 460 set_thresholds(&dbi_thresholds, warning_range, critical_range);
490 461
491 return validate_arguments (); 462 return validate_arguments();
492} 463}
493 464
494int 465int validate_arguments() {
495validate_arguments () 466 if (!np_dbi_driver)
496{ 467 usage("Must specify a DBI driver");
497 if (! np_dbi_driver)
498 usage ("Must specify a DBI driver");
499 468
500 if (((metric == METRIC_QUERY_RESULT) || (metric == METRIC_QUERY_TIME)) 469 if (((metric == METRIC_QUERY_RESULT) || (metric == METRIC_QUERY_TIME)) && (!np_dbi_query))
501 && (! np_dbi_query)) 470 usage("Must specify a query to execute (metric == QUERY_RESULT)");
502 usage ("Must specify a query to execute (metric == QUERY_RESULT)");
503 471
504 if ((metric != METRIC_CONN_TIME) 472 if ((metric != METRIC_CONN_TIME) && (metric != METRIC_SERVER_VERSION) && (metric != METRIC_QUERY_RESULT) &&
505 && (metric != METRIC_SERVER_VERSION) 473 (metric != METRIC_QUERY_TIME))
506 && (metric != METRIC_QUERY_RESULT) 474 usage("Invalid metric specified");
507 && (metric != METRIC_QUERY_TIME))
508 usage ("Invalid metric specified");
509 475
510 if (expect && (warning_range || critical_range || expect_re_str)) 476 if (expect && (warning_range || critical_range || expect_re_str))
511 usage ("Do not mix -e and -w/-c/-r/-R"); 477 usage("Do not mix -e and -w/-c/-r/-R");
512 478
513 if (expect_re_str && (warning_range || critical_range || expect)) 479 if (expect_re_str && (warning_range || critical_range || expect))
514 usage ("Do not mix -r/-R and -w/-c/-e"); 480 usage("Do not mix -r/-R and -w/-c/-e");
515 481
516 if (expect && (metric != METRIC_QUERY_RESULT)) 482 if (expect && (metric != METRIC_QUERY_RESULT))
517 usage ("Option -e requires metric QUERY_RESULT"); 483 usage("Option -e requires metric QUERY_RESULT");
518 484
519 if (expect_re_str && (metric != METRIC_QUERY_RESULT)) 485 if (expect_re_str && (metric != METRIC_QUERY_RESULT))
520 usage ("Options -r/-R require metric QUERY_RESULT"); 486 usage("Options -r/-R require metric QUERY_RESULT");
521 487
522 return OK; 488 return OK;
523} 489}
524 490
525void 491void print_help(void) {
526print_help (void) 492 print_revision(progname, NP_VERSION);
527{
528 print_revision (progname, NP_VERSION);
529 493
530 printf (COPYRIGHT, copyright, email); 494 printf(COPYRIGHT, copyright, email);
531 495
532 printf (_("This program connects to an (SQL) database using DBI and checks the\n" 496 printf(_("This program connects to an (SQL) database using DBI and checks the\n"
533 "specified metric against threshold levels. The default metric is\n" 497 "specified metric against threshold levels. The default metric is\n"
534 "the result of the specified query.\n")); 498 "the result of the specified query.\n"));
535 499
536 printf ("\n\n"); 500 printf("\n\n");
537 501
538 print_usage (); 502 print_usage();
539 503
540 printf (UT_HELP_VRSN); 504 printf(UT_HELP_VRSN);
541/* include this conditionally to avoid 'zero-length printf format string' 505/* include this conditionally to avoid 'zero-length printf format string'
542 * compiler warnings */ 506 * compiler warnings */
543#ifdef NP_EXTRA_OPTS 507#ifdef NP_EXTRA_OPTS
544 printf (UT_EXTRA_OPTS); 508 printf(UT_EXTRA_OPTS);
545#endif 509#endif
546 printf ("\n"); 510 printf("\n");
547 511
548 printf (" %s\n", "-d, --driver=STRING"); 512 printf(" %s\n", "-d, --driver=STRING");
549 printf (" %s\n", _("DBI driver to use")); 513 printf(" %s\n", _("DBI driver to use"));
550 printf (" %s\n", "-o, --option=STRING"); 514 printf(" %s\n", "-o, --option=STRING");
551 printf (" %s\n", _("DBI driver options")); 515 printf(" %s\n", _("DBI driver options"));
552 printf (" %s\n", "-q, --query=STRING"); 516 printf(" %s\n", "-q, --query=STRING");
553 printf (" %s\n", _("query to execute")); 517 printf(" %s\n", _("query to execute"));
554 printf ("\n"); 518 printf("\n");
555 519
556 printf (UT_WARN_CRIT_RANGE); 520 printf(UT_WARN_CRIT_RANGE);
557 printf (" %s\n", "-e, --expect=STRING"); 521 printf(" %s\n", "-e, --expect=STRING");
558 printf (" %s\n", _("String to expect as query result")); 522 printf(" %s\n", _("String to expect as query result"));
559 printf (" %s\n", _("Do not mix with -w, -c, -r, or -R!")); 523 printf(" %s\n", _("Do not mix with -w, -c, -r, or -R!"));
560 printf (" %s\n", "-r, --regex=REGEX"); 524 printf(" %s\n", "-r, --regex=REGEX");
561 printf (" %s\n", _("Extended POSIX regular expression to check query result against")); 525 printf(" %s\n", _("Extended POSIX regular expression to check query result against"));
562 printf (" %s\n", _("Do not mix with -w, -c, -e, or -R!")); 526 printf(" %s\n", _("Do not mix with -w, -c, -e, or -R!"));
563 printf (" %s\n", "-R, --regexi=REGEX"); 527 printf(" %s\n", "-R, --regexi=REGEX");
564 printf (" %s\n", _("Case-insensitive extended POSIX regex to check query result against")); 528 printf(" %s\n", _("Case-insensitive extended POSIX regex to check query result against"));
565 printf (" %s\n", _("Do not mix with -w, -c, -e, or -r!")); 529 printf(" %s\n", _("Do not mix with -w, -c, -e, or -r!"));
566 printf (" %s\n", "-m, --metric=METRIC"); 530 printf(" %s\n", "-m, --metric=METRIC");
567 printf (" %s\n", _("Metric to check thresholds against. Available metrics:")); 531 printf(" %s\n", _("Metric to check thresholds against. Available metrics:"));
568 printf (" CONN_TIME - %s\n", _("time used for setting up the database connection")); 532 printf(" CONN_TIME - %s\n", _("time used for setting up the database connection"));
569 printf (" QUERY_RESULT - %s\n", _("result (first column of first row) of the query")); 533 printf(" QUERY_RESULT - %s\n", _("result (first column of first row) of the query"));
570 printf (" QUERY_TIME - %s\n", _("time used to execute the query")); 534 printf(" QUERY_TIME - %s\n", _("time used to execute the query"));
571 printf (" %s\n", _("(ignore the query result)")); 535 printf(" %s\n", _("(ignore the query result)"));
572 printf ("\n"); 536 printf("\n");
573 537
574 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 538 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
575 539
576 printf (UT_VERBOSE); 540 printf(UT_VERBOSE);
577 541
578 printf ("\n"); 542 printf("\n");
579 printf (" %s\n", _("A DBI driver (-d option) is required. If the specified metric operates")); 543 printf(" %s\n", _("A DBI driver (-d option) is required. If the specified metric operates"));
580 printf (" %s\n\n", _("on a query, one has to be specified (-q option).")); 544 printf(" %s\n\n", _("on a query, one has to be specified (-q option)."));
581 545
582 printf (" %s\n", _("This plugin connects to an (SQL) database using libdbi and, optionally,")); 546 printf(" %s\n", _("This plugin connects to an (SQL) database using libdbi and, optionally,"));
583 printf (" %s\n", _("executes the specified query. The first column of the first row of the")); 547 printf(" %s\n", _("executes the specified query. The first column of the first row of the"));
584 printf (" %s\n", _("result will be parsed and, in QUERY_RESULT mode, compared with the")); 548 printf(" %s\n", _("result will be parsed and, in QUERY_RESULT mode, compared with the"));
585 printf (" %s\n", _("warning and critical ranges. The result from the query has to be numeric")); 549 printf(" %s\n", _("warning and critical ranges. The result from the query has to be numeric"));
586 printf (" %s\n\n", _("(strings representing numbers are fine).")); 550 printf(" %s\n\n", _("(strings representing numbers are fine)."));
587 551
588 printf (" %s\n", _("The number and type of required DBI driver options depends on the actual")); 552 printf(" %s\n", _("The number and type of required DBI driver options depends on the actual"));
589 printf (" %s\n", _("driver. See its documentation at http://libdbi-drivers.sourceforge.net/")); 553 printf(" %s\n", _("driver. See its documentation at http://libdbi-drivers.sourceforge.net/"));
590 printf (" %s\n\n", _("for details.")); 554 printf(" %s\n\n", _("for details."));
591 555
592 printf (" %s\n", _("Examples:")); 556 printf(" %s\n", _("Examples:"));
593 printf (" check_dbi -d pgsql -o username=postgres -m QUERY_RESULT \\\n"); 557 printf(" check_dbi -d pgsql -o username=postgres -m QUERY_RESULT \\\n");
594 printf (" -q 'SELECT COUNT(*) FROM pg_stat_activity' -w 5 -c 10\n"); 558 printf(" -q 'SELECT COUNT(*) FROM pg_stat_activity' -w 5 -c 10\n");
595 printf (" Warning if more than five connections; critical if more than ten.\n\n"); 559 printf(" Warning if more than five connections; critical if more than ten.\n\n");
596 560
597 printf (" check_dbi -d mysql -H localhost -o username=user -o password=secret \\\n"); 561 printf(" check_dbi -d mysql -H localhost -o username=user -o password=secret \\\n");
598 printf (" -q 'SELECT COUNT(*) FROM logged_in_users -w 5:20 -c 0:50\n"); 562 printf(" -q 'SELECT COUNT(*) FROM logged_in_users -w 5:20 -c 0:50\n");
599 printf (" Warning if less than 5 or more than 20 users are logged in; critical\n"); 563 printf(" Warning if less than 5 or more than 20 users are logged in; critical\n");
600 printf (" if more than 50 users.\n\n"); 564 printf(" if more than 50 users.\n\n");
601 565
602 printf (" check_dbi -d firebird -o username=user -o password=secret -o dbname=foo \\\n"); 566 printf(" check_dbi -d firebird -o username=user -o password=secret -o dbname=foo \\\n");
603 printf (" -m CONN_TIME -w 0.5 -c 2\n"); 567 printf(" -m CONN_TIME -w 0.5 -c 2\n");
604 printf (" Warning if connecting to the database takes more than half of a second;\n"); 568 printf(" Warning if connecting to the database takes more than half of a second;\n");
605 printf (" critical if it takes more than 2 seconds.\n\n"); 569 printf(" critical if it takes more than 2 seconds.\n\n");
606 570
607 printf (" check_dbi -d mysql -H localhost -o username=user \\\n"); 571 printf(" check_dbi -d mysql -H localhost -o username=user \\\n");
608 printf (" -q 'SELECT concat(@@version, \" \", @@version_comment)' \\\n"); 572 printf(" -q 'SELECT concat(@@version, \" \", @@version_comment)' \\\n");
609 printf (" -r '^5\\.[01].*MySQL Enterprise Server'\n"); 573 printf(" -r '^5\\.[01].*MySQL Enterprise Server'\n");
610 printf (" Critical if the database server is not a MySQL enterprise server in either\n"); 574 printf(" Critical if the database server is not a MySQL enterprise server in either\n");
611 printf (" version 5.0.x or 5.1.x.\n\n"); 575 printf(" version 5.0.x or 5.1.x.\n\n");
612 576
613 printf (" check_dbi -d pgsql -u username=user -m SERVER_VERSION \\\n"); 577 printf(" check_dbi -d pgsql -u username=user -m SERVER_VERSION \\\n");
614 printf (" -w 090000:090099 -c 090000:090199\n"); 578 printf(" -w 090000:090099 -c 090000:090199\n");
615 printf (" Warn if the PostgreSQL server version is not 9.0.x; critical if the version\n"); 579 printf(" Warn if the PostgreSQL server version is not 9.0.x; critical if the version\n");
616 printf (" is less than 9.x or higher than 9.1.x.\n"); 580 printf(" is less than 9.x or higher than 9.1.x.\n");
617 581
618 printf (UT_SUPPORT); 582 printf(UT_SUPPORT);
619} 583}
620 584
621void 585void print_usage(void) {
622print_usage (void) 586 printf("%s\n", _("Usage:"));
623{ 587 printf("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname);
624 printf ("%s\n", _("Usage:")); 588 printf(" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n");
625 printf ("%s -d <DBI driver> [-o <DBI driver option> [...]] [-q <query>]\n", progname); 589 printf(" [-e <string>] [-r|-R <regex>]\n");
626 printf (" [-H <host>] [-c <critical range>] [-w <warning range>] [-m <metric>]\n");
627 printf (" [-e <string>] [-r|-R <regex>]\n");
628} 590}
629 591
630#define CHECK_IGNORE_ERROR(s) \ 592#define CHECK_IGNORE_ERROR(s) \
631 do { \ 593 do { \
632 if (metric != METRIC_QUERY_RESULT) \ 594 if (metric != METRIC_QUERY_RESULT) \
633 return (s); \ 595 return (s); \
634 } while (0) 596 } while (0)
635 597
636const char * 598const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type) {
637get_field_str (dbi_conn conn, dbi_result res, unsigned short field_type)
638{
639 const char *str; 599 const char *str;
640 600
641 if (field_type != DBI_TYPE_STRING) { 601 if (field_type != DBI_TYPE_STRING) {
642 printf ("CRITICAL - result value is not a string\n"); 602 printf("CRITICAL - result value is not a string\n");
643 return NULL; 603 return NULL;
644 } 604 }
645 605
646 str = dbi_result_get_string_idx (res, 1); 606 str = dbi_result_get_string_idx(res, 1);
647 if ((! str) || (strcmp (str, "ERROR") == 0)) { 607 if ((!str) || (strcmp(str, "ERROR") == 0)) {
648 CHECK_IGNORE_ERROR (NULL); 608 CHECK_IGNORE_ERROR(NULL);
649 np_dbi_print_error (conn, "CRITICAL - failed to fetch string value"); 609 np_dbi_print_error(conn, "CRITICAL - failed to fetch string value");
650 return NULL; 610 return NULL;
651 } 611 }
652 612
653 if ((verbose && (type == TYPE_STRING)) || (verbose > 2)) 613 if ((verbose && (type == TYPE_STRING)) || (verbose > 2))
654 printf ("Query returned string '%s'\n", str); 614 printf("Query returned string '%s'\n", str);
655 return str; 615 return str;
656} 616}
657 617
658double 618double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type) {
659get_field (dbi_conn conn, dbi_result res, unsigned short *field_type)
660{
661 double val = NAN; 619 double val = NAN;
662 620
663 if (*field_type == DBI_TYPE_INTEGER) { 621 if (*field_type == DBI_TYPE_INTEGER) {
664 val = (double)dbi_result_get_longlong_idx (res, 1); 622 val = (double)dbi_result_get_longlong_idx(res, 1);
665 } 623 } else if (*field_type == DBI_TYPE_DECIMAL) {
666 else if (*field_type == DBI_TYPE_DECIMAL) { 624 val = dbi_result_get_double_idx(res, 1);
667 val = dbi_result_get_double_idx (res, 1); 625 } else if (*field_type == DBI_TYPE_STRING) {
668 }
669 else if (*field_type == DBI_TYPE_STRING) {
670 const char *val_str; 626 const char *val_str;
671 char *endptr = NULL; 627 char *endptr = NULL;
672 628
673 val_str = get_field_str (conn, res, *field_type); 629 val_str = get_field_str(conn, res, *field_type);
674 if (! val_str) { 630 if (!val_str) {
675 CHECK_IGNORE_ERROR (NAN); 631 CHECK_IGNORE_ERROR(NAN);
676 *field_type = DBI_TYPE_ERROR; 632 *field_type = DBI_TYPE_ERROR;
677 return NAN; 633 return NAN;
678 } 634 }
679 635
680 val = strtod (val_str, &endptr); 636 val = strtod(val_str, &endptr);
681 if (endptr == val_str) { 637 if (endptr == val_str) {
682 CHECK_IGNORE_ERROR (NAN); 638 CHECK_IGNORE_ERROR(NAN);
683 printf ("CRITICAL - result value is not a numeric: %s\n", val_str); 639 printf("CRITICAL - result value is not a numeric: %s\n", val_str);
684 *field_type = DBI_TYPE_ERROR; 640 *field_type = DBI_TYPE_ERROR;
685 return NAN; 641 return NAN;
686 } 642 } else if ((endptr != NULL) && (*endptr != '\0')) {
687 else if ((endptr != NULL) && (*endptr != '\0')) {
688 if (verbose) 643 if (verbose)
689 printf ("Garbage after value: %s\n", endptr); 644 printf("Garbage after value: %s\n", endptr);
690 } 645 }
691 } 646 } else {
692 else { 647 CHECK_IGNORE_ERROR(NAN);
693 CHECK_IGNORE_ERROR (NAN); 648 printf("CRITICAL - cannot parse value of type %s (%i)\n",
694 printf ("CRITICAL - cannot parse value of type %s (%i)\n", 649 (*field_type == DBI_TYPE_BINARY) ? "BINARY"
695 (*field_type == DBI_TYPE_BINARY) 650 : (*field_type == DBI_TYPE_DATETIME) ? "DATETIME"
696 ? "BINARY" 651 : "<unknown>",
697 : (*field_type == DBI_TYPE_DATETIME) 652 *field_type);
698 ? "DATETIME"
699 : "<unknown>",
700 *field_type);
701 *field_type = DBI_TYPE_ERROR; 653 *field_type = DBI_TYPE_ERROR;
702 return NAN; 654 return NAN;
703 } 655 }
704 return val; 656 return val;
705} 657}
706 658
707double 659double get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val) {
708get_query_result (dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val)
709{
710 unsigned short field_type; 660 unsigned short field_type;
711 double val = NAN; 661 double val = NAN;
712 662
713 if (dbi_result_get_numrows (res) == DBI_ROW_ERROR) { 663 if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) {
714 CHECK_IGNORE_ERROR (STATE_OK); 664 CHECK_IGNORE_ERROR(STATE_OK);
715 np_dbi_print_error (conn, "CRITICAL - failed to fetch rows"); 665 np_dbi_print_error(conn, "CRITICAL - failed to fetch rows");
716 return STATE_CRITICAL; 666 return STATE_CRITICAL;
717 } 667 }
718 668
719 if (dbi_result_get_numrows (res) < 1) { 669 if (dbi_result_get_numrows(res) < 1) {
720 CHECK_IGNORE_ERROR (STATE_OK); 670 CHECK_IGNORE_ERROR(STATE_OK);
721 printf ("WARNING - no rows returned\n"); 671 printf("WARNING - no rows returned\n");
722 return STATE_WARNING; 672 return STATE_WARNING;
723 } 673 }
724 674
725 if (dbi_result_get_numfields (res) == DBI_FIELD_ERROR) { 675 if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) {
726 CHECK_IGNORE_ERROR (STATE_OK); 676 CHECK_IGNORE_ERROR(STATE_OK);
727 np_dbi_print_error (conn, "CRITICAL - failed to fetch fields"); 677 np_dbi_print_error(conn, "CRITICAL - failed to fetch fields");
728 return STATE_CRITICAL; 678 return STATE_CRITICAL;
729 } 679 }
730 680
731 if (dbi_result_get_numfields (res) < 1) { 681 if (dbi_result_get_numfields(res) < 1) {
732 CHECK_IGNORE_ERROR (STATE_OK); 682 CHECK_IGNORE_ERROR(STATE_OK);
733 printf ("WARNING - no fields returned\n"); 683 printf("WARNING - no fields returned\n");
734 return STATE_WARNING; 684 return STATE_WARNING;
735 } 685 }
736 686
737 if (dbi_result_first_row (res) != 1) { 687 if (dbi_result_first_row(res) != 1) {
738 CHECK_IGNORE_ERROR (STATE_OK); 688 CHECK_IGNORE_ERROR(STATE_OK);
739 np_dbi_print_error (conn, "CRITICAL - failed to fetch first row"); 689 np_dbi_print_error(conn, "CRITICAL - failed to fetch first row");
740 return STATE_CRITICAL; 690 return STATE_CRITICAL;
741 } 691 }
742 692
743 field_type = dbi_result_get_field_type_idx (res, 1); 693 field_type = dbi_result_get_field_type_idx(res, 1);
744 if (field_type != DBI_TYPE_ERROR) { 694 if (field_type != DBI_TYPE_ERROR) {
745 if (type == TYPE_STRING) 695 if (type == TYPE_STRING)
746 /* the value will be freed in dbi_result_free */ 696 /* the value will be freed in dbi_result_free */
747 *res_val_str = strdup (get_field_str (conn, res, field_type)); 697 *res_val_str = strdup(get_field_str(conn, res, field_type));
748 else 698 else
749 val = get_field (conn, res, &field_type); 699 val = get_field(conn, res, &field_type);
750 } 700 }
751 701
752 *res_val = val; 702 *res_val = val;
753 703
754 if (field_type == DBI_TYPE_ERROR) { 704 if (field_type == DBI_TYPE_ERROR) {
755 CHECK_IGNORE_ERROR (STATE_OK); 705 CHECK_IGNORE_ERROR(STATE_OK);
756 np_dbi_print_error (conn, "CRITICAL - failed to fetch data"); 706 np_dbi_print_error(conn, "CRITICAL - failed to fetch data");
757 return STATE_CRITICAL; 707 return STATE_CRITICAL;
758 } 708 }
759 709
760 dbi_result_free (res); 710 dbi_result_free(res);
761 return STATE_OK; 711 return STATE_OK;
762} 712}
763 713
764#undef CHECK_IGNORE_ERROR 714#undef CHECK_IGNORE_ERROR
765 715
766int 716int do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time) {
767do_query (dbi_conn conn, const char **res_val_str, double *res_val, double *res_time)
768{
769 dbi_result res; 717 dbi_result res;
770 718
771 struct timeval timeval_start, timeval_end; 719 struct timeval timeval_start, timeval_end;
772 int status = STATE_OK; 720 int status = STATE_OK;
773 721
774 assert (np_dbi_query); 722 assert(np_dbi_query);
775 723
776 if (verbose) 724 if (verbose)
777 printf ("Executing query '%s'\n", np_dbi_query); 725 printf("Executing query '%s'\n", np_dbi_query);
778 726
779 gettimeofday (&timeval_start, NULL); 727 gettimeofday(&timeval_start, NULL);
780 728
781 res = dbi_conn_query (conn, np_dbi_query); 729 res = dbi_conn_query(conn, np_dbi_query);
782 if (! res) { 730 if (!res) {
783 np_dbi_print_error (conn, "CRITICAL - failed to execute query '%s'", np_dbi_query); 731 np_dbi_print_error(conn, "CRITICAL - failed to execute query '%s'", np_dbi_query);
784 return STATE_CRITICAL; 732 return STATE_CRITICAL;
785 } 733 }
786 734
787 status = get_query_result (conn, res, res_val_str, res_val); 735 status = get_query_result(conn, res, res_val_str, res_val);
788 736
789 gettimeofday (&timeval_end, NULL); 737 gettimeofday(&timeval_end, NULL);
790 *res_time = timediff (timeval_start, timeval_end); 738 *res_time = timediff(timeval_start, timeval_end);
791 739
792 if (verbose) 740 if (verbose)
793 printf ("Time elapsed: %f\n", *res_time); 741 printf("Time elapsed: %f\n", *res_time);
794 742
795 return status; 743 return status;
796} 744}
797 745
798double 746double timediff(struct timeval start, struct timeval end) {
799timediff (struct timeval start, struct timeval end)
800{
801 double diff; 747 double diff;
802 748
803 while (start.tv_usec > end.tv_usec) { 749 while (start.tv_usec > end.tv_usec) {
804 --end.tv_sec; 750 --end.tv_sec;
805 end.tv_usec += 1000000; 751 end.tv_usec += 1000000;
806 } 752 }
807 diff = (double)(end.tv_sec - start.tv_sec) 753 diff = (double)(end.tv_sec - start.tv_sec) + (double)(end.tv_usec - start.tv_usec) / 1000000.0;
808 + (double)(end.tv_usec - start.tv_usec) / 1000000.0;
809 return diff; 754 return diff;
810} 755}
811 756
812void 757void np_dbi_print_error(dbi_conn conn, char *fmt, ...) {
813np_dbi_print_error (dbi_conn conn, char *fmt, ...)
814{
815 const char *errmsg = NULL; 758 const char *errmsg = NULL;
816 va_list ap; 759 va_list ap;
817 760
818 va_start (ap, fmt); 761 va_start(ap, fmt);
819 762
820 dbi_conn_error (conn, &errmsg); 763 dbi_conn_error(conn, &errmsg);
821 vprintf (fmt, ap); 764 vprintf(fmt, ap);
822 printf (": %s\n", errmsg); 765 printf(": %s\n", errmsg);
823 766
824 va_end (ap); 767 va_end(ap);
825} 768}
826