summaryrefslogtreecommitdiffstats
path: root/plugins/check_mysql.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_mysql.c')
-rw-r--r--plugins/check_mysql.c337
1 files changed, 180 insertions, 157 deletions
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 2b6cfeaf..6134d6c6 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -40,66 +40,44 @@ const char *email = "devel@monitoring-plugins.org";
40#include "utils.h" 40#include "utils.h"
41#include "utils_base.h" 41#include "utils_base.h"
42#include "netutils.h" 42#include "netutils.h"
43#include "check_mysql.d/config.h"
43 44
44#include <mysql.h> 45#include <mysql.h>
45#include <mysqld_error.h> 46#include <mysqld_error.h>
46#include <errmsg.h> 47#include <errmsg.h>
47 48
48static char *db_user = NULL;
49static char *db_host = NULL;
50static char *db_socket = NULL;
51static char *db_pass = NULL;
52static char *db = NULL;
53static char *ca_cert = NULL;
54static char *ca_dir = NULL;
55static char *cert = NULL;
56static char *key = NULL;
57static char *ciphers = NULL;
58static bool ssl = false;
59static char *opt_file = NULL;
60static char *opt_group = NULL;
61static unsigned int db_port = MYSQL_PORT;
62static bool check_replica = false;
63static bool ignore_auth = false;
64static int verbose = 0; 49static int verbose = 0;
65 50
66static double warning_time = 0;
67static double critical_time = 0;
68
69#define LENGTH_METRIC_UNIT 6 51#define LENGTH_METRIC_UNIT 6
70static const char *metric_unit[LENGTH_METRIC_UNIT] = { 52static const char *metric_unit[LENGTH_METRIC_UNIT] = {
71 "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", "Threads_connected", "Threads_running"}; 53 "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache",
54 "Threads_connected", "Threads_running"};
72 55
73#define LENGTH_METRIC_COUNTER 9 56#define LENGTH_METRIC_COUNTER 9
74static const char *metric_counter[LENGTH_METRIC_COUNTER] = { 57static const char *metric_counter[LENGTH_METRIC_COUNTER] = {"Connections",
75 "Connections", "Qcache_hits", "Qcache_inserts", "Qcache_lowmem_prunes", "Qcache_not_cached", "Queries", 58 "Qcache_hits",
76 "Questions", "Table_locks_waited", "Uptime"}; 59 "Qcache_inserts",
77 60 "Qcache_lowmem_prunes",
78#define MYSQLDUMP_THREADS_QUERY \ 61 "Qcache_not_cached",
79 "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'" 62 "Queries",
80 63 "Questions",
81static thresholds *my_threshold = NULL; 64 "Table_locks_waited",
82 65 "Uptime"};
83static int process_arguments(int, char **); 66
84static int validate_arguments(void); 67#define MYSQLDUMP_THREADS_QUERY \
68 "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE " \
69 "'SELECT /*!40001 SQL_NO_CACHE */%'"
70
71typedef struct {
72 int errorcode;
73 check_mysql_config config;
74} check_mysql_config_wrapper;
75static check_mysql_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
76static check_mysql_config_wrapper validate_arguments(check_mysql_config_wrapper /*config_wrapper*/);
85static void print_help(void); 77static void print_help(void);
86void print_usage(void); 78void print_usage(void);
87 79
88int main(int argc, char **argv) { 80int main(int argc, char **argv) {
89
90 MYSQL mysql;
91 MYSQL_RES *res;
92 MYSQL_ROW row;
93
94 /* should be status */
95
96 char *result = NULL;
97 char *error = NULL;
98 char replica_result[REPLICA_RESULTSIZE] = {0};
99 char *perf;
100
101 perf = strdup("");
102
103 setlocale(LC_ALL, ""); 81 setlocale(LC_ALL, "");
104 bindtextdomain(PACKAGE, LOCALEDIR); 82 bindtextdomain(PACKAGE, LOCALEDIR);
105 textdomain(PACKAGE); 83 textdomain(PACKAGE);
@@ -107,36 +85,46 @@ int main(int argc, char **argv) {
107 /* Parse extra opts if any */ 85 /* Parse extra opts if any */
108 argv = np_extra_opts(&argc, argv, progname); 86 argv = np_extra_opts(&argc, argv, progname);
109 87
110 if (process_arguments(argc, argv) == ERROR) { 88 check_mysql_config_wrapper tmp_config = process_arguments(argc, argv);
89 if (tmp_config.errorcode == ERROR) {
111 usage4(_("Could not parse arguments")); 90 usage4(_("Could not parse arguments"));
112 } 91 }
113 92
93 const check_mysql_config config = tmp_config.config;
94
95 MYSQL mysql;
114 /* initialize mysql */ 96 /* initialize mysql */
115 mysql_init(&mysql); 97 mysql_init(&mysql);
116 98
117 if (opt_file != NULL) { 99 if (config.opt_file != NULL) {
118 mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, opt_file); 100 mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, config.opt_file);
119 } 101 }
120 102
121 if (opt_group != NULL) { 103 if (config.opt_group != NULL) {
122 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, opt_group); 104 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, config.opt_group);
123 } else { 105 } else {
124 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); 106 mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client");
125 } 107 }
126 108
127 if (ssl) { 109 if (config.ssl) {
128 mysql_ssl_set(&mysql, key, cert, ca_cert, ca_dir, ciphers); 110 mysql_ssl_set(&mysql, config.key, config.cert, config.ca_cert, config.ca_dir,
111 config.ciphers);
129 } 112 }
130 /* establish a connection to the server and error checking */ 113 /* establish a connection to the server and error checking */
131 if (!mysql_real_connect(&mysql, db_host, db_user, db_pass, db, db_port, db_socket, 0)) { 114 if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db,
115 config.db_port, config.db_socket, 0)) {
132 /* Depending on internally-selected auth plugin MySQL might return */ 116 /* Depending on internally-selected auth plugin MySQL might return */
133 /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */ 117 /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */
134 /* Semantically these errors are the same. */ 118 /* Semantically these errors are the same. */
135 if (ignore_auth && (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { 119 if (config.ignore_auth && (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR ||
136 printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql), mysql_get_proto_info(&mysql)); 120 mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) {
121 printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql),
122 mysql_get_proto_info(&mysql));
137 mysql_close(&mysql); 123 mysql_close(&mysql);
138 return STATE_OK; 124 return STATE_OK;
139 } else if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { 125 }
126
127 if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) {
140 die(STATE_WARNING, "%s\n", mysql_error(&mysql)); 128 die(STATE_WARNING, "%s\n", mysql_error(&mysql));
141 } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { 129 } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) {
142 die(STATE_WARNING, "%s\n", mysql_error(&mysql)); 130 die(STATE_WARNING, "%s\n", mysql_error(&mysql));
@@ -152,7 +140,7 @@ int main(int argc, char **argv) {
152 } 140 }
153 141
154 /* get the server stats */ 142 /* get the server stats */
155 result = strdup(mysql_stat(&mysql)); 143 char *result = strdup(mysql_stat(&mysql));
156 144
157 /* error checking once more */ 145 /* error checking once more */
158 if (mysql_error(&mysql)) { 146 if (mysql_error(&mysql)) {
@@ -165,6 +153,10 @@ int main(int argc, char **argv) {
165 } 153 }
166 } 154 }
167 155
156 char *perf = strdup("");
157 char *error = NULL;
158 MYSQL_RES *res;
159 MYSQL_ROW row;
168 /* try to fetch some perf data */ 160 /* try to fetch some perf data */
169 if (mysql_query(&mysql, "show global status") == 0) { 161 if (mysql_query(&mysql, "show global status") == 0) {
170 if ((res = mysql_store_result(&mysql)) == NULL) { 162 if ((res = mysql_store_result(&mysql)) == NULL) {
@@ -174,17 +166,19 @@ int main(int argc, char **argv) {
174 } 166 }
175 167
176 while ((row = mysql_fetch_row(res)) != NULL) { 168 while ((row = mysql_fetch_row(res)) != NULL) {
177 int i; 169 for (int i = 0; i < LENGTH_METRIC_UNIT; i++) {
178
179 for (i = 0; i < LENGTH_METRIC_UNIT; i++) {
180 if (strcmp(row[0], metric_unit[i]) == 0) { 170 if (strcmp(row[0], metric_unit[i]) == 0) {
181 xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false, 0, false, 0)); 171 xasprintf(&perf, "%s%s ", perf,
172 perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false,
173 0, false, 0));
182 continue; 174 continue;
183 } 175 }
184 } 176 }
185 for (i = 0; i < LENGTH_METRIC_COUNTER; i++) { 177 for (int i = 0; i < LENGTH_METRIC_COUNTER; i++) {
186 if (strcmp(row[0], metric_counter[i]) == 0) { 178 if (strcmp(row[0], metric_counter[i]) == 0) {
187 xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0, false, 0, false, 0)); 179 xasprintf(&perf, "%s%s ", perf,
180 perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0,
181 false, 0, false, 0));
188 continue; 182 continue;
189 } 183 }
190 } 184 }
@@ -195,8 +189,8 @@ int main(int argc, char **argv) {
195 } 189 }
196 } 190 }
197 191
198 if (check_replica) { 192 char replica_result[REPLICA_RESULTSIZE] = {0};
199 193 if (config.check_replica) {
200 // Detect which version we are, on older version 194 // Detect which version we are, on older version
201 // "show slave status" should work, on newer ones 195 // "show slave status" should work, on newer ones
202 // "show replica status" 196 // "show replica status"
@@ -210,8 +204,8 @@ int main(int argc, char **argv) {
210 unsigned long minor_version = (server_verion_int % 10000) / 100; 204 unsigned long minor_version = (server_verion_int % 10000) / 100;
211 unsigned long patch_version = (server_verion_int % 100); 205 unsigned long patch_version = (server_verion_int % 100);
212 if (verbose) { 206 if (verbose) {
213 printf("Found MariaDB: %s, main version: %lu, minor version: %lu, patch version: %lu\n", server_version, major_version, 207 printf("Found MariaDB: %s, main version: %lu, minor version: %lu, patch version: %lu\n",
214 minor_version, patch_version); 208 server_version, major_version, minor_version, patch_version);
215 } 209 }
216 210
217 if (strstr(server_version, "MariaDB") != NULL) { 211 if (strstr(server_version, "MariaDB") != NULL) {
@@ -225,16 +219,13 @@ int main(int argc, char **argv) {
225 use_deprecated_slave_status = true; 219 use_deprecated_slave_status = true;
226 } 220 }
227 } 221 }
228 } else if (strstr(server_version, "MySQL") != NULL) { 222 } else {
229 // Looks like MySQL 223 // Looks like MySQL or at least not like MariaDB
230 if (major_version < 8) { 224 if (major_version < 8) {
231 use_deprecated_slave_status = true; 225 use_deprecated_slave_status = true;
232 } else if (major_version == 10 && minor_version < 4) { 226 } else if (major_version == 10 && minor_version < 4) {
233 use_deprecated_slave_status = true; 227 use_deprecated_slave_status = true;
234 } 228 }
235 } else {
236 printf("Not a known sever implementation: %s\n", server_version);
237 exit(STATE_UNKNOWN);
238 } 229 }
239 230
240 char *replica_query = NULL; 231 char *replica_query = NULL;
@@ -283,23 +274,40 @@ int main(int argc, char **argv) {
283 274
284 } else { 275 } else {
285 /* mysql 4.x.x and mysql 5.x.x */ 276 /* mysql 4.x.x and mysql 5.x.x */
286 int replica_io_field = -1, replica_sql_field = -1, seconds_behind_field = -1, i, num_fields; 277 int replica_io_field = -1;
278 int replica_sql_field = -1;
279 int seconds_behind_field = -1;
280 int num_fields;
287 MYSQL_FIELD *fields; 281 MYSQL_FIELD *fields;
288
289 num_fields = mysql_num_fields(res); 282 num_fields = mysql_num_fields(res);
290 fields = mysql_fetch_fields(res); 283 fields = mysql_fetch_fields(res);
291 for (i = 0; i < num_fields; i++) { 284 for (int i = 0; i < num_fields; i++) {
292 if (strcmp(fields[i].name, "Slave_IO_Running") == 0) { 285 if (use_deprecated_slave_status) {
293 replica_io_field = i; 286 if (strcmp(fields[i].name, "Slave_IO_Running") == 0) {
294 continue; 287 replica_io_field = i;
295 } 288 continue;
296 if (strcmp(fields[i].name, "Slave_SQL_Running") == 0) { 289 }
297 replica_sql_field = i; 290 if (strcmp(fields[i].name, "Slave_SQL_Running") == 0) {
298 continue; 291 replica_sql_field = i;
299 } 292 continue;
300 if (strcmp(fields[i].name, "Seconds_Behind_Master") == 0) { 293 }
301 seconds_behind_field = i; 294 if (strcmp(fields[i].name, "Seconds_Behind_Master") == 0) {
302 continue; 295 seconds_behind_field = i;
296 continue;
297 }
298 } else {
299 if (strcmp(fields[i].name, "Replica_IO_Running") == 0) {
300 replica_io_field = i;
301 continue;
302 }
303 if (strcmp(fields[i].name, "Replica_SQL_Running") == 0) {
304 replica_sql_field = i;
305 continue;
306 }
307 if (strcmp(fields[i].name, "Seconds_Behind_Source") == 0) {
308 seconds_behind_field = i;
309 continue;
310 }
303 } 311 }
304 } 312 }
305 313
@@ -311,11 +319,15 @@ int main(int argc, char **argv) {
311 } 319 }
312 320
313 /* Save replica status in replica_result */ 321 /* Save replica status in replica_result */
314 snprintf(replica_result, REPLICA_RESULTSIZE, "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s", row[replica_io_field], 322 snprintf(replica_result, REPLICA_RESULTSIZE,
315 row[replica_sql_field], seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); 323 "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s",
316 324 row[replica_io_field], row[replica_sql_field],
317 /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no mysqldump threads running */ 325 seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown");
318 if (strcmp(row[replica_io_field], "Yes") != 0 || strcmp(row[replica_sql_field], "Yes") != 0) { 326
327 /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no
328 * mysqldump threads running */
329 if (strcmp(row[replica_io_field], "Yes") != 0 ||
330 strcmp(row[replica_sql_field], "Yes") != 0) {
319 MYSQL_RES *res_mysqldump; 331 MYSQL_RES *res_mysqldump;
320 MYSQL_ROW row_mysqldump; 332 MYSQL_ROW row_mysqldump;
321 unsigned int mysqldump_threads = 0; 333 unsigned int mysqldump_threads = 0;
@@ -344,20 +356,23 @@ int main(int argc, char **argv) {
344 if (seconds_behind_field == -1) { 356 if (seconds_behind_field == -1) {
345 printf("seconds_behind_field not found\n"); 357 printf("seconds_behind_field not found\n");
346 } else { 358 } else {
347 printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field, row[seconds_behind_field]); 359 printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field,
360 row[seconds_behind_field]);
348 } 361 }
349 } 362 }
350 363
351 /* Check Seconds Behind against threshold */ 364 /* Check Seconds Behind against threshold */
352 if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && strcmp(row[seconds_behind_field], "NULL") != 0)) { 365 if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL &&
366 strcmp(row[seconds_behind_field], "NULL") != 0)) {
353 double value = atof(row[seconds_behind_field]); 367 double value = atof(row[seconds_behind_field]);
354 int status; 368 int status;
355 369
356 status = get_status(value, my_threshold); 370 status = get_status(value, config.my_threshold);
357 371
358 xasprintf(&perf, "%s %s", perf, 372 xasprintf(&perf, "%s %s", perf,
359 fperfdata("seconds behind master", value, "s", true, (double)warning_time, true, (double)critical_time, false, 0, 373 fperfdata("seconds behind master", value, "s", true,
360 false, 0)); 374 (double)config.warning_time, true, (double)config.critical_time,
375 false, 0, false, 0));
361 376
362 if (status == STATE_WARNING) { 377 if (status == STATE_WARNING) {
363 printf("SLOW_REPLICA %s: %s|%s\n", _("WARNING"), replica_result, perf); 378 printf("SLOW_REPLICA %s: %s|%s\n", _("WARNING"), replica_result, perf);
@@ -377,7 +392,7 @@ int main(int argc, char **argv) {
377 mysql_close(&mysql); 392 mysql_close(&mysql);
378 393
379 /* print out the result of stats */ 394 /* print out the result of stats */
380 if (check_replica) { 395 if (config.check_replica) {
381 printf("%s %s|%s\n", result, replica_result, perf); 396 printf("%s %s|%s\n", result, replica_result, perf);
382 } else { 397 } else {
383 printf("%s|%s\n", result, perf); 398 printf("%s|%s\n", result, perf);
@@ -389,12 +404,7 @@ int main(int argc, char **argv) {
389#define CHECK_REPLICA_OPT CHAR_MAX + 1 404#define CHECK_REPLICA_OPT CHAR_MAX + 1
390 405
391/* process command-line arguments */ 406/* process command-line arguments */
392int process_arguments(int argc, char **argv) { 407check_mysql_config_wrapper process_arguments(int argc, char **argv) {
393 int c;
394 char *warning = NULL;
395 char *critical = NULL;
396
397 int option = 0;
398 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, 408 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
399 {"socket", required_argument, 0, 's'}, 409 {"socket", required_argument, 0, 's'},
400 {"database", required_argument, 0, 'd'}, 410 {"database", required_argument, 0, 'd'},
@@ -419,56 +429,67 @@ int process_arguments(int argc, char **argv) {
419 {"ciphers", required_argument, 0, 'L'}, 429 {"ciphers", required_argument, 0, 'L'},
420 {0, 0, 0, 0}}; 430 {0, 0, 0, 0}};
421 431
432 check_mysql_config_wrapper result = {
433 .errorcode = OK,
434 .config = check_mysql_config_init(),
435 };
436
422 if (argc < 1) { 437 if (argc < 1) {
423 return ERROR; 438 result.errorcode = ERROR;
439 return result;
424 } 440 }
425 441
426 while (1) { 442 char *warning = NULL;
427 c = getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); 443 char *critical = NULL;
428 444
429 if (c == -1 || c == EOF) { 445 int option = 0;
446 while (true) {
447 int option_index =
448 getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option);
449
450 if (option_index == -1 || option_index == EOF) {
430 break; 451 break;
431 } 452 }
432 453
433 switch (c) { 454 switch (option_index) {
434 case 'H': /* hostname */ 455 case 'H': /* hostname */
435 if (is_host(optarg)) { 456 if (is_host(optarg)) {
436 db_host = optarg; 457 result.config.db_host = optarg;
437 } else if (*optarg == '/') { 458 } else if (*optarg == '/') {
438 db_socket = optarg; 459 result.config.db_socket = optarg;
439 } else { 460 } else {
440 usage2(_("Invalid hostname/address"), optarg); 461 usage2(_("Invalid hostname/address"), optarg);
441 } 462 }
442 break; 463 break;
443 case 's': /* socket */ 464 case 's': /* socket */
444 db_socket = optarg; 465 result.config.db_socket = optarg;
445 break; 466 break;
446 case 'd': /* database */ 467 case 'd': /* database */
447 db = optarg; 468 result.config.db = optarg;
448 break; 469 break;
449 case 'l': 470 case 'l':
450 ssl = true; 471 result.config.ssl = true;
451 break; 472 break;
452 case 'C': 473 case 'C':
453 ca_cert = optarg; 474 result.config.ca_cert = optarg;
454 break; 475 break;
455 case 'a': 476 case 'a':
456 cert = optarg; 477 result.config.cert = optarg;
457 break; 478 break;
458 case 'k': 479 case 'k':
459 key = optarg; 480 result.config.key = optarg;
460 break; 481 break;
461 case 'D': 482 case 'D':
462 ca_dir = optarg; 483 result.config.ca_dir = optarg;
463 break; 484 break;
464 case 'L': 485 case 'L':
465 ciphers = optarg; 486 result.config.ciphers = optarg;
466 break; 487 break;
467 case 'u': /* username */ 488 case 'u': /* username */
468 db_user = optarg; 489 result.config.db_user = optarg;
469 break; 490 break;
470 case 'p': /* authentication information: password */ 491 case 'p': /* authentication information: password */
471 db_pass = strdup(optarg); 492 result.config.db_pass = strdup(optarg);
472 493
473 /* Delete the password from process list */ 494 /* Delete the password from process list */
474 while (*optarg != '\0') { 495 while (*optarg != '\0') {
@@ -477,28 +498,28 @@ int process_arguments(int argc, char **argv) {
477 } 498 }
478 break; 499 break;
479 case 'f': /* client options file */ 500 case 'f': /* client options file */
480 opt_file = optarg; 501 result.config.opt_file = optarg;
481 break; 502 break;
482 case 'g': /* client options group */ 503 case 'g': /* client options group */
483 opt_group = optarg; 504 result.config.opt_group = optarg;
484 break; 505 break;
485 case 'P': /* critical time threshold */ 506 case 'P': /* critical time threshold */
486 db_port = atoi(optarg); 507 result.config.db_port = atoi(optarg);
487 break; 508 break;
488 case 'S': 509 case 'S':
489 case CHECK_REPLICA_OPT: 510 case CHECK_REPLICA_OPT:
490 check_replica = true; /* check-slave */ 511 result.config.check_replica = true; /* check-slave */
491 break; 512 break;
492 case 'n': 513 case 'n':
493 ignore_auth = true; /* ignore-auth */ 514 result.config.ignore_auth = true; /* ignore-auth */
494 break; 515 break;
495 case 'w': 516 case 'w':
496 warning = optarg; 517 warning = optarg;
497 warning_time = strtod(warning, NULL); 518 result.config.warning_time = strtod(warning, NULL);
498 break; 519 break;
499 case 'c': 520 case 'c':
500 critical = optarg; 521 critical = optarg;
501 critical_time = strtod(critical, NULL); 522 result.config.critical_time = strtod(critical, NULL);
502 break; 523 break;
503 case 'V': /* version */ 524 case 'V': /* version */
504 print_revision(progname, NP_VERSION); 525 print_revision(progname, NP_VERSION);
@@ -514,48 +535,47 @@ int process_arguments(int argc, char **argv) {
514 } 535 }
515 } 536 }
516 537
517 c = optind; 538 int index = optind;
518
519 set_thresholds(&my_threshold, warning, critical);
520 539
521 while (argc > c) { 540 set_thresholds(&result.config.my_threshold, warning, critical);
522 541
523 if (db_host == NULL) { 542 while (argc > index) {
524 if (is_host(argv[c])) { 543 if (result.config.db_host == NULL) {
525 db_host = argv[c++]; 544 if (is_host(argv[index])) {
545 result.config.db_host = argv[index++];
526 } else { 546 } else {
527 usage2(_("Invalid hostname/address"), argv[c]); 547 usage2(_("Invalid hostname/address"), argv[index]);
528 } 548 }
529 } else if (db_user == NULL) { 549 } else if (result.config.db_user == NULL) {
530 db_user = argv[c++]; 550 result.config.db_user = argv[index++];
531 } else if (db_pass == NULL) { 551 } else if (result.config.db_pass == NULL) {
532 db_pass = argv[c++]; 552 result.config.db_pass = argv[index++];
533 } else if (db == NULL) { 553 } else if (result.config.db == NULL) {
534 db = argv[c++]; 554 result.config.db = argv[index++];
535 } else if (is_intnonneg(argv[c])) { 555 } else if (is_intnonneg(argv[index])) {
536 db_port = atoi(argv[c++]); 556 result.config.db_port = atoi(argv[index++]);
537 } else { 557 } else {
538 break; 558 break;
539 } 559 }
540 } 560 }
541 561
542 return validate_arguments(); 562 return validate_arguments(result);
543} 563}
544 564
545int validate_arguments(void) { 565check_mysql_config_wrapper validate_arguments(check_mysql_config_wrapper config_wrapper) {
546 if (db_user == NULL) { 566 if (config_wrapper.config.db_user == NULL) {
547 db_user = strdup(""); 567 config_wrapper.config.db_user = strdup("");
548 } 568 }
549 569
550 if (db_host == NULL) { 570 if (config_wrapper.config.db_host == NULL) {
551 db_host = strdup(""); 571 config_wrapper.config.db_host = strdup("");
552 } 572 }
553 573
554 if (db == NULL) { 574 if (config_wrapper.config.db == NULL) {
555 db = strdup(""); 575 config_wrapper.config.db = strdup("");
556 } 576 }
557 577
558 return OK; 578 return config_wrapper;
559} 579}
560 580
561void print_help(void) { 581void print_help(void) {
@@ -595,15 +615,17 @@ void print_help(void) {
595 printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); 615 printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!"));
596 printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); 616 printf(" %s\n", _("Your clear-text password could be visible as a process table entry"));
597 printf(" %s\n", "-S, --check-slave"); 617 printf(" %s\n", "-S, --check-slave");
598 printf(" %s\n", 618 printf(" %s\n", _("Check if the slave thread is running properly. This option is deprecated "
599 _("Check if the slave thread is running properly. This option is deprecated in favour of check-replica, which does the same")); 619 "in favour of check-replica, which does the same"));
600 printf(" %s\n", "--check-replica"); 620 printf(" %s\n", "--check-replica");
601 printf(" %s\n", _("Check if the replica thread is running properly.")); 621 printf(" %s\n", _("Check if the replica thread is running properly."));
602 printf(" %s\n", "-w, --warning"); 622 printf(" %s\n", "-w, --warning");
603 printf(" %s\n", _("Exit with WARNING status if replica server is more than INTEGER seconds")); 623 printf(" %s\n",
624 _("Exit with WARNING status if replica server is more than INTEGER seconds"));
604 printf(" %s\n", _("behind master")); 625 printf(" %s\n", _("behind master"));
605 printf(" %s\n", "-c, --critical"); 626 printf(" %s\n", "-c, --critical");
606 printf(" %s\n", _("Exit with CRITICAL status if replica server is more then INTEGER seconds")); 627 printf(" %s\n",
628 _("Exit with CRITICAL status if replica server is more then INTEGER seconds"));
607 printf(" %s\n", _("behind master")); 629 printf(" %s\n", _("behind master"));
608 printf(" %s\n", "-l, --ssl"); 630 printf(" %s\n", "-l, --ssl");
609 printf(" %s\n", _("Use ssl encryption")); 631 printf(" %s\n", _("Use ssl encryption"));
@@ -619,7 +641,8 @@ void print_help(void) {
619 printf(" %s\n", _("List of valid SSL ciphers")); 641 printf(" %s\n", _("List of valid SSL ciphers"));
620 642
621 printf("\n"); 643 printf("\n");
622 printf(" %s\n", _("There are no required arguments. By default, the local database is checked")); 644 printf(" %s\n",
645 _("There are no required arguments. By default, the local database is checked"));
623 printf(" %s\n", _("using the default unix socket. You can force TCP on localhost by using an")); 646 printf(" %s\n", _("using the default unix socket. You can force TCP on localhost by using an"));
624 printf(" %s\n", _("IP address or FQDN ('localhost' will use the socket as well).")); 647 printf(" %s\n", _("IP address or FQDN ('localhost' will use the socket as well)."));
625 648