summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_game.c363
1 files changed, 190 insertions, 173 deletions
diff --git a/plugins/check_game.c b/plugins/check_game.c
index 8cf1bf4..db28dfd 100644
--- a/plugins/check_game.c
+++ b/plugins/check_game.c
@@ -1,75 +1,54 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2*
3 * CHECK_GAME.C 3* This program is free software; you can redistribute it and/or modify
4 * 4* it under the terms of the GNU General Public License as published by
5 * Program: GAME plugin for Nagios 5* the Free Software Foundation; either version 2 of the License, or
6 * License: GPL 6* (at your option) any later version.
7 * Copyright (c) 1999 Ian Cass (ian@knowledge.com) 7*
8 * 8* This program is distributed in the hope that it will be useful,
9 * Last Modified: $Date$ 9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * 10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * Mod History 11* GNU General Public License for more details.
12 * 12*
13 * 25-8-99 Ethan Galstad <nagios@nagios.org> 13* You should have received a copy of the GNU General Public License
14 * Integrated with common plugin code, minor cleanup stuff 14* along with this program; if not, write to the Free Software
15 * 15* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 * 17-8-99 version 1.1b 16*
17 * 17*****************************************************************************/
18 * 17-8-99 make port a separate argument so we can use something like 18
19 * check_game q2s!27910 with the probe set up as 19const char *progname = "check_game";
20 * check_game $ARG1$ $HOSTADDRESS$ $ARG2$ 20const char *revision = "$Revision$";
21 * 21const char *copyright = "2002-2003";
22 * 17-8-99 Put in sanity check for ppl who enter the wrong server type 22const char *authors = "Nagios Plugin Development Team";
23 * 23const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 * 17-8-99 Release version 1.0b 24
25 * 25const char *summary = "\
26 * Command line: CHECK_GAME <server type> <ip_address> [port] 26This plugin tests %s connections with the specified host.\n";
27 * 27
28 * server type = a server type that qstat understands (type qstat & look at the -default line) 28const char *option_summary = "\
29 * ip_address = either a dotted address or a FQD name 29%s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field] [-pf ping_field]\n";
30 * port = defaults game default port 30
31 * 31const char *options = "\
32 * 32<game> = Game type that is recognised by qstat (without the leading dash)\n\
33 * Description: 33<ip_address> = The IP address of the device you wish to query\n\
34 * 34 [port] = Optional port of which to connect\n\
35 * Needed to explore writing my own probes for nagios. It looked 35 [game_field] = Field number in raw qstat output that contains game name\n\
36 * pretty simple so I thought I'd write one for monitoring the status 36 [map_field] = Field number in raw qstat output that contains map name\n\
37 * of game servers. It uses qstat to do the actual monitoring and 37 [ping_field] = Field number in raw qstat output that contains ping time\n\
38 * analyses the result. Doing it this way means I can support all the 38\n\
39 * servers that qstat does and will do in the future. 39Notes:\n\
40 * 40- This plugin uses the 'qstat' command, the popular game server status query tool .\n\
41 * 41 If you don't have the package installed, you will need to download it from\n\
42 * Dependencies: 42 http://www.activesw.com/people/steve/qstat.html before you can use this plugin.\n";
43 * 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" 44#include "common.h"
45#include "popen.h"
69#include "utils.h" 46#include "utils.h"
70 47
48void print_usage (void);
49void print_help (void);
71int process_arguments (int, char **); 50int process_arguments (int, char **);
72const char *progname = "check_game"; 51int validate_arguments (void);
73 52
74#define QSTAT_DATA_DELIMITER "," 53#define QSTAT_DATA_DELIMITER ","
75 54
@@ -78,9 +57,11 @@ const char *progname = "check_game";
78#define QSTAT_HOST_TIMEOUT "TIMEOUT" 57#define QSTAT_HOST_TIMEOUT "TIMEOUT"
79#define QSTAT_MAX_RETURN_ARGS 12 58#define QSTAT_MAX_RETURN_ARGS 12
80 59
81char server_ip[MAX_HOST_ADDRESS_LENGTH]; 60char *server_ip;
82char game_type[MAX_INPUT_BUFFER]; 61char *game_type;
83char port[MAX_INPUT_BUFFER]; 62int port = 0;
63
64int verbose;
84 65
85int qstat_game_players_max = 4; 66int qstat_game_players_max = 4;
86int qstat_game_players = 5; 67int qstat_game_players = 5;
@@ -92,13 +73,10 @@ int qstat_ping_field = 5;
92int 73int
93main (int argc, char **argv) 74main (int argc, char **argv)
94{ 75{
95 char command_line[MAX_INPUT_BUFFER]; 76 char *command_line;
96 int result; 77 int result;
97 FILE *fp; 78 FILE *fp;
98 char input_buffer[MAX_INPUT_BUFFER]; 79 char input_buffer[MAX_INPUT_BUFFER];
99 char response[MAX_INPUT_BUFFER];
100 char *temp_ptr;
101 int found;
102 char *p, *ret[QSTAT_MAX_RETURN_ARGS]; 80 char *p, *ret[QSTAT_MAX_RETURN_ARGS];
103 int i; 81 int i;
104 82
@@ -111,49 +89,28 @@ main (int argc, char **argv)
111 printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n"); 89 printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n");
112 printf ("License: GPL\n"); 90 printf ("License: GPL\n");
113 printf ("\n"); 91 printf ("\n");
114 printf
115 ("Usage: %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field] [-pf ping_field]\n",
116 argv[0]);
117 printf ("\n");
118 printf ("Options:\n");
119 printf
120 (" <game> = Game type that is recognised by qstat (without the leading dash)\n");
121 printf
122 (" <ip_address> = The IP address of the device you wish to query\n");
123 printf (" [port] = Optional port of which to connect\n");
124 printf
125 (" [game_field] = Field number in raw qstat output that contains game name\n");
126 printf
127 (" [map_field] = Field number in raw qstat output that contains map name\n");
128 printf
129 (" [ping_field] = Field number in raw qstat output that contains ping time\n");
130 printf ("\n");
131 printf ("Notes:\n");
132 printf
133 ("- This plugin uses the 'qstat' command, the popular game server status query tool .\n");
134 printf
135 (" If you don't have the package installed, you will need to download it from\n");
136 printf
137 (" http://www.activesw.com/people/steve/qstat.html before you can use this plugin.\n");
138 printf ("\n");
139 return STATE_UNKNOWN; 92 return STATE_UNKNOWN;
140 } 93 }
141 94
142 result = STATE_OK; 95 result = STATE_OK;
143 96
144 /* create the command line to execute */ 97 /* create the command line to execute */
145 snprintf (command_line, sizeof (command_line) - 1, "%s -raw %s -%s %s%s", 98 asprintf (&command_line, "%s -raw %s -%s %s",
146 PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip, port); 99 PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip);
147 command_line[sizeof (command_line) - 1] = 0; 100
101 if (port)
102 asprintf (&command_line, "%s:%-d", command_line, port);
103
104 if (verbose > 0)
105 printf ("%s\n", command_line);
148 106
149 /* run the command */ 107 /* run the command */
150 fp = popen (command_line, "r"); 108 fp = spopen (command_line);
151 if (fp == NULL) { 109 if (fp == NULL) {
152 printf ("Error - Could not open pipe: %s\n", command_line); 110 printf ("Error - Could not open pipe: %s\n", command_line);
153 return STATE_UNKNOWN; 111 return STATE_UNKNOWN;
154 } 112 }
155 113
156 found = 0;
157 fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */ 114 fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp); /* Only interested in the first line */
158 115
159 /* strip the newline character from the end of the input */ 116 /* strip the newline character from the end of the input */
@@ -203,15 +160,15 @@ main (int argc, char **argv)
203 } 160 }
204 else { 161 else {
205 printf ("OK: %s/%s %s (%s), Ping: %s ms\n", 162 printf ("OK: %s/%s %s (%s), Ping: %s ms\n",
206 ret[qstat_game_players_max], 163 ret[qstat_game_players],
207 ret[qstat_game_players], 164 ret[qstat_game_players_max],
208 ret[qstat_game_field], 165 ret[qstat_game_field],
209 ret[qstat_map_field], 166 ret[qstat_map_field],
210 ret[qstat_ping_field]); 167 ret[qstat_ping_field]);
211 } 168 }
212 169
213 /* close the pipe */ 170 /* close the pipe */
214 pclose (fp); 171 spclose (fp);
215 172
216 return result; 173 return result;
217} 174}
@@ -221,79 +178,139 @@ main (int argc, char **argv)
221int 178int
222process_arguments (int argc, char **argv) 179process_arguments (int argc, char **argv)
223{ 180{
224 int x; 181 int c;
225 182
226 /* not enough options were supplied */ 183 int opt_index = 0;
227 if (argc < 3) 184 static struct option long_opts[] = {
185 {"help", no_argument, 0, 'h'},
186 {"version", no_argument, 0, 'V'},
187 {"verbose", no_argument, 0, 'v'},
188 {"timeout", required_argument, 0, 't'},
189 {"hostname", required_argument, 0, 'H'},
190 {"port", required_argument, 0, 'P'},
191 {"game-type", required_argument, 0, 'G'},
192 {"map-field", required_argument, 0, 'm'},
193 {"ping-field", required_argument, 0, 'p'},
194 {"game-field", required_argument, 0, 'g'},
195 {"players-field", required_argument, 0, 129},
196 {"max-players-field", required_argument, 0, 130},
197 {0, 0, 0, 0}
198 };
199
200 if (argc < 2)
228 return ERROR; 201 return ERROR;
229 202
230 /* first option is always the game type */ 203 for (c = 1; c < argc; c++) {
231 strncpy (game_type, argv[1], sizeof (game_type) - 1); 204 if (strcmp ("-mf", argv[c]) == 0)
232 game_type[sizeof (game_type) - 1] = 0; 205 strcpy (argv[c], "-m");
233 206 else if (strcmp ("-pf", argv[c]) == 0)
234 /* Second option is always the server name */ 207 strcpy (argv[c], "-p");
235 strncpy (server_ip, argv[2], sizeof (server_ip) - 1); 208 else if (strcmp ("-gf", argv[c]) == 0)
236 server_ip[sizeof (server_ip) - 1] = 0; 209 strcpy (argv[c], "-g");
237 210 }
238 /* process all remaining arguments */
239 for (x = 4; x <= argc; x++) {
240
241 /* we got the port number to connect to */
242 if (!strcmp (argv[x - 1], "-p")) {
243 if (x < argc) {
244 snprintf (port, sizeof (port) - 2, ":%s", argv[x]);
245 port[sizeof (port) - 1] = 0;
246 x++;
247 }
248 else
249 return ERROR;
250 }
251 211
252 /* we got the game field */ 212 while (1) {
253 else if (!strcmp (argv[x - 1], "-gf")) { 213 c = getopt_long (argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index);
254 if (x < argc) {
255 qstat_game_field = atoi (argv[x]);
256 if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
257 return ERROR;
258 x++;
259 }
260 else
261 return ERROR;
262 }
263 214
264 /* we got the map field */ 215 if (c == -1 || c == EOF)
265 else if (!strcmp (argv[x - 1], "-mf")) { 216 break;
266 if (x < argc) {
267 qstat_map_field = atoi (argv[x]);
268 if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
269 return ERROR;
270 x++;
271 }
272 else
273 return ERROR;
274 }
275 217
276 /* we got the ping field */ 218 switch (c) {
277 else if (!strcmp (argv[x - 1], "-pf")) { 219 case '?': /* args not parsable */
278 if (x < argc) { 220 printf ("%s: Unknown argument: %s\n\n", progname, optarg);
279 qstat_ping_field = atoi (argv[x]); 221 print_usage ();
280 if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS) 222 exit (STATE_UNKNOWN);
281 return ERROR; 223 case 'h': /* help */
282 x++; 224 print_help ();
283 } 225 exit (STATE_OK);
284 else 226 case 'V': /* version */
227 print_revision (progname, revision);
228 exit (STATE_OK);
229 case 'v': /* version */
230 verbose = TRUE;
231 break;
232 case 't': /* timeout period */
233 timeout_interval = atoi (optarg);
234 break;
235 case 'H': /* hostname */
236 if (strlen (optarg) >= MAX_HOST_ADDRESS_LENGTH)
237 terminate (STATE_UNKNOWN, "Input buffer overflow\n");
238 server_ip = strdup (optarg);
239 break;
240 case 'P': /* port */
241 port = atoi (optarg);
242 break;
243 case 'G': /* hostname */
244 if (strlen (optarg) >= MAX_INPUT_BUFFER)
245 terminate (STATE_UNKNOWN, "Input buffer overflow\n");
246 game_type = strdup (optarg);
247 break;
248 case 'p': /* index of ping field */
249 qstat_ping_field = atoi (optarg);
250 if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS)
251 return ERROR;
252 break;
253 case 'm': /* index on map field */
254 qstat_map_field = atoi (optarg);
255 if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
285 return ERROR; 256 return ERROR;
257 break;
258 case 'g': /* index of game field */
259 qstat_game_field = atoi (optarg);
260 if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
261 return ERROR;
262 break;
263 case 129: /* index of player count field */
264 qstat_game_players = atoi (optarg);
265 if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS)
266 return ERROR;
267 break;
268 case 130: /* index of max players field */
269 qstat_game_players_max = atoi (optarg);
270 if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
271 return ERROR;
272 break;
286 } 273 }
287
288 /* else we got something else... */
289 else
290 return ERROR;
291 } 274 }
292 275
293 return OK; 276 c = optind;
277 /* first option is the game type */
278 if (!game_type && c<argc)
279 game_type = strdup (argv[c++]);
280
281 /* Second option is the server name */
282 if (!server_ip && c<argc)
283 server_ip = strdup (argv[c++]);
284
285 return validate_arguments ();
294} 286}
295 287
296void print_usage (void) 288int
289validate_arguments (void)
297{ 290{
298 return STATE_OK; 291 return OK;
299} 292}
293
294
295void
296print_help (void)
297{
298 print_revision (progname, revision);
299 printf ("Copyright (c) %s %s\n\t<%s>\n\n",
300 copyright, authors, email);
301 printf (summary, progname);
302 print_usage ();
303 printf ("\nOptions:\n");
304 printf (options, DEFAULT_SOCKET_TIMEOUT);
305 support ();
306}
307
308void
309print_usage (void)
310{
311 printf
312 ("Usage: %s %s\n"
313 " %s (-h|--help)\n"
314 " %s (-V|--version)\n", progname, option_summary, progname, progname);
315}
316