Set timeout within nc, rather than the test script
[monitoring-plugins.git] / plugins / check_mysql_query.c
blobb542fb4461995388913dfd5048ae69523ad7729e
1 /******************************************************************************
3 * CHECK_MYSQL_QUERY.C
5 * Program: Mysql plugin for Nagios
6 * License: GPL
7 * Copyright (c) 2006 Nagios Plugins Team, after Didi Rieder (check_mysql)
8 *
9 * $Id$
11 * Description:
12 * This plugin is for running arbitrary SQL and checking the results
14 ******************************************************************************/
16 const char *progname = "check_mysql_query";
17 const char *revision = "$Revision$";
18 const char *copyright = "2006";
19 const char *email = "nagiosplug-devel@lists.sourceforge.net";
21 #include "common.h"
22 #include "utils.h"
23 #include "netutils.h"
25 #include <mysql.h>
26 #include <errmsg.h>
28 char *db_user = NULL;
29 char *db_host = NULL;
30 char *db_pass = NULL;
31 char *db = NULL;
32 unsigned int db_port = MYSQL_PORT;
34 int process_arguments (int, char **);
35 int validate_arguments (void);
36 void print_help (void);
37 void print_usage (void);
39 char *sql_query = NULL;
40 int verbose = 0;
41 thresholds *my_thresholds = NULL;
44 int
45 main (int argc, char **argv)
48 MYSQL mysql;
49 MYSQL_RES *res;
50 MYSQL_ROW row;
52 double value;
53 char *error = NULL;
54 int status;
56 setlocale (LC_ALL, "");
57 bindtextdomain (PACKAGE, LOCALEDIR);
58 textdomain (PACKAGE);
60 if (process_arguments (argc, argv) == ERROR)
61 usage4 (_("Could not parse arguments"));
63 /* initialize mysql */
64 mysql_init (&mysql);
66 mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
68 /* establish a connection to the server and error checking */
69 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,NULL,0)) {
70 if (mysql_errno (&mysql) == CR_UNKNOWN_HOST)
71 die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
72 else if (mysql_errno (&mysql) == CR_VERSION_ERROR)
73 die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
74 else if (mysql_errno (&mysql) == CR_OUT_OF_MEMORY)
75 die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
76 else if (mysql_errno (&mysql) == CR_IPSOCK_ERROR)
77 die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
78 else if (mysql_errno (&mysql) == CR_SOCKET_CREATE_ERROR)
79 die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error (&mysql));
80 else
81 die (STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error (&mysql));
84 if (mysql_query (&mysql, sql_query) != 0) {
85 error = strdup(mysql_error(&mysql));
86 mysql_close (&mysql);
87 die (STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error);
90 /* store the result */
91 if ( (res = mysql_store_result (&mysql)) == NULL) {
92 error = strdup(mysql_error(&mysql));
93 mysql_close (&mysql);
94 die (STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error);
97 /* Check there is some data */
98 if (mysql_num_rows(res) == 0) {
99 mysql_close(&mysql);
100 die (STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned"));
103 /* fetch the first row */
104 if ( (row = mysql_fetch_row (res)) == NULL) {
105 error = strdup(mysql_error(&mysql));
106 mysql_free_result (res);
107 mysql_close (&mysql);
108 die (STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error);
111 /* free the result */
112 mysql_free_result (res);
114 /* close the connection */
115 mysql_close (&mysql);
117 if (! is_numeric(row[0])) {
118 die (STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]);
121 value = strtod(row[0], NULL);
123 if (verbose >= 3)
124 printf("mysql result: %f\n", value);
126 status = get_status(value, my_thresholds);
128 if (status == STATE_OK) {
129 printf("QUERY %s: ", _("OK"));
130 } else if (status == STATE_WARNING) {
131 printf("QUERY %s: ", _("WARNING"));
132 } else if (status == STATE_CRITICAL) {
133 printf("QUERY %s: ", _("CRITICAL"));
135 printf(_("'%s' returned %f"), sql_query, value);
136 printf("\n");
138 return status;
142 /* process command-line arguments */
144 process_arguments (int argc, char **argv)
146 int c;
147 char *warning = NULL;
148 char *critical = NULL;
150 int option = 0;
151 static struct option longopts[] = {
152 {"hostname", required_argument, 0, 'H'},
153 {"database", required_argument, 0, 'd'},
154 {"username", required_argument, 0, 'u'},
155 {"password", required_argument, 0, 'p'},
156 {"port", required_argument, 0, 'P'},
157 {"verbose", no_argument, 0, 'v'},
158 {"version", no_argument, 0, 'V'},
159 {"help", no_argument, 0, 'h'},
160 {"query", required_argument, 0, 'q'},
161 {"warning", required_argument, 0, 'w'},
162 {"critical", required_argument, 0, 'c'},
163 {0, 0, 0, 0}
166 if (argc < 1)
167 return ERROR;
169 while (1) {
170 c = getopt_long (argc, argv, "hvVSP:p:u:d:H:q:w:c:", longopts, &option);
172 if (c == -1 || c == EOF)
173 break;
175 switch (c) {
176 case 'H': /* hostname */
177 if (is_host (optarg)) {
178 db_host = optarg;
180 else {
181 usage2 (_("Invalid hostname/address"), optarg);
183 break;
184 case 'd': /* hostname */
185 db = optarg;
186 break;
187 case 'u': /* username */
188 db_user = optarg;
189 break;
190 case 'p': /* authentication information: password */
191 asprintf(&db_pass, "%s", optarg);
193 /* Delete the password from process list */
194 while (*optarg != '\0') {
195 *optarg = 'X';
196 optarg++;
198 break;
199 case 'P': /* critical time threshold */
200 db_port = atoi (optarg);
201 break;
202 case 'v':
203 verbose++;
204 break;
205 case 'V': /* version */
206 print_revision (progname, revision);
207 exit (STATE_OK);
208 case 'h': /* help */
209 print_help ();
210 exit (STATE_OK);
211 case 'q':
212 asprintf(&sql_query, "%s", optarg);
213 break;
214 case 'w':
215 warning = optarg;
216 break;
217 case 'c':
218 critical = optarg;
219 break;
220 case '?': /* help */
221 usage2 (_("Unknown argument"), optarg);
225 c = optind;
227 set_thresholds(&my_thresholds, warning, critical);
229 return validate_arguments ();
234 validate_arguments (void)
236 if (sql_query == NULL)
237 usage("Must specify a SQL query to run");
239 if (db_user == NULL)
240 db_user = strdup("");
242 if (db_host == NULL)
243 db_host = strdup("");
245 if (db_pass == NULL)
246 db_pass == strdup("");
248 if (db == NULL)
249 db = strdup("");
251 return OK;
255 void
256 print_help (void)
258 char *myport;
259 asprintf (&myport, "%d", MYSQL_PORT);
261 print_revision (progname, revision);
263 printf (_(COPYRIGHT), copyright, email);
265 printf ("%s\n", _("This program checks a query result against threshold levels"));
267 print_usage ();
270 printf (_(UT_HELP_VRSN));
271 printf (" -q, --query=STRING\n");
272 printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
273 printf (_(UT_WARN_CRIT_RANGE));
274 printf (_(UT_HOST_PORT), 'P', myport);
275 printf (" -d, --database=STRING\n");
276 printf (" %s\n", _("Database to check"));
277 printf (" -u, --username=STRING\n");
278 printf (" %s\n", _("Username to login with"));
279 printf (" -p, --password=STRING\n");
280 printf (" %s\n", _("Password to login with"));
281 printf (" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!"));
283 printf ("\n");
285 printf ("%s\n", _("A query is required. The result from the query should be numeric."));
286 printf ("%s\n", _("For extra security, create a user with minimal access."));
288 printf (_(UT_SUPPORT));
292 void
293 print_usage (void)
295 printf ("\
296 Usage: %s -q SQL_query [-w warn] [-c crit]\n\
297 [-d database] [-H host] [-P port] [-u user] [-p password]\n",
298 progname);