Module: monitoring-plugins
 Branch: master
 Commit: de392a81ede00fef1c25e220ee253d487453f6cd
 Author: Lorenz Kästle <12514511+rincewinds...@users.noreply.github.com>
   Date: Wed Mar 12 02:16:41 2025 +0100
    URL: 
https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=de392a81

Refactor check_pgsql

---

 plugins/Makefile.am            |   1 +
 plugins/check_pgsql.c          | 143 +++++++++++++++++++----------------------
 plugins/check_pgsql.d/config.h |  61 ++++++++++++++++++
 3 files changed, 128 insertions(+), 77 deletions(-)

diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 5d4449bf..6ee121ba 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -61,6 +61,7 @@ EXTRA_DIST = t \
                         check_mysql_query.d \
                         check_mrtg.d \
                         check_apt.d \
+                        check_pgsql.d \
                         check_by_ssh.d \
                         check_smtp.d \
                         check_mysql.d \
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 0c0ef415..84305adb 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -28,6 +28,7 @@
  *
  *****************************************************************************/
 
+#include "states.h"
 const char *progname = "check_pgsql";
 const char *copyright = "1999-2024";
 const char *email = "devel@monitoring-plugins.org";
@@ -35,12 +36,13 @@ const char *email = "devel@monitoring-plugins.org";
 #include "common.h"
 #include "utils.h"
 #include "utils_cmd.h"
+#include "check_pgsql.d/config.h"
+#include "thresholds.h"
 
 #include "netutils.h"
 #include <libpq-fe.h>
 #include <pg_config_manual.h>
 
-#define DEFAULT_DB   "template1"
 #define DEFAULT_HOST "127.0.0.1"
 
 /* return the PSQL server version as a 3-tuple */
@@ -53,33 +55,18 @@ const char *email = "devel@monitoring-plugins.org";
 #define PSQL_SOCKET3(host, port)                                               
                                                            \
        ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, 
PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port
 
-enum {
-       DEFAULT_PORT = 5432,
-       DEFAULT_WARN = 2,
-       DEFAULT_CRIT = 8
-};
+typedef struct {
+       int errorcode;
+       check_pgsql_config config;
+} check_pgsql_config_wrapper;
+static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** 
/*argv*/);
 
-static int process_arguments(int /*argc*/, char ** /*argv*/);
 static void print_help(void);
 static bool is_pg_logname(char * /*username*/);
-static int do_query(PGconn * /*conn*/, char * /*query*/);
+static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char 
/*pgqueryname*/[], thresholds * /*qthresholds*/,
+                                                         char * 
/*query_warning*/, char * /*query_critical*/);
 void print_usage(void);
 
-static char *pghost = NULL; /* host name of the backend server */
-static char *pgport = NULL; /* port of the backend server */
-static char *pgoptions = NULL;
-static char *pgtty = NULL;
-static char dbName[NAMEDATALEN] = DEFAULT_DB;
-static char *pguser = NULL;
-static char *pgpasswd = NULL;
-static char *pgparams = NULL;
-static double twarn = (double)DEFAULT_WARN;
-static double tcrit = (double)DEFAULT_CRIT;
-static char *pgquery = NULL;
-static char *pgqueryname = NULL;
-static char *query_warning = NULL;
-static char *query_critical = NULL;
-static thresholds *qthresholds = NULL;
 static int verbose = 0;
 
 #define OPTID_QUERYNAME -1000
@@ -139,20 +126,16 @@ int main(int argc, char **argv) {
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
 
-       /* begin, by setting the parameters for a backend connection if the
-        * parameters are null, then the system will try to use reasonable
-        * defaults by looking up environment variables or, failing that,
-        * using hardwired constants */
-
-       pgoptions = NULL; /* special options to start up the backend server */
-       pgtty = NULL;     /* debugging tty for the backend server */
-
        /* Parse extra opts if any */
        argv = np_extra_opts(&argc, argv, progname);
 
-       if (process_arguments(argc, argv) == ERROR) {
+       check_pgsql_config_wrapper tmp_config = process_arguments(argc, argv);
+       if (tmp_config.errorcode == ERROR) {
                usage4(_("Could not parse arguments"));
        }
+
+       const check_pgsql_config config = tmp_config.config;
+
        if (verbose > 2) {
                printf("Arguments initialized\n");
        }
@@ -164,31 +147,31 @@ int main(int argc, char **argv) {
        alarm(timeout_interval);
 
        char *conninfo = NULL;
-       if (pgparams) {
-               asprintf(&conninfo, "%s ", pgparams);
+       if (config.pgparams) {
+               asprintf(&conninfo, "%s ", config.pgparams);
        }
 
-       asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", 
dbName);
-       if (pghost) {
-               asprintf(&conninfo, "%s host = '%s'", conninfo, pghost);
+       asprintf(&conninfo, "%sdbname = '%s'", conninfo ? conninfo : "", 
config.dbName);
+       if (config.pghost) {
+               asprintf(&conninfo, "%s host = '%s'", conninfo, config.pghost);
        }
-       if (pgport) {
-               asprintf(&conninfo, "%s port = '%s'", conninfo, pgport);
+       if (config.pgport) {
+               asprintf(&conninfo, "%s port = '%s'", conninfo, config.pgport);
        }
-       if (pgoptions) {
-               asprintf(&conninfo, "%s options = '%s'", conninfo, pgoptions);
+       if (config.pgoptions) {
+               asprintf(&conninfo, "%s options = '%s'", conninfo, 
config.pgoptions);
        }
        /* if (pgtty) -- ignored by PQconnectdb */
-       if (pguser) {
-               asprintf(&conninfo, "%s user = '%s'", conninfo, pguser);
+       if (config.pguser) {
+               asprintf(&conninfo, "%s user = '%s'", conninfo, config.pguser);
        }
 
        if (verbose) { /* do not include password (see right below) in output */
-               printf("Connecting to PostgreSQL using conninfo: %s%s\n", 
conninfo, pgpasswd ? " password = <hidden>" : "");
+               printf("Connecting to PostgreSQL using conninfo: %s%s\n", 
conninfo, config.pgpasswd ? " password = <hidden>" : "");
        }
 
-       if (pgpasswd) {
-               asprintf(&conninfo, "%s password = '%s'", conninfo, pgpasswd);
+       if (config.pgpasswd) {
+               asprintf(&conninfo, "%s password = '%s'", conninfo, 
config.pgpasswd);
        }
 
        /* make a connection to the database */
@@ -203,7 +186,7 @@ int main(int argc, char **argv) {
                end_timeval.tv_usec += 1000000;
        }
        double elapsed_time =
-               (double)(end_timeval.tv_sec - start_timeval.tv_sec) + 
(double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0;
+               (double)(end_timeval.tv_sec - start_timeval.tv_sec) + 
((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0);
 
        if (verbose) {
                printf("Time elapsed: %f\n", elapsed_time);
@@ -214,15 +197,15 @@ int main(int argc, char **argv) {
                printf("Verifying connection\n");
        }
        if (PQstatus(conn) == CONNECTION_BAD) {
-               printf(_("CRITICAL - no connection to '%s' (%s).\n"), dbName, 
PQerrorMessage(conn));
+               printf(_("CRITICAL - no connection to '%s' (%s).\n"), 
config.dbName, PQerrorMessage(conn));
                PQfinish(conn);
                return STATE_CRITICAL;
        }
 
-       int status = STATE_UNKNOWN;
-       if (elapsed_time > tcrit) {
+       mp_state_enum status = STATE_UNKNOWN;
+       if (elapsed_time > config.tcrit) {
                status = STATE_CRITICAL;
-       } else if (elapsed_time > twarn) {
+       } else if (elapsed_time > config.twarn) {
                status = STATE_WARNING;
        } else {
                status = STATE_OK;
@@ -239,23 +222,23 @@ int main(int argc, char **argv) {
                           PQprotocolVersion(conn), PQbackendPID(conn));
        }
 
-       printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), 
dbName, elapsed_time,
-                  fperfdata("time", elapsed_time, "s", !!(twarn > 0.0), twarn, 
!!(tcrit > 0.0), tcrit, true, 0, false, 0));
+       printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), 
config.dbName, elapsed_time,
+                  fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), 
config.twarn, (config.tcrit > 0.0), config.tcrit, true, 0, false, 0));
 
-       int query_status = STATE_UNKNOWN;
-       if (pgquery) {
-               query_status = do_query(conn, pgquery);
+       mp_state_enum query_status = STATE_UNKNOWN;
+       if (config.pgquery) {
+               query_status = do_query(conn, config.pgquery, 
config.pgqueryname, config.qthresholds, config.query_warning, 
config.query_critical);
        }
 
        if (verbose) {
                printf("Closing connection\n");
        }
        PQfinish(conn);
-       return (pgquery && query_status > status) ? query_status : status;
+       return (config.pgquery && query_status > status) ? query_status : 
status;
 }
 
 /* process command-line arguments */
-int process_arguments(int argc, char **argv) {
+check_pgsql_config_wrapper process_arguments(int argc, char **argv) {
        static struct option longopts[] = {{"help", no_argument, 0, 'h'},
                                                                           
{"version", no_argument, 0, 'V'},
                                                                           
{"timeout", required_argument, 0, 't'},
@@ -275,6 +258,11 @@ int process_arguments(int argc, char **argv) {
                                                                           
{"verbose", no_argument, 0, 'v'},
                                                                           {0, 
0, 0, 0}};
 
+       check_pgsql_config_wrapper result = {
+               .errorcode = OK,
+               .config = check_pgsql_config_init(),
+       };
+
        while (true) {
                int option = 0;
                int option_char = getopt_long(argc, argv, 
"hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option);
@@ -303,65 +291,65 @@ int process_arguments(int argc, char **argv) {
                        if (!is_nonnegative(optarg)) {
                                usage2(_("Critical threshold must be a positive 
integer"), optarg);
                        } else {
-                               tcrit = strtod(optarg, NULL);
+                               result.config.tcrit = strtod(optarg, NULL);
                        }
                        break;
                case 'w': /* warning time threshold */
                        if (!is_nonnegative(optarg)) {
                                usage2(_("Warning threshold must be a positive 
integer"), optarg);
                        } else {
-                               twarn = strtod(optarg, NULL);
+                               result.config.twarn = strtod(optarg, NULL);
                        }
                        break;
                case 'C': /* critical query threshold */
-                       query_critical = optarg;
+                       result.config.query_critical = optarg;
                        break;
                case 'W': /* warning query threshold */
-                       query_warning = optarg;
+                       result.config.query_warning = optarg;
                        break;
                case 'H': /* host */
                        if ((*optarg != '/') && (!is_host(optarg))) {
                                usage2(_("Invalid hostname/address"), optarg);
                        } else {
-                               pghost = optarg;
+                               result.config.pghost = optarg;
                        }
                        break;
                case 'P': /* port */
                        if (!is_integer(optarg)) {
                                usage2(_("Port must be a positive integer"), 
optarg);
                        } else {
-                               pgport = optarg;
+                               result.config.pgport = optarg;
                        }
                        break;
                case 'd': /* database name */
                        if (strlen(optarg) >= NAMEDATALEN) {
                                usage2(_("Database name exceeds the maximum 
length"), optarg);
                        }
-                       snprintf(dbName, NAMEDATALEN, "%s", optarg);
+                       snprintf(result.config.dbName, NAMEDATALEN, "%s", 
optarg);
                        break;
                case 'l': /* login name */
                        if (!is_pg_logname(optarg)) {
                                usage2(_("User name is not valid"), optarg);
                        } else {
-                               pguser = optarg;
+                               result.config.pguser = optarg;
                        }
                        break;
                case 'p': /* authentication password */
                case 'a':
-                       pgpasswd = optarg;
+                       result.config.pgpasswd = optarg;
                        break;
                case 'o':
-                       if (pgparams) {
-                               asprintf(&pgparams, "%s %s", pgparams, optarg);
+                       if (result.config.pgparams) {
+                               asprintf(&result.config.pgparams, "%s %s", 
result.config.pgparams, optarg);
                        } else {
-                               asprintf(&pgparams, "%s", optarg);
+                               asprintf(&result.config.pgparams, "%s", optarg);
                        }
                        break;
                case 'q':
-                       pgquery = optarg;
+                       result.config.pgquery = optarg;
                        break;
                case OPTID_QUERYNAME:
-                       pgqueryname = optarg;
+                       result.config.pgqueryname = optarg;
                        break;
                case 'v':
                        verbose++;
@@ -369,9 +357,9 @@ int process_arguments(int argc, char **argv) {
                }
        }
 
-       set_thresholds(&qthresholds, query_warning, query_critical);
+       set_thresholds(&result.config.qthresholds, result.config.query_warning, 
result.config.query_critical);
 
-       return OK;
+       return result;
 }
 
 /**
@@ -416,7 +404,7 @@ bool is_pg_logname(char *username) {
 void print_help(void) {
        char *myport;
 
-       xasprintf(&myport, "%d", DEFAULT_PORT);
+       xasprintf(&myport, "%d", 5432);
 
        print_revision(progname, NP_VERSION);
 
@@ -504,7 +492,8 @@ void print_usage(void) {
                   "[-q <query>] [-C <critical query range>] [-W <warning query 
range>]\n");
 }
 
-int do_query(PGconn *conn, char *query) {
+mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], 
thresholds *qthresholds, char *query_warning,
+                                          char *query_critical) {
        if (verbose) {
                printf("Executing SQL query \"%s\".\n", query);
        }
@@ -548,7 +537,7 @@ int do_query(PGconn *conn, char *query) {
                }
        }
 
-       int my_status = get_status(value, qthresholds);
+       mp_state_enum my_status = get_status(value, qthresholds);
        printf("QUERY %s - ", (my_status == STATE_OK)         ? _("OK")
                                                  : (my_status == 
STATE_WARNING)  ? _("WARNING")
                                                  : (my_status == 
STATE_CRITICAL) ? _("CRITICAL")
diff --git a/plugins/check_pgsql.d/config.h b/plugins/check_pgsql.d/config.h
new file mode 100644
index 00000000..2d4b8b89
--- /dev/null
+++ b/plugins/check_pgsql.d/config.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "../../config.h"
+#include "thresholds.h"
+#include <stddef.h>
+#include <pg_config_manual.h>
+
+#define DEFAULT_DB "template1"
+
+enum {
+       DEFAULT_WARN = 2,
+       DEFAULT_CRIT = 8,
+};
+
+typedef struct {
+       char *pghost;    /* host name of the backend server */
+       char *pgport;    /* port of the backend server */
+       char *pgoptions; /* special options to start up the backend server */
+       char *pgtty;     /* debugging tty for the backend server */
+       char dbName[NAMEDATALEN];
+       char *pguser;
+       char *pgpasswd;
+       char *pgparams;
+       char *pgquery;
+       char *pgqueryname;
+
+       double twarn;
+       double tcrit;
+       thresholds *qthresholds;
+       char *query_warning;
+       char *query_critical;
+} check_pgsql_config;
+
+/* begin, by setting the parameters for a backend connection if the
+ * parameters are null, then the system will try to use reasonable
+ * defaults by looking up environment variables or, failing that,
+ * using hardwired constants
+ * this targets  .pgoptions and .pgtty
+ */
+
+check_pgsql_config check_pgsql_config_init() {
+       check_pgsql_config tmp = {
+               .pghost = NULL,
+               .pgport = NULL,
+               .pgoptions = NULL,
+               .pgtty = NULL,
+               .dbName = DEFAULT_DB,
+               .pguser = NULL,
+               .pgpasswd = NULL,
+               .pgparams = NULL,
+               .pgquery = NULL,
+               .pgqueryname = NULL,
+
+               .twarn = (double)DEFAULT_WARN,
+               .tcrit = (double)DEFAULT_CRIT,
+               .qthresholds = NULL,
+               .query_warning = NULL,
+               .query_critical = NULL,
+       };
+       return tmp;
+}

Reply via email to