diff options
Diffstat (limited to 'plugins/check_game.c')
-rw-r--r-- | plugins/check_game.c | 453 |
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 | ||
20 | const char *progname = "check_game"; | 20 | const char *progname = "check_game"; |
21 | const char *revision = "$Revision$"; | 21 | const char *revision = "$Revision$"; |
22 | const char *copyright = "2002-2004"; | 22 | const char *copyright = "2002-2005"; |
23 | const char *email = "nagiosplug-devel@lists.sourceforge.net"; | 23 | const 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); | |||
31 | void print_help (void); | 31 | void print_help (void); |
32 | void print_usage (void); | 32 | void 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 | ||
41 | char *server_ip; | 41 | char *server_ip; |
42 | char *game_type; | 42 | char *game_type; |
@@ -54,239 +54,241 @@ int qstat_ping_field = -1; | |||
54 | int | 54 | int |
55 | main (int argc, char **argv) | 55 | main (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 | ||
142 | int | 142 | int |
143 | process_arguments (int argc, char **argv) | 143 | process_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 | ||
253 | int | 253 | int |
254 | validate_arguments (void) | 254 | validate_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 | ||
275 | void | 275 | void |
276 | print_help (void) | 276 | print_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:")); |
300 | Notes:\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\ | |||
310 | void | 322 | void |
311 | print_usage (void) | 323 | print_usage (void) |
312 | { | 324 | { |
313 | printf ("\ | 325 | printf (_("Usage:")); |
314 | Usage: %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 | /****************************************************************************** |