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.c453
1 files changed, 232 insertions, 221 deletions
diff --git a/plugins/check_game.c b/plugins/check_game.c
index 8548bbd..9f9ff7d 100644
--- a/plugins/check_game.c
+++ b/plugins/check_game.c
@@ -19,7 +19,7 @@
19 19
20const char *progname = "check_game"; 20const char *progname = "check_game";
21const char *revision = "$Revision$"; 21const char *revision = "$Revision$";
22const char *copyright = "2002-2004"; 22const char *copyright = "2002-2005";
23const char *email = "nagiosplug-devel@lists.sourceforge.net"; 23const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 24
25#include "common.h" 25#include "common.h"
@@ -31,12 +31,12 @@ int validate_arguments (void);
31void print_help (void); 31void print_help (void);
32void print_usage (void); 32void print_usage (void);
33 33
34#define QSTAT_DATA_DELIMITER "," 34#define QSTAT_DATA_DELIMITER ","
35 35
36#define QSTAT_HOST_ERROR "ERROR" 36#define QSTAT_HOST_ERROR "ERROR"
37#define QSTAT_HOST_DOWN "DOWN" 37#define QSTAT_HOST_DOWN "DOWN"
38#define QSTAT_HOST_TIMEOUT "TIMEOUT" 38#define QSTAT_HOST_TIMEOUT "TIMEOUT"
39#define QSTAT_MAX_RETURN_ARGS 12 39#define QSTAT_MAX_RETURN_ARGS 12
40 40
41char *server_ip; 41char *server_ip;
42char *game_type; 42char *game_type;
@@ -54,239 +54,241 @@ int qstat_ping_field = -1;
54int 54int
55main (int argc, char **argv) 55main (int argc, char **argv)
56{ 56{
57 char *command_line; 57 char *command_line;
58 int result = STATE_UNKNOWN; 58 int result = STATE_UNKNOWN;
59 char *p, *ret[QSTAT_MAX_RETURN_ARGS]; 59 char *p, *ret[QSTAT_MAX_RETURN_ARGS];
60 size_t i = 0; 60 size_t i = 0;
61 output chld_out; 61 output chld_out;
62 62
63 setlocale (LC_ALL, ""); 63 setlocale (LC_ALL, "");
64 bindtextdomain (PACKAGE, LOCALEDIR); 64 bindtextdomain (PACKAGE, LOCALEDIR);
65 textdomain (PACKAGE); 65 textdomain (PACKAGE);
66 66
67 if (process_arguments (argc, argv) == ERROR) 67 if (process_arguments (argc, argv) == ERROR)
68 usage_va(_("Could not parse arguments")); 68 usage_va(_("Could not parse arguments"));
69 69
70 result = STATE_OK; 70 result = STATE_OK;
71 71
72 /* create the command line to execute */ 72 /* create the command line to execute */
73 asprintf (&command_line, "%s -raw %s -%s %s", 73 asprintf (&command_line, "%s -raw %s -%s %s",
74 PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip); 74 PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip);
75 75
76 if (port) 76 if (port)
77 asprintf (&command_line, "%s:%-d", command_line, port); 77 asprintf (&command_line, "%s:%-d", command_line, port);
78 78
79 if (verbose > 0) 79 if (verbose > 0)
80 printf ("%s\n", command_line); 80 printf ("%s\n", command_line);
81 81
82 /* run the command. historically, this plugin ignores output on stderr, 82 /* run the command. historically, this plugin ignores output on stderr,
83 * as well as return status of the qstat program */ 83 * as well as return status of the qstat program */
84 (void)np_runcmd(command_line, &chld_out, NULL, 0); 84 (void)np_runcmd(command_line, &chld_out, NULL, 0);
85 85
86 /* sanity check */ 86 /* sanity check */
87 /* was thinking about running qstat without any options, capturing the 87 /* was thinking about running qstat without any options, capturing the
88 -default line, parsing it & making an array of all know server types 88 -default line, parsing it & making an array of all know server types
89 but thought this would be too much hassle considering this is a tool 89 but thought this would be too much hassle considering this is a tool
90 for intelligent sysadmins (ha). Could put a static array of known 90 for intelligent sysadmins (ha). Could put a static array of known
91 server types in a header file but then we'd be limiting ourselves 91 server types in a header file but then we'd be limiting ourselves
92 92
93 In the end, I figured I'd simply let an error occur & then trap it 93 In the end, I figured I'd simply let an error occur & then trap it
94 */ 94 */
95 95
96 if (!strncmp (chld_out.line[0], "unknown option", 14)) { 96 if (!strncmp (chld_out.line[0], "unknown option", 14)) {
97 printf (_("CRITICAL - Host type parameter incorrect!\n")); 97 printf (_("CRITICAL - Host type parameter incorrect!\n"));
98 result = STATE_CRITICAL; 98 result = STATE_CRITICAL;
99 return result; 99 return result;
100 } 100 }
101 101
102 p = (char *) strtok (chld_out.line[0], QSTAT_DATA_DELIMITER); 102 p = (char *) strtok (chld_out.line[0], QSTAT_DATA_DELIMITER);
103 while (p != NULL) { 103 while (p != NULL) {
104 ret[i] = p; 104 ret[i] = p;
105 p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER); 105 p = (char *) strtok (NULL, QSTAT_DATA_DELIMITER);
106 i++; 106 i++;
107 if (i >= QSTAT_MAX_RETURN_ARGS) 107 if (i >= QSTAT_MAX_RETURN_ARGS)
108 break; 108 break;
109 } 109 }
110 110
111 if (strstr (ret[2], QSTAT_HOST_ERROR)) { 111 if (strstr (ret[2], QSTAT_HOST_ERROR)) {
112 printf (_("CRITICAL - Host not found\n")); 112 printf (_("CRITICAL - Host not found\n"));
113 result = STATE_CRITICAL; 113 result = STATE_CRITICAL;
114 } 114 }
115 else if (strstr (ret[2], QSTAT_HOST_DOWN)) { 115 else if (strstr (ret[2], QSTAT_HOST_DOWN)) {
116 printf (_("CRITICAL - Game server down or unavailable\n")); 116 printf (_("CRITICAL - Game server down or unavailable\n"));
117 result = STATE_CRITICAL; 117 result = STATE_CRITICAL;
118 } 118 }
119 else if (strstr (ret[2], QSTAT_HOST_TIMEOUT)) { 119 else if (strstr (ret[2], QSTAT_HOST_TIMEOUT)) {
120 printf (_("CRITICAL - Game server timeout\n")); 120 printf (_("CRITICAL - Game server timeout\n"));
121 result = STATE_CRITICAL; 121 result = STATE_CRITICAL;
122 } 122 }
123 else { 123 else {
124 printf ("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", 124 printf ("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n",
125 ret[qstat_game_players], 125 ret[qstat_game_players],
126 ret[qstat_game_players_max], 126 ret[qstat_game_players_max],
127 ret[qstat_game_field], 127 ret[qstat_game_field],
128 ret[qstat_map_field], 128 ret[qstat_map_field],
129 ret[qstat_ping_field], 129 ret[qstat_ping_field],
130 perfdata ("players", atol(ret[qstat_game_players]), "", 130 perfdata ("players", atol(ret[qstat_game_players]), "",
131 FALSE, 0, FALSE, 0, 131 FALSE, 0, FALSE, 0,
132 TRUE, 0, TRUE, atol(ret[qstat_game_players_max])), 132 TRUE, 0, TRUE, atol(ret[qstat_game_players_max])),
133 fperfdata ("ping", strtod(ret[qstat_ping_field], NULL), "", 133 fperfdata ("ping", strtod(ret[qstat_ping_field], NULL), "",
134 FALSE, 0, FALSE, 0, 134 FALSE, 0, FALSE, 0,
135 TRUE, 0, FALSE, 0)); 135 TRUE, 0, FALSE, 0));
136 } 136 }
137 137
138 return result; 138 return result;
139} 139}
140 140
141 141
142int 142int
143process_arguments (int argc, char **argv) 143process_arguments (int argc, char **argv)
144{ 144{
145 int c; 145 int c;
146 146
147 int opt_index = 0; 147 int opt_index = 0;
148 static struct option long_opts[] = { 148 static struct option long_opts[] = {
149 {"help", no_argument, 0, 'h'}, 149 {"help", no_argument, 0, 'h'},
150 {"version", no_argument, 0, 'V'}, 150 {"version", no_argument, 0, 'V'},
151 {"verbose", no_argument, 0, 'v'}, 151 {"verbose", no_argument, 0, 'v'},
152 {"timeout", required_argument, 0, 't'}, 152 {"timeout", required_argument, 0, 't'},
153 {"hostname", required_argument, 0, 'H'}, 153 {"hostname", required_argument, 0, 'H'},
154 {"port", required_argument, 0, 'P'}, 154 {"port", required_argument, 0, 'P'},
155 {"game-type", required_argument, 0, 'G'}, 155 {"game-type", required_argument, 0, 'G'},
156 {"map-field", required_argument, 0, 'm'}, 156 {"map-field", required_argument, 0, 'm'},
157 {"ping-field", required_argument, 0, 'p'}, 157 {"ping-field", required_argument, 0, 'p'},
158 {"game-field", required_argument, 0, 'g'}, 158 {"game-field", required_argument, 0, 'g'},
159 {"players-field", required_argument, 0, 129}, 159 {"players-field", required_argument, 0, 129},
160 {"max-players-field", required_argument, 0, 130}, 160 {"max-players-field", required_argument, 0, 130},
161 {0, 0, 0, 0} 161 {0, 0, 0, 0}
162 }; 162 };
163 163
164 if (argc < 2) 164 if (argc < 2)
165 return ERROR; 165 return ERROR;
166 166
167 for (c = 1; c < argc; c++) { 167 for (c = 1; c < argc; c++) {
168 if (strcmp ("-mf", argv[c]) == 0) 168 if (strcmp ("-mf", argv[c]) == 0)
169 strcpy (argv[c], "-m"); 169 strcpy (argv[c], "-m");
170 else if (strcmp ("-pf", argv[c]) == 0) 170 else if (strcmp ("-pf", argv[c]) == 0)
171 strcpy (argv[c], "-p"); 171 strcpy (argv[c], "-p");
172 else if (strcmp ("-gf", argv[c]) == 0) 172 else if (strcmp ("-gf", argv[c]) == 0)
173 strcpy (argv[c], "-g"); 173 strcpy (argv[c], "-g");
174 } 174 }
175 175
176 while (1) { 176 while (1) {
177 c = getopt_long (argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index); 177 c = getopt_long (argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index);
178 178
179 if (c == -1 || c == EOF) 179 if (c == -1 || c == EOF)
180 break; 180 break;
181 181
182 switch (c) { 182 switch (c) {
183 case 'h': /* help */ 183 case 'h': /* help */
184 print_help (); 184 print_help ();
185 exit (STATE_OK); 185 exit (STATE_OK);
186 case 'V': /* version */ 186 case 'V': /* version */
187 print_revision (progname, revision); 187 print_revision (progname, revision);
188 exit (STATE_OK); 188 exit (STATE_OK);
189 case 'v': /* version */ 189 case 'v': /* version */
190 verbose = TRUE; 190 verbose = TRUE;
191 break; 191 break;
192 case 't': /* timeout period */ 192 case 't': /* timeout period */
193 timeout_interval = atoi (optarg); 193 timeout_interval = atoi (optarg);
194 break; 194 break;
195 case 'H': /* hostname */ 195 case 'H': /* hostname */
196 if (strlen (optarg) >= MAX_HOST_ADDRESS_LENGTH) 196 if (strlen (optarg) >= MAX_HOST_ADDRESS_LENGTH)
197 die (STATE_UNKNOWN, _("Input buffer overflow\n")); 197 die (STATE_UNKNOWN, _("Input buffer overflow\n"));
198 server_ip = optarg; 198 server_ip = optarg;
199 break; 199 break;
200 case 'P': /* port */ 200 case 'P': /* port */
201 port = atoi (optarg); 201 port = atoi (optarg);
202 break; 202 break;
203 case 'G': /* hostname */ 203 case 'G': /* hostname */
204 if (strlen (optarg) >= MAX_INPUT_BUFFER) 204 if (strlen (optarg) >= MAX_INPUT_BUFFER)
205 die (STATE_UNKNOWN, _("Input buffer overflow\n")); 205 die (STATE_UNKNOWN, _("Input buffer overflow\n"));
206 game_type = optarg; 206 game_type = optarg;
207 break; 207 break;
208 case 'p': /* index of ping field */ 208 case 'p': /* index of ping field */
209 qstat_ping_field = atoi (optarg); 209 qstat_ping_field = atoi (optarg);
210 if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS) 210 if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS)
211 return ERROR; 211 return ERROR;
212 break; 212 break;
213 case 'm': /* index on map field */ 213 case 'm': /* index on map field */
214 qstat_map_field = atoi (optarg); 214 qstat_map_field = atoi (optarg);
215 if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS) 215 if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS)
216 return ERROR; 216 return ERROR;
217 break; 217 break;
218 case 'g': /* index of game field */ 218 case 'g': /* index of game field */
219 qstat_game_field = atoi (optarg); 219 qstat_game_field = atoi (optarg);
220 if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS) 220 if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS)
221 return ERROR; 221 return ERROR;
222 break; 222 break;
223 case 129: /* index of player count field */ 223 case 129: /* index of player count field */
224 qstat_game_players = atoi (optarg); 224 qstat_game_players = atoi (optarg);
225 if (qstat_game_players_max == 0) 225 if (qstat_game_players_max == 0)
226 qstat_game_players_max = qstat_game_players - 1; 226 qstat_game_players_max = qstat_game_players - 1;
227 if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS) 227 if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS)
228 return ERROR; 228 return ERROR;
229 break; 229 break;
230 case 130: /* index of max players field */ 230 case 130: /* index of max players field */
231 qstat_game_players_max = atoi (optarg); 231 qstat_game_players_max = atoi (optarg);
232 if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) 232 if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
233 return ERROR; 233 return ERROR;
234 break; 234 break;
235 default: /* args not parsable */ 235 default: /* args not parsable */
236 usage_va(_("Unknown argument - %s"), optarg); 236 usage_va(_("Unknown argument - %s"), optarg);
237 } 237 }
238 } 238 }
239 239
240 c = optind; 240 c = optind;
241 /* first option is the game type */ 241 /* first option is the game type */
242 if (!game_type && c<argc) 242 if (!game_type && c<argc)
243 game_type = strdup (argv[c++]); 243 game_type = strdup (argv[c++]);
244 244
245 /* Second option is the server name */ 245 /* Second option is the server name */
246 if (!server_ip && c<argc) 246 if (!server_ip && c<argc)
247 server_ip = strdup (argv[c++]); 247 server_ip = strdup (argv[c++]);
248 248
249 return validate_arguments (); 249 return validate_arguments ();
250} 250}
251 251
252 252
253int 253int
254validate_arguments (void) 254validate_arguments (void)
255{ 255{
256 if (qstat_game_players_max < 0) 256 if (qstat_game_players_max < 0)
257 qstat_game_players_max = 4; 257 qstat_game_players_max = 4;
258 258
259 if (qstat_game_players < 0) 259 if (qstat_game_players < 0)
260 qstat_game_players = 5; 260 qstat_game_players = 5;
261 261
262 if (qstat_game_field < 0) 262 if (qstat_game_field < 0)
263 qstat_game_field = 2; 263 qstat_game_field = 2;
264 264
265 if (qstat_map_field < 0) 265 if (qstat_map_field < 0)
266 qstat_map_field = 3; 266 qstat_map_field = 3;
267 267
268 if (qstat_ping_field < 0) 268 if (qstat_ping_field < 0)
269 qstat_ping_field = 5; 269 qstat_ping_field = 5;
270 270
271 return OK; 271 return OK;
272} 272}
273 273
274 274
275void 275void
276print_help (void) 276print_help (void)
277{ 277{
278 print_revision (progname, revision); 278 print_revision (progname, revision);
279 279
280 printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n"); 280 printf ("Copyright (c) 1999 Ian Cass, Knowledge Matters Limited\n");
281 printf (COPYRIGHT, copyright, email); 281 printf (COPYRIGHT, copyright, email);
282 282
283 printf (_("This plugin tests game server connections with the specified host.")); 283 printf (_("This plugin tests game server connections with the specified host."));
284 284
285 print_usage (); 285 printf ("\n\n");
286
287 print_usage ();
286 288
287 printf (_(UT_HELP_VRSN)); 289 printf (_(UT_HELP_VRSN));
288 290
289 printf (_("\ 291 printf (_("\
290<game> = Game type that is recognised by qstat (without the leading dash)\n\ 292<game> = Game type that is recognised by qstat (without the leading dash)\n\
291<ip_address> = The IP address of the device you wish to query\n\ 293<ip_address> = The IP address of the device you wish to query\n\
292 [port] = Optional port of which to connect\n\ 294 [port] = Optional port of which to connect\n\
@@ -294,15 +296,25 @@ print_help (void)
294 [map_field] = Field number in raw qstat output that contains map name\n\ 296 [map_field] = Field number in raw qstat output that contains map name\n\
295 [ping_field] = Field number in raw qstat output that contains ping time\n")); 297 [ping_field] = Field number in raw qstat output that contains ping time\n"));
296 298
297 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); 299 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
298 300
299 printf (_("\n\ 301 printf (_("Notes:"));
300Notes:\n\ 302
301- This plugin uses the 'qstat' command, the popular game server status query tool .\n\ 303 printf ("\n");
302 If you don't have the package installed, you will need to download it from\n\
303 http://www.activesw.com/people/steve/qstat.html before you can use this plugin.\n"));
304 304
305 printf (_(UT_SUPPORT)); 305 printf (_("This plugin uses the 'qstat' command, the popular game server status query tool ."));
306
307 printf ("\n");
308
309 printf (_("If you don't have the package installed, you will need to download it from"));
310
311 printf ("\n");
312
313 printf (_("http://www.activesw.com/people/steve/qstat.html before you can use this plugin."));
314
315 printf ("\n");
316
317 printf (_(UT_SUPPORT));
306} 318}
307 319
308 320
@@ -310,9 +322,8 @@ Notes:\n\
310void 322void
311print_usage (void) 323print_usage (void)
312{ 324{
313 printf ("\ 325 printf (_("Usage:"));
314Usage: %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field]\n\ 326 printf (" %s <game> <ip_address> [-p port] [-gf game_field] [-mf map_field] [-pf ping_field]\n", progname);
315 [-pf ping_field]\n", progname);
316} 327}
317 328
318/****************************************************************************** 329/******************************************************************************