summaryrefslogtreecommitdiffstats
path: root/plugins/check_game.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_game.c')
-rw-r--r--plugins/check_game.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/plugins/check_game.c b/plugins/check_game.c
new file mode 100644
index 0000000..63d1be6
--- /dev/null
+++ b/plugins/check_game.c
@@ -0,0 +1,287 @@
1/******************************************************************************
2 *
3 * CHECK_GAME.C
4 *
5 * Program: GAME plugin for Nagios
6 * License: GPL
7 * Copyright (c) 1999 Ian Cass (ian@knowledge.com)
8 *
9 * Last Modified: $Date$
10 *
11 * Mod History
12 *
13 * 25-8-99 Ethan Galstad <nagios@nagios.org>
14 * Integrated with common plugin code, minor cleanup stuff
15 *
16 * 17-8-99 version 1.1b
17 *
18 * 17-8-99 make port a separate argument so we can use something like
19 * check_game q2s!27910 with the probe set up as
20 * check_game $ARG1$ $HOSTADDRESS$ $ARG2$
21 *
22 * 17-8-99 Put in sanity check for ppl who enter the wrong server type
23 *
24 * 17-8-99 Release version 1.0b
25 *
26 * Command line: CHECK_GAME <server type> <ip_address> [port]
27 *
28 * server type = a server type that qstat understands (type qstat & look at the -default line)
29 * ip_address = either a dotted address or a FQD name
30 * port = defaults game default port
31 *
32 *
33 * Description:
34 *
35 * Needed to explore writing my own probes for nagios. It looked
36 * pretty simple so I thought I'd write one for monitoring the status
37 * of game servers. It uses qstat to do the actual monitoring and
38 * analyses the result. Doing it this way means I can support all the
39 * servers that qstat does and will do in the future.
40 *
41 *
42 * Dependencies:
43 *
44 * This plugin uses the 'qstat' command If you don't
45 * have the package installed you will need to download it from
46 * http://www.activesw.com/people/steve/qstat.html or any popular files archive
47 * before you can use this plugin.
48 *
49 * License Information:
50 *
51 * This program is free software; you can redistribute it and/or modify
52 * it under the terms of the GNU General Public License as published by
53 * the Free Software Foundation; either version 2 of the License, or
54 * (at your option) any later version.
55 *
56 * This program is distributed in the hope that it will be useful,
57 * but WITHOUT ANY WARRANTY; without even the implied warranty of
58 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59 * GNU General Public License for more details.
60 *
61 * You should have received a copy of the GNU General Public License
62 * along with this program; if not, write to the Free Software
63 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
64 *
65 *****************************************************************************/
66
67#include "config.h"
68#include "common.h"
69#include "utils.h"
70
71int process_arguments (int, char **);
72
73#define QSTAT_DATA_DELIMITER ","
74
75#define QSTAT_HOST_ERROR "ERROR"
76#define QSTAT_HOST_DOWN "DOWN"
77#define QSTAT_HOST_TIMEOUT "TIMEOUT"
78#define QSTAT_MAX_RETURN_ARGS 12
79
80char server_ip[MAX_HOST_ADDRESS_LENGTH];
81char game_type[MAX_INPUT_BUFFER];
82char port[MAX_INPUT_BUFFER];
83
84int qstat_game_field = 2;
85int qstat_map_field = 3;
86int qstat_ping_field = 5;
87
88
89int
90main (int argc, char **argv)
91{
92 char command_line[MAX_INPUT_BUFFER];
93 int result;
94 FILE *fp;
95 char input_buffer[MAX_INPUT_BUFFER];
96 char response[MAX_INPUT_BUFFER];
97 char *temp_ptr;
98 int found;
99 char *p, *ret[QSTAT_MAX_RETURN_ARGS];
100 int i;
101
102 result = process_arguments (argc, argv);
103
104 if (result != OK) {
105 printf ("Incorrect arguments supplied\n");
106 printf ("\n");
107 print_revision (argv[0], "$Revision$");
108 printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n");
109 printf ("License: GPL\n");
110 printf ("\n");
111 printf
112 ("Usage: %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field] [-pf ping_field]\n",
113 argv[0]);
114 printf ("\n");
115 printf ("Options:\n");
116 printf
117 (" <game> = Game type that is recognised by qstat (without the leading dash)\n");
118 printf
119 (" <ip_address> = The IP address of the device you wish to query\n");
120 printf (" [port] = Optional port of which to connect\n");
121 printf
122 (" [game_field] = Field number in raw qstat output that contains game name\n");
123 printf
124 (" [map_field] = Field number in raw qstat output that contains map name\n");
125 printf
126 (" [ping_field] = Field number in raw qstat output that contains ping time\n");
127 printf ("\n");
128 printf ("Notes:\n");
129 printf
130 ("- This plugin uses the 'qstat' command, the popular game server status query tool .\n");
131 printf
132 (" If you don't have the package installed, you will need to download it from\n");
133 printf
134 (" http://www.activesw.com/people/steve/qstat.html before you can use this plugin.\n");
135 printf ("\n");
136 return STATE_UNKNOWN;
137 }
138
139 result = STATE_OK;
140
141 /* create the command line to execute */
142 snprintf (command_line, sizeof (command_line) - 1, "%s -raw %s -%s %s%s",
143 PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip, port);
144 command_line[sizeof (command_line) - 1] = 0;
145
146 /* run the command */
147 fp = popen (command_line, "r");
148 if (fp == NULL) {
149 printf ("Error - Could not open pipe: %s\n", command_line);
150 return STATE_UNKNOWN;
151 }
152
153 found = 0;
154 fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */
155
156 /* strip the newline character from the end of the input */
157 input_buffer[strlen (input_buffer) - 1] = 0;
158
159 /* sanity check */
160 /* was thinking about running qstat without any options, capturing the
161 -default line, parsing it & making an array of all know server types
162 but thought this would be too much hassle considering this is a tool
163 for intelligent sysadmins (ha). Could put a static array of known
164 server types in a header file but then we'd be limiting ourselves
165
166 In the end, I figured I'd simply let an error occur & then trap it
167 */
168
169 if (!strncmp (input_buffer, "unknown option", 14)) {
170 printf ("ERROR: Host type parameter incorrect!\n");
171 result = STATE_CRITICAL;
172 return result;
173 }
174
175 /* initialize the returned data buffer */
176 for (i = 0; i < QSTAT_MAX_RETURN_ARGS; i++)
177 ret[i] = "";
178
179 i = 0;
180 p = (char *) strtok (input_buffer, QSTAT_DATA_DELIMITER);
181 while (p != NULL) {
182 ret[i] = p;
183 p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER);
184 i++;
185 if (i >= QSTAT_MAX_RETURN_ARGS)
186 break;
187 }
188
189 if (strstr (ret[2], QSTAT_HOST_ERROR)) {
190 printf ("ERROR: Host not found\n");
191 result = STATE_CRITICAL;
192 }
193 else if (strstr (ret[2], QSTAT_HOST_DOWN)) {
194 printf ("ERROR: Game server down or unavailable\n");
195 result = STATE_CRITICAL;
196 }
197 else if (strstr (ret[2], QSTAT_HOST_TIMEOUT)) {
198 printf ("ERROR: Game server timeout\n");
199 result = STATE_CRITICAL;
200 }
201 else {
202 printf ("OK: %s (%s), Ping: %s ms\n", ret[qstat_game_field],
203 ret[qstat_map_field], ret[qstat_ping_field]);
204 }
205
206 /* close the pipe */
207 pclose (fp);
208
209 return result;
210}
211
212
213
214int
215process_arguments (int argc, char **argv)
216{
217 int x;
218
219 /* not enough options were supplied */
220 if (argc < 3)
221 return ERROR;
222
223 /* first option is always the game type */
224 strncpy (game_type, argv[1], sizeof (game_type) - 1);
225 game_type[sizeof (game_type) - 1] = 0;
226
227 /* Second option is always the server name */
228 strncpy (server_ip, argv[2], sizeof (server_ip) - 1);
229 server_ip[sizeof (server_ip) - 1] = 0;
230
231 /* process all remaining arguments */
232 for (x = 4; x <= argc; x++) {
233
234 /* we got the port number to connect to */
235 if (!strcmp (argv[x - 1], "-p")) {
236 if (x < argc) {
237 snprintf (port, sizeof (port) - 2, ":%s", argv[x]);
238 port[sizeof (port) - 1] = 0;
239 x++;
240 }
241 else
242 return ERROR;
243 }
244
245 /* we got the game field */
246 else if (!strcmp (argv[x - 1], "-gf")) {
247 if (x < argc) {
248 qstat_game_field = atoi (argv[x]);
249 if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
250 return ERROR;
251 x++;
252 }
253 else
254 return ERROR;
255 }
256
257 /* we got the map field */
258 else if (!strcmp (argv[x - 1], "-mf")) {
259 if (x < argc) {
260 qstat_map_field = atoi (argv[x]);
261 if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
262 return ERROR;
263 x++;
264 }
265 else
266 return ERROR;
267 }
268
269 /* we got the ping field */
270 else if (!strcmp (argv[x - 1], "-pf")) {
271 if (x < argc) {
272 qstat_ping_field = atoi (argv[x]);
273 if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS)
274 return ERROR;
275 x++;
276 }
277 else
278 return ERROR;
279 }
280
281 /* else we got something else... */
282 else
283 return ERROR;
284 }
285
286 return OK;
287}