Module: monitoring-plugins
 Branch: master
 Commit: 9f8a485744ba8de13c01cc48a4db0d8d73189c97
 Author: Lorenz Kästle <12514511+rincewinds...@users.noreply.github.com>
   Date: Fri Mar  7 15:58:30 2025 +0100
    URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=9f8a4857

Refactor check_game

---

 plugins/check_game.c          | 211 ++++++++++++++++++++++--------------------
 plugins/check_game.d/config.h |  30 ++++++
 2 files changed, 139 insertions(+), 102 deletions(-)

diff --git a/plugins/check_game.c b/plugins/check_game.c
index 619277e7..58014c3e 100644
--- a/plugins/check_game.c
+++ b/plugins/check_game.c
@@ -36,9 +36,15 @@ const char *email = "devel@monitoring-plugins.org";
 #include "common.h"
 #include "utils.h"
 #include "runcmd.h"
+#include "check_game.d/config.h"
+#include "../lib/monitoringplug.h"
 
-static int process_arguments(int /*argc*/, char ** /*argv*/);
-static int validate_arguments(void);
+typedef struct {
+       int errorcode;
+       check_game_config config;
+} check_game_config_wrapper;
+
+static check_game_config_wrapper process_arguments(int /*argc*/, char ** 
/*argv*/);
 static void print_help(void);
 void print_usage(void);
 
@@ -49,26 +55,9 @@ void print_usage(void);
 #define QSTAT_HOST_TIMEOUT    "TIMEOUT"
 #define QSTAT_MAX_RETURN_ARGS 12
 
-static char *server_ip;
-static char *game_type;
-static int port = 0;
-
 static bool verbose = false;
 
-static int qstat_game_players_max = -1;
-static int qstat_game_players = -1;
-static int qstat_game_field = -1;
-static int qstat_map_field = -1;
-static int qstat_ping_field = -1;
-
 int main(int argc, char **argv) {
-       char *command_line;
-       int result = STATE_UNKNOWN;
-       char *p;
-       char *ret[QSTAT_MAX_RETURN_ARGS];
-       size_t i = 0;
-       output chld_out;
-
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
@@ -76,22 +65,31 @@ int main(int argc, char **argv) {
        /* Parse extra opts if any */
        argv = np_extra_opts(&argc, argv, progname);
 
-       if (process_arguments(argc, argv) == ERROR)
+       check_game_config_wrapper tmp = process_arguments(argc, argv);
+
+       if (tmp.errorcode == ERROR) {
                usage_va(_("Could not parse arguments"));
+       }
 
-       result = STATE_OK;
+       check_game_config config = tmp.config;
+
+       mp_state_enum result = STATE_OK;
 
        /* create the command line to execute */
-       xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, 
QSTAT_DATA_DELIMITER, game_type, server_ip);
+       char *command_line = NULL;
+       xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, 
QSTAT_DATA_DELIMITER, config.game_type, config.server_ip);
 
-       if (port)
-               xasprintf(&command_line, "%s:%-d", command_line, port);
+       if (config.port) {
+               xasprintf(&command_line, "%s:%-d", command_line, config.port);
+       }
 
-       if (verbose)
+       if (verbose) {
                printf("%s\n", command_line);
+       }
 
        /* run the command. historically, this plugin ignores output on stderr,
         * as well as return status of the qstat program */
+       output chld_out = {};
        (void)np_runcmd(command_line, &chld_out, NULL, 0);
 
        /* sanity check */
@@ -104,19 +102,22 @@ int main(int argc, char **argv) {
           In the end, I figured I'd simply let an error occur & then trap it
         */
 
-       if (!strncmp(chld_out.line[0], "unknown option", 14)) {
+       if (!strncmp(chld_out.line[0], "unknown option", strlen("unknown 
option"))) {
                printf(_("CRITICAL - Host type parameter incorrect!\n"));
                result = STATE_CRITICAL;
-               return result;
+               exit(result);
        }
 
-       p = (char *)strtok(chld_out.line[0], QSTAT_DATA_DELIMITER);
-       while (p != NULL) {
-               ret[i] = p;
-               p = (char *)strtok(NULL, QSTAT_DATA_DELIMITER);
+       char *ret[QSTAT_MAX_RETURN_ARGS];
+       size_t i = 0;
+       char *sequence = strtok(chld_out.line[0], QSTAT_DATA_DELIMITER);
+       while (sequence != NULL) {
+               ret[i] = sequence;
+               sequence = strtok(NULL, QSTAT_DATA_DELIMITER);
                i++;
-               if (i >= QSTAT_MAX_RETURN_ARGS)
+               if (i >= QSTAT_MAX_RETURN_ARGS) {
                        break;
+               }
        }
 
        if (strstr(ret[2], QSTAT_HOST_ERROR)) {
@@ -129,18 +130,19 @@ int main(int argc, char **argv) {
                printf(_("CRITICAL - Game server timeout\n"));
                result = STATE_CRITICAL;
        } else {
-               printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", 
ret[qstat_game_players], ret[qstat_game_players_max], ret[qstat_game_field],
-                          ret[qstat_map_field], ret[qstat_ping_field],
-                          perfdata("players", atol(ret[qstat_game_players]), 
"", false, 0, false, 0, true, 0, true, atol(ret[qstat_game_players_max])),
-                          fperfdata("ping", strtod(ret[qstat_ping_field], 
NULL), "", false, 0, false, 0, true, 0, false, 0));
+               printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", 
ret[config.qstat_game_players], ret[config.qstat_game_players_max], 
ret[config.qstat_game_field],
+                          ret[config.qstat_map_field], 
ret[config.qstat_ping_field],
+                          perfdata("players", 
atol(ret[config.qstat_game_players]), "", false, 0, false, 0, true, 0, true, 
atol(ret[config.qstat_game_players_max])),
+                          fperfdata("ping", 
strtod(ret[config.qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, 
false, 0));
        }
 
-       return result;
+       exit(result);
 }
 
-int process_arguments(int argc, char **argv) {
-       int c;
+#define players_field_index 129
+#define max_players_field_index 130
 
+check_game_config_wrapper process_arguments(int argc, char **argv) {
        int opt_index = 0;
        static struct option long_opts[] = {{"help", no_argument, 0, 'h'},
                                                                                
{"version", no_argument, 0, 'V'},
@@ -152,29 +154,38 @@ int process_arguments(int argc, char **argv) {
                                                                                
{"map-field", required_argument, 0, 'm'},
                                                                                
{"ping-field", required_argument, 0, 'p'},
                                                                                
{"game-field", required_argument, 0, 'g'},
-                                                                               
{"players-field", required_argument, 0, 129},
-                                                                               
{"max-players-field", required_argument, 0, 130},
+                                                                               
{"players-field", required_argument, 0, players_field_index},
+                                                                               
{"max-players-field", required_argument, 0, max_players_field_index},
                                                                                
{0, 0, 0, 0}};
 
-       if (argc < 2)
-               return ERROR;
+       check_game_config_wrapper result = {
+               .config = check_game_config_init(),
+               .errorcode = OK,
+       };
 
-       for (c = 1; c < argc; c++) {
-               if (strcmp("-mf", argv[c]) == 0)
-                       strcpy(argv[c], "-m");
-               else if (strcmp("-pf", argv[c]) == 0)
-                       strcpy(argv[c], "-p");
-               else if (strcmp("-gf", argv[c]) == 0)
-                       strcpy(argv[c], "-g");
+       if (argc < 2) {
+               result.errorcode = ERROR;
+               return result;
+       }
+
+       for (int option_counter = 1; option_counter < argc; option_counter++) {
+               if (strcmp("-mf", argv[option_counter]) == 0) {
+                       strcpy(argv[option_counter], "-m");
+               } else if (strcmp("-pf", argv[option_counter]) == 0) {
+                       strcpy(argv[option_counter], "-p");
+               } else if (strcmp("-gf", argv[option_counter]) == 0) {
+                       strcpy(argv[option_counter], "-g");
+               }
        }
 
        while (1) {
-               c = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, 
&opt_index);
+               int option_index = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", 
long_opts, &opt_index);
 
-               if (c == -1 || c == EOF)
+               if (option_index == -1 || option_index == EOF) {
                        break;
+               }
 
-               switch (c) {
+               switch (option_index) {
                case 'h': /* help */
                        print_help();
                        exit(STATE_UNKNOWN);
@@ -188,79 +199,75 @@ int process_arguments(int argc, char **argv) {
                        timeout_interval = atoi(optarg);
                        break;
                case 'H': /* hostname */
-                       if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH)
+                       if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH) {
                                die(STATE_UNKNOWN, _("Input buffer 
overflow\n"));
-                       server_ip = optarg;
+                       }
+                       result.config.server_ip = optarg;
                        break;
                case 'P': /* port */
-                       port = atoi(optarg);
+                       result.config.port = atoi(optarg);
                        break;
                case 'G': /* hostname */
-                       if (strlen(optarg) >= MAX_INPUT_BUFFER)
+                       if (strlen(optarg) >= MAX_INPUT_BUFFER) {
                                die(STATE_UNKNOWN, _("Input buffer 
overflow\n"));
-                       game_type = optarg;
+                       }
+                       result.config.game_type = optarg;
                        break;
                case 'p': /* index of ping field */
-                       qstat_ping_field = atoi(optarg);
-                       if (qstat_ping_field < 0 || qstat_ping_field > 
QSTAT_MAX_RETURN_ARGS)
-                               return ERROR;
+                       result.config.qstat_ping_field = atoi(optarg);
+                       if (result.config.qstat_ping_field < 0 || 
result.config.qstat_ping_field > QSTAT_MAX_RETURN_ARGS) {
+                               result.errorcode = ERROR;
+                               return result;
+                       }
                        break;
                case 'm': /* index on map field */
-                       qstat_map_field = atoi(optarg);
-                       if (qstat_map_field < 0 || qstat_map_field > 
QSTAT_MAX_RETURN_ARGS)
-                               return ERROR;
+                       result.config.qstat_map_field = atoi(optarg);
+                       if (result.config.qstat_map_field < 0 || 
result.config.qstat_map_field > QSTAT_MAX_RETURN_ARGS) {
+                               result.errorcode = ERROR;
+                               return result;
+                       }
                        break;
                case 'g': /* index of game field */
-                       qstat_game_field = atoi(optarg);
-                       if (qstat_game_field < 0 || qstat_game_field > 
QSTAT_MAX_RETURN_ARGS)
-                               return ERROR;
+                       result.config.qstat_game_field = atoi(optarg);
+                       if (result.config.qstat_game_field < 0 || 
result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) {
+                               result.errorcode = ERROR;
+                               return result;
+                       }
                        break;
-               case 129: /* index of player count field */
-                       qstat_game_players = atoi(optarg);
-                       if (qstat_game_players_max == 0)
-                               qstat_game_players_max = qstat_game_players - 1;
-                       if (qstat_game_players < 0 || qstat_game_players > 
QSTAT_MAX_RETURN_ARGS)
-                               return ERROR;
+               case players_field_index: /* index of player count field */
+                       result.config.qstat_game_players = atoi(optarg);
+                       if (result.config.qstat_game_players_max == 0) {
+                               result.config.qstat_game_players_max = 
result.config.qstat_game_players - 1;
+                       }
+                       if (result.config.qstat_game_players < 0 || 
result.config.qstat_game_players > QSTAT_MAX_RETURN_ARGS) {
+                               result.errorcode = ERROR;
+                               return result;
+                       }
                        break;
-               case 130: /* index of max players field */
-                       qstat_game_players_max = atoi(optarg);
-                       if (qstat_game_players_max < 0 || 
qstat_game_players_max > QSTAT_MAX_RETURN_ARGS)
-                               return ERROR;
+               case max_players_field_index: /* index of max players field */
+                       result.config.qstat_game_players_max = atoi(optarg);
+                       if (result.config.qstat_game_players_max < 0 || 
result.config.qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) {
+                               result.errorcode = ERROR;
+                               return result;
+                       }
                        break;
                default: /* args not parsable */
                        usage5();
                }
        }
 
-       c = optind;
+       int option_counter = optind;
        /* first option is the game type */
-       if (!game_type && c < argc)
-               game_type = strdup(argv[c++]);
+       if (!result.config.game_type && option_counter < argc) {
+               result.config.game_type = strdup(argv[option_counter++]);
+       }
 
        /* Second option is the server name */
-       if (!server_ip && c < argc)
-               server_ip = strdup(argv[c++]);
-
-       return validate_arguments();
-}
-
-int validate_arguments(void) {
-       if (qstat_game_players_max < 0)
-               qstat_game_players_max = 4;
-
-       if (qstat_game_players < 0)
-               qstat_game_players = 5;
-
-       if (qstat_game_field < 0)
-               qstat_game_field = 2;
-
-       if (qstat_map_field < 0)
-               qstat_map_field = 3;
-
-       if (qstat_ping_field < 0)
-               qstat_ping_field = 5;
+       if (!result.config.server_ip && option_counter < argc) {
+               result.config.server_ip = strdup(argv[option_counter++]);
+       }
 
-       return OK;
+       return result;
 }
 
 void print_help(void) {
diff --git a/plugins/check_game.d/config.h b/plugins/check_game.d/config.h
new file mode 100644
index 00000000..c95a1ced
--- /dev/null
+++ b/plugins/check_game.d/config.h
@@ -0,0 +1,30 @@
+#pragma once
+#include "../../config.h"
+#include <stddef.h>
+
+typedef struct {
+       char *server_ip;
+       char *game_type;
+       int port;
+
+       int qstat_game_players_max;
+       int qstat_game_players;
+       int qstat_game_field;
+       int qstat_map_field;
+       int qstat_ping_field;
+} check_game_config;
+
+check_game_config check_game_config_init() {
+       check_game_config tmp = {
+               .server_ip = NULL,
+               .game_type = NULL,
+               .port = 0,
+
+               .qstat_game_players_max = 4,
+               .qstat_game_players = 5,
+               .qstat_map_field = 3,
+               .qstat_game_field = 2,
+               .qstat_ping_field = 5,
+       };
+       return tmp;
+}

Reply via email to