Code

mysql detection cleanup: fixes runtime linking, autodetection of main
[nagiosplug.git] / plugins / check_mysql_query.c
1 /******************************************************************************
2 *
3 * CHECK_MYSQL_QUERY.C
4 *
5 * Program: Mysql plugin for Nagios
6 * License: GPL
7 * Copyright (c) 2006 Nagios Plugins Team, after Didi Rieder (check_mysql)
8
9 * $Id$
10 *
11 * Description:
12 *  This plugin is for running arbitrary SQL and checking the results
13 *
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)
46 {
48         MYSQL mysql;
49         MYSQL_RES *res;
50         MYSQL_ROW row;
51         
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));
82         }
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);
88         }
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);
95         }
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"));
101         }
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);
109         }
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]);
119         }
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"));
134         }
135         printf(_("'%s' returned %f"), sql_query, value);
136         printf("\n");
138         return status;
142 /* process command-line arguments */
143 int
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}
164         };
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;
179                         }
180                         else {
181                                 usage2 (_("Invalid hostname/address"), optarg);
182                         }
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++;
197                         }
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);
222                 }
223         }
225         c = optind;
227         set_thresholds(&my_thresholds, warning, critical);
229         return validate_arguments ();
233 int
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);